Jump to content
Sign in to follow this  
zephyrdark

Scoreboard Script - Issues with call compile

Recommended Posts

Working on a script that allows mission makers to easily set up a point based score system that judges player's performance based on players left alive and if side objectives were completed. It currently uses CBA functions for sake of ease.

So far everything appears to work, but when it reaches the final global execute, it doesn't want to do anything. Through attempts of debugging, I also found that the variable bScore becomes useless once I define it via the call on the compiled string. I've attempted to use typeName to determine if its still a valid variable, but nothing has arisen from that.

In the Case of:


nul = [ [0,0,0,70],[ [sec1,10],[sec2,10],[sec3,10] ] ]execVM "scoreCard.sqf";
[/Code]

the copyToClipboard returns:

[Code]
{
_bsArray = [];
tScore = 0;
if (false) then {_bonusScore0 = 10;} else {_bonusScore0 = 0};
_bsArray = _bsArray + [_bonusScore0];
if (false) then {_bonusScore1 = 10;} else {_bonusScore1 = 0};
_bsArray = _bsArray + [_bonusScore1];
if (false) then {_bonusScore2 = 10;} else {_bonusScore2 = 0};
_bsArray = _bsArray + [_bonusScore2];
{tScore = tScore + _x} forEach _bsArray;
tScore
}
[/Code]

Here is the entire code.

[Code]
//ScoreCard.sqf




private ["_numPlayers","_numAlive","_listNum","_newString","_bonusScoreString","_Q1","_Q2","_Q3","_Q4","_compiled"];


_Q1= _this select 0 select 0;
_Q2= _this select 0 select 1;
_Q3= _this select 0 select 2;
_Q4= _this select 0 select 3;
tScore = 0;


_listNum = -1;
_bonusScoreString = "#";


{
_listNum = _listNum + 1;
_newString = format ["if (%1) then {_bonusScore%2 = %3;} else {_bonusScore%2 = 0}; _bsArray = _bsArray + [_bonusScore%2]; #", _x select 0, _listNum, _x select 1];
_bonusScoreString = [_bonusScoreString, "#", _newString] call CBA_fnc_replace;
sleep .1;
} forEach (_this select 1);


_bonusScoreString = ["_bsArray = []; tScore = 0; # {tScore = tScore + _x} forEach _bsArray; tScore", "#", _bonusScoreString ] call CBA_fnc_replace;
_bonusScoreString = [_bonusScoreString, "#", ""] call CBA_fnc_replace;
//copyToClipboard _bonusScoreString;
_compiled = compile _bonusScoreString;
copyToClipboard format ["%1",_compiled];
bScore = call _compiled;
hint typeName bScore;
//hintC _bonusScoreString;
//sleep 1;


_numPlayers = 0;
_numAlive = 0;




{
if (isPlayer _x) then
{
_numPlayers = _numPlayers + 1;
};

} forEach allUnits;




{
if (isPlayer _x && alive _x) then
{
_numAlive = _numAlive + 1;
};

} forEach allUnits;












switch (true) do
{
case ( (_numAlive / _numPlayers) <= 0.25 ):
{
baseScore = _Q1;
};
case ( ((_numAlive / _numPlayers) > 0.25) && ((_numAlive / _numPlayers) <= 0.50) ):
{
baseScore = _Q2;
};
case ( ((_numAlive / _numPlayers) > 0.50) && ((_numAlive / _numPlayers) <= 0.75) ):
{
baseScore = _Q3;
};
case ( ((_numAlive / _numPlayers) > 0.75) && ((_numAlive / _numPlayers) <= 1) ):
{
baseScore = _Q4
};
};


//hint "resolving final score...";
sleep 1;


finalScore = baseScore + bScore;
hint str(finalScore);
[
-2,
{
player globalChat "Mission Complete!";
sleep 2;
player globalChat format ["Your Score: %1", _this];
sleep 4;
endMission "END1";
}, finalScore
] call CBA_fnc_globalExecute;
[/Code]

Share this post


Link to post
Share on other sites

Trying to create dynamic code seems like a nice idea!

Although I think you went for something by far over-complicated.

Stuff like

{
   if (isPlayer _x && alive _x) then
   {
       _numAlive = _numAlive + 1;
   };

} forEach allUnits;

is basically what the count command will do.

Also remember that forEach has a _forEachIndex variable defined, so you shouldn't have to use additions to count stuff.

As to the efficiency of your script, could you comment it a bit, so at least we know what each variable contains (or is supposed to contain)? I'm a bit lost, but my overall feeling is that all the time and commands you need to create dynamic code, could be used with simple if checks and variable changes.

Share this post


Link to post
Share on other sites

Thanks BlackMamb, I'll have a look through my script and see if I can make some simplifications and comment up a bit of the variables. I keep forgetting that the count command has a condition argument to it.

---------- Post added at 09:08 AM ---------- Previous post was at 08:35 AM ----------

I appear to have solved it.


//ScoreCard.sqf




private ["_numPlayers","_numAlive","_newString","_bonusScoreString","_Q1","_Q2","_Q3","_Q4","_compiled","_aliveRatio"];


_Q1= _this select 0 select 0; //Quartile 1 (0-25% Alive Score)
_Q2= _this select 0 select 1; //Quartile 2 (25-50% Alive Score)
_Q3= _this select 0 select 2; //Quartile 3 (50-75% Alive Score)
_Q4= _this select 0 select 3; //Quartile 4 (75-100% Alive Score)
MEC_BP = false; //Mission End Condition Variable. Once true, allows script to finish.
_bonusScoreString = "#"; //Base To-Be Compiled String. "#" will be replaced with _newString formatted text via CBA.
//_bonusScoreString will result in creating a dynamic function that should return with variable tScore.
_numPlayers = 0;
_numAlive = 0;


_numPlayers = {isPlayer _x} count allUnits;
MEC_BP = true; //Debug. Allows for calling of script via trigger for testing purposes.
waitUntil {MEC_BP};


_numAlive = {isPlayer _x && alive _x} count allUnits;
_aliveRatio = _numAlive/_numPlayers; // Ratio of players alive at end of mission over the total players.


switch (true) do
{
case ( (_aliveRatio) <= 0.25 ): //Quartile 1
{
baseScore = _Q1;
};
case ( (_aliveRatio > 0.25) && (_aliveRatio <= 0.50) ): //Quartile 2
{
baseScore = _Q2;
};
case ( (_aliveRatio > 0.50) && (_aliveRatio<= 0.75) ): //Quartile 3
{
baseScore = _Q3;
};
case ( (_aliveRatio > 0.75) && (_aliveRatio <= 1) ): //Quartile 4
{
baseScore = _Q4
};
};


//hint "resolving final score...";
sleep 1;


{
_newString = format ["if (%1) then {_tScore= _tScore + %2};
#", _x select 0, _x select 1];
_bonusScoreString = [_bonusScoreString, "#", _newString] call CBA_fnc_replace;
sleep .1;
} forEach (_this select 1); //Loops through second script argument which is an array of arrays. (i.e., [[sec1,10][sec2,10]) where Element 1 is boolean variable and element 2 is a number.


_bonusScoreString = ["_tScore = 0;
#
[-2, {hint str(_tScore)}] call CBA_fnc_globalExecute;
_tScore", "#", _bonusScoreString ] call CBA_fnc_replace;
_bonusScoreString = [_bonusScoreString, "#", ""] call CBA_fnc_replace;
//copyToClipboard _bonusScoreString;






_compiled = compile _bonusScoreString; //Compiles Above string producing Bonus Score function dependent on arguments of the string.
copyToClipboard format ["%1",_compiled];
bScore = call _compiled;
finalScore = baseScore + bScore; // Final Score = Base Score + Bonus Score


[
-2, //Execute on Clients & Server
{
player globalChat "Mission Complete!";
sleep 2;
player globalChat format ["Your Score: %1", _this];
sleep 4;
endMission "END1";
}, finalScore
] call CBA_fnc_globalExecute;
hint "End of Script
Test";

[/Code]

I moved around the compiled code to the bottom of the script to ensure it is run only at the end of the mission. I also changed the behaviour of the script-string, it no longer creates an array in which it adds up, but just adds onto the value, _tScore, if the conditions are met. I also added in a waitUntil{} to hold off the script to ensure it is accurate, making it required to run at mission start. Thanks for the help BlackMamb! I will probably be releasing this with my script pack later on with a little bit more refined version of this script in it.

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  

×