Jump to content
stanhope

Unknownn bug in a script that I can't locate

Recommended Posts

Right, so I've been breaking my head over this for a few days now.  I'm maintaining an (older) mission for a community until they can get the new version out.  And recently some stuff has been going wrong with the spawning of these missions.  I've personally observed something that's supposed to be impossible happen and I can't figure out why it's happening. 

 

The thing that's happening is that a mission spawns while the other one of the same type is still active.  I've checked server RPTs from several days, they don't contain any errors related to this script.  I've tried to recreate the problem on my own dedi server, again, no luck.  So I was wondering if you guys might be able to help. 

Here's a watered down version of the mission(, complete scripts at the bottom in the spoiler):

 

initserver:

prioObjScript = [] execVM "Missions\Priority\MissionControl.sqf";

MissionControl.sqf (a controller script that spawns the actual mission):

while { true } do { /*While loop to keep it going (almost) forever*/
	
  _currentMission = execVM "missions\Priority\priorityarty.sqf"; /*Execute the mission itself*/
  prioMissionSpawnComplete = false; /*global variable that the above called script will set to true when it's done spawning*/
  _shouldterminate = true; /*local var to see if the script should be killed or not (in case it doesn't spawn in time)*/

  for "_i" from 0 to 60 do { /*loop 60 times 5 seconds or until the mission is done spawning*/
  	sleep 5;
  	if (prioMissionSpawnComplete) exitWith {
  		_shouldterminate = false; /*if the mission has finished spawning and is now up and running set this var to false*/
  	};
  };

  if (_shouldterminate) then { /*if the mission didn't spawn in time kill it and report the error*/
  	terminate _currentMission;
  	diag_log "ERROR: PRIO MISSION CONTROL: a mission failed to spawn and was terminated";
  } else { /*if it has wait until it's done and sleep for a certain amount before doing everything again*/
  	waitUntil {sleep 5;	scriptDone _currentMission};
  	sleep _delay;
  };
};

Priorityarty.sqf, the actual mission:

//some code to find a decent place to spawn
private _accepted = false;
private _flatPos = [0,0,0];

while { !_accepted } do {
	//get a place at random that meet some criterea
    _flatPos = [getMarkerPos currentAO, missionsMinimumSpawnDistance, 8000, 5, 0, 0.2, 0, [], [0,0,0]] call BIS_fnc_findSafePos;

  	//for now accept this place
    _accepted = true;
  	//loop over all FOBs and see if we're too close to one
    {
        if ( (_flatPos distance2D (getMarkerPos _x)) < missionsMinimumSpawnDistance) then {
            _accepted = false;
        }
    } forEach BaseArray + [currentAO];
};

/*A bunch of things left out, short summary: priorityObj1, priorityObj2 (2 objects) get spawned and some troops, a few H-barriers, ...*/

//Let players know that we have spawned: 
[west,["priorArtyTask"],["OPFOR forces are setting up an artillery battery to hit you guys damned hard! We've picked up their positions with thermal imaging scans and have marked it on your map. This is a priority target, boys! They're just setting up now; they'll be firing in about five minutes!  Previous sites looked like this: <br/><br/><img image='Media\Briefing\prioArty.jpg' width='300' height='150'/>","Priority Target: Artillery","priorityCircle"],(getMarkerPos "priorityCircle"),"Created",0,true,"NewPriorityTarget",true] call BIS_fnc_taskCreate;

//inform the controller script that we have successfully spawned
prioMissionSpawnComplete = true;
publicVariableServer "prioMissionSpawnComplete";
	

while {canFire priorityObj1 || canFire priorityObj2} do {
	/*Fire subroutine here, while loop prevents the script from finishing as long as these arty pieces can fire.*/
};


//Debrief:
["priorArtyTask", "Succeeded",true] call BIS_fnc_taskSetState;
sleep 5;
["priorArtyTask",west] call bis_fnc_deleteTask;
{ _x setMarkerPos [-10000,-10000,-10000] } forEach ["priorityMarker","priorityCircle"];

//-------------------- DELETE
sleep 120;
_ToDelete = _unitsArray + _spawnedUnits;
{ deleteVehicle _x } forEach _ToDelete;

To describe the bug a bit more extensively:  One arty mission is running just fine.  It's not showing any signs of it doing anything special.  Next thing I see is that a new arty mission spawns but I've never seen the task complete.  And there's a significant amount of time between these missions spawning 10+ minutes.  Several people have actually seen this happen. 

This is happening on a server that contains anywhere between 0 and 60 players, usually about 10-14 hours after the server was rebooted. 

 

Spoiler

InitServer:


prioObjScript = [] execVM "Missions\Priority\MissionControl.sqf";

missionControl:


/*
Author: 

	Quiksilver

Last modified: 

	4/02/2016

Description:

	Priority Mission control

To do:

______________________________________________*/

private ["_mission","_currentMission","_nextMission","_delay","_playerCount","_minPlayerCount"];

prioMissionList = [
	"Priorityarty",
	"Priorityarty",
	"Priorityarty",
	"priorityAA",
	"priorityreinforceAO"
];

PRIO_SWITCH = true; 
publicVariable "PRIO_SWITCH";
	
while { missionActive } do {

	_delay = 1500 + (random 600);
	
	_players = allPlayers - entities "B_Helipilot_F";
	_playerCount = count _players;
	_minPlayerCount = 15 + round (random 5);
	
	if (PRIO_SWITCH && (_playerCount >= _minPlayerCount)) then {
	
		_mission = selectRandom prioMissionList;
		_currentMission = execVM format ["missions\Priority\%1.sqf", _mission];
		prioMissionSpawnComplete = false;
		_shouldterminate = true;
	
		for "_i" from 0 to 60 do {
			sleep 5;
			if (prioMissionSpawnComplete) exitWith {
			_shouldterminate = false;
			};
		};
		
		if (_shouldterminate) then {
			terminate _currentMission;
			diag_log "ERROR: PRIO MISSION CONTROL: a mission failed to spawn and was terminated";
		} else {
			waitUntil {sleep 5;	scriptDone _currentMission};
			sleep _delay;
		};
		
		PRIO_SWITCH = true; publicVariable "PRIO_SWITCH";
	};
	
	sleep 10;
};

prioarty:


/*
Author:

	Quiksilver
	Rarek [AW]

Last modified:3/09/2017 by stanhope

modified:
Fixed it getting stuck in a loop

Description:

	Not done with this, want to get the Commanders gun firing, and some other stuff.
*/

private ["_MaxSleepTime","_position","_PTdir","_unitsArray","_priorityGroup",
"_distance","_dir","_c","_pos","_barrier","_enemiesArray","_unit","_targetPos","_fuzzyPos","_briefing","_completeText","_targetUnit"];

private _spawnedUnits = [];

//-------------------- 1. FIND POSITION
private _accepted = false;
private _flatPos = [0,0,0];

while { !_accepted } do {

    _flatPos = [getMarkerPos currentAO, missionsMinimumSpawnDistance, 8000, 5, 0, 0.2, 0, [], [0,0,0]] call BIS_fnc_findSafePos;

    _accepted = true;
    {
        if ( (_flatPos distance2D (getMarkerPos _x)) < missionsMinimumSpawnDistance) then {
            _accepted = false;
        }
    } forEach BaseArray + [currentAO];

};

private _position = _flatPos;
	
	private _flatPos1 = _flatpos getPos [5, 0];
	private _flatPos2 = _flatpos getPos [5, 180];
	private _flatPos3 = _flatpos getPos [25, random 360];

//-------------------- 2. SPAWN OBJECTIVES

	_PTdir = random 360;

	priorityObj1 = "O_MBT_02_arty_F" createVehicle _flatPos1;
	priorityObj2 = "O_MBT_02_arty_F" createVehicle _flatPos2;
	ammoTruck = "O_Truck_03_ammo_F" createVehicle _flatPos3;
	
	waitUntil {!isNull priorityObj1 && !isNull priorityObj2 && !isNull ammoTruck};
	{
	_x lock 3;
	_x allowCrewInImmobile true; 
	_spawnedUnits pushBack _x;
	_x setDir _PTdir;
	_x setFuel 0;
	} forEach [priorityObj1,priorityObj2,ammoTruck];

//-------------------- 3. SPAWN CREW - Same method as in priorityaa

	sleep 0.1;

	_unitsArray = [objNull];                        // for crew and h-barriers
	_groupsArray= [objNull];

	_priorityGroup = createGroup east;
	
	{
		_x addEventHandler ["Fired",{(_this select 0) setVehicleAmmo 1}];
		createvehiclecrew _x;
		(crew _x) join _priorityGroup;
		sleep 0.1;
		_x dowatch getMarkerpos currentAO;
	} forEach [priorityObj1, priorityObj2];
	
	_priorityGroup setGroupIdGlobal [format ['Prio-arty']];

	 {
	_spawnedUnits = _spawnedUnits + units _x;
	[(units _x)] call AW_fnc_setSkill4;
	_x setBehaviour "COMBAT";
	_x setCombatMode "RED";
	_x allowFleeing 0;
	} foreach [_priorityGroup];

	//=====zeus adding
	_groupsArray = _groupsArray + [_priorityGroup];	
	{_x addCuratorEditableObjects [[priorityObj1, priorityObj2, ammoTruck]+ (units _priorityGroup), false];} foreach allCurators;

//-------------------- 4. SPAWN H-BARRIER RING

	sleep 0.1;

	private _distance = 18;
	private _dir = 0;
	for "_c" from 1 to 8 do
	{
		_pos = _flatpos getPos [_distance, _dir];
		_barrier = "Land_HBarrierBig_F" createVehicle _pos;
		waitUntil {alive _barrier};
		_barrier setDir _dir;
		_dir = _dir + 45;
		_barrier allowDamage false; 
		_barrier setVectorUp surfaceNormal position _barrier;
		_unitsArray = _unitsArray + [_barrier];
	};	
	sleep 0.1;

//-------------------- 5. SPAWN FORCE PROTECTION

	private _infantryGroupamount = 0;
	_infPos = getPos priorityObj1;
	for "_x" from 1 to 5 do {
		private _randomPos = [_infPos, 0, (300 * 1.2), 1, 0, 0.4, 0, [], _infPos] call BIS_fnc_findSafePos;
		
		private _infantryGroup = createGroup EAST;
		_infantryGroupamount = _infantryGroupamount + 1;
		_infantryGroup setGroupIdGlobal [format ['Prio-protection-inf-%1', _infantryGroupamount]];
		for "_x" from 1 to 8 do {
			private _squadPos = [_randomPos, 0, (20), 1, 0, 0.4, 0, [], _randomPos] call BIS_fnc_findSafePos;
			_unitArray = (missionconfigfile >> "unitList" >> MainFaction >> "units") call BIS_fnc_getCfgData;
			_unit = _unitArray call BIS_fnc_selectRandom;
			_grpMember = _infantryGroup createUnit [_unit, _squadPos, [], 0, "FORM"];
		};

		[_infantryGroup, _infPos, 300 / 1.6] call AW_FNC_taskPatrol;
		_spawnedUnits = _spawnedUnits + (units _infantryGroup);
		{_x addCuratorEditableObjects [(units _infantryGroup), true];} foreach allCurators;
		sleep 0.5;
	};

	sleep 0.1;


//-------------------- 7. BRIEF

	_fuzzyPos = [((_flatPos select 0) - 300) + (random 600),((_flatPos select 1) - 300) + (random 600),0];
	{ _x setMarkerPos _fuzzyPos; } forEach ["priorityMarker", "priorityCircle"];

	priorityTargetText = "Artillery";
	"priorityMarker" setMarkerText "Priority Target: Artillery";
	[west,["priorArtyTask"],["OPFOR forces are setting up an artillery battery to hit you guys damned hard! We've picked up their positions with thermal imaging scans and have marked it on your map. This is a priority target, boys! They're just setting up now; they'll be firing in about five minutes!  Previous sites looked like this: <br/><br/><img image='Media\Briefing\prioArty.jpg' width='300' height='150'/>","Priority Target: Artillery","priorityCircle"],(getMarkerPos "priorityCircle"),"Created",0,true,"NewPriorityTarget",true] call BIS_fnc_taskCreate;

	prioMissionSpawnComplete = true;
	publicVariableServer "prioMissionSpawnComplete";
	
//-------------------- FIRING SEQUENCE LOOP

while {canFire priorityObj1 || canFire priorityObj2} do {
	_shouldSearchTargets = true;
	_targetUnit = objNull;
	_targetPos = [0, 0, 0];

	while {_shouldSearchTargets} do {
	
		if (!(canFire priorityObj1) && !(canFire priorityObj2)) exitWith{ _shouldSearchTargets = false; };
		
		_playerCount = count playableUnits;

		if (_playerCount >= 0) then {
		
			_targetUnit = selectRandom playableUnits;
			
			if ( !(isNull _targetUnit) && (vehicle _targetUnit == _targetUnit) && (side _targetUnit == WEST)) then {
				
				_targetPos = getPos _targetUnit;
				private _farEnoughFromBase = true;
				_distance = 0;
				{
					_distance = _targetPos distance (getMarkerPos _x);
					if (_distance < 1000) then {_farEnoughFromBase = false;};
				} forEach BaseArray;
				
				if ( _farEnoughFromBase ) then {
					if ( ((East knowsAbout _targetUnit) > 1.9) || ((Independent knowsAbout _targetUnit) > 1.9) ) then { 
						if (!(canFire priorityObj1) && !(canFire priorityObj2)) exitWith{_shouldSearchTargets = false;};
						{if (alive _x) then {[_x, _targetPos] call AW_fnc_artyStrike;};} forEach [priorityObj1, priorityObj2];
						_shouldSearchTargets = false;
					};
				};
			};
		} else {
			_shouldSearchTargets = false;	//Because there's less than three players on the server.
		};
		sleep 2;
	};
	
	if (!(canFire priorityObj1) && !(canFire priorityObj2)) exitWith{};
	
	private _TimeSlept = 0;
	
	_MaxSleepTime = abs (PARAMS_ArtilleryTargetTickTimeMax - PARAMS_ArtilleryTargetTickTimeMin);
	
	while {_TimeSlept < PARAMS_ArtilleryTargetTickTimeMin} do {
		private _TimeToSleep = random _MaxSleepTime;
		if (_TimeToSleep < 20) then {_TimeToSleep = 20;};
		_TimeSlept = _TimeSlept + _TimeToSleep;
		sleep _TimeToSleep;
		if (!(canFire priorityObj1) && !(canFire priorityObj2)) exitWith{}; 
	};
		
};
//-------------------- DE-BRIEF

	["priorArtyTask", "Succeeded",true] call BIS_fnc_taskSetState;
	sleep 5;
	["priorArtyTask",west] call bis_fnc_deleteTask;
	{ _x setMarkerPos [-10000,-10000,-10000] } forEach ["priorityMarker","priorityCircle"];

//-------------------- DELETE
	sleep 120;
	_ToDelete = _unitsArray + _spawnedUnits;
	{ deleteVehicle _x } forEach _ToDelete;

 

 

(I know the scripts themselves are rather bad scripts, definitely not optimal for performance, I've wanted to rewrite them completely several times but just haven't found the time for it yet)

 

So anyone have any idea what might be causing this bug and how I could fix 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

×