Jump to content
swift39

Scripting a Group of Protesting Civilians

Recommended Posts

2 hours ago, swift39 said:

Thank You...

I am away with work for a couple days so will switch it over when I get home. When you say it should work fine in SP is that a typo or do I need to script different for MP?

Anyway thank you again everyone, I am enjoying the learning process and will post my results when I get home mid week.

 

Cheers

Greg

Quite a few things actually.

Just saw that you mentioned MP in the middle of this thread, always good practice to put as much info in the first post as possible.

 

You need to take command locality into account, some commands will only affect the client they're executed on.

Taking switchMove/playMove as an example you can get different animations on different clients, so it's best to randomize the animation on the server, then use remoteExec to broadcast the unit and animation to all clients, so every player sees the same unit doing the same animation, same goes for sound and say/say3D.

 

Cheers

Share this post


Link to post
Share on other sites

So finally having sometime to get back on this little excursion, I have spent the morning sorting everything out that has been provided to date. 

 

I decided I would create a script using AZCoder's script and with a "few suggestions" from GOM mainly to understand the principles of functions and the process of there is always more than one way to achieve the same results when it comes to coding. I also figured having a script in the tool box that provided animation loops then when triggered the AI carry on there merry way could never hurt.

 

so with AZCoder's animation script I came up with this:

 

AI Init

this setVariable ["TWR_fnc_ProtesterAnim",true,true];

 

the Init.sqf

//inits the civilian protesters sqf
_init = [] execVM "scripts\TWR\TWR_fnc_protestanim.sqf";//this initializes all functions within the .sqf file
waitUntil {scriptDone _init};
_initProtesters = [] spawn TWR_fnc_ProtesterInit;

_flee = player addEventHandler ["FiredNear", {

	player remoteExec [[] spawn TWR_fnc_ProtesterRelease];
	player removeEventHandler ["FiredNear", _thisEventHandler];

}];

As I am sure, most have figured out the remoteExec is not in the right place or written wrong, because I am getting a scripting error. I am still sorting this out becuase I really dont know the "proper" approach. To me this makes sense to have the remoteExec command fire in the init.sqf, to ensure all players receive it on their respective systems. I am still reading up on this and will welcome a sure fire way to make this command work properly or an explanation on how this works.

 

The .sqf

TWR_fnc_ProtesterInit = 
{
	_Protesters = allUnits select {_x getVariable ["TWR_fnc_ProtesterAnim", false]};
//Random Animations for loop
	#define __RandomAnimation (["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom);
//grab all usable civilian classes, needed to randomize loadout in the forEach loop
	_rndCivClasses = ("getNumber (_x >> 'side') isEqualTo 3 AND configName _x isKindOf 'Man' AND getNumber (_x >> 'scope') >= 2" configClasses (configFile >> "CfgVehicles")) apply {configName _x};

	{
	_dir = getDir _x;
	
	//get and set random loadout
		_rndLoadout = getUnitLoadout selectRandom _rndCivClasses;
		_x setUnitLoadout _rndLoadout;
		_x switchMove "";//to skip weapon holster animation after weapon removal
		_x doWatch (_x getRelPos [50,_dir]);//reset watch direction after group change
	
	// AI prevented to move or change behavior.
		_x disableAI "ALL";
		_x stop true;
		_x setBehaviour "CARELESS";

	//Disable Animation and Set AI direction to South.
		sleep 0.1;
		_dirToFace = [_x, player] call BIS_fnc_dirTo;
		_x disableAI "ANIM";
		_x setFormDir _dirToFace;
		_x setDir _dirToFace;

	//AI animation is selected randomly and started
		_x switchMove __RandomAnimation;

	//AI animation is looped and randomly changed
		_animLoop = _x addEventHandler ["AnimDone", 
		{
			_x = _this select 0;
			_x switchMove __RandomAnimation;
		}];
		_x setVariable [ "animLoop", _animLoop, true ];

	//Protest Chant
	
		//playSound ["fx_protest1", 30] remoteExec ["say3D", 0];

	}forEach _Protesters;
};


TWR_fnc_ProtesterRelease = 
{
	_Protesters = allUnits select {_x getVariable ["TWR_fnc_ProtesterAnim", false]};
	{
//Stop animation
	_animLoop = _x getVariable "animLoop";
	_x removeEventHandler ["AnimDone",_animLoop];
		
//Release AI from current state
	_x enableAI "ALL";
	_x stop false;
	_x switchMove "";
	}forEach _Protesters;
}; 
true;

The first function seems to work well with no noted issues yet. The second function (Release Function) not so much, well it seems to release the AI it appears they go back to the animation loop after a few seconds. I am thinking it is in the Stop Animation lines, but having some difficulty figuring out how to ensure this will indeed stop the loop because the variable is in the first function.

//Stop animation
	_animLoop = _x getVariable "animLoop";
	_x removeEventHandler ["AnimDone",_animLoop];

 

 

Grumpy Old Mans Script

 

AI Init

this setVariable ["GOM_fnc_potentialArmedProtester",true,true];

 

Init.sqf

_attack = player addEventHandler ["FiredNear", {

	player remoteExec [[10] spawn GOM_fnc_armedProtestersAttack];//starts the attack with amount of attackers as param, defaults to 5 if no number is given
	player removeEventHandler ["FiredNear", _thisEventHandler];

}];

without the remoteExec portion this works well thank you GOM. Otherwise it is the same as above with regards to scripting error.

 

GOM's .sqf

Spoiler

GOM_fnc_armedProtestersInit = {

	_potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]};

	//grab all usable civilian classes, needed to randomize loadout in the forEach loop
	_rndCivClasses = ("getNumber (_x >> 'side') isEqualTo 3 AND configName _x isKindOf 'Man' AND getNumber (_x >> 'scope') >= 2" configClasses (configFile >> "CfgVehicles")) apply {configName _x};

	{

		//get direction of unit
		_dir = getDir _x;

		//join civilian group
		_oldGroup = group _x;
		_newGroup = createGroup civilian;
		[_x] joinSilent _newGroup;
		deleteGroup _oldGroup;//keep things tidy
		_x setBehaviour "SAFE";

		//get and set random loadout
		_rndLoadout = getUnitLoadout selectRandom _rndCivClasses;
		_x setUnitLoadout _rndLoadout;
		_x switchMove "";//to skip weapon holster animation after weapon removal
		_x doWatch (_x getRelPos [50,_dir]);//reset watch direction after group change

		//dumb them down to stay put and allow random animations to be played
		_x disableAI "ALL";

		//handle animation looping
		_anim = _x spawn {

			sleep random 5;

			while {alive _this AND behaviour _this == "SAFE"} do {

				_rndAnimation = selectRandom ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"];

				if (alive _this) then {_this switchMove _rndAnimation;};
				waitUntil {sleep 1;animationState _this != _rndAnimation OR behaviour _this != "SAFE" OR !alive _this};
				if (!alive _this) exitWith {false};

			}
		};

	} forEach _potentialProtesters;
	//done, always return boolean
	true
};


//improved BIS function by pedeathtrian
NEW_fnc_arrayShuffle = {
	_this = []+_this;

	private _cnt = count _this;

	for "_i" from 1 to _cnt do
	{
		_this pushBack (_this deleteAt floor random (_cnt + 1 - _i));
	};
	_this
};


GOM_fnc_armedProtestersAttack = {

	params [["_amount",5]];

	_potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]};

	_armedProtesters = _potentialProtesters call NEW_fnc_arrayShuffle;
	_armedProtesters resize _amount;

	_potentialProtesters = _potentialProtesters - _armedProtesters;

	_pistols = "getnumber (_x >> 'type') isEqualTo 2 AND getnumber (_x >> 'scope') isEqualTo 2" configClasses (configfile >> 'CfgWeapons') apply {configName _x};

	_potentialProtesters apply {

		_x enableAI "ALL";
		_x setBehaviour "AWARE";
		_x switchMove "";

	};

	_armedProtesters apply {

		_x setVariable ["GOM_fnc_armedProtester",true,true];
		_x enableAI "ALL";
		_x setBehaviour "AWARE";
		_x switchMove "";

		//arm them
		[_x,selectRandom _pistols,4] call BIS_fnc_addWeapon;

		[_x] joinSilent createGroup east;
		//help AI to detect hostiles after group switch
		_unit = _x;
		{_unit reveal [_x,4]} forEach (_unit nearEntities ["CAManBase",150]);

		//reveal the hostile protester to nearby AI
		{_x reveal [_unit,4]} forEach (_unit nearEntities ["CAManBase",150]);

	};

	true;

};

true;

 

No changes and works flawlessly. Thank you again.

 

 

So that is were this at and welcome any suggestions, comments or guidance...

 

Cheers

Greg

Share this post


Link to post
Share on other sites

Ok so I believe I am making some progress.

 

First thank you to XianGrim....

On ‎2018‎-‎04‎-‎05 at 7:48 PM, XianGrim said:

If you want, for the sound to stop, you could place an invisible helipad down in the center of the protesters, call it "ProtesterVoice" or some such. Then play the sound from there with the code I mentioned but use the voice instead so it would be:


[ProtesterVoice,["fx_protest1",50,1]] remoteExec ["say3D",0];

Then in your EH, you could simply delete it with deleteVehicle. Though you'd have to come up with a createVehicle solution to spawn the voice again if you wanted it to be reuseable.

Just a thought!

 

The Helipad linked to the Protester script works great, then adding a sleep and delete vehicle gives the scene a little realism, well I think anyway.... I will post the script later.

 

I think I am slowly understanding the remoteExec application, but am having some difficulty with errors...

 

GOM's script init

//inits the protesters sqf
_init = [] execVM "scripts\GOM\GOM_fnc_armedProtesters.sqf";	//this initializes all functions within the .sqf file
waitUntil {scriptDone _init};
_initProtesters = [] spawn GOM_fnc_armedProtestersInit;

_attack = player addEventHandler ["FiredNear", {

	[10] spawn GOM_fnc_armedProtestersAttack;	//starts the attack with amount of attackers as param, defaults to 5 if no number is given
	player removeEventHandler ["FiredNear", _thisEventHandler];

}] remoteExec ["call", 0];

My script init (AKA AZCoder's work) 

//inits the civilian protesters sqf
_init = [] execVM "scripts\TWR\TWR_fnc_protestanim.sqf";	//this initializes all functions within the .sqf file
waitUntil {scriptDone _init};
_initProtesters = [] spawn TWR_fnc_ProtesterInit;

_flee = player addEventHandler ["FiredNear", {

	[] spawn TWR_fnc_ProtesterRelease;
	player removeEventHandler ["FiredNear", _thisEventHandler];

}]remoteExec ["call", 0];

While the script seems to run and for the most part work, although in my script it seems to work intermittently. I get this error

 

'[#]call (_this)'
Error _call: Type Number, expected code

My understanding is  when 0, the function or command will be executed globally. Confusing...

 

Like I stated yesterday the purpose of the two scripts is just me learning, but also I am thinking having Mine/AZCoder script to have civilians protest (the Bulk of them) then when firedNear they do what civilians do and then Have GOM's script (a realistic amount) provide the armed civilians to continue the Riot.

 

Anyway thanks for the interest and will continue to sort this out. Suggestions, Comments or feedback always welcome

 

Cheers

Greg

 

*****UPDATE******

 

Ok I am feeling a little stupid right now and assuming this is right, because it removed the scripting errors, but this worked:

//inits the protesters sqf
_init = [] execVM "scripts\GOM\GOM_fnc_armedProtesters.sqf";	//this initializes all functions within the .sqf file
waitUntil {scriptDone _init};
_initProtesters = [] spawn GOM_fnc_armedProtestersInit;

_attack = player addEventHandler ["FiredNear", {

	[10] spawn GOM_fnc_armedProtestersAttack;	//starts the attack with amount of attackers as param, defaults to 5 if no number is given
	player removeEventHandler ["FiredNear", _thisEventHandler];

}] remoteExec ["_attack", 0];

//inits the civilian protesters sqf
_init = [] execVM "scripts\TWR\TWR_fnc_protestanim.sqf";	//this initializes all functions within the .sqf file
waitUntil {scriptDone _init};
_initProtesters = [] spawn TWR_fnc_ProtesterInit;

_flee = player addEventHandler ["FiredNear", {

	[] spawn TWR_fnc_ProtesterRelease;
	player removeEventHandler ["FiredNear", _thisEventHandler];

}]remoteExec ["_flee", 0];

The only thing left is to get my script to release the civilians when shots are fired.

 

Cheers

Greg

Share this post


Link to post
Share on other sites
On ‎2018‎-‎04‎-‎09 at 9:40 PM, Grumpy Old Man said:

You need to take command locality into account, some commands will only affect the client they're executed on.

Taking switchMove/playMove as an example you can get different animations on different clients, so it's best to randomize the animation on the server, then use remoteExec to broadcast the unit and animation to all clients, so every player sees the same unit doing the same animation, same goes for sound and say/say3D.

 

Ok so yesterday I had everything working in GOM's script on SP and the EDEN MP. Placed it on the Dedicated server and it fell down.

 

Assuming this is right...

//inits the protesters sqf
_init = [] execVM "scripts\GOM\GOM_fnc_armedProtesters.sqf";	//this initializes all functions within the .sqf file
waitUntil {scriptDone _init};
_initProtesters = [] spawn GOM_fnc_armedProtestersInit;

_attack = player addEventHandler ["FiredNear", {

	[10] spawn GOM_fnc_armedProtestersAttack;	//starts the attack with amount of attackers as param, defaults to 5 if no number is given
	player removeEventHandler ["FiredNear", _thisEventHandler];

}] remoteExec ["_attack", 0];

I am at a complete loss as to how to adapt GOM's script  to function on a dedicated server. Mainly I am just getting confused. I have tried a few techniques, i.e placing it in the Serverinit.sqf and such but to no avail.

Spoiler

GOM_fnc_armedProtestersInit = {

	_potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]};

	//grab all usable civilian classes, needed to randomize loadout in the forEach loop
	_rndCivClasses = ("getNumber (_x >> 'side') isEqualTo 3 AND configName _x isKindOf 'Man' AND getNumber (_x >> 'scope') >= 2" configClasses (configFile >> "CfgVehicles")) apply {configName _x};

	{

		//get direction of unit
		_dir = getDir _x;

		//join civilian group
		_oldGroup = group _x;
		_newGroup = createGroup civilian;
		[_x] joinSilent _newGroup;
		deleteGroup _oldGroup;//keep things tidy
		_x setBehaviour "SAFE";

		//get and set random loadout
		_rndLoadout = getUnitLoadout selectRandom _rndCivClasses;
		_x setUnitLoadout _rndLoadout;
		_x switchMove "";//to skip weapon holster animation after weapon removal
		_x doWatch (_x getRelPos [50,_dir]);//reset watch direction after group change

		//dumb them down to stay put and allow random animations to be played
		_x disableAI "ALL";

		//handle animation looping
		_anim = _x spawn {

			sleep random 5;

			while {alive _this AND behaviour _this == "SAFE"} do {

				_rndAnimation = selectRandom ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"];

				if (alive _this) then {_this switchMove _rndAnimation;};
				waitUntil {sleep 1;animationState _this != _rndAnimation OR behaviour _this != "SAFE" OR !alive _this};
				if (!alive _this) exitWith {false};

			}
		};

	} forEach _potentialProtesters;
	//done, always return boolean
	true
};


//improved BIS function by pedeathtrian
NEW_fnc_arrayShuffle = {
	_this = []+_this;

	private _cnt = count _this;

	for "_i" from 1 to _cnt do
	{
		_this pushBack (_this deleteAt floor random (_cnt + 1 - _i));
	};
	_this
};


GOM_fnc_armedProtestersAttack = {

	params [["_amount",5]];

	_potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]};

	_armedProtesters = _potentialProtesters call NEW_fnc_arrayShuffle;
	_armedProtesters resize _amount;

	_potentialProtesters = _potentialProtesters - _armedProtesters;

	_pistols = "getnumber (_x >> 'type') isEqualTo 2 AND getnumber (_x >> 'scope') isEqualTo 2" configClasses (configfile >> 'CfgWeapons') apply {configName _x};

	_potentialProtesters apply {

		_x enableAI "ALL";
		_x setBehaviour "AWARE";
		_x switchMove "";

	};

	_armedProtesters apply {

		_x setVariable ["GOM_fnc_armedProtester",true,true];
		_x enableAI "ALL";
		_x setBehaviour "AWARE";
		_x switchMove "";

		//arm them
		[_x,selectRandom _pistols,4] call BIS_fnc_addWeapon;

		[_x] joinSilent createGroup east;
		//help AI to detect hostiles after group switch
		_unit = _x;
		{_unit reveal [_x,4]} forEach (_unit nearEntities ["CAManBase",150]);

		//reveal the hostile protester to nearby AI
		{_x reveal [_unit,4]} forEach (_unit nearEntities ["CAManBase",150]);

	};

	true;

};

true;

 

Any suggestions or an explanation on how to script this for dedicated server, the steps to be followed and such would be greatly appreciated. I apologize in advance for lack of understanding with this, but am just trying figure this out.

 

Cheers

Greg

Share this post


Link to post
Share on other sites
1 hour ago, swift39 said:

Ok so yesterday I had everything working in GOM's script on SP and the EDEN MP. Placed it on the Dedicated server and it fell down.

 

Well, SP, local MP and dedicated are different things which require different approaches on how to make stuff work.

Again, putting into the first post that you plan on making a mission to be run on a dedicated server is mandatory, since there's a lot to be taken into account when making a dedicated server compatible mission.

Might take a look at it during he weekend.

 

Cheers

Share this post


Link to post
Share on other sites

Thank you very much for your consideration. I am looking for a guide explaining the differences and have read Fockers Arma 3 Scripting Guide, but doesn't touch dedicated. I will continue to read forums and hopefully come to some understanding of the main or key differences when it comes to this segment. Although I don't understand it would require such a different approach from multi-player. Anyways thank you for your assistance and take care

 

Cheers

Greg

Share this post


Link to post
Share on other sites

Here's the working version for SP, local MP and dedicated.

Don't forget to place OPFOR units with this in their init fields:

this setVariable ["GOM_fnc_potentialArmedProtester",true,true];

This way they will get randomly picked as an armed protester.

 

initServer.sqf:

//init the protesters script file
_init = [] call compile preprocessFileLineNumbers "scripts\GOM\GOM_fnc_armedProtesters.sqf";//this initializes all functions within the .sqf file
_initProtesters = [] spawn GOM_fnc_armedProtestersInit;

//this is just an example of how the attack could happen

_attack = [] spawn {
	sleep 15;//delay or condition for the attack to happen
	[10] spawn GOM_fnc_armedProtestersAttack;//starts the attack with amount of attackers as param, defaults to 5 if no number is given

};

 

scripts\GOM\GOM_fnc_armedProtesters.sqf:


//initializes every protester and selects randomly which ones are armed
GOM_fnc_armedProtestersInit = {

	_potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]};

	//grab all usable civilian classes, needed to randomize loadout in the forEach loop
	_rndCivClasses = ("getNumber (_x >> 'side') isEqualTo 3 AND configName _x isKindOf 'Man' AND getNumber (_x >> 'scope') >= 2" configClasses (configFile >> "CfgVehicles")) apply {configName _x};

	{

		//get direction of unit
		_dir = getDir _x;

		//join civilian group
		_oldGroup = group _x;
		_newGroup = createGroup civilian;
		[_x] joinSilent _newGroup;
		deleteGroup _oldGroup;//keep things tidy
		_x setBehaviour "SAFE";//group created on server, so no remoteExec needed

		//get and set random loadout
		_rndLoadout = getUnitLoadout selectRandom _rndCivClasses;
		_x setUnitLoadout _rndLoadout;
		[_x,""] remoteExec ["switchMove",[0,-2] select isDedicated,true];//to skip weapon holster animation after weapon removal
		_x doWatch (_x getRelPos [50,_dir]);//reset watch direction after group change

		//dumb them down to stay put and allow random animations to be played
		_x disableAI "ALL";

		//handle animation looping
		_anim = _x spawn {

			sleep random 5;
			_EHID = _this addEventHandler ["AnimDone", {

					params ["_unit", "_anim"];
					if (alive _unit AND behaviour _unit == "SAFE") then {

						_rndAnimation = selectRandom ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"];
						[_unit,_rndAnimation] remoteExec ["switchMove",[0,-2] select isDedicated,true];

					} else {_unit removeEventHandler ["AnimDone",_thisEventHandler]};
			}];


			_rndAnimation = selectRandom ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"];

				if (alive _this) then {

					[_this,_rndAnimation] remoteExec ["switchMove",[0,-2] select isDedicated,true];
				waitUntil {sleep 1;behaviour _this != "SAFE" OR !alive _this};
				_this removeEventHandler ["AnimDone",_EHID];
			};
				if (!alive _this) exitWith {_this removeEventHandler ["AnimDone",_EHID];false};


		};

	} forEach _potentialProtesters;
	//done, always return boolean
	true
};


//improved BIS function by pedeathtrian
NEW_fnc_arrayShuffle = {
	_this = []+_this;

	private _cnt = count _this;

	for "_i" from 1 to _cnt do
	{
		_this pushBack (_this deleteAt floor random (_cnt + 1 - _i));
	};
	_this
};


GOM_fnc_armedProtestersAttack = {

	params [["_amount",5]];

	_potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]};

	_armedProtesters = _potentialProtesters call NEW_fnc_arrayShuffle;
	_armedProtesters resize _amount;

	_uunarmedProtesters = _potentialProtesters - _armedProtesters;

	_pistols = "getnumber (_x >> 'type') isEqualTo 2 AND getnumber (_x >> 'scope') isEqualTo 2" configClasses (configfile >> 'CfgWeapons') apply {configName _x};

	_uunarmedProtesters apply {

		_delay = _x spawn {

			sleep (0.5 + random 1.2);//decent reaction time
			_this enableAI "ALL";
			_this setBehaviour "AWARE";
			[_this,""] remoteExec ["switchMove",[0,-2] select isDedicated,true];
			_this setSpeedmode "FULL";
			_this doMove (_this getPos [50,random 360]);//make AI run away in a random dir
			if (random 100 < 30) then {

				_this setUnitPos "DOWN";
				sleep 5 + random 5;
				_this setUnitPos "AUTO";

				} else {

				_this setUnitPos "MIDDLE";
				sleep 10 + random 5;
				_this setUnitPos "AUTO";

			};


		};
	};

	_armedProtesters apply {


		_delay = [_x,_pistols] spawn {

			sleep random 0.5;//faster reaction time than unarmed protesters
			params ["_unit","_pistols"];

			_unit setVariable ["GOM_fnc_armedProtester",true,true];
			_unit enableAI "ALL";
			_unit setBehaviour "AWARE";
			[_unit,""] remoteExec ["switchMove",[0,-2] select isDedicated,true];
			//arm them
			[_unit,selectRandom _pistols,4] call BIS_fnc_addWeapon;

			[_unit] joinSilent createGroup east;
			//help AI to detect hostiles after group switch
			{_unit reveal [_x,4]} forEach (_unit nearEntities ["CAManBase",150]);

			//reveal the hostile protester to nearby AI
			{_x reveal [_unit,4]} forEach (_unit nearEntities ["CAManBase",150]);

	};

	};

	true;

};

true;

Had to goof around a bit with the animations. animationState refused to work for dedicated, so I switched to an eventHandler based solution.

 

Cheers

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, RL - AVE said:

Read this thread with great interest. Would you mind posting your working version for SP, local MP and dedicated again? @Grumpy Old Man

Sure, updated the first link in my post above.

 

Cheers

  • Like 2

Share this post


Link to post
Share on other sites
On 1/12/2020 at 3:21 AM, typhoontiger said:

Any way we could get an updated file? Thanks!

 

Of course, same  version as on 28 April 2018,  so the  latest one.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
On 10/1/2019 at 11:06 PM, Grumpy Old Man said:

Sure, updated the first link in my post above.

 

Cheers

Hello. I am a, considerably new mission maker. And new to scripting as well. Can I get the protest script, as the current link reports that it is deleted. Additionally, if possible, can I get some assistance installing it to my mission file? 

Many thanks!

Share this post


Link to post
Share on other sites
On 8/16/2021 at 3:24 AM, Grumpy Old Man said:

Here's the file again.

Note that indeedPetes animation mod is needed for it, as mentioned above.

 

Cheers

Grumpy lives!  Yay! :yay:

  • Like 2
  • Haha 1

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

×