Proof read some scripts for me?

Workshop for all Mission Engineer Comrades. Home of the FA Mission Making Template.
Post Reply
User avatar
Eagle_Eye
Posts: 209
Joined: Wed Feb 11, 2015 2:35 am
Location: Cork, Ireland

Proof read some scripts for me?

Post by Eagle_Eye »

Hi all,

I have written 2 scripts for the mission that I am making (hope to try and submit to the database later on today, if this update ever finishes), and I would love some feedback on whether they are correct/necessary/optimal. They work as intended as far as I can tell testing on my machine.

So anyway, in the editor I have a bunch of vehicles for the platoon to destroy. In my init.sqf at the end I have:

Code: Select all

//Check the status of the motor_pool objective for this mission.
veh_destroyed = 0;
motorpool = [veh1,veh2,veh3,veh4,veh5,veh6,veh7,veh8,veh9,veh10,veh11,veh12,veh13,veh14,veh15,veh16,veh17,veh18,veh19,veh20,veh21,veh22,veh23,veh24];
[] execVM "ee_check_veh_destroyed.sqf";

// Check if all the remaining playable units are downed to set the loss condition. 
all_downed = 0;
[] execVM "ee_check_all_downed.sqf";
Now, really what I want to know is when the veh_destroyed reaches 20/24, the mission is considered a success, and that is in a trigger in the editor. Same with all_downed, a trigger checks if it changes to 1, set the loss of the mission. So the two scripts that I have running are as follows:

ee_check_veh_destroyed.sqf:

Code: Select all

if !(isServer) exitWith {};

while {count motorpool > 0} do
{
{
	if !(alive _x) then
	{
		veh_destroyed = veh_destroyed+1;
		motorpool = motorpool - [_x];
	}
} foreach motorpool;
sleep 5;
};
and ee_check_all_downed.sqf:

Code: Select all

if !(isServer) exitWith {};

while {count playableUnits > 0} do
{
_units = f_var_men_BLU;
{
if !(isPlayer _x) then
	{
		_units = _units - [_x];
	}
} foreach _units;

_unitcount = count _units;
_downedcount = 0;
{
  if(_x getVariable ["f_wound_down",false]) then
  {
	_downedcount = (_downedcount + 1);
  }
  else {};
} foreach _units;

if (_downedcount == _unitcount ) then { all_downed = 1;} else{};
sleep 3;
};
My main concerns are:
  • 1)Am I using isServer right here? (It should only run on the server right?)
    2)Am I checking too often, could it affect performance?
    3)Is there a better alternative I am missing?
Im not a total noob at programming, but I am a scientist not a programmer, so my knowledge of big software systems is limited. If anyone could give me confirmation that I am on the right track, that would be great, or point out where I am going wrong.

Thanks!
Eagle_Eye


Bonus Script:
I also wrote a little script called manOP, which can be used to place units from the editor into the 3 main positions of the Observation Posts (the green one with the stairs). It basically goes as manOP[_unit,_post,_position] in the init field, and then places the unit either in the front left/right position looking out of the post, or in the back of the post at the top of the stairs looking behind.

Code: Select all

// Call manOP in a units init box to place them in an OP, either facing forward through the portholes, or at the top of the stairs.
// Function takes 2 required inputs, the unit and the  OP which are named in the editor.
_man = _this select 0;
_post = _this select 1;
//check for optional position input, if none there then select "left". 
//If a string other than "left","right" or "back" is supplied, then the unit is moved away from the OP
_position = "";
if (count _this > 2) then
{
_position = _this select 2;
}
else
{
_position = "left";
};

_vecx = 0;
_vecy = 0;
//choose the required vector to move the unit. Values determined by brute force and ignorance in the editor. 
if (_position == "left") then
{
_vecx = -1.7;
_vecy = -0.13;
}
else 
{
	if (_position == "right") then
	{
	_vecx = 1.7;
	_vecy = -0.13;
	}
	else
	{
		if (_position == "back") then
		{
		_vecx = 2.6;
		_vecy = 2.6;
		}
		else{_vecx = 10;
		_vecy = 10;};
	};
};
//get the facing of the post (-90 to convert azimuth to a cartesian angle)
_angle = (getdir _post) - 90;
//rotate the x and y vectors
_ypos = _vecx * sin(_angle) + _vecy * cos(_angle);
_xpos = _vecx * cos(_angle) - _vecy * sin(_angle);
//move the unit to the right position
_man setpos ([_ypos,_xpos,3.5] vectoradd getpos _post);

User avatar
wolfenswan
Posts: 1209
Joined: Wed May 25, 2011 4:59 pm

Re: Proof read some scripts for me?

Post by wolfenswan »

ee_check_veh_destroyed.sqf
I think what you're doing is identical to:

Code: Select all

veh_destroyed = {!alive _x} count motorpool
You could put this in the condition field of a trigger as well:

Code: Select all

{!alive _x} count motorpool > 1
ee_check_all_downed.sqf:
Looks good but isn't really necessary unless vital for your mission. Hosts can easily call the mission should the situation occur.
1)Am I using isServer right here? (It should only run on the server right?)
Unfortunately it depends a lot, depending on the effects of the commands and where you need your variables to be known. In general you want everything with global effect only run on the server and local effects either everywhere or only on the server and then broadcast the effects.
2)Am I checking too often, could it affect performance?
A normal while loop will check it's conditions every frames, which is usually unnecessary. Add a short sleep (sleep 0.1 is usually fine) to help with this. There's an article about code optimization on the BIKI.

In general, a simple loop is not going to kill the server. When testing locally your FPS should not dip below 25 (given open terrain), when testing on the dedicated server you should always have very high FPS on an adequate system, as all the AI is handled by the server. It's really locality errors that's going to have a noticeable effect when you end up doing something times the connected clients.
3)Is there a better alternative I am missing?
Alternative to what? :)
For the population of the motorpool array you might want to look at ws_fnc_collectObjectsNum to save you some "manual labor".
I also wrote a little script called manOP
Looks good, but are the positions taken any different to the ones that ws_fnc_createGarrison or ws_fnc_taskDefend would occupy? I assume only the facings differ?

User avatar
Eagle_Eye
Posts: 209
Joined: Wed Feb 11, 2015 2:35 am
Location: Cork, Ireland

Re: Proof read some scripts for me?

Post by Eagle_Eye »

Thanks for having a look Wolf,

You're dead right about the

Code: Select all

veh_destroyed = {!alive _x} count motorpool
That's just me not thinking about the built in functions that the scripting language has, and is exactly the alternative I was looking for. I have a nasty habit of liking to do all the manual labor because then I know in my head how everything is working.

I know the host can decide to end the mission when it seems appropriate, but I like the idea that you shouldn't need to, and it should be possible to leave the mission to run out of its own accord.

I have not read the garrison function, only briefly to see how to call it. In this case my script was written because I wanted to set guards in an observation post that I had manually placed in the editor using an addon. When its placed you cant see the positions in the editor to tell ai to occupy them, so I decided to write the script just because is was pretty much the only buildings I had placed (for some simple roadblocks). Does ws_fnc_createGarrison recognise manually placed buildings? And if so will it set the ai facing the right way? That was another thing I wanted out of my script.

User avatar
wolfenswan
Posts: 1209
Joined: Wed May 25, 2011 4:59 pm

Re: Proof read some scripts for me?

Post by wolfenswan »

Does ws_fnc_createGarrison recognise manually placed buildings? And if so will it set the ai facing the right way?
Recognize yes but facing will be random as I've never got around writing proper code for that as it would require some nastily expensive stuff using lineIntersects. You could try placing units with createGarrison, then loop through the array of units created by it and set the facing for all those which have the guard tower as nearest building. Just an idea though, might not be feasible.

Post Reply