Jump to content
Sign in to follow this  
Nebulazer

What am I doing wrong wtth this XP/Level script?

Recommended Posts

I thought this would be a pretty simple thing to do to update the variable, i just learned how to do a money variable that updates on my UI that you can find here http://forums.bistudio.com/showthread.php?190980-Need-help-with-my-GUI-for-displaying-level-and-money

here is a picture of how i have it looking now, all I cant get the 1 on the level to change. http://cloud-4.steamusercontent.com/ugc/45376357726208726/6F30F700C484378D2E0414557A8E251665BCB660/

So I am trying to make a script where as you get more p_exp your level will go up. I am not sure if this script is just comletely wrong or if it just not updating with the GUI.

if (isPlayer) then {

_xp = (p_exp * 2) 

//Level 1 
if (_xp > 0) then {
       level = 1;

};

//level 2
if (_xp > 1500) then {
	level = 2;

};

//level 3
if (_xp > 3000) then {
	level = 3;

};

//level 4
if (_xp > 6000) then {
	level = 4;

};

//level 5
if (_xp > 12000) then {
	level = 5;

};

//level 6
if (_xp > 24000) then {
	level = 6;

};


};

Testing it with this script in the debug console

		p_exp=p_exp+1500;
	hint "XP +1500";

(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];

Share this post


Link to post
Share on other sites

I have been still trying to figure this out after a few days. I have been experimenting with some scripts but have no results yet :( Here is another one I have tried. Am I on the right track at least? is there something I am missing so that it will skip the first line and read the next one or does that not matter?

if (isPlayer) then {

//_xp = (p_exp * 2) 

//Level 1 
if (p_exp => 0) then {
       p_level = 1;
	   (uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];



//level 2
if (p_exp => 1500) then {
	p_level = 2;
	(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];



//level 3
if (p_exp => 3000) then {
	p_level = 3;
	(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];



//level 4
if (p_exp => 6000) then {
	p_level = 4;
	(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];



//level 5
if (p_exp => 12000) then {
	p_level = 5;
	(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];



//level 6
if (p_exp => 24000) then {
	p_level = 6;
	(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];


						};
					};
				};
			};
		}:
	};
};

I am giving my self xp in game with this script

		p_exp=p_exp+1500;
	hint "XP +1500";

execVM "Levels.sqf";

Share this post


Link to post
Share on other sites

if isPlayer then {

That's an odd structure. AFAIK that should give you an error message, even, as it's faulty syntax. I hope you run the game with -showscripterrors?

Try

if (isPlayer player) then {

But it's kind of a redundant check, because the player (almost) always will be a player ;) .

Once again, debugging is key. Spam your script with systemchats and print variables at different steps to see where it starts to go off the rails.

You should check the basic debugging howto by Terox : http://forums.bistudio.com/showthread.php?176096-Zeu-Debugging-Tutorial-amp-Foundation-Template

No need for his templates, just the basic tips. In addition, once you get the script error messages, look them up on the wiki. It gives pretty good info on how to properly use all those commands: https://community.bistudio.com/wiki/isPlayer

Share this post


Link to post
Share on other sites

If this is all you're putting in the debug console:

p_exp=p_exp+1500;
hint "XP +1500";

(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1",level];

Then you need to actually run the script again before you will see any changes.

I'll go ahead and suggest you post everything you've done, rather than pieces (which are completely useless if you don't post the right ones)

Share this post


Link to post
Share on other sites

Thank you for the pointers senshi, I was not aware of that -showscripterror command. Dreaded, that is pretty much all I have for the script, so I am going to take that as I cant just manipulate the variables to make a level script? Do I need some type of event handler?

Share this post


Link to post
Share on other sites

I've simplified your "Levels.sqf", it should be shorter and run faster:

switch (true) do
{
case (p_exp >= 24000):
{
	p_level = 6;
};
case (p_exp >= 12000):
{
	p_level = 5;
};
case (p_exp >= 6000):
{
	p_level = 4;
};
case (p_exp >= 3000):
{
	p_level = 3
};
case (p_exp >= 1500):
{
	p_level = 2;
};
case (p_exp >= 0):
{
	p_level = 1;
};
};
(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1", p_level];

The only other thing you need to know now is that every time you give a player exp, they need to run the script again and recalculate their level

EDIT: Also that there is no "=>" operand

Edited by DreadedEntity

Share this post


Link to post
Share on other sites

I could kiss you! haha. Thank you so much for explaining how an "or" statement works to me. I was trying to wrap my head around that for some time. This works like a charm in game and now i should be able to save my p_exp and cash variables using iniDB to save my players data on a dedicated server. This should be scale-able up to whatever level i want to make it to correct? Is there any limitations due to performance or is it a light enough script that it should work no matter how high of a level i make it?

I am using this to give players XP and Money when they kill things, and it works for me but im not sure if it works for other players.

//Get Cash and xp when you kill
if (!isDedicated)then{
_unit=(_this select 0);

_unit addEventHandler ["killed", {
_unit=        (_this select 0); 
_killer=    (_this select 1); 


if (isPlayer _killer)then{ 

	p_exp=p_exp+100;
       cash=cash+100;
	execVM "Levels.sqf";
       hint "$+100 and +100XP";

(uiNameSpace getVariable "myUI_DollarTitle") ctrlSetText format ["Money: $%1",cash];

_unit removeAllEventHandlers "killed"; 
           };
       }];
   };  

Is there a way I can execute that on all AI without putting this line of code in all of their Init's?

null =[this]execVM "cashOnKill.sqf" call BIS_fnc_MP;

EDIT: Also I got it the UI to show at least level 10 so far, I want to make it go to level 100, maybe beyond eventually.

switch (true) do
{
   case (p_exp >= 19600):
   {
       p_level = 10;
   };
case (p_exp >= 11200):
   {
       p_level = 9;
   };
case (p_exp >= 6400):
   {
       p_level = 8;
   };
case (p_exp >= 3600):
   {
       p_level = 7;
   };
case (p_exp >= 1200):
   {
       p_level = 6;
   };
   case (p_exp >= 2100):
   {
       p_level = 5;
   };
   case (p_exp >= 1200):
   {
       p_level = 4;
   };
   case (p_exp >= 700):
   {
       p_level = 3
   };
   case (p_exp >= 400):
   {
       p_level = 2;
   };
   case (p_exp >= 0):
   {
       p_level = 1;
   };
};
(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1", p_level];  

Edited by Nebulazer

Share this post


Link to post
Share on other sites

EDIT: Also I got it the UI to show at least level 10 so far, I want to make it go to level 100, maybe beyond eventually.

switch (true) do
{
   case (p_exp >= 19600):
   {
       p_level = 10;
   };
case (p_exp >= 11200):
   {
       p_level = 9;
   };
case (p_exp >= 6400):
   {
       p_level = 8;
   };
case (p_exp >= 3600):
   {
       p_level = 7;
   };
case (p_exp >= 1200):
   {
       p_level = 6;
   };
   case (p_exp >= 2100):
   {
       p_level = 5;
   };
   case (p_exp >= 1200):
   {
       p_level = 4;
   };
   case (p_exp >= 700):
   {
       p_level = 3
   };
   case (p_exp >= 400):
   {
       p_level = 2;
   };
   case (p_exp >= 0):
   {
       p_level = 1;
   };
};
(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1", p_level];  

That should be possible. simply keep adding cases to the switch

---------- Post added at 00:36 ---------- Previous post was at 00:31 ----------

I am using this to give players XP and Money when they kill things, and it works for me but im not sure if it works for other players.

//Get Cash and xp when you kill
if (!isDedicated)then{
_unit=(_this select 0);

_unit addEventHandler ["killed", {
_unit=        (_this select 0); 
_killer=    (_this select 1); 


if (isPlayer _killer)then{ 

      null =[this]execVM "cashOnKillKiller.sqf" call BIS_fnc_MP;

    };

_unit removeAllEventHandlers "killed"; 
       }];
   };  

Is there a way I can execute that on all AI without putting this line of code in all of their Init's?

null =[this]execVM "cashOnKill.sqf" call BIS_fnc_MP;

simply add the killed eventhandler to all units on creation, it will then fire on the client where the AI was killed (so it fires on server if it owns that AI, you'll need to make a script and use bis_fnc_mp to send info to killer to give them xp for the kill since all players run their own copy of scripts completely seperate of others).

/Get Cash and xp when you kill
if (!isDedicated)then{
_unit=(_this select 0);

_unit addEventHandler ["killed", {
_unit=        (_this select 0); 
_killer=    (_this select 1); 


if (isPlayer _killer)then{ 

      null =[_unit,],"cashonKillerFunction",_killer,false,true] call BIS_fnc_MP; //send to killer only

    };

_unit removeAllEventHandlers "killed"; 
       }];
   };

a seperate function possibly created in init.sqf

cashonKillerFunction =
{
     p_exp=p_exp+100;
       cash=cash+100;
       execVM "Levels.sqf";
       hint "$+100 and +100XP";

(uiNameSpace getVariable "myUI_DollarTitle") ctrlSetText format ["Money: $%1",cash];
};

Edited by austin_medic

Share this post


Link to post
Share on other sites

hmm, are you saying I have to put it in the init of each playable unit instead? or just execVM from the init in the mission file?

Share this post


Link to post
Share on other sites

Honestly, if you want to make this infinitely scale-able, you could just keep adding cases, but a much better option is to use a mathematical function to calculate levels. Say the function you're using is y = 2x^3, where x represents a level and y represents the amount of exp needed to reach that level. Your function would probably look something like this:

calcLevel =
{
_level = _this; //function should always take "p_level" as an argument. ex. _currentLevel = (p_level) call calcLevel;

while (p_exp >= 2(_level^3)) do
{
	_level = _level + 1; //test level starting from input level and going until the correct level is found
};

p_level = _level;
_level; //set the global level identifier and return the value
};

Using this function, you're entire levels.sqf can be reduced to:

(uiNameSpace getVariable "myUI_LevelTitle") ctrlSetText format ["Level: %1", (p_level) call calcLevel];

At this point, I would question the use of a separate script to hold it, and just put it in a function instead

Share this post


Link to post
Share on other sites

So, I cant get either of those examples to work, i guess i dont quite understand how functions work? I tried putting the function in the init right below my variables, but when I ran it in game it just stopped the UI from showing up for both the money and the level UI. If you want to see the whole mission and maybe you will see another problem I have in their that is stopping it from working or something I have it on a github https://github.com/Nebulazer/CWCKunduz

Share this post


Link to post
Share on other sites
hmm, are you saying I have to put it in the init of each playable unit instead? or just execVM from the init in the mission file?

no no no. simply stick my function inside init.sqf or use dreaded entities example. these functions simply are put into memory when they get executed then can be called again simply by using the name with call or spawn

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×