sreVbriefing.htmlNbriefing.sqfN1description.extNQforceTracker_init.sqfN init.sqfN,mission.sqm2pNmk4\changelog.txtNmk4\f\ai\fDoStop.sqfNmk4\f\ai\fFleeToBuildings.sqfNmk4\f\ai\fTaskDefend.sqfNmk4\f\ai\fTaskPatrol.sqfN]mk4\f\ai\fTaskRetreat.sqfNmk4\f\ai\fUPS.sqfNzmk4\f\array\fArrayCountOccurrences.sqfN$mk4\f\array\fEnumMixedArray.sqfNmk4\f\array\fInMixedArray.sqfNmk4\f\briefing\fAssignTask.sqfNmk4\f\briefing\fCancelTask.sqfN mk4\f\briefing\fCreateNote.sqfNfmk4\f\briefing\fCreateTaskNLmk4\f\briefing\fCreateTask.sqfN mk4\f\briefing\fCreateTaskbak.sqfNLmk4\f\briefing\fFailTask.sqfN+mk4\f\briefing\fSucceedTask.sqfN mk4\f\briefing\fTaskHint.sqfNmk4\f\fAddMagazinesTurret.sqfNmk4\f\fAddPersistentAction.sqfNQmk4\f\fAssignTeam.sqfNmk4\f\fBuildingEffects.sqfN mk4\f\fCreateLHD.sqfNmk4\f\fCreateMarkerLocal.sqfNmk4\f\fCreateStaticUnit.sqfN mk4\f\fDestroyBuildings.sqfNtmk4\f\fDirTo.sqfN>mk4\f\fDisplayName.sqfNmk4\f\fEcho.sqfNmk4\f\fFormattedTime.sqfNymk4\f\fGroupName.sqfNYmk4\f\fHALO.sqfNt0mk4\f\fObjectName.sqfNmk4\f\forceTracker\fAddToForceTracker.sqfNmk4\f\forceTracker\fHighlightForce.sqfNmk4\f\forceTracker\fMapClickEvent.sqfNBmk4\f\forceTracker\fMapKeyDownEvent.sqfNmk4\f\forceTracker\fNearestTrackedForce.sqfNmk4\f\forceTracker\fShowGroupInfo.sqfNmk4\f\forceTracker\fShowVehicleInfo.sqfNmk4\f\forceTracker\fUnHighlightForces.sqfNmk4\f\fRegisterScript.sqfNmk4\f\fRelativeFilePath.sqfNmk4\f\fSetHeightASL.sqfNmk4\f\fSetHeightATL.sqfNmk4\f\fTaskHint.sqfNmk4\f\fUnitName.sqfNmk4\f\fUnitPos.sqfNmk4\f\fUnregisterScript.sqfNmk4\f\init.sqfNRmk4\f\loadout\fLoadout.sqfN mk4\f\loadout\fSelectPrimaryMuzzle.sqfNmk4\f\loadout\fSetMagazines.sqfN mk4\f\loadout\fSetRuckMagazines.sqfNmk4\f\loadout\fSetRuckWeapons.sqfNmk4\f\loadout\fSetWeaponOnBack.sqfNmk4\f\loadout\fSetWeapons.sqfNmk4\f\network\fExec.sqfN}mk4\f\network\fSend.sqfNmk4\f\text\fBlueText.sqfNmk4\f\text\fGoldText.sqfNmk4\f\text\fGrayText.sqfNmk4\f\text\fGreenText.sqfNmk4\f\text\fRedText.sqfNmk4\f\text\fYellowText.sqfNmk4\l\BAF.sqfNrmk4\l\INS_TK.sqfNmk4\l\RU.sqfNmk4\l\SF.sqfNmk4\l\test.sqfNmk4\l\TK.sqfNmk4\l\UN.sqfNmk4\l\USMC.sqfNmk4\s\adminMenu.sqfN mk4\s\authorizedCrew.sqfNmk4\s\borderControl.sqfNmk4\s\debugger\dialog.hppNXmk4\s\debugger\init.sqfN mk4\s\debugMenu.sqfN{mk4\s\defines.hppNmk4\s\detectMarkerDeletion.sqfN9 mk4\s\detectTeamKilling.sqfN' mk4\s\dynamicViewDistance.sqfNmk4\s\forceTracker.sqfN4 mk4\s\HousePatrol.sqfNL mk4\s\includes.hppNkmk4\s\intro_namesAndRoles.sqfN}mk4\s\intro_namesOnly.sqfN>mk4\s\mk4_init.sqfN>mk4\s\monitor.sqfN mk4\s\nodeDiscovery.sqfNmk4\s\outro.sqfNmk4\s\processEndings.sqfNmk4\s\processParams.sqfNmk4\s\setSideSkill.sqfNmk4\s\setTime.sqfNfmk4\s\setWeather.sqfNmk4\s\timeLimitWarning.sqfNmk4\s\unitTracker\init.sqfN5mk4\s\unitTracker\overlay.hppNmk4\s\UPS.sqfN}mk4\s\weatherSync.sqfNonPlayerRespawnAsSeagull.sqsNkpre_init.sqfNiscripts\Init_UPSMON.sqfNbscripts\UPSMON\!R\markerAlpha.sqfNscripts\UPSMON\!R\R_functions.sqfNx"scripts\UPSMON\actions\followme.sqfN scripts\UPSMON\common\MON_functions.sqfNscripts\UPSMON\MON_artillery_add.sqfN scripts\UPSMON\MON_spawn.sqfNscripts\UPSMON\MON_surrended.sqfN,scripts\upsmon changelog.txtNBIscripts\upsmon known problem and hints !R .txtN)scripts\UPSMON.sqfNTbsound.sqfN3wind.oggN3windSound.sqfN Title

Mission Failed


The team sustained too many casualties.




Mission Complete


All objectives complete, well done.




You took too long


Mission time limit exceeded.

















ENDEX by Admin


/* -------------------------------------------------------------------------------------------------------------------------------------- The syntax for mk4_fCreateNote is: [ [scope] ,[ "noteSubject", "noteMessage"]] call mk4_fCreateNote; 1st arg can be of type: ARRAY -> You can also send a array of the following datatypes: SIDE -> Specify sides that are allowed to see the marker, [WEST] or [WEST, RESISTANCE] STRING -> To specify factions, [Bgrp3] or [Bgrp3, "CDF", "CIV_RU"] GROUP -> To specify groups, [BLU_1Plt_HQ, BLU_1Plt_1Sqd, BLU_1Plt_2Sqd] OBJECT -> To specify individual units, [plt_ldr, plt_sgt] 2nd arg must contain an array containing 2 strings. 1st -> Note Subject 2nd -> Note Message ------------------------------------------------------------------------------------------------------------------------------------------- */ // wait until the template has finished initializing waitUntil { MK4_INIT }; // ---------------------------------------------------------------- West briefing ------------------------------------------------------------------// _westSituation = "
Welcome to Unspecifiedistan.
Last month Takistani forces crossed the border in an act of presumably unprovoked aggression raising tensions in the region, intelligence gathered from our sources inside the Takistani military indicate that a number of soviet designed scud missile launcher systems belonging to the Takistani Army have been deployed to the desert border area.
If it were to come to light that the Takistanis had the capability to launch a chemical or nuclear attack on their neighbours the region would likely go up like a keg of gun powder as such you are to locate and destroy these launchers.

Satelite and aerial recon of the area has been unable to provide much if any intel on the location of these launchers due to the frequent sandstorms this time of year, and the maps available to us were probably last updated some time in the 13th century.
As such we can only provide you with rough aproximations as to the coordinates of the three scud launchers in your OA. You will have to use your DAGR GPS units for navigation and location of the targets.

You will be inserted in to the OA by Mi-17, visibility is likely to be extremely low when you land so be on alert for contacts.

See your location notes for relavent mission critical coordinates.
"; _westMission = "
Locate and destroy all three scud launchers within your OA. "; _westFriendly = "
With the exception of your squad there are no other friendly groups in the area.

(06) -- [Alpha] -- [SF Team]
(06) -- [Bravo] -- [SF Team] "; _westEnemy = "Exact composition unknown, expect close to a platoon of takisani regulars with possible supporting light armour.

"; _westServiceAndSupport = "
a) Communications

Recommended PRC - 343 Channels

[Team - 1] -- [Channel 1]
[Team - 2] -- [Channel 2]

Recommended PRC - 148/119/117F Channels

All team leaders and platoon CO have either PRC - 148 or 119 long range radios.

[Command Net] -- [Channel 1]
[Air/JTAC Net] -- [N/A]
[Artillery/FO Net] -- [N/A]
"; _westLocations = "
Insertion point: 015020

Scud Locations (within 300m):

Scud 1: 009006
Scud 2: 001014
Scud 3: 015016
"; _info = "
GENERAL INFORMATION

---- Mission maker: ToadBall
---- Respawn: None
---- Cas Limit: 95% BLUFOR

---- mk4_template 0.27 "; // ---------------------------------------------------------------- West Tasks ------------------------------------------------------------------// _taskName1 = "task1"; _taskTitle1 = "Destroy Scud 1"; _taskInfo1 = "Destroy Scud located near 009006"; _taskDestination1 = getMarkerPos ""; _taskName2 = "task2"; _taskTitle2 = "Destroy Scud 2"; _taskInfo2 = "Destroy Scud located near 001014"; _taskDestination2 = getMarkerPos ""; _taskName3 = "task3"; _taskTitle3 = "Destroy Scud 3"; _taskInfo3 = "Destroy Scud located near 015016"; _taskDestination3 = getMarkerPos ""; // --------------------------------------------------------------------------------------------------------------------------------------------------------// [allUnits, [" INFO", _info]] call mk4_fCreateNote; // [[WEST], ["6) LOCATIONS", _westServiceAndSupport]] call mk4_fCreateNote; [[WEST], ["1) SITUATION", _westSituation]] call mk4_fCreateNote; sleep 0.5; [[WEST], ["2) MISSION", _westMission]] call mk4_fCreateNote; sleep 0.5; [[WEST], ["3) FRIENDLY FORCES", _westFriendly]] call mk4_fCreateNote; sleep 0.5; [[WEST], ["4) ENEMY FORCES", _westEnemy]] call mk4_fCreateNote; sleep 0.5; [[WEST], ["5) SERVICE AND SUPPORT", _westLocations]] call mk4_fCreateNote; sleep 0.5; [[WEST], ["6) LOCATIONS", _westServiceAndSupport]] call mk4_fCreateNote; sleep 0.5; [[WEST], _taskName1, [ _taskTitle1, _taskInfo1, _taskDestination1]] call mk4_fCreateTask; sleep 0.5; [[WEST], _taskName2, [ _taskTitle2, _taskInfo2]] call mk4_fCreateTask; sleep 0.5; [[WEST], _taskName3, [ _taskTitle3, _taskInfo3, _taskDestination3]] call mk4_fCreateTask; sleep 0.5; #include "mk4\s\defines.hpp" #include "mk4\s\includes.hpp" //----------------------------------------------------------------------------- // Mission Settings //----------------------------------------------------------------------------- respawn = 4; // 0 = none, 1 = bird, 2 = instant, 3 = base, 4 = group, 5 = side (Only 2 and 3 are persistent-compatible) respawndelay = 5; // Time delay in seconds for respawn to occur (NEVER use 0) disabledAI = true; // disable AI in playable slots? aiKills = false; // show the AI on the scoring list? onLoadMissionTime = false; // show the time and date when mission loads? onLoadMission = "Scud Storm"; // the text that will be shown while the mission loads //LoadScreen = "mk4\i\picture.jpg"; // picture that will be shown during loading class Header { gameType = Coop; // values: DM, CTF, FF, Coop, Team, Scont, Hold, Unknown minPlayers = 1; // min # of players the mission supports maxPlayers = 12; // max # of players the mission supports }; // n00b proofing //class Extended_PreInit_Eventhandlers //{ //mk4_init_EH = "['XEH'] call compile (preprocessFileLineNumbers 'mk4\s\mk4_init.sqf');"; //}; //----------------------------------------------------------------------------- // Template Settings //----------------------------------------------------------------------------- class MK4_Settings { version = 3; class General { processParams = true; // process the mission parameters? missionMonitor = true; // start monitoring casrates? weatherSync = true; // sync weather over network? adminMenu = true; // Give the currently logged in admin a special menu dynamicViewDistance = true; // changes the VD to the type of vehicle youre in (you can set the distances in the param classes below) forceTracker = false; // run forceTracker? unitTracker = false; // run unit tracker? enableSaving = false; // let ArmA save the session when you quit in MP hosted? noConversations = true; // disable BIS conversation module? debugRPT = true; // allow debug output in the RPT file? (enabling this is recommended) debuggerHotkey = 0x58; // key used to open the debugger (F12 in this case) intro = true; // run intro? introJIP = false; // run intro for JIPers? introScript = "mk4\s\intro_namesOnly.sqf"; // specify which script to run as intro outro = true; // run outro (requires mission endings) outroDuration = 12.5; // after how many seconds should the mission end outroScript = "mk4\s\outro.sqf"; // specify which script to run as outro }; class ACE { tracking = false; // disables ACE tracking spectator = true; // use the ACE spectating script spectatePlayable = true; // only add playable units to the spectator spectateNoButterfly = true; // dont turn into butterfly when player exits spectator, restart spectator instead noStaminaEffects = false; // disables stamina system (N.B. disables ruck system as well) noRecognize = false; // disables ACE recognize system }; class Admin { adminUIDs[] = { 3064774, 1299718, 1262592, 656449, 1470662, 3064710 }; detectMarkerDeletion= true; // let all admins know who is deleting markers detectTeamKilling = true; // let all admins know who is teamkilling }; class MissionMonitor { // specify the SIDEs, factions, classnames, groups and/or objects that need to be monitored // NB. sides must be in uppercase! source[] = { EAST, WEST}; initDelay = 25; // delay (in secs) before starting the mission monitor updateDelay = 5; // delay (in secs) between each update }; class MissionEndings { // 1st array element is condition to make mission end, 2nd is the message shown during the outro end1[] = {(WCasRate > 80), "Mission Failed. BLUFOR combat ineffective."}; end2[] = { (objAllDone), "Mission Complete."}; end3[] = { }; end4[] = { }; end5[] = { }; end6[] = { }; loser[] = { (mk4_adminEndex), "ENDEX by admin" }; // reserved for admin menu (Do not edit) }; class UnitTracker { // specified colors will be overridden if units were mk4_fAssignTeam'ed (given team colors) myType = "MIL_DOT"; // player's marker type mySize[] = {0.6,0.6}; // marker size [x,y] myAlpha = 1.0; // marker alpha myColor = "colorRed"; // marker color otherType = "MIL_TRIANGLE";// other people's marker type otherSize[] = {0.35,0.55}; //marker size [x,y] otherAlpha = 0.6; // marker alpha otherColor = "colorBlue"; // color updateDelay = 1.0; // delay between updates in seconds showName = false; // show name when mouse is hovered above unit marker (NOT working yet) }; }; //----------------------------------------------------------------------------- // Parameters //----------------------------------------------------------------------------- class Params { class Debug { title = "Debug Mode"; values[] = { 0, 1, 2, 3 }; texts[] = { "Off", "Low", "Medium", "High" }; default = 0; code = "if (%1 > 0) then {['init'] execVM 'mk4\s\debugMenu.sqf'; mk4_debugMode = %1;}"; }; class Spacer0 PARAM(""); class Spacer1 PARAM("View Distance:"); //class ClientViewDistance //{ // title = " Client (default)"; // values[] = { 400, 500 }; // texts[] = { "400m", "500m" }; // default = 400; // code = "if (!isDedicated) then {setViewDistance %1; mk4_defaultVD = %1;};"; //}; //class ServerViewDistance //{ // title = " Server"; // values[] = { 75 }; // texts[] = { "75m" }; // default = 75; // code = "if (isDedicated) then {setViewDistance %1; mk4_defaultVD = %1;}; "; //}; //class Spacer2 PARAM(""); //class Spacer3 PARAM("Environment Settings:"); //class TimeOfDay //{ // title = " Time of Day"; // 9999 is reserved for random weather // values[] = { 9999, 0500, 0515, 0530, 0545, 0600, 0615, 0630, 0645, 0700, 0900, 1200, 1500, 1700, 1715, 1730, 1745, 1800, 1815, 1830, 1845, 1900 }; // 9999 is reserved for random time // texts[] = { "Random", "0500", "0515", "0530", "0545", "0600", "0615", "0630", "0645", "0700", "0900", "1200", "1500", "1700", "1715", "1730", "1745", "1800", "1815", "1830", "1845", "1900" }; // default = 9999; // code = "if (isServer) then {[%1] call compile (preprocessFileLineNumbers 'mk4\s\setTime.sqf')}"; //}; //class Weather //{ // title = " Weather"; // values[] = { 99, 0, 1, 2, 3, 4, 5 }; // 99 is reserved for random weather // texts[] = { "Random", "Clear", "Overcast", "Light Rain", "Heavy Rain", "Light Fog", "Heavy Fog" }; // default = 0; // code = "[%1] execVM 'mk4\s\setWeather.sqf'"; //}; class Grass { title = " Grass Setting"; values[] = { 50, 25, 12.5, 6.25 }; texts[] = {"None", "Low", "Normal", "High"}; default = 25; code = "setTerrainGrid %1"; }; class Spacer4 PARAM(""); class Spacer5 PARAM("Mission Settings:"); //class Nationality //{ // title = "Loadouts:"; // values[] = { 0, 1}; // texts[] = { "Classic USMC", "Modern USMC" }; // default = 0; // code = "Nationality = ['USMC1', 'USMC2'] select %1"; //}; //class Spacer6 PARAM(""); //class Spacer7 PARAM("Skill Settings:"); class EastSkill { title = " REDFOR"; values[] = { 05, 06, 07, 08, 09}; texts[] = { "0.5", "0.6", "0.7", "0.8", "0.9" }; default = 06; code = "if (isServer) then {[EAST, %1] execVM 'mk4\s\setSideSkill.sqf'};"; }; }; class CfgSounds { class wind { name="wind"; sound[]={"wind.ogg",0.5,1.0}; titles[]={}; }; };/* The syntax for the mk4_fAddToForceTracker function is as followed: [ [scope], forceName, [ "markerClass1", "markerClass2", "markerClass3" ], "groupID", "markerName","colorName", markerSize] scope => Control who is allowed to see the marker. arg can be of type: ARRAY -> You can also send a array of the following datatypes: SIDE -> Specify sides that are allowed to see the marker, [WEST] or [WEST, RESISTANCE] STRING -> To specify factions, ["CDF"] or ["CDF", "CIV_RU"] GROUP -> To specify groups, [BLU_1Plt_HQ, BLU_1Plt_1Sqd, BLU_1Plt_2Sqd] OBJECT -> To specify individual units, [plt_ldr, plt_sgt] forceName => The group reference stored in a variable (example from unit init line: BLU_1plt_HQ = (group this);), or the object's name if you want to track a vehicle. DONT SEND THE VARIABLE, SEND THE NAME OF THE VARIABLE AS A STRING!! markerClasses => The marker system now supports unlimited marker composition, so you can draw as many markers over eachother as you want. Classnames: "" (this will make it an empty marker) , "HQ", "RECON", "INFANTRY", "MOTORIZED_INF", "MECHANIZED_INF", "ARMOR", "ROTARY_WING", "FIXED_WING", "MEDICAL", "ARTILLERY", "MORTAR", "SUPPORT", "MAINTENANCE", "SERVICE", "FIRETEAM", "SQUAD", "SECTION", "PLATOON", "COMPANY", "BATTALION", "REGIMENT", "BRIGADE", "DIVISION" groupID => You will see this group name in the chat for example. Enter an empty string ("") if this is a vehicle. markerName => The text that will be shown next to the marker colorName => The color of the marker, colors: "ColorBlack", "ColorRed", "ColorGreen", "ColorBlue", "ColorYellow", "ColorOrange", "ColorWhite", "ColorPink", "ColorBrown", "ColorKhaki" markerSize => The size of X and Y of the marker: 1 Author: mikey Date: 15/3/11 */ waitUntil { MK4_INIT }; // set up group ID's and add the groups to the forceTracker // [[WEST], "BLU_1Plt_A", ["INFANTRY", "SECTION"], "1 Section ", " 1", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; // [[WEST], "BLU_1Plt_B", ["INFANTRY", "SECTION"], "2 Section ", " 2", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; //[[WEST], "WAG", ["INFANTRY", "SECTION"], "1 Section", " 1-S", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; //[[WEST], "WBG", ["INFANTRY", "FIRETEAM"], "2 Section", " 2-S", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; // [[WEST], "WCG", ["INFANTRY", "FIRETEAM"], "Alpha 2", " A-2", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; // [[WEST], "WDG", ["INFANTRY", "FIRETEAM"], "Alpha 3", " A-3", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; // [[WEST], "WEG", ["INFANTRY", "FIRETEAM"], "Whisky 1", " W-1", "ColorBlue", 0.75] spawn mk4_fAddToForceTracker; // wait until template is init and player synched waitUntil { MK4_INIT }; // create briefing execVM "briefing.sqf"; // create tasks //execVM "tasks.sqf"; // add groups and init the forceTracker //execVM "forceTracker_init.sqf"; // give a time limit warning 15, 10 and 5 minutes before the time limit hits (requires the timeLimit Param) //[timeLimit, -900, -600, -300] execVM "mk4\s\timeLimitWarning.sqf"; //[[WEST], [_taskvariable,_TaskName, _taskDescription, _taskMarker, _taskSta]] call mk4_fCreateTask; execVM "windSound.sqf";version=11; class Mission { addOns[]= { "ca_modules_e_weather", "ca_modules_functions", "cacharacters2", "CAWheeled_E_ATV", "zargabad", "caair_e_mi8", "cacharacters_e", "camisc3", "camisc_e", "cabuildings2_misc_cargo", "CAWheeled_E_SCUD", "caweapons_e", "ace_c_men", "CATracked_E", "cawheeled_e_brdm2", "ace_sys_map", "ace_sys_aitalk" }; addOnsAuto[]= { "ca_modules_e_weather", "ca_modules_functions", "cacharacters2", "caair_e_mi8", "cacharacters_e", "ace_c_men", "CATracked_E", "cawheeled_e_brdm2", "ace_sys_map", "ace_sys_aitalk", "camisc3", "CAWheeled_E_SCUD", "caweapons_e", "camisc_e", "zargabad" }; randomSeed=10565445; class Intel { briefingName="ACE co 12 Scud Storm v1"; briefingDescription="SF search for Scuds, in a sandstorm, without maps?!"; startWeather=0; startFog=0.21049668; forecastWeather=0; forecastFog=0.2982963; year=2009; day=29; hour=16; }; class Groups { items=45; class Item0 { side="LOGIC"; class Vehicles { items=1; class Item0 { position[]={2246.9463,88.958763,1328.2881}; azimut=-6.9237967; id=0; side="LOGIC"; vehicle="WeatherPostprocessManager"; leader=1; lock="UNLOCKED"; skill=0.60000002; init="this setvariable [""intensity"",0.75];"; }; }; }; class Item1 { side="LOGIC"; class Vehicles { items=1; class Item0 { position[]={2204.0322,101.93462,1330.4619}; azimut=-6.9237967; id=1; side="LOGIC"; vehicle="WeatherParticlesManager"; leader=1; lock="UNLOCKED"; skill=0.60000002; init="this setvariable [""particleEffects"",[1,2]]; this setvariable [""intensity"",0.9];"; }; }; }; class Item2 { side="LOGIC"; class Vehicles { items=1; class Item0 { position[]={2260.1396,91.957451,1400.9717}; azimut=-6.9237967; id=2; side="LOGIC"; vehicle="FunctionsManager"; leader=1; lock="UNLOCKED"; skill=0.60000002; }; }; }; class Item3 { side="LOGIC"; class Vehicles { items=1; class Item0 { position[]={2210.4521,114.75038,1395.1309}; azimut=-6.9238; id=3; side="LOGIC"; vehicle="Logic"; leader=1; skill=0.5; init="""colorCorrections"" ppEffectAdjust [2, 30, 0, [0.0, 0.0, 0.0, 0.0], [0.8*2, 0.5*2, 0.0, 0.7], [0.9, 0.9, 0.9, 0.0]]; ""colorCorrections"" ppEffectCommit 0; ""colorCorrections"" ppEffectAdjust [1, 1, 0, [0.0, 0.0, 0.0, 0.0], [0.8*2, 0.5*2, 0.0, 0.7], [0.9, 0.9, 0.9, 0.0]]; ""colorCorrections"" ppEffectAdjust [1, 0.8, -0.001, [0.0, 0.0, 0.0, 0.0], [0.8*2, 0.5*2, 0.0, 0.7], [0.9, 0.9, 0.9, 0.0]]; ""colorCorrections"" ppEffectCommit 0; ""colorCorrections"" ppEffectEnable true; ""filmGrain"" ppEffectEnable true; ""filmGrain"" ppEffectAdjust [0.02, 1, 1, 0.1, 1, false]; ""filmGrain"" ppEffectCommit 0; setviewdistance 250"; }; }; }; class Item4 { side="EAST"; class Vehicles { items=2; class Item0 { presence=0; position[]={2157.1709,104.75114,1302.5234}; id=5; side="EAST"; vehicle="RU_Soldier"; leader=1; skill=0.60000002; }; class Item1 { position[]={2158.4746,103.25476,1293.0078}; id=4; side="LOGIC"; vehicle="Logic"; skill=0.60000002; text="mk4"; init="call compile (preprocessFileLineNumbers ""mk4\s\mk4_init.sqf""); "; }; }; }; class Item5 { side="WEST"; class Vehicles { items=1; class Item0 { position[]={1531.7623,105.64884,6046.5674}; azimut=180; special="FLY"; id=6; side="WEST"; vehicle="Mi171Sh_CZ_EP1"; leader=1; skill=0.60000002; text="bird1"; init="this setcaptive true"; }; }; class Waypoints { items=2; class Item0 { position[]={1596.725,196.75452,2053.041}; type="TR UNLOAD"; combatMode="BLUE"; class Effects { }; showWP="NEVER"; }; class Item1 { position[]={3417.8057,22.35,3969.0581}; type="HOLD"; expActiv="bird1 Land ""LAND"""; class Effects { }; showWP="NEVER"; }; }; }; class Item6 { side="WEST"; class Vehicles { items=6; class Item0 { position[]={1602.7393,196.64655,2037.1421}; id=7; side="WEST"; vehicle="CZ_Special_Forces_TL_DES_EP1"; player="PLAYER COMMANDER"; leader=1; rank="LIEUTENANT"; skill=0.59999996; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""FTL""] call mk4_fLoadout; this setgroupid [""TEAM 1""];"; description="Team 1 Leader"; }; class Item1 { position[]={1605.7393,196.59787,2032.1421}; id=8; side="WEST"; vehicle="CZ_Special_Forces_MG_DES_EP1"; player="PLAY CDG"; rank="SERGEANT"; skill=0.46666664; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""AR""] call mk4_fLoadout; this setgroupid [""TEAM 1""];"; description="Team 1 Auto Rifleman"; }; class Item2 { position[]={1607.7393,196.62787,2032.1421}; id=9; side="WEST"; vehicle="CZ_Special_Forces_GL_DES_EP1"; player="PLAY CDG"; rank="SERGEANT"; skill=0.46666664; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""GN""] call mk4_fLoadout; this setgroupid [""TEAM 1""];"; description="Team 1 Operator"; }; class Item3 { position[]={1609.7393,196.74306,2032.1421}; id=10; side="WEST"; vehicle="CZ_Special_Forces_DES_EP1"; player="PLAY CDG"; rank="CORPORAL"; skill=0.33333331; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""RF"", ""FTL""] call mk4_fLoadout; this setgroupid [""TEAM 1""];"; description="Team 1 Operator"; }; class Item4 { position[]={1611.7393,196.87305,2032.1421}; id=11; side="WEST"; vehicle="ACE_CZ_Medic_EP1"; player="PLAY CDG"; rank="CORPORAL"; skill=0.33333331; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""ME""] call mk4_fLoadout; this setgroupid [""TEAM 1""];"; description="Team 1 Medic"; }; class Item5 { position[]={1613.7393,196.9594,2032.1421}; id=12; side="WEST"; vehicle="CZ_Special_Forces_Scout_DES_EP1"; player="PLAY CDG"; rank="CORPORAL"; skill=0.33333331; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""DM""] call mk4_fLoadout; this setgroupid [""TEAM 1""];"; description="Team 1 Demo Specialist"; }; }; }; class Item7 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={362.70901,59.585266,1375.6561}; azimut=226.689; id=37; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; }; class Item8 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={359.7648,59.589203,1371.8489}; azimut=355.26401; id=38; side="EAST"; vehicle="TK_Soldier_GL_EP1"; leader=1; skill=0.60000002; }; }; }; class Item9 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={363.47549,59.602409,1372.9941}; azimut=274.91199; id=39; side="EAST"; vehicle="TK_Soldier_MG_EP1"; leader=1; skill=0.60000002; }; }; }; class Item10 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={376.42703,59.731644,1338.7435}; azimut=204.79601; id=40; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; }; class Item11 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={385.10721,59.740307,1337.5078}; azimut=146.48801; id=41; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; leader=1; skill=0.60000002; }; }; }; class Item12 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={356.4379,59.574039,1358.2739}; azimut=158.901; id=43; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; class Waypoints { items=2; class Item0 { position[]={356.4379,59.574039,1358.2739}; id=43; type="SENTRY"; class Effects { }; showWP="NEVER"; }; class Item1 { position[]={381.24857,59.724964,1336.7362}; id=27; type="GETIN"; class Effects { }; showWP="NEVER"; }; }; }; class Item13 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={358.84952,59.630219,1354.1088}; azimut=287.47601; id=44; side="EAST"; vehicle="TK_Soldier_GL_EP1"; leader=1; skill=0.60000002; }; }; }; class Item14 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={359.19205,59.586075,1357.9773}; azimut=207.12399; id=45; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; leader=1; skill=0.60000002; }; }; }; class Item15 { side="EAST"; class Vehicles { items=2; class Item0 { position[]={346.3428,59.658073,1336.8094}; azimut=61.792999; id=46; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; init="nul=[this,""area2s""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={348.3721,59.663532,1337.7854}; azimut=190.368; id=47; side="EAST"; vehicle="TK_Soldier_GL_EP1"; skill=0.60000002; }; }; }; class Item16 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={952.32813,81.659103,438.18207}; azimut=379.39368; id=62; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; }; class Item17 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={953.19849,81.545204,442.91559}; azimut=507.96863; id=63; side="EAST"; vehicle="TK_Soldier_GL_EP1"; leader=1; skill=0.60000002; }; }; }; class Item18 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={950.42615,81.569679,440.1962}; azimut=427.6167; id=64; side="EAST"; vehicle="TK_Soldier_MG_EP1"; leader=1; skill=0.60000002; }; }; }; class Item19 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={926.86523,81.282135,454.4267}; azimut=316.14767; id=65; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; }; class Item20 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={922.55383,81.280251,446.79227}; azimut=257.83972; id=66; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; leader=1; skill=0.60000002; }; }; }; class Item21 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={930.82538,81.268211,453.05426}; azimut=236.22861; id=68; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; class Waypoints { items=2; class Item0 { position[]={930.82538,81.268211,453.05426}; id=68; type="SENTRY"; class Effects { }; showWP="NEVER"; }; class Item1 { position[]={923.2403,81.266159,450.66696}; id=60; type="GETIN"; class Effects { }; showWP="NEVER"; }; }; }; class Item22 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={927.29071,81.249855,449.78769}; azimut=364.80362; id=69; side="EAST"; vehicle="TK_Soldier_GL_EP1"; leader=1; skill=0.60000002; }; }; }; class Item23 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={931.14014,81.262154,450.30234}; azimut=284.45157; id=70; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; leader=1; skill=0.60000002; }; }; }; class Item24 { side="EAST"; class Vehicles { items=2; class Item0 { position[]={908.46161,81.455742,457.99692}; azimut=272.42899; id=71; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; init="nul=[this,""area1s""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={909.06647,81.431885,456.42889}; azimut=267.69559; id=72; side="EAST"; vehicle="TK_Soldier_GL_EP1"; skill=0.60000002; }; }; }; class Item25 { side="EAST"; class Vehicles { items=2; class Item0 { position[]={1004.1668,83.608757,447.98889}; azimut=223.924; id=73; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; init="nul=[this,""area1s""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={1005.7817,83.748344,446.41983}; azimut=210.54634; id=74; side="EAST"; vehicle="TK_Soldier_GL_EP1"; skill=0.60000002; }; }; }; class Item26 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1422.8833,114.28937,1424.6062}; azimut=437.03119; id=89; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; }; class Item27 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1427.3472,114.70221,1426.4043}; azimut=565.60602; id=90; side="EAST"; vehicle="TK_Soldier_GL_EP1"; leader=1; skill=0.60000002; }; }; }; class Item28 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1423.5662,114.50566,1427.2902}; azimut=485.25421; id=91; side="EAST"; vehicle="TK_Soldier_MG_EP1"; leader=1; skill=0.60000002; }; }; }; class Item29 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1422.9752,116.32284,1454.8093}; azimut=373.78516; id=92; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; }; class Item30 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1414.2186,115.34447,1454.3646}; azimut=315.47717; id=93; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; leader=1; skill=0.60000002; }; }; }; class Item31 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1423.9352,116.0712,1450.7295}; azimut=293.86603; id=95; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; }; }; class Waypoints { items=2; class Item0 { position[]={1423.9352,116.0712,1450.7295}; id=95; type="SENTRY"; class Effects { }; showWP="NEVER"; }; class Item1 { position[]={1417.8589,115.80534,1455.8585}; id=87; type="GETIN"; class Effects { }; showWP="NEVER"; }; }; }; class Item32 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1419.2845,115.62228,1451.9666}; azimut=422.4411; id=96; side="EAST"; vehicle="TK_Soldier_GL_EP1"; leader=1; skill=0.60000002; }; }; }; class Item33 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1421.7794,115.65806,1448.9906}; azimut=342.08905; id=97; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; leader=1; skill=0.60000002; }; }; }; class Item34 { side="EAST"; class Vehicles { items=2; class Item0 { position[]={1415.882,116.60974,1473.0408}; azimut=196.758; id=98; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; init="nul=[this,""area3s""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={1415.1387,116.45647,1470.9156}; azimut=325.33301; id=99; side="EAST"; vehicle="TK_Soldier_GL_EP1"; skill=0.60000002; }; }; }; class Item35 { side="EAST"; class Vehicles { items=2; class Item0 { position[]={1459.0562,115.03301,1386.0288}; azimut=196.758; id=100; side="EAST"; vehicle="TK_Soldier_EP1"; leader=1; skill=0.60000002; init="nul=[this,""area3s""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={1458.3127,114.87262,1383.9033}; azimut=325.33301; id=101; side="EAST"; vehicle="TK_Soldier_GL_EP1"; skill=0.60000002; }; }; }; class Item36 { side="WEST"; class Vehicles { items=6; class Item0 { position[]={1603.6711,196.84631,2027.1338}; id=102; side="WEST"; vehicle="CZ_Special_Forces_TL_DES_EP1"; player="PLAY CDG"; leader=1; rank="LIEUTENANT"; skill=0.59999996; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""FTL""] call mk4_fLoadout; this setgroupid [""TEAM 2""];"; description="Team 2 Leader"; }; class Item1 { position[]={1606.6711,197.33371,2022.1338}; id=103; side="WEST"; vehicle="CZ_Special_Forces_MG_DES_EP1"; player="PLAY CDG"; rank="SERGEANT"; skill=0.46666664; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""AR""] call mk4_fLoadout; this setgroupid [""TEAM 2""];"; description="Team 2 Auto Rifleman"; }; class Item2 { position[]={1608.6711,197.49525,2022.1338}; id=104; side="WEST"; vehicle="CZ_Special_Forces_GL_DES_EP1"; player="PLAY CDG"; rank="SERGEANT"; skill=0.46666664; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""GN""] call mk4_fLoadout; this setgroupid [""TEAM 2""];"; description="Team 2 Operator"; }; class Item3 { position[]={1610.6711,197.6263,2022.1338}; id=105; side="WEST"; vehicle="CZ_Special_Forces_DES_EP1"; player="PLAY CDG"; rank="CORPORAL"; skill=0.33333331; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""RF""] call mk4_fLoadout; this setgroupid [""TEAM 2""];"; description="Team 2 Operator"; }; class Item4 { position[]={1612.6711,197.76126,2022.1338}; id=106; side="WEST"; vehicle="ACE_CZ_Medic_EP1"; player="PLAY CDG"; rank="CORPORAL"; skill=0.33333331; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""ME""] call mk4_fLoadout; this setgroupid [""TEAM 2""];"; description="Team 2 Medic"; }; class Item5 { position[]={1614.6711,197.89027,2022.1338}; id=107; side="WEST"; vehicle="CZ_Special_Forces_Scout_DES_EP1"; player="PLAY CDG"; rank="CORPORAL"; skill=0.33333331; init="if (( isServer ) && (time == 0)) then {this moveinCargo bird1}; WAG = (group this); [this, ""WHITE""] call mk4_fAssignTeam; [this, ""SF"", ""DM""] call mk4_fLoadout; this setgroupid [""TEAM 2""];"; description="Team 2 Demo Specialist"; }; }; }; class Item37 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={1168.2397,77.14476,885.23193}; id=108; side="EAST"; vehicle="BMP2_TK_EP1"; leader=1; rank="CORPORAL"; skill=0.33333331; init="nul=[this,""areaL"",""random""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; }; }; class Item38 { side="EAST"; class Vehicles { items=4; class Item0 { position[]={1837.6973,220.97356,1090.4102}; id=109; side="EAST"; vehicle="TK_Soldier_SL_EP1"; leader=1; rank="CORPORAL"; skill=0.33333331; init="nul=[this,""areaL"",""random""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={1843.0396,221.55466,1082.5107}; id=110; side="EAST"; vehicle="TK_Soldier_B_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item2 { position[]={1852.4418,221.80815,1084.6455}; id=111; side="EAST"; vehicle="TK_Soldier_GL_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item3 { position[]={1863.34,220.9691,1082.9375}; id=112; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; rank="CORPORAL"; skill=0.33333331; }; }; }; class Item39 { side="EAST"; class Vehicles { items=4; class Item0 { position[]={289.08533,93.086517,1845.4336}; id=113; side="EAST"; vehicle="TK_Soldier_SL_EP1"; leader=1; rank="CORPORAL"; skill=0.33333331; init="nul=[this,""areaL"",""random""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={294.42761,92.222153,1837.5342}; id=114; side="EAST"; vehicle="TK_Soldier_B_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item2 { position[]={303.82983,92.478592,1839.6689}; id=115; side="EAST"; vehicle="TK_Soldier_GL_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item3 { position[]={314.72803,92.744728,1837.9609}; id=116; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; rank="CORPORAL"; skill=0.33333331; }; }; }; class Item40 { side="EAST"; class Vehicles { items=4; class Item0 { position[]={477.65118,177.08151,232.06982}; id=117; side="EAST"; vehicle="TK_Soldier_SL_EP1"; leader=1; rank="CORPORAL"; skill=0.33333331; init="nul=[this,""areaL"",""random""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={482.99347,177.64308,224.17041}; id=118; side="EAST"; vehicle="TK_Soldier_B_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item2 { position[]={492.39569,178.66948,226.30518}; id=119; side="EAST"; vehicle="TK_Soldier_GL_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item3 { position[]={503.29388,179.35814,224.59717}; id=120; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; rank="CORPORAL"; skill=0.33333331; }; }; }; class Item41 { side="EAST"; class Vehicles { items=4; class Item0 { position[]={1534.6829,123.1433,194.91992}; id=121; side="EAST"; vehicle="TK_Soldier_SL_EP1"; leader=1; rank="CORPORAL"; skill=0.33333331; init="nul=[this,""areaL"",""random""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; class Item1 { position[]={1540.0251,121.3583,187.02051}; id=122; side="EAST"; vehicle="TK_Soldier_B_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item2 { position[]={1549.4275,120.32522,189.15527}; id=123; side="EAST"; vehicle="TK_Soldier_GL_EP1"; rank="CORPORAL"; skill=0.33333331; }; class Item3 { position[]={1560.3257,118.85223,187.44727}; id=124; side="EAST"; vehicle="TK_Soldier_LAT_EP1"; rank="CORPORAL"; skill=0.33333331; }; }; }; class Item42 { side="EAST"; class Vehicles { items=1; class Item0 { position[]={873.43939,65.768127,1153.2417}; id=125; side="EAST"; vehicle="BRDM2_TK_EP1"; leader=1; rank="CORPORAL"; skill=0.33333331; init="nul=[this,""areaL"",""random""] execVM ""mk4\f\ai\fUPS.sqf""; "; }; }; }; class Item43 { side="LOGIC"; class Vehicles { items=1; class Item0 { position[]={2335.5564,84.640068,1329.1206}; id=126; side="LOGIC"; vehicle="ACE_Map_Logic"; leader=1; lock="UNLOCKED"; skill=0.60000002; }; }; }; class Item44 { side="LOGIC"; class Vehicles { items=1; class Item0 { position[]={2306.2915,94.901833,1281.832}; id=127; side="LOGIC"; vehicle="ACE_AITalk_Logic"; leader=1; lock="UNLOCKED"; skill=0.60000002; }; }; }; }; class Vehicles { items=55; class Item0 { position[]={1596.9092,196.77371,2054.208}; id=13; side="EMPTY"; vehicle="HeliHEmpty"; skill=0.60000002; }; class Item1 { position[]={352.59354,59.530415,1380.2137}; azimut=29.380217; id=14; side="EMPTY"; vehicle="Land_tent_east"; skill=0.60000002; }; class Item2 { position[]={386.37796,59.748413,1354.6783}; azimut=29.380217; id=15; side="EMPTY"; vehicle="Land_tent_east"; skill=0.60000002; }; class Item3 { position[]={368.46964,59.627419,1369.5017}; azimut=215; id=16; side="EMPTY"; vehicle="MAZ_543_SCUD_TK_EP1"; lock="LOCKED"; skill=0.60000002; text="scud2V"; }; class Item4 { position[]={375.00797,59.71463,1336.5623}; azimut=215; id=17; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item5 { position[]={377.69693,59.714241,1335.4001}; azimut=551.43951; id=18; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item6 { position[]={380.56766,59.724258,1335.073}; azimut=181.02232; id=19; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item7 { position[]={383.51077,59.732498,1335.2555}; azimut=173.39589; id=20; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item8 { position[]={386.30862,59.737312,1336.3083}; azimut=146.15152; id=21; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item9 { position[]={378.68802,59.656719,1375.6201}; azimut=63.500298; id=22; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item10 { position[]={376.87943,59.647385,1377.9252}; azimut=399.93994; id=23; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item11 { position[]={374.5126,59.637325,1379.5815}; azimut=29.522665; id=24; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item12 { position[]={371.83902,59.629196,1380.826}; azimut=21.896252; id=25; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item13 { position[]={368.87833,59.614391,1381.2351}; azimut=-5.3481364; id=26; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item14 { position[]={381.24857,59.724964,1336.7362}; azimut=171.80452; id=27; side="EMPTY"; vehicle="DSHKM_TK_INS_EP1"; skill=0.60000002; }; class Item15 { position[]={375.90579,59.669292,1365.0693}; azimut=140; id=28; side="EMPTY"; vehicle="Land_CamoNetVar_EAST_EP1"; leader=1; skill=0.60000002; }; class Item16 { position[]={373.81558,59.669247,1364.1001}; azimut=140; id=29; side="EMPTY"; vehicle="PowGen_Big_EP1"; leader=1; skill=0.60000002; }; class Item17 { position[]={377.2908,59.664242,1366.8021}; azimut=140; id=30; side="EMPTY"; vehicle="PowGen_Big_EP1"; leader=1; skill=0.60000002; }; class Item18 { position[]={352.92422,59.553791,1359.8026}; azimut=-91.016685; id=31; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item19 { position[]={353.56485,59.576836,1356.9438}; azimut=245.4229; id=32; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item20 { position[]={354.9888,59.614944,1354.4302}; azimut=-124.99435; id=33; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item21 { position[]={356.86636,59.659431,1352.1563}; azimut=-132.62077; id=34; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item22 { position[]={359.36319,59.672123,1350.5135}; azimut=-159.86516; id=35; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item23 { position[]={361.02664,59.585484,1373.9298}; azimut=379.89618; id=36; side="EMPTY"; vehicle="Land_Fire_barrel"; skill=0.60000002; init="this inflame true"; }; class Item24 { position[]={357.40042,59.593025,1356.0636}; azimut=312.10779; id=42; side="EMPTY"; vehicle="Land_Fire_barrel"; skill=0.60000002; init="this inflame true"; }; class Item25 { position[]={936.27454,81.404778,436.00308}; azimut=17.284304; id=48; side="EMPTY"; vehicle="Land_tent_east"; skill=0.60000002; }; class Item26 { position[]={943.3067,81.312904,449.17679}; azimut=292.328; id=49; side="EMPTY"; vehicle="MAZ_543_SCUD_TK_EP1"; lock="LOCKED"; skill=0.60000002; text="scud1V"; }; class Item27 { position[]={925.35022,81.291359,456.54257}; azimut=326.35168; id=50; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item28 { position[]={923.28888,81.278168,454.46146}; azimut=662.7912; id=51; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item29 { position[]={921.93915,81.27623,451.90683}; azimut=292.37405; id=52; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item30 { position[]={921.03723,81.28756,449.09924}; azimut=284.74765; id=53; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item31 { position[]={920.99927,81.298637,446.11011}; azimut=257.50323; id=54; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item32 { position[]={952.63013,81.731079,435.15164}; azimut=140.8279; id=55; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item33 { position[]={954.48236,81.730072,437.42178}; azimut=477.26755; id=56; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item34 { position[]={955.57898,81.696411,440.09433}; azimut=106.85027; id=57; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item35 { position[]={956.20685,81.617943,442.97586}; azimut=99.223854; id=58; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item36 { position[]={955.95642,81.535271,445.95407}; azimut=71.979469; id=59; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item37 { position[]={923.2403,81.266159,450.66696}; azimut=283.15628; id=60; side="EMPTY"; vehicle="DSHKM_TK_INS_EP1"; skill=0.60000002; }; class Item38 { position[]={953.03149,81.619934,440.4877}; azimut=532.60077; id=61; side="EMPTY"; vehicle="Land_Fire_barrel"; skill=0.60000002; init="this inflame true"; }; class Item39 { position[]={928.88,81.267799,451.6304}; azimut=389.43539; id=67; side="EMPTY"; vehicle="Land_Fire_barrel"; skill=0.60000002; init="this inflame true"; }; class Item40 { position[]={1412.449,114.35029,1436.9994}; azimut=74.921745; id=75; side="EMPTY"; vehicle="Land_tent_east"; skill=0.60000002; }; class Item41 { position[]={1427.3416,115.5624,1438.1116}; azimut=349.965; id=76; side="EMPTY"; vehicle="MAZ_543_SCUD_TK_EP1"; lock="LOCKED"; skill=0.60000002; text="scud3V"; }; class Item42 { position[]={1423.9509,116.59971,1457.2217}; azimut=383.9892; id=77; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item43 { position[]={1421.0903,116.30713,1457.8485}; azimut=720.42847; id=78; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item44 { position[]={1418.2092,115.9893,1457.6215}; azimut=350.01154; id=79; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item45 { position[]={1415.3555,115.62048,1456.8804}; azimut=342.38513; id=80; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item46 { position[]={1412.8099,115.32169,1455.3124}; azimut=315.14069; id=81; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item47 { position[]={1420.4847,114.03599,1422.7288}; azimut=198.46533; id=82; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item48 { position[]={1423.3937,114.19041,1422.379}; azimut=534.90497; id=83; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item49 { position[]={1426.2385,114.41248,1422.8834}; azimut=164.4877; id=84; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item50 { position[]={1429.0088,114.65235,1423.8958}; azimut=156.8613; id=85; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item51 { position[]={1431.3903,114.92943,1425.7013}; azimut=129.6169; id=86; side="EMPTY"; vehicle="Land_fort_bagfence_long"; skill=0.60000002; }; class Item52 { position[]={1417.8589,115.80534,1455.8585}; azimut=340.79376; id=87; side="EMPTY"; vehicle="DSHKM_TK_INS_EP1"; skill=0.60000002; }; class Item53 { position[]={1425.2074,114.48248,1425.2458}; azimut=590.23804; id=88; side="EMPTY"; vehicle="Land_Fire_barrel"; skill=0.60000002; init="this inflame true"; }; class Item54 { position[]={1421.6909,115.87439,1451.6108}; azimut=447.07288; id=94; side="EMPTY"; vehicle="Land_Fire_barrel"; skill=0.60000002; init="this inflame true"; }; }; class Markers { items=4; class Item0 { position[]={947.01105,81.169785,471.51611}; name="area1s"; markerType="ELLIPSE"; type="Empty"; a=150; b=150; }; class Item1 { position[]={1424.8673,115.44377,1439.334}; name="area3s"; markerType="ELLIPSE"; type="Empty"; a=150; b=150; }; class Item2 { position[]={372.68958,59.671043,1350.9873}; name="area2s"; markerType="ELLIPSE"; type="Empty"; a=150; b=150; }; class Item3 { position[]={1002.1622,71.10466,1002.9058}; name="areaL"; markerType="RECTANGLE"; type="Empty"; a=1000; b=1000; }; }; class Sensors { items=8; class Item0 { position[]={371.05215,59.652184,1354.0366}; a=0; b=0; timeoutMax=5; interruptable=1; age="UNKNOWN"; expCond="!(alive scud2V )"; expActiv="if ( isServer ) then { scud2 = true; publicVariable ""scud2""; }; player sidechat ""Scud 2 Destroyed"""; class Effects { }; }; class Item1 { position[]={929.8974,81.346306,437.86667}; a=0; b=0; angle=77.327599; activationBy="WEST SEIZED"; timeoutMax=5; interruptable=1; age="UNKNOWN"; expCond="!(alive scud1V )"; expActiv="if ( isServer ) then { scud1 = true; publicVariable ""scud1""; }; player sidechat ""Scud 1 Destroyed"""; class Effects { }; }; class Item2 { position[]={1410.6101,114.47391,1443.384}; a=0; b=0; angle=134.965; timeoutMax=5; interruptable=1; age="UNKNOWN"; expCond="!(alive scud3V )"; expActiv="if ( isServer ) then { scud3 = true; publicVariable ""scud3""; }; player sidechat ""Scud 3 Destroyed""; "; class Effects { }; }; class Item3 { position[]={2030.2528,170.19727,1697.4814}; a=0; b=0; interruptable=1; age="UNKNOWN"; expCond="scud1"; expActiv="task1 setTaskState ""Succeeded""; [task1] call mk_fTaskHint; "; class Effects { }; }; class Item4 { position[]={2029.0532,164.42413,1654.335}; a=0; b=0; interruptable=1; age="UNKNOWN"; expCond="scud2"; expActiv="task2 setTaskState ""Succeeded""; [task2] call mk_fTaskHint; "; class Effects { }; }; class Item5 { position[]={2029.0532,167.22693,1601.6011}; a=0; b=0; interruptable=1; age="UNKNOWN"; expCond="scud2"; expActiv="task3 setTaskState ""Succeeded""; [task3] call mk_fTaskHint; "; class Effects { }; }; class Item6 { position[]={2031.6084,160.78876,1768.9487}; a=0; b=0; timeoutMin=15; timeoutMid=15; timeoutMax=15; age="UNKNOWN"; expCond="scud1 && scud2 && scud3"; expActiv="objAllDone = true"; class Effects { }; }; class Item7 { position[]={999.70642,70.920219,1005.104}; a=1500; b=1500; rectangular=1; activationBy="EAST"; interruptable=1; age="UNKNOWN"; expActiv="{ _x setBehaviour ""SAFE""} forEach thisList"; class Effects { }; }; }; }; class Intro { addOns[]= { "zargabad" }; addOnsAuto[]= { "zargabad" }; randomSeed=7428049; class Intel { startWeather=0.25; forecastWeather=0; year=2009; day=29; hour=11; }; }; class OutroWin { addOns[]= { "zargabad" }; addOnsAuto[]= { "zargabad" }; randomSeed=11106053; class Intel { startWeather=0.25; forecastWeather=0; year=2009; day=29; hour=11; }; }; class OutroLoose { addOns[]= { "zargabad" }; addOnsAuto[]= { "zargabad" }; randomSeed=1223972; class Intel { startWeather=0.25; forecastWeather=0; year=2009; day=29; hour=11; }; }; - MK4_ACE variable was wrong - changed template island to default BIS island - added fSetRuckMagazines function - added fSetRuckWeapons function - added fSetWeaponOnBack functionprivate "_unit"; _unit = _this select 0; if ( local _unit ) then { _this spawn { _unit = _this select 0; doStop _unit; }; }; true // ret private ["_units", "_radius", "_houses", "_buildingPositions", "_i"]; _units = _this select 0; _radius = _this select 1; if ( !isServer ) exitWith { }; if ( count _units == 0 ) exitWith { }; // collect an array of all houses in the specified radius, quit if none found _houses = nearestObjects [(_units select 0), ["house"], _radius]; if ( (count _houses) == 0 ) exitWith { }; // list all major building positions _buildingPositions = []; { if ( (((_x buildingPos 6) select 0) != 0) && (alive _x) ) then // filter out small houses that arent enterable anyway { for [{_i = 0}, { true }, {_i = _i + 1}] do { if ( ((_x buildingPos _i) select 0) == 0 ) exitWith { }; _buildingPositions set [count _buildingPositions, (_x buildingPos _i)]; }; }; } forEach _houses; mk4_buildingPositions = _buildingPositions; // now send every given unit to a random building position { {deleteWaypoint _x} forEach waypoints (group _x); (group _x) setSpeedMode "FULL"; (group _x) setBehaviour "CARELESS"; _x allowFleeing 0; _x setSkill ["Courage", 1]; _x doMove (_buildingPositions select (floor(random(count _buildingPositions)))); } forEach _units; true // ret /* ======================================================================================================================= Script: BIN_taskDefend.sqf v1.4 Author(s): Binesi Partly based on original code by BIS Description: Group will man all nearby static defenses and vehicle turrets and guard/patrol the position and surrounding area. Parameter(s): _this select 0: group (Group) _this select 1: defense position (Array) Returns: Boolean - success flag Example(s): null = [group this,(getPos this)] execVM "BIN_taskDefend.sqf" ----------------------------------------------------------------------------------------------------------------------- Notes: To prevent this script from manning vehicle turrets find and replace "LandVehicle" with "StaticWeapon". The "DISMISS" waypoint is nice but bugged in a few ways. The odd hacks in this code are used to force the desired behavior. The ideal method would be to write a new FSM and I may attempt that in a future project if no one else does. ======================================================================================================================= */ _this spawn { private ["_grp", "_pos"]; _grp = _this select 0; _pos = _this select 1; _grp setBehaviour "SAFE"; private ["_list", "_units","_staticWeapons"]; _list = _pos nearObjects ["LandVehicle", 120]; _units = (units _grp) - [leader _grp]; // The leader should not man defenses _staticWeapons = []; // Find all nearby static defenses or vehicles without a gunner { if ((_x emptyPositions "gunner") > 0) then { _staticWeapons = _staticWeapons + [_x]; }; } forEach _list; // Have the group man empty static defenses and vehicle turrets { // Are there still units available? if ((count _units) > 0) then { private ["_unit"]; _unit = (_units select ((count _units) - 1)); _unit assignAsGunner _x; [_unit] orderGetIn true; sleep 16; // Give gunner time to get in, otherwise force. _unit moveInGunner _x; _units resize ((count _units) - 1); }; } forEach _staticWeapons; // Setup Waypoints private ["_wp1","_wp2","_wp3","_wp4"]; _wp1 = _grp addWaypoint [_pos, 0]; _wp1 setWaypointType "MOVE"; [_grp, 1] setWaypointSpeed "LIMITED"; [_grp, 1] setWaypointBehaviour "SAFE"; [_grp, 1] setWaypointCombatMode "YELLOW"; [_grp, 1] setWaypointFormation "STAG COLUMN"; [_grp, 1] setWaypointCompletionRadius 50; [_grp, 1] setWaypointStatements ["true", "null = [this] spawn { _grp = group (_this select 0); sleep (30+(random 60)); {doStop _x} forEach units _grp; _grp setCurrentWaypoint [_grp,3]; {_x doMove getPos _x} forEach units _grp; sleep 1; {_x forceSpeed 3} forEach units _grp; if ((random 3)> 2) then {sleep 3} else {sleep 30 + (random 30)}; _grp setCurrentWaypoint [_grp, 1]; }; "]; _wp2 = _grp addWaypoint [_pos, 0]; _wp2 setWaypointType "DISMISS"; [_grp, 2] setWaypointStatements ["true", "null = [this] spawn { _grp = group (_this select 0); {_x forceSpeed -1 } forEach units _grp; }; "]; _wp3 = _grp addWaypoint [_pos, 0]; _wp3 setWaypointType "SAD"; [_grp, 3] setWaypointSpeed "FULL"; [_grp, 3] setWaypointBehaviour "ALERT"; [_grp, 3] setWaypointCombatMode "RED"; [_grp, 3] setWaypointFormation "VEE"; [_grp, 3] setWaypointCompletionRadius 50; [_grp, 3] setWaypointStatements ["true", "null = [this] spawn { _grp = group (_this select 0); _list = position (_this select 0) nearObjects ['LandVehicle', 30]; _static_weapons = []; { if ((_x emptyPositions 'gunner') > 0) then { _static_weapons = _static_weapons + [_x]; }; } forEach _list; { _units = units _grp; if ((count _units) > 0) then { _unit = (_units select ((count _units) - 1)); _unit assignAsGunner _x; [_unit] orderGetIn true; _unit spawn { _this moveInGunner _x; }; _units resize ((count _units) - 1); }; } forEach _static_weapons; _grp setCurrentWaypoint [_grp, 1]; }; "]; _wp4 = _grp addWaypoint [_pos, 0]; _wp4 setWaypointType "CYCLE"; // Redundant failsafe }; true // ret/* ======================================================================================================================= Script: BIN_taskPatrol.sqf v1.4 Author(s): Binesi Partly based on original code by BIS Description: Creates a continually randomized patrol path which circles and intersects a given position. Parameter(s): _this select 0: the group to which to assign the waypoints (Group) _this select 1: the position on which to base the patrol (Array) _this select 2: the maximum distance between waypoints (Number) _this select 3: (optional) debug markers on or off (Number) _this select 4: (optional) blacklist of areas (Array) Returns: Boolean - success flag Example(s): null = [group this,(getPos this),250] execVM "BIN_taskPatrol.sqf" null = [group this,(getPos this),250,1] execVM "BIN_taskPatrol.sqf" // Same with debug markers ----------------------------------------------------------------------------------------------------------------------- Notes: Edited by mikey - debug markers will now be on if mk4_debugMode > 0 ======================================================================================================================= */ _this spawn { _grp = _this select 0; _pos = _this select 1; _max_dist = _this select 2; _debug = if ((count _this) > 3) then {_this select 3} else {0}; _blacklist = if ((count _this) > 4) then {_blacklist = _this select 4} else {[]}; //_mode = ["YELLOW", "RED"] call BIS_fnc_selectRandom; _mode = "RED"; _formation = ["STAG COLUMN", "FILE", "DIAMOND"] call BIS_fnc_selectRandom; _grp setBehaviour "SAFE"; _grp setSpeedMode "LIMITED"; _grp setCombatMode _mode; _grp setFormation _formation; _center_x = (_pos) select 0; _center_y = (_pos) select 1; _center_z = (_pos) select 2; if(isNil "_center_z")then{_center_z = 0;}; _wp_count = 4 + (floor random 3) + (floor (_max_dist / 100 )); _angle = (360 / (_wp_count -1)); _new_angle = 0; _wp_array = []; _slack = _max_dist / 5.5; if ( _slack < 20 ) then { _slack = 20 }; _angle_offset = random 360; while {count _wp_array < _wp_count} do { private ["_x1","_y1","_wp_pos", "_prepos","_bldgpos","_bldgs"]; _newangle = (count _wp_array * _angle) + _angle_offset; _x1 = _center_x - (sin _newangle * _max_dist); _y1 = _center_y - (cos _newangle * _max_dist); _prepos = [_x1, _y1, _center_z]; if ( isNil "_center_z" ) then { _prepos = [_x1, _y1]; }; _wp_pos = [_prepos, 0, _slack, 6, 0, 50 * (pi / 180), 0, _blacklist] call BIS_fnc_findSafePos; if (leader _grp isKindOf "Man") then { ////////////////////////////////////////////////////////////////// // The following code is an extract from Random Building Position Script v1.0 by Tophe of stgta Ops ////////////////////////////////////////////////////////////////// _bldgpos = []; _bldgs = nearestObjects [_wp_pos, ["Building"], 50]; { private["_i","_y"]; _i = 0; _y = _x buildingPos _i; while {format["%1", _y] != "[0,0,0]"} do { _bldgpos = _bldgpos + [_y]; _i = _i + 1; _y = _x buildingPos _i; }; } forEach _bldgs; if(count _bldgpos != 0) then {_wp_pos = _bldgpos call BIS_fnc_selectRandom;}; _wp_array = _wp_array + [_wp_pos]; sleep 0.5; }; }; sleep 1; for "_i" from 1 to (_wp_count - 1) do { private ["_wp","_cur_pos","_marker","_marker_name"]; _cur_pos = (_wp_array select _i); // Create waypoints based on array of positions _wp = _grp addWaypoint [_cur_pos, 0]; _wp setWaypointType "MOVE"; _wp setWaypointCompletionRadius (5 + _slack); [_grp,_i] setWaypointTimeout [0, 2, 16]; // When completing waypoint have 33% chance to choose a random next wp [_grp,_i] setWaypointStatements ["true", "if ((random 3) > 2) then { group this setCurrentWaypoint [(group this), (floor (random (count (waypoints (group this)))))];};"]; if (_debug > 0) then { _marker_name = str(_wp_array select _i); _marker = createMarker[_marker_name,[_cur_pos select 0,_cur_pos select 1]]; _marker setMarkerShape "ICON"; _marker_name setMarkerType "DOT"; }; sleep 0.5; }; // End back near start point and then pick a new random point _wp1 = _grp addWaypoint [_pos, 0]; _wp1 setWaypointType "SAD"; _wp1 setWaypointCompletionRadius (random (_max_dist)); [_grp,(count waypoints _grp)] setWaypointStatements ["true", "group this setCurrentWaypoint [(group this), (round (random 2) + 1)];"]; // Cycle in case we reach the end _wp2 = _grp addWaypoint [_pos, 0]; _wp2 setWaypointType "CYCLE"; _wp2 setWaypointCompletionRadius 100; }; true // ret // ========================================================================================================= // Urban Patrol Script // Version: 2.1.0 // Author: Kronzky (www.kronzky.info / kronzky@gmail.com) // --------------------------------------------------------------------------------------------------------- // Required parameters: // unit = Unit to patrol area (1st argument) // markername = Name of marker that covers the active area. (2nd argument) // (e.g. nul=[this,"town"] execVM "mk4\s\ups.sqf"; ) // // Optional parameters: // random = Place unit at random start position. // randomdn = Only use random positions on ground level. // randomup = Only use random positions at top building positions. // min:n/max:n = Create a random number (between min and max) of 'clones'. // init:string = Cloned units' init string. // prefix:string = Cloned units' names will start with this prefix. // nomove = Unit will stay at start position until enemy is spotted. // nofollow = Unit will only follow an enemy within the marker area. // delete:n = Delete dead units after 'n' seconds. // nowait = Do not wait at patrol end points. // noslow = Keep default behaviour of unit (don't change to "safe" and "limited"). // noai = Don't use enhanced AI for evasive and flanking maneuvers. // showmarker = Display the area marker. // trigger = Display a message when no more units are left in sector. // empty:n = Consider area empty, even if 'n' units are left. // track = Display a position and destination marker for each unit. // // ========================================================================================================= // hide the area marker quickly (_this select 1) setMarkerAlphaLocal 0; if (!isServer) exitWith {}; _this spawn { // how far opfors should move away if they're under attack // set this to 200-300, when using the script in open areas (rural surroundings) #define SAFEDIST 75 // how close unit has to be to target to generate a new one #define CLOSEENOUGH 10 // how close units have to be to each other to share information #define SHAREDIST 100 // how long AI units should be in alert mode after initially spotting an enemy #define ALERTTIME 180 // --------------------------------------------------------------------------------------------------------- //echo format["[K] %1",_this]; // convert argument list to uppercase _UCthis = []; for [{_i=0},{_i=0} do {_bp = _bld BuildingPos _bi;if ((_bp select 0)==0) then {_bi=-99} else {_bz=_bp select 2; _higher = ((_bz>_maxZ) || ((abs(_bz-_maxZ)<.5) && (random 1>.5))); if ((_bz>4) && _higher) then {_maxZ=_bz; _bldpos=_bi}};_bi=_bi+1};_bldpos}; KRON_OnRoad = {private["_pos","_car","_tries","_lst"];_pos=_this select 0; _car=_this select 1; _tries=_this select 2; _lst=_pos nearRoads 4; if ((count _lst!=0) && (_car || !(surfaceIsWater _pos))) then {_tries=99}; (_tries+1)}; KRON_getDirPos = {private["_a","_b","_from","_to","_return"]; _from = _this select 0; _to = _this select 1; _return = 0; _a = ((_to select 0) - (_from select 0)); _b = ((_to select 1) - (_from select 1)); if (_a != 0 || _b != 0) then {_return = _a atan2 _b}; if ( _return < 0 ) then { _return = _return + 360 }; _return}; KRON_distancePosSqr = {(((_this select 0) select 0)-((_this select 1) select 0))^2 + (((_this select 0) select 1)-((_this select 1) select 1))^2}; KRON_relPos = {private["_p","_d","_a","_x","_y","_xout","_yout"];_p=_this select 0; _x=_p select 0; _y=_p select 1; _d=_this select 1; _a=_this select 2; _xout=_x + sin(_a)*_d; _yout=_y + cos(_a)*_d;[_xout,_yout,0]}; KRON_rotpoint = {private["_cp","_a","_tx","_ty","_cd","_sd","_cx","_cy","_xout","_yout"];_cp=_this select 0; _cx=_cp select 0; _cy=_cp select 1; _a=_this select 1; _cd=cos(_a*-1); _sd=sin(_a*-1); _tx=_this select 2; _ty=_this select 3; _xout=if (_a!=0) then {_cx+ (_cd*_tx - _sd*_ty)} else {_cx+_tx}; _yout=if (_a!=0) then {_cy+ (_sd*_tx + _cd*_ty)} else {_cy+_ty}; [_xout,_yout,0]}; KRON_stayInside = { private["_np","_nx","_ny","_cp","_cx","_cy","_rx","_ry","_d","_tp","_tx","_ty","_fx","_fy"]; _np=_this select 0; _nx=_np select 0; _ny=_np select 1; _cp=_this select 1; _cx=_cp select 0; _cy=_cp select 1; _rx=_this select 2; _ry=_this select 3; _d=_this select 4; _tp = [_cp,_d,(_nx-_cx),(_ny-_cy)] call KRON_rotpoint; _tx = _tp select 0; _fx=_tx; _ty = _tp select 1; _fy=_ty; if (_tx<(_cx-_rx)) then {_fx=_cx-_rx}; if (_tx>(_cx+_rx)) then {_fx=_cx+_rx}; if (_ty<(_cy-_ry)) then {_fy=_cy-_ry}; if (_ty>(_cy+_ry)) then {_fy=_cy+_ry}; if ((_fx!=_tx) || (_fy!=_ty)) then {_np = [_cp,_d*-1,(_fx-_cx),(_fy-_cy)] call KRON_rotpoint}; _np; }; // Misc KRON_getArg = {private["_cmd","_arg","_list","_a","_v"]; _cmd=_this select 0; _arg=_this select 1; _list=_this select 2; _a=-1; {_a=_a+1; _v=format["%1",_list select _a]; if (_v==_cmd) then {_arg=(_list select _a+1)}} foreach _list; _arg}; KRON_deleteDead = {private["_u","_s"];_u=_this select 0; _s= _this select 1; _u removeAllEventHandlers "killed"; sleep _s; deletevehicle _u}; KRON_AllWest=[]; KRON_AllEast=[]; KRON_AllRes=[]; KRON_KnownEnemy=[objNull,objNull]; // find all units in mission { _s = side _x; switch (_s) do { case west: { KRON_AllWest=KRON_AllWest+[_x]; }; case east: { KRON_AllEast=KRON_AllEast+[_x]; }; case resistance: { KRON_AllRes=KRON_AllRes+[_x]; }; }; }forEach allUnits; if (isNil("KRON_UPS_Debug")) then {KRON_UPS_Debug=0}; KRON_HQ="Logic" createVehicleLocal [0,0]; KRON_UPS_Instances=0; KRON_UPS_Total=0; KRON_UPS_Exited=0; KRON_UPS_INIT=1; }; if ((count _this)<2) exitWith { if (format["%1",_this]!="INIT") then {hint "UPS: Unit and marker name have to be defined!"}; }; _exit = false; _onroof = false; // --------------------------------------------------------------------------------------------------------- waitUntil {KRON_UPS_INIT==1}; sleep (random 1); KRON_UPS_Instances = KRON_UPS_Instances + 1; // get name of area marker _areamarker = _this select 1; if (isNil ("_areamarker")) exitWith { hint "UPS: Area marker not defined.\n(Typo, or name not enclosed in quotation marks?)"; }; _centerpos = []; _centerX = []; _centerY = []; _rangeX = 0; _rangeY = 0; _areadir = 0; _areaname = ""; _areatrigger = objNull; _showmarker = "HIDEMARKER"; _getAreaInfo = { if (typeName _areamarker=="String") then { // remember center position of area marker _centerpos = getMarkerPos _areamarker; _centerX = abs(_centerpos select 0); _centerY = abs(_centerpos select 1); // X/Y range of target area _areasize = getMarkerSize _areamarker; _rangeX = _areasize select 0; _rangeY = _areasize select 1; // marker orientation (needed as negative value!) _areadir = (markerDir _areamarker) * -1; _areaname = _areamarker; // show area marker _showmarker = if ("SHOWMARKER" in _UCthis) then {"SHOWMARKER"} else {"HIDEMARKER"}; if (_showmarker=="HIDEMARKER") then { _areamarker setMarkerPos [-abs(_centerX),-abs(_centerY)]; }; } else { _centerpos = getPos _areamarker; _centerX = abs(_centerpos select 0); _centerY = abs(_centerpos select 1); // X/Y range of target area _rangeX = triggerArea _areamarker select 0; _rangeY = triggerArea _areamarker select 1; // marker orientation (needed as negative value!) _areadir = (getDir _areamarker) * -1; _areaname = vehicleVarName _areamarker; }; // update trigger position if !(isNull _areatrigger) then { _areatrigger setPos [_centerX,_centerY]; }; }; [] call _getAreaInfo; sleep .01; // unit that's moving _obj = _this select 0; _npc = _obj; // is anybody alive in the group? _exit = true; if (typename _obj=="OBJECT") then { if (alive _npc) then {_exit = false;} } else { if (count _obj>0) then { {if (alive _x) then {_npc = _x; _exit = false;}} forEach _obj; }; }; // give this group a unique index _grpidx = format["%1",KRON_UPS_Instances]; _grpname = format["%1_%2",(side _npc),_grpidx]; // remember the original group members, so we can later find a new leader, in case he dies _members = units _npc; KRON_UPS_Total = KRON_UPS_Total + (count _members); // what type of "vehicle" is unit ? _isman = _npc isKindOf "Man"; _iscar = _npc isKindOf "vbs2_LandVehicles"; _isboat = _npc isKindOf "Ship"; _isplane = _npc isKindOf "Air"; // check to see whether group is an enemy of the player (for attack and avoidance maneuvers) // since countenemy doesn't count vehicles, and also only counts enemies if they're known, // we just have to brute-force it for now, and declare *everyone* an enemy who isn't a civilian _issoldier = side _npc != civilian; _friends=[]; _enemies=[]; _sharedenemy=0; //TODO: FIND A WAY TO DETERMINE ASSOCIATION OF RESISTANCE UNITS if (_issoldier) then { switch (side _npc) do { case west: { _friends=_friends+KRON_AllWest; _enemies=_enemies+KRON_AllEast+KRON_AllRes; _sharedenemy=0; }; case east: { _friends=_friends+KRON_AllEast; _enemies=_enemies+KRON_AllWest+KRON_AllRes; _sharedenemy=1; }; case resistance: { _enemies=_enemies+KRON_AllEast+KRON_AllWest; _sharedenemy=2; }; }; { _friends=_friends-[_x]; _x disableAI "autotarget"; } forEach _members; }; sleep .01; // global unit variable to externally influence script _named = false; _npcname = str(side _npc); if ("NAMED" in _UCthis) then { _named = true; _npcname = format["%1",_npc]; _grpidx = _npcname; }; // create global variable for this group call compile format ["KRON_UPS_%1=1",_npcname]; // store some trig calculations _cosdir=cos(_areadir); _sindir=sin(_areadir); // minimum distance of new target position if (_rangeX==0) exitWith { hint format["UPS: Cannot patrol Sector: %1\nArea Marker doesn't exist",_areaname]; }; _mindist=(_rangeX^2+_rangeY^2)/4; // remember the original mode & speed _orgMode = behaviour _npc; _orgSpeed = speedmode _npc; _speedmode = _orgSpeed; // set first target to current position (so we'll generate a new one right away) _currPos = getpos _npc; _orgPos = _currPos; _orgWatch=[_currPos,50,getDir _npc] call KRON_relPos; _orgDir = getDir _npc; _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0]; _dist = 0; _lastdist = 0; _lastmove1 = 0; _lastmove2 = 0; _maxmove=0; _moved=0; _damm=0; _dammchg=0; _lastdamm = 0; _timeontarget = 0; _fightmode = "walk"; _fm=0; _gothit = false; _hitPos=[0,0,0]; _react = 99; _lastdamage = 0; _lastknown = 0; _opfknowval = 0; _sin90=1; _cos90=0; _sin270=-1; _cos270=0; // set target tolerance high for choppers & planes _closeenough=CLOSEENOUGH*CLOSEENOUGH; if (_isplane) then {_closeenough=5000}; sleep .01; // ***************************************** optional arguments ***************************************** // wait at patrol end points _pause = if ("NOWAIT" in _UCthis) then {"NOWAIT"} else {"WAIT"}; // don't move until an enemy is spotted _nomove = if ("NOMOVE" in _UCthis) then {"NOMOVE"} else {"MOVE"}; // don't follow outside of marker area _nofollow = if ("NOFOLLOW" in _UCthis) then {"NOFOLLOW"} else {"FOLLOW"}; // share enemy info _shareinfo = if ("NOSHARE" in _UCthis) then {"NOSHARE"} else {"SHARE"}; // "area cleared" trigger activator _usetrigger = if ("TRIGGER" in _UCthis) then {"TRIGGER"} else {if ("NOTRIGGER" in _UCthis) then {"NOTRIGGER"} else {"SILENTTRIGGER"}}; // suppress fight behaviour if ("NOAI" in _UCthis) then {_issoldier=false}; // adjust cycle delay _cycle = ["CYCLE:",5,_UCthis] call KRON_getArg; // drop units at random positions _initpos = "ORIGINAL"; if ("RANDOM" in _UCthis) then {_initpos = "RANDOM"}; if ("RANDOMUP" in _UCthis) then {_initpos = "RANDOMUP"}; if ("RANDOMDN" in _UCthis) then {_initpos = "RANDOMDN"}; // don't position groups or vehicles on rooftops if ((_initpos!="ORIGINAL") && ((!_isman) || (count _members)>1)) then {_initpos="RANDOMDN"}; // set behaviour modes (or not) _noslow = if ("NOSLOW" in _UCthis) then {"NOSLOW"} else {"SLOW"}; if (_noslow!="NOSLOW") then { _npc setbehaviour "safe"; _npc setSpeedMode "limited"; _speedmode = "limited"; }; // make start position random if (_initpos!="ORIGINAL") then { // find a random position (try a max of 20 positions) _try=0; _bld=0; _bldpos=0; while {_try<20} do { _currPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; if ((_initpos=="RANDOMUP") || ((_initpos=="RANDOM") && (random 1>.75))) then { _posinfo=[_currPos] call KRON_PosInfo; // _posinfo: [0,0]=no house near, [obj,-1]=house near, but no roof positions, [obj,pos]=house near, with roof pos _bld=_posinfo select 0; _bldpos=_posinfo select 1; }; if (_isplane || _isboat || !(surfaceiswater _currPos)) then { if (((_initpos=="RANDOM") || (_initpos=="RANDOMUP")) && (_bldpos>0)) then {_try=99}; if (((_initpos=="RANDOM") || (_initpos=="RANDOMDN")) && (_bldpos==0)) then {_try=99}; }; _try=_try+1; }; if (_bldpos==0) then { if (_isman) then { {_x setPos _currPos} foreach units _npc; } else { _npc setPos _currPos; }; } else { // put the unit on top of a building _npc setPos (_bld buildingPos _bldpos); _npc setUnitPos "up"; _currPos = getPos _npc; _onroof = true; _exit=true; // don't patrol if on roof }; }; sleep .01; // track unit _track = if (("TRACK" in _UCthis) || (KRON_UPS_Debug>0)) then {"TRACK"} else {"NOTRACK"}; _trackername = ""; _destname = ""; if (_track=="TRACK") then { _track = "TRACK"; _trackername=format["trk_%1",_grpidx]; _markerobj = createMarker[_trackername,[0,0]]; _markerobj setMarkerShape "ICON"; _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Dot")) then {"WTF_DOT"} else {"DOT"}; _trackername setMarkerType _markertype; _markercolor = switch (side _npc) do { case west: {"ColorGreen"}; case east: {"ColorRed"}; case resistance: {"ColorBlue"}; default {"ColorBlack"}; }; _trackername setMarkerColor _markercolor; _trackername setMarkerText format["%1",_grpidx]; _trackername setmarkerpos _currPos; _trackername setMarkerSize [.5,.5]; _destname=format["dest_%1",_grpidx]; _markerobj = createMarker[_destname,[0,0]]; _markerobj setMarkerShape "ICON"; _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Flag")) then {"WTF_FLAG"} else {"FLAG"}; _destname setMarkerType _markertype; _destname setMarkerColor _markercolor; _destname setMarkerText format["%1",_grpidx]; _destname setMarkerSize [.5,.5]; }; sleep .01; // delete dead units _deletedead = ["DELETE:",0,_UCthis] call KRON_getArg; if (_deletedead>0) then { {_x addEventHandler['killed',format["[_this select 0,%1] spawn KRON_deleteDead",_deletedead]]}forEach _members; }; // how many group clones? // TBD: add to global side arrays? _mincopies = ["MIN:",0,_UCthis] call KRON_getArg; _maxcopies = ["MAX:",0,_UCthis] call KRON_getArg; if (_mincopies>_maxcopies) then {_maxcopies=_mincopies}; if (_maxcopies>140) exitWith {hint "Cannot create more than 140 groups!"}; if (_maxcopies>0) then { if !(_isMan) exitWith {hint "Vehicles cannot be cloned."}; _copies=_mincopies+round(random (_maxcopies-_mincopies)); // any init strings? _initstr = ["INIT:","",_UCthis] call KRON_getArg; // name of clones _nameprefix = ["PREFIX:","UPSCLONE",_UCthis] call KRON_getArg; // create the clones for "_grpcnt" from 1 to _copies do { // group leader _unittype=typeof _npc; // copy groups if (isNil ("KRON_cloneindex")) then { KRON_cloneindex = 0; }; // make the clones civilians // use random Civilian models for single unit groups if ((_unittype=="Civilian") && (count _members==1)) then {_rnd=1+round(random 20); if (_rnd>1) then {_unittype=format["Civilian%1",_rnd]}}; _grp=createGroup side _npc; _lead = _grp createUnit [_unittype, getpos _npc, [], 0, "form"]; KRON_cloneindex = KRON_cloneindex+1; _lead setVehicleVarName format["%1%2",_nameprefix,KRON_cloneindex]; call compile format["%1%2=_lead",_nameprefix,KRON_cloneindex]; _lead setBehaviour _orgMode; _lead setSpeedMode _orgSpeed; _lead setSkill skill _npc; _lead setVehicleInit _initstr; [_lead] join _grp; _grp selectLeader _lead; // copy team members (skip the leader) _c=0; { _c=_c+1; if (_c>1) then { _newunit = _grp createUnit [typeof _x, getpos _x, [],0,"form"]; KRON_cloneindex = KRON_cloneindex+1; _newunit setVehicleVarName format["%1%2",_nameprefix,KRON_cloneindex]; call compile format["%1%2=_newunit",_nameprefix,KRON_cloneindex]; _newunit setBehaviour _orgMode; _newunit setSpeedMode _orgSpeed; _newunit setSkill skill _x; _newunit setVehicleInit _initstr; [_newunit] join _grp; }; } foreach _members; _nul=[_lead,_areamarker,_pause,_noslow,_nomove,_nofollow,_initpos,_track,_showmarker,_shareinfo,"DELETE:",_deletedead] execVM "ups.sqf"; sleep .05; }; processInitCommands; }; sleep .01; // units that can be left for area to be "cleared" _zoneempty = ["EMPTY:",0,_UCthis] call KRON_getArg; // create area trigger if (_usetrigger!="NOTRIGGER") then { _trgside = switch (side _npc) do { case west: {"WEST"}; case east: {"EAST"}; case resistance: {"GUER"}; case civilian: {"CIV"};}; _trgname="KRON_Trig_"+_trgside+"_"+_areaname; _flgname="KRON_Cleared_"+_areaname; // has the trigger been created already? KRON_TRGFlag=-1; call compile format["%1=false",_flgname]; call compile format["KRON_TRGFlag=%1",_trgname]; if (isNil ("KRON_TRGFlag")) then { // trigger doesn't exist yet, so create one (make it a bit bigger than the marker, to catch path finding 'excursions' and flanking moves) call compile format["%1=createTrigger['EmptyDetector',[_centerX,_centerY]];",_trgname]; call compile format["_areatrigger = %1",_trgname]; call compile format["%1 setTriggerArea[_rangeX*1.5,_rangeY*1.5,markerDir _areaname,true]",_trgname]; call compile format["%1 setTriggerActivation[_trgside,'PRESENT',true]",_trgname]; call compile format["%1 setEffectCondition 'true'",_trgname]; call compile format["%1 setTriggerTimeout [5,7,10,true]",_trgname]; if (_usetrigger!="SILENTTRIGGER") then { _markerhide = [-_centerX,-_centerY]; _markershow = [_centerX,_centerY]; if (_showmarker=="HIDEMARKER") then { _markershow = [-_centerX,-_centerY]; }; call compile format["%1 setTriggerStatements['count thislist<=%6', 'titletext [''SECTOR <%2> CLEARED'',''PLAIN''];''%2'' setmarkerpos %4;%3=true;', 'titletext [''SECTOR <%2> HAS BEEN RE-OCCUPIED'',''PLAIN''];''%2'' setmarkerpos %5;%3=false;']", _trgname,_areaname,_flgname,_markerhide,_markershow,_zoneempty]; } else { call compile format["%1 setTriggerStatements['count thislist<=%3', '%2=true;', '%2=false;']", _trgname,_flgname,_zoneempty]; }; }; sleep .01; }; // init done _makenewtarget=true; _newpos=false; _targetPos = _currPos; _swimming = false; _waiting = if (_nomove=="NOMOVE") then {9999} else {0}; // exit if something went wrong during initialization (or if unit is on roof) if (_exit) exitWith { if ((KRON_UPS_DEBUG>0) && !_onroof) then {hint "Initialization aborted"}; }; // *********************************************************************************************************** // ************************************************ MAIN LOOP ************************************************ _loop=true; _currcycle=_cycle; while {_loop} do { sleep .01; // keep track of how long we've been moving towards a destination _timeontarget=_timeontarget+_currcycle; _react=_react+_currcycle; // did anybody in the group got hit? _newdamage=0; { if((damage _x)>0.2) then { _newdamage=_newdamage+(damage _x); // damage has increased since last round if (_newdamage>_lastdamage) then { _lastdamage=_newdamage; _gothit=true; }; _hitPos=getpos _x; if (!alive _x) then { _members=_members-[_x]; _friends=_friends-[_x]; }; }; } foreach _members; sleep .01; // nobody left alive, exit routine if (count _members==0) then { _exit=true; } else { // did the leader die? if (!alive _npc) then { _npc = _members select 0; group _npc selectLeader _npc; if (isPlayer _npc) then {_exit=true}; }; }; // current position _currPos = getpos _npc; _currX = _currPos select 0; _currY = _currPos select 1; if (_track=="TRACK") then { _trackername setmarkerpos _currPos; }; // if the AI is a civilian we don't have to bother checking for enemy encounters if ((_issoldier) && ((count _enemies)>0) && !(_exit)) then { // if the leader comes across another unit that's either injured or dead, go into combat mode as well. // If the other person is still alive, share enemy information. if ((_shareinfo=="SHARE") && (behaviour _npc=="SAFE")) then { _others=_friends-_members; { if ((!(isNull _x) && (_npc distance _x.5) || (behaviour _x in ["AWARE","COMBAT"]))) exitWith { _npc setBehaviour "aware"; _gothit=true; if ((_hitPos select 0)==0) then {_hitPos = getPos _x}; if (_npc knowsabout _x>3) then { if (alive _x) then {_npc reveal (KRON_KnownEnemy select _sharedenemy)}; }; }; }forEach _others; }; sleep .01; // did the group spot an enemy? _lastknown=_opfknowval; _opfknowval=0; _maxknowledge=0; { _knows=_npc knowsabout _x; if ((alive _x) && (_knows>0.2) && (_knows>_maxknowledge)) then { KRON_KnownEnemy set [_sharedenemy,_x]; _opfknowval=_opfknowval+_knows; _maxknowledge=_knows; }; if (!alive _x) then {_enemies=_enemies-[_x]}; if (_maxknowledge==4) exitWith {}; }forEach _enemies; sleep .01; _pursue=false; _accuracy=100; // opfor spotted an enemy or got shot, so start pursuit if (_opfknowval>_lastknown || _gothit) then { _npc setbehaviour "combat"; _pursue=true; // make the exactness of the target dependent on the knowledge about the shooter _accuracy=21-(_maxknowledge*5); }; if (isNull (KRON_KnownEnemy select _sharedenemy)) then { _pursue=false; }; // don't react to new fatalities if less than 60 seconds have passed since the last one if ((_react<60) && (_fightmode!="walk")) then {_pursue=false}; if (_pursue) then { // get position of spotted unit in player group, and watch that spot _offsx=_accuracy/2-random _accuracy; _offsY=_accuracy/2-random _accuracy; _targetPos = getpos (KRON_KnownEnemy select _sharedenemy); _targetPos = [(_targetPos select 0) + _offsX, (_targetPos select 1) + _offsY]; _targetX = _targetPos select 0; _targetY = _targetPos select 1; {_x dowatch _targetPos} foreach units _npc; sleep .01; // also go into "combat mode" _npc setSpeedMode "full"; _speedmode = "full"; _npc setbehaviour "combat"; _pause="NOWAIT"; _waiting=0; // angle from unit to target _dir1 = [_currPos,_targetPos] call KRON_getDirPos; // angle from target to unit (reverse direction) _dir2 = (_dir1+180) mod 360; // angle from fatality to target _dir3 = if (_hitPos select 0!=0) then {[_hitPos,_targetPos] call KRON_getDirPos} else {_dir1}; _dd=(_dir1-_dir3); // unit position offset straight towards target _relUX = sin(_dir1)*SAFEDIST; _relUY = cos(_dir1)*SAFEDIST; // target position offset straight towards unit _relTX = sin(_dir2)*SAFEDIST; _relTY = cos(_dir2)*SAFEDIST; // go either left or right (depending on location of fatality - or randomly if no fatality) _sinU=_sin90; _cosU=_cos90; _sinT=_sin270; _cosT=_cos270; if ((_dd<0) || (_dd==0 && (random 1)>.5)) then {_sinU=_sin270; _cosU=_cos270; _sinT=_sin90; _cosT=_cos90}; // avoidance position (right or left of unit) _avoidX = _currX + _cosU*_relUX - _sinU*_relUY; _avoidY = _currY + _sinU*_relUX + _cosU*_relUY; _avoidPos = [_avoidX,_avoidY]; // flanking position (right or left of target) _flankX = _targetX + _cosT*_relTX - _sinT*_relTY; _flankY = _targetY + _sinT*_relTX + _cosT*_relTY; _flankPos = [_flankX,_flankY]; // final target position _attackPos = _targetPos; // for now we're stepping a bit to the side _targetPos = _avoidPos; if (_nofollow=="NOFOLLOW") then { _avoidPos = [_avoidPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _flankPos = [_flankPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _attackPos = [_attackPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _targetPos = [_targetPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; }; _react=0; _fightmode="fight"; _timeontarget=0; _fm=1; if (KRON_UPS_Debug!=0) then { "dead" setmarkerpos _hitPos; "avoid" setmarkerpos _avoidPos; "flank" setmarkerpos _flankPos; "target" setmarkerpos _attackPos; }; _newpos=true; // speed up the cycle duration after an incident if (_currcycle>=_cycle) then {_currcycle=1}; }; }; sleep .01; if !(_newpos) then { // calculate new distance // if we're waiting at a waypoint, no calculating necessary if (_waiting<=0) then { // distance to target _dist = [_currPos,_targetPos] call KRON_distancePosSqr; if (_lastdist==0) then {_lastdist=_dist}; _moved = abs(_dist-_lastdist); // adjust the target tolerance for fast moving vehicles if (_moved>_maxmove) then {_maxmove=_moved; if ((_maxmove/40) > _closeenough) then {_closeenough=_maxmove/40}}; // how much did we move in the last three cycles? _totmove=_moved+_lastmove1+_lastmove2; _damm = damage _npc; // is our damage changing (increasing)? _dammchg = abs(_damm - _lastdamm); // we're either close enough, seem to be stuck, or are getting damaged, so find a new target if ((!_swimming) && ((_dist<=_closeenough) || (_totmove<.2) || (_dammchg>0.01) || (_timeontarget>ALERTTIME))) then {_makenewtarget=true;}; // in 'attack (approach) mode', so follow the flanking path (don't make it too predictable though) if ((_fightmode!="walk") && (_dist<=_closeenough)) then { if ((random 1)<.95) then { if (_flankPos select 0!=0) then { _targetPos=_flankPos; _flankPos=[0,0]; _makenewtarget=false; _newpos=true; _fm=1; } else { if (_attackPos select 0!=0) then { _targetPos=_attackPos; _attackPos=[0,0]; _makenewtarget=false; _newpos=true; _fm=2; }; }; }; }; sleep .01; // make new target if (_makenewtarget) then { if ((_nomove=="NOMOVE") && (_timeontarget>ALERTTIME)) then { if (([_currPos,_orgPos] call KRON_distancePosSqr)<_closeenough) then { _newpos = false; } else { _targetPos=_orgPos; }; } else { // re-read marker position/size [] call _getAreaInfo; // find a new target that's not too close to the current position _targetPos=_currPos; _tries=0; while {((([_currPos,_targetPos] call KRON_distancePosSqr) < _mindist)) && (_tries<20)} do { _tries=_tries+1; // generate new target position (on the road) _tries=0; while {_tries<20} do { _targetPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; if (_iscar) then { _roadlist = _targetPos nearRoads 100; if (count _roadlist>0) then { _targetPos = getPos (_roadlist select 0); _tries=99; }; } else { _tries=99; }; //_road=[_targetPos,(_isplane||_isboat),_road] call KRON_OnRoad; sleep .01; }; }; }; _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0]; _gothit=false; _hitPos=[0,0,0]; _fm=0; _npc setSpeedMode _orgSpeed; _newpos=true; // if we're waiting at patrol end points then don't create a new target right away. Keep cycling though to check for enemy encounters if ((_pause!="NOWAIT") && (_waiting<0)) then {_waiting = (15 + random 20)}; }; }; }; sleep .01; // if in water, get right back out of it again if (surfaceIsWater _currPos) then { if (_isman && !_swimming) then { _drydist=999; // look around, to find a dry spot for [{_a=0}, {_a<=270}, {_a=_a+90}] do { _dp=[_currPos,30,_a] call KRON_relPos; if !(surfaceIsWater _dp) then {_targetPos=_dp}; }; _newpos=true; _swimming=true; }; } else { _swimming=false; }; _waiting = _waiting - _currcycle; if ((_waiting<=0) && _newpos) then { // tell unit about new target position if (_fightmode!="walk") then { // reset patrol speed after following enemy for a while if (_timeontarget>ALERTTIME) then { _fightmode="walk"; _speedmode = _orgSpeed; { _x setSpeedMode _speedmode; _x setBehaviour _orgMode; }forEach _members; }; // use individual doMoves if pursuing enemy, // as otherwise the group breaks up too much {_x doMove _targetPos}forEach _members; } else { (group _npc) move _targetPos; (group _npc) setSpeedMode _speedmode; }; if (_track=="TRACK") then { switch (_fm) do { case 1: {_destname setmarkerSize [.4,.4]}; case 2: {_destname setmarkerSize [.6,.6]}; default {_destname setmarkerSize [.5,.5]}; }; _destname setMarkerPos _targetPos; }; _dist=0; _moved=0; _lastmove1=10; _waiting=-1; _newpos=false; _swimming=false; _timeontarget = 0; }; // move on _lastdist = _dist; _lastmove2 = _lastmove1; _lastmove1 = _moved; _lastdamm = _damm; // check external loop switch _cont = (call compile format ["KRON_UPS_%1",_npcname]); if (_cont==0) then {_exit=true}; _makenewtarget=false; if ((_exit) || (isNil("_npc"))) then { _loop=false; } else { // slowly increase the cycle duration after an incident if (_currcycle<_cycle) then {_currcycle=_currcycle+.5}; sleep _currcycle; }; }; if !(isNil("_npc")) then { {doStop _x; _x domove getPos _x; _x move getPos _x} forEach _members; }; KRON_UPS_Exited=KRON_UPS_Exited+1; if (_track=="TRACK") then { _trackername setMarkerType "Dot"; _destname setMarkerType "Empty"; }; _friends=nil; _enemies=nil; }; true //ret// props to killswitch private ["_arrIn", "_arrOut"]; _arrIn = _this select 0; _arrOut = []; while { count _arrIn > 0 } do { _arrOut set [count _arrOut, [_arrIn select 0, ({_x == _arrIn select 0} count _arrIn)] ]; _arrIn = _arrIn - [_arrIn select 0]; }; _arrOut // ret private["_arrIn", "_arrOut", "_begin", "_end"]; _arrIn = _this; _begin = diag_tickTime; _arrOut = []; { switch ( typeName(_x) ) do { case "SIDE": { _side = _x; { if ( side _x == _side ) then { _arrOut set [count _arrOut, _x]; }; } forEach allUnits; }; case "SCALAR": { _side = switch ( _x ) do { case 0: { EAST }; case 1: { WEST }; case 2: { RESISTANCE }; case 3: { CIVILIAN }; }; { if ( side _x == _side ) then { _arrOut set [count _arrOut, _x]; }; } forEach allUnits; }; case "STRING": // check for faction and/or classname { _string = _x; switch ( true ) do { case (isClass(configFile >> "CfgFactionClasses" >> _string)): // faction { { if ( faction _x == _string ) then { _arrOut set [count _arrOut, _x]; }; } forEach allUnits; }; case (isClass(configFile >> "CfgVehicles" >> _string)): // classname { { if ( typeOf _x == _string ) then { _arrOut set [count _arrOut, _x]; }; } forEach allUnits; }; default { _variable = call compile _x; switch ( typeName _variable ) do { case "GROUP": { if ( !(isNull _variable) ) then { { _arrOut set [count _arrOut, _x]; } forEach (units _variable); }; }; case "OBJECT": { if ( !(isNull _variable) ) then { _arrOut set [count _arrOut, _variable]; }; }; }; }; }; }; case "GROUP": { if ( !(isNull _x) ) then { { _arrOut set [count _arrOut, _x]; } forEach (units _x); }; }; case "OBJECT": { if ( !(isNull _x) ) then { _arrOut set [count _arrOut, _x]; }; }; default { [__FILE__, __LINE__, "ERROR, unsupported datatype", typeName(_this select 0)] call mk4_fEcho; } }; } forEach _arrIn; _end = diag_tickTime; if ( mk4_debugMode == 3 ) then // only when debug mode is high { [__FILE__, __LINE__, "function duration", (_end - _begin)] call mk4_fEcho; }; _arrOut // ret private ["_unit", "_mixedArray", "_inArray"]; _unit = _this select 0; _mixedArray = _this select 1; _inArray = false; // check if unit is in mixed array { _inArray = switch ( typeName _x ) do { case "SIDE": { (side _unit == _x) }; case "STRING":{ (faction _unit == _x) || (typeOf _unit == _x) }; case "GROUP": { (group _unit == _x) }; case "OBJECT":{ (_unit == _x) }; default { false } }; if ( _inArray ) exitWith { }; } forEach _mixedArray; _inArray // ret private ["_taskName"]; // [__FILE__] call mk4_fRegisterScript; _taskName = _this select 0; // if 1 arg sent, show taskHint regardless, but if 2 args sent, grab the value for showHint _showHint = if ( count(_this) > 1 ) then { (_this select 1) } else { true }; // check if the task exists. if not, gtfo if ( (isNil {mk4 getVariable _taskName}) ) exitWith { }; if ( !isDedicated ) then // only let clients set their current task { // only assign task if task isnt completed yet if ( !(call compile format["taskCompleted %1", _taskName]) ) then { call compile format ["player setCurrentTask %1", _taskName]; // dont show the taskHint if the person is a jipper if ( _showHint ) then { call compile format ["[%1] call mk4_fTaskHint", _taskName]; }; }; }; if ( isServer ) then // let the server record the state change { mk4 setVariable [_taskName, "ASSIGNED", true]; }; // [__FILE__] call mk4_fUnregisterScript;private ["_taskName"]; // [__FILE__] call mk4_fRegisterScript; _taskName = _this select 0; // if 1 arg sent, show taskHint regardless, but if 2 args sent, grab the value for showHint _showHint = if ( count(_this) > 1 ) then { (_this select 1) } else { true }; // check if the task exists. if not, gtfo if ( (isNil {mk4 getVariable _taskName}) ) exitWith { }; if ( !isDedicated ) then // only let clients change state { call compile format ["%1 setTaskState 'CANCELED'", _taskName]; if ( _showHint ) then { call compile format ["[%1] call mk4_fTaskHint", _taskName]; }; }; if ( isServer ) then // let the server record the state change { mk4 setVariable [_taskName, "CANCELED", true]; }; // [__FILE__] call mk4_fUnregisterScript; if ( !isDedicated ) then { _this spawn { _mixedArray = _this select 0; _subject = (_this select 1) select 0; _message = (_this select 1) select 1; waitUntil { MK4_INIT }; if ( [player, _mixedArray] call mk4_fInMixedArray ) then { player createDiaryRecord ["Diary", [_subject, _message]]; }; }; }; true // ret if ( !isDedicated ) then { _this spawn { _mixedArray = _this select 0; _taskVar = (_this select 1) select 0; _taskNam = (_this select 1) select 1; _taskDes = (_this select 1) select 2; _taskMar = (_this select 1) select 3; _taskSta = (_this select 1) select 4; waitUntil { MK4_INIT }; if ( [player, _mixedArray] call mk4_fInMixedArray ) then { call compile format ["%1 = player createSimpleTask %2", _taskVar,_taskNam]; call compile format ["%1 setSimpleTaskDescription [_taskMessage, _taskSubject, _taskSubject]", _taskName]; //_taskVar = player createSimpleTask [_taskNam]; _taskVar setSimpleTaskDescription [_taskDes, _taskNam, _taskNam]; _taskVar setSimpleTaskDestination (getMarkerPos _taskMar); _taskVar setTaskState _taskSta; }; }; }; true // ret private ["_inScope", "_taskName", "_taskSubject", "_taskMessage", "_taskDestination", "_showHint"]; // [__FILE__] call mk4_fRegisterScript; // let clients figure out if they're in scope, but a dedi will always be in scope if ( !isDedicated ) then { _inScope = if ([player, _this select 0] call mk4_fInMixedArray) then { true } else { false }; } else { _inScope = true; }; // if not, gtfo if ( !_inScope ) exitWith { [__FILE__, __LINE__, "player is not in scope of this task", _this] call mk4_fEcho; // [__FILE__] call mk4_fUnregisterScript; }; _taskName = _this select 1; _taskSubject = (_this select 2) select 0; _taskMessage = (_this select 2) select 1; if ( count(_this select 2) > 2 ) then { _taskDestination = (_this select 2) select 2 }; // if 3 args sent, dont show a taskHint, but if 4 args sent, grab the value for showHint _showHint = if ( count(_this) > 3 ) then { (_this select 3) } else { false }; diag_log str(_this); if ( !isNil _taskName ) exitWith { [__FILE__, __LINE__, "ERROR, given task name has already been defined", _taskName] call mk4_fEcho }; if ( isClient ) then // only create the task on clients { call compile format ["%1 = player createSimpleTask ['']", _taskName]; call compile format ["%1 setSimpleTaskDescription [_taskMessage, _taskSubject, _taskSubject]", _taskName]; if ( !(isNil "_taskDestination") ) then // set the task Destination if one was given { call compile format ["%1 setSimpleTaskDestination _taskDestination", _taskName]; }; if ( _showHint ) then { call compile format ["[%1] call mk4_fTaskHint", _taskName]; }; }; // NO JIP (new task on server) if ( (isNil {mk4 getVariable _taskName}) ) then { if ( isServer ) then // record the state of the task { mk4 setVariable [_taskName, "CREATED", true]; }; } else // JIP (task existed on server) { // get the task state, and do the appropriate thing switch ( (mk4 getVariable _taskName) ) do { case "ASSIGNED": { [_taskName, false] call mk4_fAssignTask }; case "CANCELED": { [_taskName, false] call mk4_fCancelTask }; case "CREATED": { }; case "FAILED": { [_taskName, false] call mk4_fFailTask }; case "SUCCEEDED": { [_taskName, false] call mk4_fSucceedTask }; default { [__FILE__, __LINE__, "ERROR, unknown task state", (mk4 getVariable _taskName)] call mk4_fEcho} }; }; // [__FILE__] call mk4_fUnregisterScript; if ( !isDedicated ) then { _this spawn { _mixedArray = _this select 0; _taskVar = (_this select 1) select 0; _taskNam = (_this select 1) select 1; _taskDes = (_this select 1) select 2; _taskMar = (_this select 1) select 3; _taskSta = (_this select 1) select 4; waitUntil { MK4_INIT }; if ( [player, _mixedArray] call mk4_fInMixedArray ) then { call compile format ["%1 = player createSimpleTask %2", _taskVar,_taskNam]; call compile format ["%1 setSimpleTaskDescription [_taskMessage, _taskSubject, _taskSubject]", _taskName]; //_taskVar = player createSimpleTask [_taskNam]; _taskVar setSimpleTaskDescription [_taskDes, _taskNam, _taskNam]; _taskVar setSimpleTaskDestination (getMarkerPos _taskMar); _taskVar setTaskState _taskSta; }; }; }; true // ret private ["_taskName"]; // [__FILE__] call mk4_fRegisterScript; _taskName = _this select 0; // if 1 arg sent, show taskHint regardless, but if 2 args sent, grab the value for showHint _showHint = if ( count(_this) > 1 ) then { (_this select 1) } else { true }; // check if the task exists. if not, gtfo if ( (isNil {mk4 getVariable _taskName}) ) exitWith { [__FILE__] call mk4_fUnregisterScript }; if ( !isDedicated ) then // only let clients change state { call compile format ["%1 setTaskState 'FAILED'", _taskName]; if ( _showHint ) then { call compile format ["[%1] call mk4_fTaskHint", _taskName]; }; }; if ( isServer ) then // let the server record the state change { mk4 setVariable [_taskName, "FAILED", true]; }; // [__FILE__] call mk4_fUnregisterScript;private ["_taskName"]; // [__FILE__] call mk4_fRegisterScript; _taskName = _this select 0; // if 1 arg sent, show taskHint regardless, but if 2 args sent, grab the value for showHint _showHint = if ( count(_this) > 1 ) then { (_this select 1) } else { true }; // check if the task exists. if not, gtfo if ( (isNil {mk4 getVariable _taskName}) ) exitWith { }; if ( !isDedicated ) then // only let clients change state { call compile format ["%1 setTaskState 'SUCCEEDED'", _taskName]; if ( _showHint ) then { call compile format ["[%1] call mk4_fTaskHint", _taskName]; }; }; if ( isServer ) then // let the server record the state change { mk4 setVariable [_taskName, "SUCCEEDED", true]; }; // [__FILE__] call mk4_fUnregisterScript;#define WHITE [1,1,1,1] #define GREY [0.75,0.75,0.75,1] #define GREEN [0.6,0.8,0.4,1] #define RED [1,0.1,0,1] private["_task", "_taskDescription", "_taskStatus", "_taskParams"]; _task = _this select 0; _taskDescription = (taskDescription _task) select 1; _taskStatus = toUpper(taskState _task); _taskParams = switch (_taskStatus) do { case "CREATED": { [format["NEW TASK ASSIGNED: \n%1", _taskDescription], WHITE, "taskNew"] }; case "ASSIGNED": { [format["ASSIGNED TASK: \n%1", _taskDescription], WHITE, "taskCurrent"] }; case "SUCCEEDED": { [format["TASK ACCOMPLISHED: \n%1", _taskDescription], GREEN, "taskDone"] }; case "FAILED": { [format["TASK FAILED: \n%1", _taskDescription], RED, "taskFAILED"] }; case "CANCELED": { [format["TASK CANCELED: \n%1", _taskDescription], GREY, "taskDone"] }; }; taskHint _taskParams;private ["_vehicle", "_turret", "_magazines"]; _vehicle = _this select 0; _turret = _this select 1; _magazines = _this select 2; mk4 globalChat str(_this); { _vehicle addMagazineTurret [_x, _turret]; } forEach _magazines; true // ret private ["_actionID"]; _actionID = (vehicle player) addAction _this; [_this, _actionID] spawn { _pObject = player; _pVehicle = vehicle player; _actionArgs = _this select 0; _actionID = _this select 1; while { true } do { if( !(alive _pObject) ) then { waitUntil { alive player }; _pObject = player }; if( _pVehicle != (vehicle _pObject) ) then { _pVehicle removeAction _actionID; _pVehicle = vehicle _pObject; _actionID = _pVehicle addAction _actionArgs; }; sleep 1; }; }; // return the action ID _actionID _this spawn { _unit = _this select 0; _color = _this select 1; _global = if ( (count _this) > 2 ) then { _this select 2 } else { false }; _unit setVariable ["mk4_assignedTeam", _color, _global]; // save the team color waitUntil { (time > 0) && MK4_INIT }; if ( _global ) then { [1, { (_this select 0) assignTeam (_this select 1) }, [_unit, _color] ] call mk4_network_fSend; } else { _unit assignTeam _color; }; }; true // ret // props to karel moricky // [player, 100, 0, "ON"] call mk4_fHouseEffects private ["_logic", "_radius", "_mode", "_state", "_houses", "_chimneyPos", "_ps", "_limit", "_i"]; _logic = _this select 0; _radius = _this select 1; _mode = _this select 2; // 0 = chimneys only, 1 = lights only, 2 = both _state = toUpper(_this select 3); // "ON" or "OFF" if ( isNil "mk4_smokingChimneys" ) then { mk4_smokingChimneys = [] }; // collect an array of all houses in the specified radius, quit if none found _houses = nearestObjects [_logic, ["house"], _radius]; if ( (count _houses) == 0 ) exitWith { }; switch ( _state ) do { case "ON": { { if ( _mode != 1 ) then // if chimney smoke was allowed { for [{_i = 0}, {_i < 5}, {_i = _i + 1}] do { _chimneyPos = _x selectionPosition format["AIChimney_small_%1",_i]; if ( (_chimneyPos select 0) == 0 ) exitWith { }; // no chimney found if ( random(1) > .4 ) then { _ps = "#particlesource" createVehicle (_x modelToWorld _chimneyPos); _ps setParticleCircle [0, [0, 0, 0]]; _ps setParticleRandom [1, [0, 0, 0], [0.1, 0.1, 0.1], 2, 0.2, [0.05, 0.05, 0.05, 0.05], 0, 0]; _ps setParticleParams [["\Ca\Data\ParticleEffects\Universal\universal.p3d", 16, 8, 16], "", "Billboard", 1, (10 + random 5), [0,0,0], [0, 0, 0.5 + random 0.5], 1, 1.275, 1, 0.066, [0.4, 1 + random 0.5, 2 + random 2], [[0.4, 0.4, 0.4*1.2, 0.1 + random 0.1], [0.5, 0.5, 0.5*1.2, 0.05 + random 0.05], [0.7, 0.7, 0.7*1.2, 0]], [0], 1, 0, "", "", ""]; _ps setDropInterval (0.05 + random(0.1)); // randomize the thickness of the smoke heree mk4_smokingChimneys set [count mk4_smokingChimneys, _ps]; }; }; }; if ( _mode > 0 ) then // lights are allowed { _limit = 0.4; if ( daytime > 17 && daytime < 24 ) then { _limit = 0.2 }; if ( daytime > 0 && daytime < 5 ) then { _limit = 0.9 }; for [{_i = 1}, {_i < 6}, {_i = _i + 1}] do { if ( random(1) > _limit ) then { _x animate [ format["Lights_%1", _i], 1]; // vayehi or }; }; }; } forEach _houses; }; case "OFF": { if ( _mode != 1 ) then // turn of all chimneys { { deleteVehicle _x } forEach mk4_smokingChimneys; mk4_smokingChimneys = []; }; if ( _mode > 0 ) then // turn off all lights { { for [{_i = 1}, {_i < 6}, {_i = _i + 1}] do { _x animate [ format["Lights_%1", _i], 0]; }; } forEach _houses; }; }; }; true // retprivate ["_obj", "_populate", "_dir", "_pos", "_parts", "_blah", "_house", "_crap"]; _obj = _this select 0; _populate = if ( count _this > 1 ) then { _this select 1 } else { false }; if ( isServer ) then { _dir = getDir _obj; _pos = getPosASL _obj; _parts = [ "Land_LHD_house_1", "Land_LHD_house_2", "Land_LHD_elev_R", "Land_LHD_1", "Land_LHD_2", "Land_LHD_3", "Land_LHD_4", "Land_LHD_5", "Land_LHD_6" ]; { _blah = createVehicle [_x, _pos, [], 0, "CAN_COLLIDE"]; _blah setDir _dir; _blah setPos _pos; // save reference to the briefing room if ( _x == "Land_LHD_house_2" ) then { _house = _blah } else { _blah enableSimulation false }; }forEach _parts; // populate teh LHD if wanted if ( _populate ) then { _crap = [ ["MetalBucket",[11.4697,-6.94531,17.0435],358.741], ["FloorMop",[11.4678,-7.36035,16.976],27.035], ["FoldChair",[6.95801,-16.9004,17.1536],3.5926], ["FoldChair",[4.81641,-19.0645,17.1025],355.842], ["FoldChair",[6.06445,-18.7207,17.1327],359.387], ["FoldChair",[7.42578,-19.0527,17.1577],4.81861], ["FoldChair",[5.52637,-20.4961,17.1108],2.04862], ["FoldChair",[8.91797,-19.4434,17.1795],21.2588], ["FoldChair",[6.7959,-20.6484,17.1395],13.5918], ["FoldChair",[3.23242,-21.8164,17.046],320.869], ["FoldChair",[2.21191,-22.4229,17.0208],325.511], ["FoldChair",[8.09375,-21.0889,17.1644],27.4292], ["SatPhone",[6.04004,-23.1904,17.9562],3.48026], ["Can_small",[6.91406,-23.1748,17.9062],0], ["FoldChair",[8.16309,-22.8145,17.159],44.522], ["FoldTable",[6.39063,-23.3926,17.1383],186.373], ["Misc_Videoprojektor",[6.66992,-24.1621,20.1559],0.3455], ["FoldChair",[6.10449,-24.5811,17.0989],180.362], ["Misc_Videoprojektor_platno",[6.63477,-26.0869,18.8424],180] ]; { _crapClass = _x select 0; _crapPos = LHD modelToWorld (_x select 1); _crapDir = (getDir LHD) + (_x select 2); _blah = createVehicle [_crapClass, [0,0,0], [], 0, "CAN_COLLIDE"]; _blah setDir _crapDir; _blah setPosASL _crapPos; } forEach _crap; // create some athmosphere _towTractor = "TowingTractor" createVehicle [0,0,0]; _towTractor setDir ((getDir LHD) + 30); _towTractor setPosASL (LHD modelToWorld [4.45703,-46.791,17.1]); _towTractor lock true; _actorsGrp = createGroup WEST; mk4_towMech = _actorsGrp createUnit ["USMC_LHD_Crew_Green", [1,1,1], [], 0, "NONE"]; mk4_towMech setPosASL (_towTractor modelToWorld [2.31318,-0.90945,-0.3]); mk4_towMech setDir (getDir _towTractor - 90); { mk4_towMech disableAI _x } forEach ["ANIM", "MOVE"]; mk4_towMech2 = _actorsGrp createUnit ["USMC_LHD_Crew_Green", [1,1,1], [], 0, "NONE"]; mk4_towMech2 setPosASL (_towTractor modelToWorld [1.62002,1.90547,-0.333914]); mk4_towMech2 setDir (getDir _towTractor - 160); { mk4_towMech2 disableAI _x } forEach ["MOVE"]; _choppa = "UH1Y" createVehicle [1,1,1]; _choppa setPosASL (LHD modelToWorld [3.5645,55.8867,17.2]); _choppa setDir ((getDir LHD) - 80); _choppa lock true; mk4_choppaMech = _actorsGrp createUnit ["USMC_LHD_Crew_Red", [1,1,1], [], 0, "NONE"]; mk4_choppaMech setPosASL (_choppa modelToWorld [-2.16602,-4.36035,-1.72095]); mk4_choppaMech setDir (getDir _choppa +90); { mk4_choppaMech disableAI _x } forEach ["ANIM", "MOVE"]; mk4_actor1 = _actorsGrp createUnit ["USMC_Soldier_Officer", [1,1,1], [], 0, "NONE"]; mk4_actor1 setPosASL (LHD modelToWorld [6.3125,-41.5799,23.4253]); mk4_actor1 setDir (getDir LHD + 187); removeAllWeapons mk4_actor1; mk4_actor2 = _actorsGrp createUnit ["USMC_LHD_Crew_Blue", [1,1,1], [], 0, "NONE"]; mk4_actor2 setPosASL (LHD modelToWorld [11.0449,-14.1035,26.6695]); mk4_actor2 setDir (getDir LHD + 52.9903); mk4_actor3 = _actorsGrp createUnit ["USMC_Soldier_Light", [1,1,1], [], 0, "NONE"]; mk4_actor3 setPosASL (LHD modelToWorld [1.07578,8.32734,25.8316]); mk4_actor3 setDir (getDir LHD + 219.927); mk4_actor4 = _actorsGrp createUnit ["USMC_LHD_Crew_Blue", [1,1,1], [], 0, "NONE"]; mk4_actor4 setPosASL (LHD modelToWorld [1.73438,6.8252,26.5912]); mk4_actor4 setDir (getDir LHD + 270.361); { _x disableAI "MOVE" } forEach [mk4_actor1,mk4_actor2,mk4_actor3,mk4_actor4]; }; }; [] spawn { waitUntil { MK4_INIT && time > 0 }; if ( isServer ) then { mk4_towMech playMove "actspercsnonwnondnon_carfixing2"; mk4_towMech2 playMove "ctspercmstpsnonwnondnon_idle32podrbaninanose"; mk4_choppaMech playMove "actspercsnonwnondnon_assembling"; mk4_actor1 playMove "csdr_lhd_oprenozabradli118cm_a"; mk4_actor2 playMove "ctspercmstpsnonwnondnon_idle31rejpanivnose"; mk4_actor3 playMove "csdr_lhd_oprenozabradli118cm_a"; mk4_actor4 playMove "ctspercmstpsnonwnondnon_idle31rejpanivnose"; }; if ( !isDedicated ) then { // create a border trigger so people on foot cant walk towards the gap in the deck _trg = createTrigger["EmptyDetector", (LHD modelToWorld [0,64.5996,17.1401])]; _trg setTriggerArea[20,5,0,true]; _trg setTriggerActivation["WEST","PRESENT",true]; _trg setTriggerStatements["(vehicle player in thisList)", "nul = ['You really don''t want to walk into the invisible hole there'] execVM 'mk4\s\borderControl.sqf'", ""]; helo addAction ["Rearm/Refuel/Repair Aircraft", "_actionHandler.sqf","RRR",100, false, true, "", "mk4_replenish && (speed(vehicle player) < 1)"]; sandy_1 addAction ["Rearm/Refuel/Repair Aircraft", "_actionHandler.sqf","RRR",100, false, true, "", "mk4_replenish && (speed(vehicle player) < 1)"]; sandy_2 addAction ["Rearm/Refuel/Repair Aircraft", "_actionHandler.sqf","RRR",100, false, true, "", "mk4_replenish && (speed(vehicle player) < 1)"]; // soundloop breaks when in a vehicle while { true } do { if ( ((vehicle player) distance LHD) < 200 ) then { playSound "LHD_engine"; mk4_replenish = ((vehicle player != player) && (driver(vehicle player) == player)); } else { mk4_replenish = false; }; sleep 6.8; }; }; }; private ["_marker", "_markerName", "_markerPos", "_markerShape", "_markerType", "_markerColor", "_markerText", "_markerDir", "_markerSize", "_markerDuration"]; _markerPos = _this select 0; // [x,y] or [x,y,z] _markerShape = _this select 1; // "ICON", "RECTANGLE", "ELLIPSE" _markerType = _this select 2; // "DOT" _markerColor = _this select 3; // "ColorRed" _markerSize = _this select 4; // [A-axis, B-axis]; // other args are optional _markerText = if (count _this > 5 ) then { _this select 5 } else { "" }; // "hello" _markerDir = if (count _this > 6 ) then { _this select 6 } else { 0 }; // 0 _markerDuration = if (count _this > 7 ) then { _this select 7 } else { 0 }; // create an unique number each time if ( isNil "mk4_uniqueMarkerID" ) then { mk4_uniqueMarkerID = 0 }; mk4_uniqueMarkerID = mk4_uniqueMarkerID + 1; // make a "unique" marker name _markerName = format["mk4_mkr_%1", mk4_uniqueMarkerID ]; // dbg if ( mk4_debugMode == 3 ) then { [__FILE__, __LINE__, "created marker:", [_markerName, _this]] call mk4_fEcho; }; _marker = createMarkerLocal [_markerName, [_markerPos select 0, _markerPos select 1]]; _marker setMarkerShapeLocal _markerShape; _markerName setMarkerTypeLocal _markerType; _markerName setMarkerColorLocal _markerColor; _markerName setMarkerTextLocal _markerText; _markerName setMarkerDirLocal _markerDir; _markerName setMarkerSizeLocal _markerSize; // if a marker lifetime was defined, fade it out over time, and give the spawn handle back if ( _markerDuration != 0 ) then { [_marker, _markerDuration] spawn { _marker = _this select 0; _markerDuration = (_this select 1) / 10; while { (markerAlpha _marker) > 0 } do { _marker setMarkerAlphaLocal ((markerAlpha _marker) - 0.1); sleep _markerDuration; }; deleteMarkerLocal _marker; } // ret (spawn handle) } else // otherwise we have a permanent marker, and return marker name { _markerName // ret }; private ["_side", "_className", "_groupName", "_pos", "_dir", "_unitPos", "_probability", "_unit", "_group"]; // _side = _this select 0; _className = _this select 0; // can be string or array of strings _groupName = _this select 1; // group variable name (string) _pos = _this select 2; // 3d ATL pos _dir = _this select 3; // 0-359 _unitPos = _this select 4; // can be string or array of strings _probability = _this select 5; // can be number, 0-100, or boolean _group = grpNull; // check if a % was given or a boolean _probability = switch ( typeName(_probability) ) do { case "SCALAR": { _probability > random(100) }; case "BOOL": { _probability }; }; if ( _probability ) then { // check if array of classnames/stances were given, if so choose a random class/stance if ( typeName(_className) == "ARRAY" ) then { _className = _className select floor(random(count _className)) }; if ( typeName(_unitPos) == "ARRAY" ) then { _unitPos = _unitPos select floor(random(count _unitPos)) }; // // get the implied unit side _side = switch ( getNumber(configFile >> "CfgVehicles" >> _className >> "side") ) do { case 0: { EAST }; case 1: { WEST }; case 2: { RESISTANCE }; case 3: { CIVILIAN }; default { WEST }; }; // if not specified group was passed, just create one if ( _groupName == "" ) then { _group = createGroup _side; } else { // group name was passed, create the group if it didnt exist yet if ( isNil _groupName ) then { call compile format["%1 = createGroup _side", _groupName]; }; call compile format["_group = %1", _groupName]; }; _unit = _group createUnit [_className, _pos, [], 0, "NONE"]; // tell the unit to watch a position 10m away in the given direction _unit doWatch [((_pos select 0) + sin(_dir) * 10), ((_pos select 1) + cos(_dir) * 10)]; // finish positioning _unit setPosATL _pos; _unit setUnitPos _unitPos; _unit disableAI "TARGET"; // set proper skill levels _unit setSkill 0.58500001; _unit setSkill ["aimingAccuracy",0.1]; _unit setSkill ["aimingShake",1]; _unit setSkill ["aimingSpeed",0.9]; _unit setSkill ["spotDistance",0.9]; _unit setSkill ["spotTime",0.7]; // tell him to stay in this position [_unit] spawn { doStop (_this select 0) }; // disable conversations _unit setVariable ["BIS_noCoreConversations", true]; // disable special zeus AI features // doesnt help if the bypass gets removed time after time without making that known... //_unit setVariable ["zeu_AIBypass", true]; //diag_log format["%1 %2 %3 %4", side _unit, _unit, _group, _className ]; } else { _unit = objNull; }; _unit // ret private ["_obj", "_radius", "_houses"]; _obj = _this select 0; _radius = _this select 1; if ( !isServer ) exitWith { }; // collect an array of all houses in the specified radius, quit if none found _houses = nearestObjects [_obj, ["house"], _radius]; if ( (count _houses) == 0 ) exitWith { false }; { _x setDamage 1; } forEach _houses; true // retprivate ["_pos1", "_pos2", "_angle"]; _pos1 = _this select 0; _pos2 = _this select 1; // if an object was passed, get their position if( typename _pos1 == "OBJECT" ) then { _pos1 = getPosASL _pos1 }; if( typename _pos2 == "OBJECT" ) then { _pos2 = getPosASL _pos2 }; // get the angle between the 2 positions _angle = ((_pos2 select 0) - (_pos1 select 0)) atan2 ((_pos2 select 1) - (_pos1 select 1)); // normalize the angle ( make it an angle from 0 to 360) while { _angle < 0 } do { _angle = _angle + 360; }; _angle = _angle % 360; _angle // retprivate ["_obj", "_displayName"]; _obj = _this select 0; _displayName = getText (configFile >> "CfgVehicles" >> (typeOf _obj) >> "displayName"); _displayName // ret private["_msg", "_file", "_lineNumber", "_data"]; // if the end-user doesnt even wanna log to RPT, then this function is useless if ( getNumber(MK4_Settings >> "General" >> "debugRPT") == 0 ) exitWith { false }; _msg = switch ( count _this ) do { case 1: // just 1 string { str(_this select 0) }; case 2: // file + msg { // _file = [_this select 0] call mk4_fRelativeFilePath; _file = str(_this select 0); _msg = str(_this select 1); format["%1, %2", _file, _msg] }; case 3: // file + linenumber + msg { _file = [_this select 0] call mk4_fRelativeFilePath; _lineNumber = _this select 1; _msg = str(_this select 2); format["%1:%2 %3", _file, _lineNumber, _msg] }; case 4: // file + linenumber + msg + data { _file = [_this select 0] call mk4_fRelativeFilePath; _lineNumber = _this select 1; _msg = _this select 2; _data = _this select 3; format["%1:%2 ""%3"" -> %4", _file, _lineNumber, _msg, _data] }; default { "error, wrong syntax" } }; // get the time and compile the msg _msg = format["[%1] %2", ([time] call mk4_fFormattedTime), _msg]; diag_log text _msg; // send to chat if debugMode is at least low if ( mk4_debugMode > 0 ) then { mk4 globalChat _msg; }; true // ret private ["_timeInSeconds", "_hours", "_hoursStr", "_minutes", "_minutesStr", "_seconds", "_secondsStr", "_milliseconds", "_millisecStr"]; _timeInSeconds = _this select 0; _hours = floor(_timeInSeconds / 3600); _hoursStr = [("0" + str(_hours)), str(_hours)] select (_hours > 9); _minutes = floor(_timeInSeconds / 60) % 60; _minutesStr = [("0" + str(_minutes)), str(_minutes)] select (_minutes > 9); _seconds = floor(_timeInSeconds % 60); _secondsStr = [("0" + str(_seconds)), str(_seconds)] select (_seconds > 9); _millisec = floor(((_timeInSeconds - floor(_timeInSeconds)) * 1000)); _millisecStr = switch ( true ) do { case (_millisec > 99): { str(_millisec) }; case (_millisec > 9): { ("0" + str(_millisec)) }; default { ("00" + str(_millisec)) }; }; format["%1:%2:%3,%4", _hoursStr, _minutesStr, _secondsStr, _millisecStr] // ret private ["_group", "_groupName", "_trimmedGroupName"]; _group = group (_this select 0); _groupName = toArray(str(_group)); _trimmedGroupName = []; for [ { _i = 2 }, { _i < count(_groupName) }, { _i = _i + 1 }] do { _trimmedGroupName set [count _trimmedGroupName, (_groupName select _i)]; }; toString(_trimmedGroupName) // ret/* Author: Karel Moricky Edited by mikey Description: High Altitude Low Opening Parameter(s): _this: ARRAY - starts HALO jump directly OBJECT - waits until unit in array is out of vehicle Returns: Nothing */ sleep 0.01; //--- HALO ------------------------------------------------------------------------------------------------------------------------------------- if ( typeName _this == "OBJECT" ) then { _unit = _this; //--- Eject! waituntil { ((getPos _unit select 2) > 10) || !isNil {_unit getVariable "BIS_fnc_halo_now"}}; if (!local _unit) exitwith {}; //--- Delete parachute _parachute = vehicle _unit; if (_parachute != _unit) then { deletevehicle _parachute; }; //--- Init _dir = ([[0,0,0],velocity _unit] call mk4_fDirTo); _unit setdir _dir; //_unit switchmove "HaloFreeFall_non"; [2, {_this switchMove "HaloFreeFall_non"}, _unit] call mk4_network_fSend; //--- Key controls if (_unit == player) then { //--- PLAYER ------------------------------------------------ _brightness = 0.99; _pos = position player; _parray = [ /* 00 */ ["\Ca\Data\ParticleEffects\Universal\Universal", 16, 12, 13, 0], /* 01 */ "", /* 02 */ "Billboard", /* 03 */ 1, /* 04 */ 3, /* 05 */ [0,0,-200], /* 06 */ wind, /* 07 */ 0, /* 08 */ 1.275, /* 09 */ 1, /* 10 */ 0, /* 11 */ [100], /* 12 */ [ [_brightness,_brightness,_brightness,0], [_brightness,_brightness,_brightness,0.01], [_brightness,_brightness,_brightness,0.10], [_brightness,_brightness,_brightness,0] ], /* 13 */ [1000], /* 14 */ 0, /* 15 */ 0, /* 16 */ "", /* 17 */ "", /* 18 */ player ]; bis_fnc_halo_clouds = "#particlesource" createVehicleLocal _pos; bis_fnc_halo_clouds setParticleParams _parray; bis_fnc_halo_clouds setParticleRandom [0, [100, 100, 0], [0, 0, 0], 0, 0, [0, 0, 0, 0], 0, 1]; bis_fnc_halo_clouds setParticleCircle [00, [00, 00, 00]]; bis_fnc_halo_clouds setDropInterval (0.4 - (0.3 * overcast)); //--- Effects bis_fnc_halo_ppRadialBlur = ppeffectcreate ["RadialBlur",464]; bis_fnc_halo_ppRadialBlur ppEffectAdjust [0.01,0.01,0.3,0.3]; bis_fnc_halo_ppRadialBlur ppEffectCommit 0.01; bis_fnc_halo_ppRadialBlur ppEffectEnable true ; bis_fnc_halo_soundLoop = time; playsound "BIS_HALO_Flapping"; bis_fnc_halo_action = _unit addaction ["Open Chute", "mk4\f\fHALO.sqf",[],1,true,true,"Eject"]; bis_fnc_halo_keydown = { _key = _this select 1; //--- Forward if (_key in (actionkeys 'MoveForward')) then { if (bis_fnc_halo_vel < +bis_fnc_halo_velLimit) then {bis_fnc_halo_vel = bis_fnc_halo_vel + bis_fnc_halo_velAdd}; }; //--- Backward if (_key in (actionkeys 'MoveBack')) then { if (bis_fnc_halo_vel > -bis_fnc_halo_velLimit) then {bis_fnc_halo_vel = bis_fnc_halo_vel - bis_fnc_halo_velAdd}; }; //--- Left if (_key in (actionkeys 'TurnLeft')) then { if (bis_fnc_halo_dir > -bis_fnc_halo_dirLimit) then {bis_fnc_halo_dir = bis_fnc_halo_dir - bis_fnc_halo_dirAdd}; }; //--- Right if (_key in (actionkeys 'TurnRight')) then { if (bis_fnc_halo_dir < +bis_fnc_halo_dirLimit) then {bis_fnc_halo_dir = bis_fnc_halo_dir + bis_fnc_halo_dirAdd}; }; }; bis_fnc_halo_keydown_eh = (finddisplay 46) displayaddeventhandler ["keydown","_this call bis_fnc_halo_keydown;"]; //--- Loop bis_fnc_halo_vel = 0; bis_fnc_halo_velLimit = 0.2; bis_fnc_halo_velAdd = 0.03; bis_fnc_halo_dir = 0; bis_fnc_halo_dirLimit = 1; bis_fnc_halo_dirAdd = 0.06; [] spawn { _time = time - 0.1; while {alive player && vehicle player == player && isnil {player getvariable "bis_fnc_halo_terminate"}} do { //--- FPS counter _fpsCoef = ((time - _time) * 60) / acctime; //Script is optimized for 60 FPS _time = time; bis_fnc_halo_velLimit = 0.2 * _fpsCoef; bis_fnc_halo_velAdd = 0.03 * _fpsCoef; bis_fnc_halo_dirLimit = 1 * _fpsCoef; bis_fnc_halo_dirAdd = 0.06 * _fpsCoef; //--- Dir bis_fnc_halo_dir = bis_fnc_halo_dir * 0.98; _dir = direction player + bis_fnc_halo_dir; player setdir _dir; //--- Velocity _vel = velocity player; bis_fnc_halo_vel = bis_fnc_halo_vel * 0.96; player setvelocity [ (_vel select 0) + (sin _dir * bis_fnc_halo_vel), (_vel select 1) + (cos _dir * bis_fnc_halo_vel), (_vel select 2) ]; //--- Animation system _anim = "HaloFreeFall_non"; _v = bis_fnc_halo_vel; _h = bis_fnc_halo_dir; _vLimit = 0.1; _hLimit = 0.3; if ((abs _v) > _vLimit || (abs _h) > _hLimit) then { _vAnim = ""; if (_v > +_vLimit) then {_vAnim = "F"}; if (_v < -_vLimit) then {_vAnim = "B"}; _hAnim = ""; if (_h > +_hLimit) then {_hAnim = "R"}; if (_h < -_hLimit) then {_hAnim = "L"}; _anim = "HaloFreeFall_" + _vAnim + _hAnim; }; player playmovenow _anim; //--- Sound if ((time - bis_fnc_halo_soundLoop) > 4.5) then { playsound "BIS_HALO_Flapping"; bis_fnc_halo_soundLoop = time; }; //--- Effects bis_fnc_halo_ppRadialBlur ppEffectAdjust [0.02,0.02,0.3 - (bis_fnc_halo_vel/7)/_fpsCoef,0.3 - (bis_fnc_halo_vel/7)/_fpsCoef]; bis_fnc_halo_ppRadialBlur ppEffectCommit 0.01; sleep 0.01; }; //--- End player removeaction bis_fnc_halo_action; (finddisplay 46) displayremoveeventhandler ["keydown",bis_fnc_halo_keydown_eh]; ppeffectdestroy bis_fnc_halo_ppRadialBlur; deletevehicle bis_fnc_halo_clouds; bis_fnc_halo_clouds = nil; bis_fnc_halo_vel = nil; bis_fnc_halo_velLimit = nil; bis_fnc_halo_velAdd = nil; bis_fnc_halo_dir = nil; bis_fnc_halo_dirLimit = nil; bis_fnc_halo_dirAdd = nil; bis_fnc_halo_action = nil; bis_fnc_halo_keydown = nil; bis_fnc_halo_keydown_eh = nil; if (!alive player) then { //player switchmove "adthppnemstpsraswrfldnon_1"; [2, {_this switchMove "adthppnemstpsraswrfldnon_1"}, player] call mk4_network_fSend; player setVelocity [0,0,0]; }; }; } else { // //--- AI ------------------------------------------------ // while { (getPosATL _unit select 2) > 200 } do // { // //_destination = expectedDestination _unit select 0; // if ( (leader _unit) distance _unit > 100 ) then // { // _vel = velocity _unit; // _dirTo = [_unit, (leader _unit)] call mk4_fDirTo; // // if ( ) then { // _unit setdir _dirTo; // // }; // _unit setvelocity [ // (_vel select 0) + (sin _dirTo * 0.2), // (_vel select 1) + (cos _dirTo * 0.2), // (_vel select 2) // ]; // }; // sleep 0.5; // }; // //--- Open // [_unit] spawn bis_fnc_halo; }; }; //--- PARA ------------------------------------------------------------------------------------------------------------------------------------- if (typename _this == typename []) then { _unit = _this select 0; if (!local _unit) exitwith {}; //--- Free fall if (count _this == 2) exitwith { _alt = _this select 1; _unit setpos [position _unit select 0,position _unit select 1,_alt]; _unit setvariable ["bis_fnc_halo_now",true]; _unit spawn bis_fnc_halo; }; //------------- _para = "ParachuteC" createVehicle position _unit; //_para = "BIS_Steerable_Parachute" createVehicle position _unit; _para setpos position _unit; _para setdir direction _unit; _vel = velocity _unit; _unit moveindriver _para; //_unit moveingunner _para; _para lock false; bis_fnc_halo_para_dirAbs = direction _para; //--- Key controls if (_unit == player) then { _para setvelocity [(_vel select 0),(_vel select 1),(_vel select 2)*1]; bis_fnc_halo_DynamicBlur = ppeffectcreate ["DynamicBlur",463]; bis_fnc_halo_DynamicBlur ppEffectEnable true; bis_fnc_halo_DynamicBlur ppEffectAdjust [8.0]; bis_fnc_halo_DynamicBlur ppEffectCommit 0; bis_fnc_halo_DynamicBlur ppEffectAdjust [0.0]; bis_fnc_halo_DynamicBlur ppEffectCommit 1; bis_fnc_halo_para_vel = 0; bis_fnc_halo_para_velLimit = 0.5; bis_fnc_halo_para_velAdd = 0.01; bis_fnc_halo_para_dir = 0; bis_fnc_halo_para_dirLimit = 1.5; bis_fnc_halo_para_dirAdd = 0.03; bis_fnc_halo_para_keydown = { _key = _this select 1; //--- Forward if (_key in (actionkeys 'MoveForward')) then { if (bis_fnc_halo_para_vel < +bis_fnc_halo_para_velLimit) then {bis_fnc_halo_para_vel = bis_fnc_halo_para_vel + bis_fnc_halo_para_velAdd}; }; //--- Backward if (_key in (actionkeys 'MoveBack')) then { if (bis_fnc_halo_para_vel > -bis_fnc_halo_para_velLimit*0) then {bis_fnc_halo_para_vel = bis_fnc_halo_para_vel - bis_fnc_halo_para_velAdd}; }; //--- Left if (_key in (actionkeys 'TurnLeft')) then { if (bis_fnc_halo_para_dir > -bis_fnc_halo_para_dirLimit) then {bis_fnc_halo_para_dir = bis_fnc_halo_para_dir - bis_fnc_halo_para_dirAdd}; }; //--- Right if (_key in (actionkeys 'TurnRight')) then { if (bis_fnc_halo_para_dir < +bis_fnc_halo_para_dirLimit) then {bis_fnc_halo_para_dir = bis_fnc_halo_para_dir + bis_fnc_halo_para_dirAdd}; }; }; bis_fnc_halo_para_loop_time = time - 0.1; bis_fnc_halo_para_velZ = velocity _para select 2; bis_fnc_halo_para_loop = { if (!isnil {player getvariable "bis_fnc_halo_terminate"}) exitwith {}; if (time == bis_fnc_halo_para_loop_time) exitwith {}; //--- FPS too high _para = vehicle player; //--- FPS counter _fpsCoef = ((time - bis_fnc_halo_para_loop_time) * 20) / acctime; //Script is optimized for 20 FPS bis_fnc_halo_para_loop_time = time; //_fpsCoef = _fpsCoef / 3; bis_fnc_halo_para_velLimit = 0.3 * _fpsCoef; bis_fnc_halo_para_velAdd = 0.002 * _fpsCoef; bis_fnc_halo_para_dirLimit = 1.5 * _fpsCoef; bis_fnc_halo_para_dirAdd = 0.03 * _fpsCoef; //--- Dir bis_fnc_halo_para_dir = bis_fnc_halo_para_dir * 0.98; bis_fnc_halo_para_dirAbs = bis_fnc_halo_para_dirAbs + bis_fnc_halo_para_dir; _para setdir bis_fnc_halo_para_dirAbs; _dir = direction _para; //--- Crash _velZ = velocity _para select 2; if ((_velZ - bis_fnc_halo_para_velZ) > 7 && (getposatl _para select 2) < 100) then {player setdamage 1;debuglog ["Log::::::::::::::",(_velZ - bis_fnc_halo_para_velZ)];}; bis_fnc_halo_para_velZ = _velZ; //--- Pos _para setposasl [ (getposasl _para select 0) + (sin _dir * (0.1 + bis_fnc_halo_para_vel)), (getposasl _para select 1) + (cos _dir * (0.1 + bis_fnc_halo_para_vel)), (getposasl _para select 2) - 0.01 - 0.1 * abs bis_fnc_halo_para_vel ]; [ _para, (-bis_fnc_halo_para_vel * 75) + 0.5*(sin (time * 180)), (+bis_fnc_halo_para_dir * 25) + 0.5*(cos (time * 180)) ] call bis_fnc_setpitchbank; }; bis_fnc_halo_para_mousemoving_eh = (finddisplay 46) displayaddeventhandler ["mousemoving","_this call bis_fnc_halo_para_loop;"]; bis_fnc_halo_para_mouseholding_eh = (finddisplay 46) displayaddeventhandler ["mouseholding","_this call bis_fnc_halo_para_loop;"]; sleep 4; ppeffectdestroy bis_fnc_halo_DynamicBlur; bis_fnc_halo_para_keydown_eh = (finddisplay 46) displayaddeventhandler ["keydown","_this call bis_fnc_halo_para_keydown;"]; //--- End //waituntil {vehicle player == player}; player setvariable ["bis_fnc_halo_terminate",nil]; waituntil {(position vehicle player select 2) < 2 || !isnil {player getvariable "bis_fnc_halo_terminate"}}; (finddisplay 46) displayremoveeventhandler ["keydown",bis_fnc_halo_para_keydown_eh]; (finddisplay 46) displayremoveeventhandler ["mousemoving",bis_fnc_halo_para_mousemoving_eh]; (finddisplay 46) displayremoveeventhandler ["mouseholding",bis_fnc_halo_para_mouseholding_eh]; bis_fnc_halo_para_vel = nil; bis_fnc_halo_para_velLimit = nil; bis_fnc_halo_para_velAdd = nil; bis_fnc_halo_para_dir = nil; bis_fnc_halo_para_dirLimit = nil; bis_fnc_halo_para_dirAdd = nil; bis_fnc_halo_para_keydown = nil; bis_fnc_halo_para_loop = nil; bis_fnc_halo_para_keydown_eh = nil; bis_fnc_halo_para_mousemoving_eh = nil; bis_fnc_halo_para_mouseholding_eh = nil; }; }; diag_log "end";private ["_obj", "_objName", "_temp"]; _obj = _this select 0; // figure out if passed unit has a vehicleVarName if ( vehicleVarName _obj == "" ) then { _objName = str(_obj); } else // if so, remove the vehVarName, and grab the objname { _temp = vehicleVarName _obj; _obj setVehicleVarName ""; _objName = str(_obj); _obj setVehicleVarName _temp; }; _objName // ret private ["_scope", "_inScope", "_force", "_forcePos", "_groupID", "_markers", "_markerText", "_markerColor", "_markerSize", "_createdMarkers", "_logic"]; // [__FILE__] call mk4_fRegisterScript; _scope = _this select 0; _force = _this select 1; _markers = _this select 2; _groupID = _this select 3; _markerText = _this select 4; _markerColor = _this select 5; _markerSize = _this select 6; _createdMarkers = []; if ( isDedicated ) exitWith { }; // if a string was passed, like a group var, check if the var actually exists because // it might've been deselected at the assignment screen // if ( typeName _force == "STRING" ) then // { if ( isNil _force ) exitWith { _this spawn { _force = _this select 1; diag_log format["undefined group, delaying addition to forcetracker"]; diag_log format[">> %1", _this]; while { isNil _force } do { sleep 10; }; _this spawn mk4_fAddToForceTracker; }; }; // }; // the force variable actually exists now, so assign the value to force _force = call compile format ["%1", _force]; // check if _force actually has a value if ( isNull _force ) exitWith { [__FILE__, __LINE__, "ERROR, variable has no assigned value"] call mk4_fEcho; }; // set the group ID if we're dealing with a group if ( typeName _force == "GROUP" ) then { _force setGroupID [_groupID] }; // figure out if the player is allowed to see this force marker _inScope = if ( [player, _scope] call mk4_fInMixedArray ) then { true } else { false }; if ( !_inScope ) exitWith { //[__FILE__, __LINE__, "player is not in scope of this force marker", _this] call mk4_fEcho; // [__FILE__] call mk4_fUnregisterScript; }; // is the force a group or an object? _forcePos = switch ( typeName _force ) do { case "GROUP": { getPos (leader _force) }; case "OBJECT": { getPos _force }; }; /* --------------------------------------------------------------------------------------------------------------- */ { private ["_marker", "_markerClassName"]; _markerClassName = switch ( toUpper(_x) ) do { case "HQ": { "b_hq" }; case "RECON": { "b_recon" }; case "INFANTRY": { "b_inf" }; case "MOTORIZED_INF": { "b_motor_inf" }; case "MECHANIZED_INF": { "b_mech_inf" }; case "ARMOR": { "b_armor" }; case "ROTARY_WING": { "b_air" }; case "FIXED_WING": { "b_plane" }; case "MEDICAL": { "b_med" }; case "ARTILLERY": { "b_art" }; case "MORTAR": { "b_mortar" }; case "SUPPORT": { "b_support" }; case "MAINTENANCE": { "b_main" }; case "SERVICE": { "b_service" }; case "FIRETEAM": { "group_0" }; case "SQUAD": { "group_1" }; case "SECTION": { "group_2" }; case "PLATOON": { "group_3" }; case "COMPANY": { "group_4" }; case "BATTALION": { "group_5" }; case "REGIMENT": { "group_6" }; case "BRIGADE": { "group_7" }; case "DIVISION": { "group_8" }; default { "Empty" } // if wrong name passed, just return an empty marker }; _marker = [_forcePos, "ICON", _markerClassName, _markerColor, [_markerSize, _markerSize], _markerText] call mk4_fCreateMarkerLocal; _markerText = ""; _createdMarkers = _createdMarkers + [_marker]; } forEach _markers; /* --------------------------------------------------------------------------------------------------------------- */ // create a local logic that will be used to do something! _logic = "logic" createVehicleLocal _forcePos; // now that the markers have been created, save all important data in the group variable _force setVariable ["_markers", _createdMarkers]; _force setVariable ["_markerColor", _markerColor]; _force setVariable ["_markerSize", _markerSize]; _force setVariable ["_logic", _logic]; _logic setVariable ["_force", _force]; // add the group to the global marker array, which the groupTracker uses mk4_forcesToTrack = mk4_forcesToTrack + [_force]; // dbg [__FILE__, __LINE__, "adding to force tracker:", _force] call mk4_fEcho; // [__FILE__] call mk4_fUnregisterScript; // done!private "_force"; _force = _this select 0; { _x setMarkerColorLocal "ColorWhite"; } forEach (_force getVariable "_markers"); // add this force to the list of forces to highlight mk4_highLightedForces set [count mk4_highLightedForces, _force]; private ["_display", "_button", "_xPos", "_yPos", "_shift", "_control", "_alt", "_pos", "_handled"]; _display = _this select 0; _button = _this select 1; _xPos = _this select 2; _yPos = _this select 3; _shift = _this select 4; _control = _this select 5; _alt = _this select 6; _handled = false; // get the 3d pos of the map click _pos = (_display displayCtrl 51) posScreenToWorld [_xPos, _yPos]; // check if alt+LMB was used if ( _button == 0 && _alt ) then { // if so, let the engine know it no longer needs to process the mouse click _handled = true; // first get rid of any other selected forces if there were any if ( count(mk4_highlightedForces) > 0 ) then { call mk4_fUnHighlightForces; }; // now check if there was a force near the mouseclick _force = [_pos] call mk4_fNearestTrackedForce; // returns null if nothing was found if ( !(isNull _force) ) then // a force entity was found { [_force] call mk4_fHighlightForce; // check what the force is, and call the appropriate function to display force info switch (true) do { case (typeName _force == "GROUP"): { [_force] call mk4_fShowGroupInfo }; case (_force isKindOf "Man"): { [_force] call mk4_fShowGroupInfo }; // only possibilities now are cars, tanks, planes, ships, etc.... default { [_force] call mk4_fShowVehicleInfo }; }; } else { hintSilent ""; }; } else { if ( count(mk4_highlightedForces) > 0 ) then { call mk4_fUnHighlightForces; hintSilent ""; }; _handled = false; }; _handled // ret private ["_display", "_dikCode", "_shift", "_control", "_alt", "_keys"]; _display = _this select 0; _dikCode = _this select 1; _shift = _this select 2; _control = _this select 3; _alt = _this select 4; // keys to check for is exiting the map and the escape button _keys = (actionKeys "hideMap") + [0x01]; if ( _dikCode in _keys ) then { hintSilent ""; call mk4_fUnHighlightForces; }; false // Let the engine process this keypress as well #define MAX_DISTANCE 10 private ["_pos", "_objects", "_force"]; _pos = _this select 0; _objects = nearestObjects [_pos, ["Logic"], MAX_DISTANCE]; _force = if ( count(_objects) > 0 ) then { if ( !isNil {(_objects select 0) getVariable "_force"} ) then { ((_objects select 0) getVariable "_force") } else { objNull }; } else { objNull }; _force // ret #define PRIVATE_ICON "" #define CORPORAL_ICON "" #define SERGEANT_ICON "" #define LIEUTENANT_ICON "" #define CAPTAIN_ICON "" #define MAJOR_ICON "" #define COLONEL_ICON "" #define COMMANDER_ICON "" #define GUNNER_ICON "" #define DRIVER_ICON "" #define CARGO_ICON "" #define ONFOOT_ICON "" private ["_group", "_groupName", "_icon", "_unitName", "_rankImage", "_content"]; _group = _this select 0; _content = "
"; _groupName = [leader _group] call mk4_fGroupName; _content = _content + format["%1

", _groupName]; { if ( alive _x && !(isNull _x) ) then { _rankImage = switch (rank _x) do // { case "PRIVATE": { PRIVATE_ICON }; case "CORPORAL": { CORPORAL_ICON }; case "SERGEANT": { SERGEANT_ICON }; case "LIEUTENANT": { LIEUTENANT_ICON }; case "CAPTAIN": { CAPTAIN_ICON }; case "MAJOR": { MAJOR_ICON }; case "COLONEL": { COLONEL_ICON }; default {}; }; _rankImage = "" + _rankImage + ""; _unitNumber = [_x] call mk4_fUnitNumber; _unitName = [_x] call mk4_fUnitName; if ( _x == vehicle _x ) then { _icon = ONFOOT_ICON; } else { _icon = CARGO_ICON; if ( _x == commander vehicle _x ) then { _icon = COMMANDER_ICON }; if ( _x == gunner vehicle _x ) then { _icon = GUNNER_ICON }; if ( _x == driver vehicle _x ) then { _icon = DRIVER_ICON }; }; _content = _content + format[" %1 %2. %3 (%4)
", _rankImage, _unitNumber, _unitName, _icon]; }; } forEach (units _group); hintSilent parseText("" + _content + "
"); #define COMMANDER_ICON "" #define GUNNER_ICON "" #define DRIVER_ICON "" #define CARGO_ICON "" #define PRIVATE_ICON "" #define CORPORAL_ICON "" #define SERGEANT_ICON "" #define LIEUTENANT_ICON "" #define CAPTAIN_ICON "" #define MAJOR_ICON "" #define COLONEL_ICON "" #define GROUP_COLOR "FFFF00" #define OTHER_COLOR "888888" _vehicle = _this select 0; private ["_forceMarkerColor"]; { _forceMarkerColor = (_x getVariable "_markerColor"); { _x setMarkerColorLocal _forceMarkerColor; } forEach (_x getVariable "_markers"); } forEach mk4_highLightedForces; mk4_highLightedForces = []; private ["_script", "_msg"]; _script = [(_this select 0)] call mk4_fRelativeFilePath; // compile the msg _msg = format ['[%1] %2, "Starting script"', ([time] call mk4_fFormattedTime), _script]; // record it to screen and rpt diag_log text _msg; mk4 globalChat _msg; // Put the script path in the array mk4_runningScripts set [count mk4_runningScripts, _script]; true // ret#define ASCII_FOLDER_DELIMITER 92 private["_absolutePath", "_relativePath", "_i"]; _absolutePath = toArray(_this select 0); _absolutePathLength = count(_absolutePath); _relativePath = []; for [ { _i = mk4_missionFilePathLength }, { _i < _absolutePathLength }, { _i = _i + 1 }] do { _relativePath set [count _relativePath, (_absolutePath select _i)]; }; toString(_relativePath) // ret private ["_unit", "_height", "_pos"]; _unit = _this select 0; _height = _this select 1; if ( local _unit ) then { _pos = getPosASL _unit; _pos set [2, _height]; _unit setPosASL _pos; true // ret } else { false // ret }; private ["_unit", "_height", "_pos"]; _unit = _this select 0; _height = _this select 1; if ( local _unit ) then { _pos = getPosATL _unit; _pos set [2, _height]; _unit setPosATL _pos; true // ret } else { false // ret }; #define WHITE [1,1,1,1] #define GREY [0.75,0.75,0.75,1] #define GREEN [0.6,0.8,0.4,1] #define RED [1,0.1,0,1] private["_task", "_taskDescription", "_taskStatus", "_taskParams"]; _task = _this select 0; _taskDescription = (taskDescription _task) select 1; _taskStatus = toUpper(taskState _task); _taskParams = switch ( _taskStatus ) do { case "CREATED": { [format["NEW TASK ASSIGNED: \n%1", _taskDescription], WHITE, "taskNew"] }; case "ASSIGNED": { [format["ASSIGNED TASK: \n%1", _taskDescription], WHITE, "taskCurrent"] }; case "SUCCEEDED": { [format["TASK ACCOMPLISHED: \n%1", _taskDescription], GREEN, "taskDone"] }; case "FAILED": { [format["TASK FAILED: \n%1", _taskDescription], RED, "taskFAILED"] }; case "CANCELED": { [format["TASK CANCELED: \n%1", _taskDescription], GREY, "taskDone"] }; }; // show the task hint taskHint _taskParams; true // retprivate ["_unit", "_unitName"]; _unit = _this select 0; _unitName = if ( !(isNull _unit) ) then { if ( isPlayer _unit ) then { name _unit } else { "AI" } } else { "" }; _unitName // retprivate ["_unit", "_animation", "_stance"]; _unit = _this select 0; _stance = ""; // only check if player isn't in a vehicle if ( player == vehicle player ) then { _animation = animationState _unit; _stance = switch ( (toArray(_animation) select 5) ) do { case 101: { "UP" }; // 'e' for erect case 107: { "MIDDLE" }; // 'k' for kneeling case 112: { "DOWN" }; // 'p' for prone default { "" } }; }; _stance // ret private ["_script", "_msg", "_scriptIndex"]; _script = [(_this select 0)] call mk4_fRelativeFilePath; // compile the msg _msg = format ['[%1] %2, "Ending script"', ([time] call mk4_fFormattedTime), _script]; // record it to screen and rpt diag_log text _msg; mk4 globalChat _msg; _scriptIndex = mk4_runningScripts find _script; if ( _scriptIndex > -1 ) then { mk4_runningScripts set [_scriptIndex, objNull]; // set the first found string to objNull mk4_runningScripts = mk4_runningScripts - [objNull]; // remove all objNulls from the array true // ret } else { [__FILE__, __LINE__, "script was not registered", _fileName] call mk4_fEcho; false // ret }; ///////////////////// // General Functions // ///////////////////// mk4_fAddMagazinesTurret = compile (preprocessFileLineNumbers "mk4\f\fAddMagazinesTurret.sqf"); mk4_fAddPersistentAction = compile (preprocessFileLineNumbers "mk4\f\fAddPersistentAction.sqf"); mk4_fAssignTeam = compile (preprocessFileLineNumbers "mk4\f\fAssignTeam.sqf"); mk4_fBuildingEffects = compile (preprocessFileLineNumbers "mk4\f\fBuildingEffects.sqf"); mk4_fCreateLHD = compile (preprocessFileLineNumbers "mk4\f\fCreateLHD.sqf"); mk4_fCreateMarkerLocal = compile (preprocessFileLineNumbers "mk4\f\fCreateMarkerLocal.sqf"); mk4_fCreateStaticUnit = compile (preprocessFileLineNumbers "mk4\f\fCreateStaticUnit.sqf"); mk4_fDestroyBuildings = compile (preprocessFileLineNumbers "mk4\f\fDestroyBuildings.sqf"); mk4_fDirTo = compile (preprocessFileLineNumbers "mk4\f\fDirTo.sqf"); mk4_fDisplayName = compile (preprocessFileLineNumbers "mk4\f\fDisplayName.sqf"); mk4_fEcho = compile (preprocessFileLineNumbers "mk4\f\fEcho.sqf"); mk4_fGroupName = compile (preprocessFileLineNumbers "mk4\f\fGroupName.sqf"); mk4_fHALO = compile (preprocessFileLineNumbers "mk4\f\fHALO.sqf"); mk4_fFormattedTime = compile (preprocessFileLineNumbers "mk4\f\fFormattedTime.sqf"); mk4_fObjectName = compile (preprocessFileLineNumbers "mk4\f\fObjectName.sqf"); mk4_fRegisterScript = compile (preprocessFileLineNumbers "mk4\f\fRegisterScript.sqf"); mk4_fRelativeFilePath = compile (preprocessFileLineNumbers "mk4\f\fRelativeFilePath.sqf"); mk4_fSetHeightATL = compile (preprocessFileLineNumbers "mk4\f\fSetHeightATL.sqf"); mk4_fSetHeightASL = compile (preprocessFileLineNumbers "mk4\f\fSetHeightASL.sqf"); mk4_fTaskHint = compile (preprocessFileLineNumbers "mk4\f\fTaskHint.sqf"); mk4_fUnitName = compile (preprocessFileLineNumbers "mk4\f\fUnitName.sqf"); mk4_fUnitPos = compile (preprocessFileLineNumbers "mk4\f\fUnitPos.sqf"); mk4_fUnregisterScript = compile (preprocessFileLineNumbers "mk4\f\fUnregisterScript.sqf"); ///////////////// // AI Functions // //////////////// mk4_fFleeToBuildings = compile (preprocessFileLineNumbers "mk4\f\ai\fFleeToBuildings.sqf"); mk4_fDoStop = compile (preprocessFileLineNumbers "mk4\f\ai\fDoStop.sqf"); mk4_fTaskPatrol = compile (preprocessFileLineNumbers "mk4\f\ai\fTaskPatrol.sqf"); mk4_fTaskDefend = compile (preprocessFileLineNumbers "mk4\f\ai\fTaskDefend.sqf"); //mk4_fTaskRetreat = compile (preprocessFileLineNumbers "mk4\f\ai\fTaskRetreat.sqf"); mk4_fUPS = compile (preprocessFileLineNumbers "mk4\f\ai\fUPS.sqf"); /////////////////// // Array Functions // /////////////////// mk4_fArrayCountOccurrences = compile (preprocessFileLineNumbers "mk4\f\array\fArrayCountOccurrences.sqf"); mk4_fEnumMixedArray = compile (preprocessFileLineNumbers "mk4\f\array\fEnumMixedArray.sqf"); mk4_fInMixedArray = compile (preprocessFileLineNumbers "mk4\f\array\fInMixedArray.sqf"); ///////////////////// // Briefing Functions // ///////////////////// mk4_fCreateNote = compile (preprocessFileLineNumbers "mk4\f\briefing\fCreateNote.sqf"); mk4_fAssignTask = compile (preprocessFileLineNumbers "mk4\f\briefing\fAssignTask.sqf"); mk4_fCancelTask = compile (preprocessFileLineNumbers "mk4\f\briefing\fCancelTask.sqf"); mk4_fCreateTask = compile (preprocessFileLineNumbers "mk4\f\briefing\fCreateTask.sqf"); mk4_fFailTask = compile (preprocessFileLineNumbers "mk4\f\briefing\fFailTask.sqf"); mk4_fSucceedTask = compile (preprocessFileLineNumbers "mk4\f\briefing\fSucceedTask.sqf"); mk_fTaskHint = compile (preprocessFileLineNumbers "mk4\f\briefing\fTaskHint.sqf"); /////////////////////////// // ForceTracker Functions // ////////////////////////// mk4_fAddToForceTracker = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fAddToForceTracker.sqf"); mk4_fHighlightForce = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fHighlightForce.sqf"); mk4_fMapClickEvent = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fMapClickEvent.sqf"); mk4_fMapKeyDownEvent = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fMapKeyDownEvent.sqf"); mk4_fNearestTrackedForce = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fNearestTrackedForce.sqf"); mk4_fShowGroupInfo = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fShowGroupInfo.sqf"); mk4_fShowVehicleInfo = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fShowVehicleInfo.sqf"); mk4_fUnHighlightForces = compile (preprocessFileLineNumbers "mk4\f\forceTracker\fUnHighlightForces.sqf"); ///////////////////// // Loadout Functions // ///////////////////// mk4_fLoadout = compile (preprocessFileLineNumbers "mk4\f\loadout\fLoadout.sqf"); mk4_fSelectPrimaryMuzzle = compile (preprocessFileLineNumbers "mk4\f\loadout\fSelectPrimaryMuzzle.sqf"); mk4_fSetMagazines = compile (preprocessFileLineNumbers "mk4\f\loadout\fSetMagazines.sqf"); mk4_fSetWeapons = compile (preprocessFileLineNumbers "mk4\f\loadout\fSetWeapons.sqf"); mk4_fSetRuckMagazines = compile (preprocessFileLineNumbers "mk4\f\loadout\fSetRuckMagazines.sqf"); mk4_fSetRuckWeapons = compile (preprocessFileLineNumbers "mk4\f\loadout\fSetRuckWeapons.sqf"); mk4_fSetWeaponOnBack = compile (preprocessFileLineNumbers "mk4\f\loadout\fSetWeaponOnBack.sqf"); /////////////////////// // Network Functions // /////////////////////// mk4_network_fExec = compile (preprocessFileLineNumbers "mk4\f\network\fExec.sqf"); mk4_network_fSend = compile (preprocessFileLineNumbers "mk4\f\network\fSend.sqf"); "mk4_network_cmd" addPublicVariableEventHandler { (_this select 1) call mk4_network_fExec }; ///////////////////// // Text Functions // //////////////////// mk4_fBlueText = compile (preprocessFileLineNumbers "mk4\f\text\fBlueText.sqf"); mk4_fGoldText = compile (preprocessFileLineNumbers "mk4\f\text\fGoldText.sqf"); mk4_fGreenText = compile (preprocessFileLineNumbers "mk4\f\text\fGreenText.sqf"); mk4_fGrayText = compile (preprocessFileLineNumbers "mk4\f\text\fGrayText.sqf"); mk4_fRedText = compile (preprocessFileLineNumbers "mk4\f\text\fRedText.sqf"); mk4_fYellowText = compile (preprocessFileLineNumbers "mk4\f\text\fYellowText.sqf"); //////////////////// // BIS Functions // //////////////////// BIS_fnc_rotateVector2D = compile (preprocessFileLineNumbers "ca\modules\Functions\vectors\fn_rotateVector2D.sqf"); BIS_fnc_setPitchBank = compile (preprocessFileLineNumbers "ca\modules\Functions\objects\fn_setPitchBank.sqf"); ///////////////////// // Other Functions // ///////////////////// private ["_unit", "_fileName", "_loadout", "_handled"]; _unit = _this select 0; _fileName = _this select 1; _loadout = _this select 2; // put filename and loadout name in uppercase _fileName = toUpper(_fileName); _loadout = toUpper(_loadout); // check if we've compiled the loadout file already, if not, compile and cache it if ( (isNil format["mk4_fLoadout_%1", _fileName]) ) then { call compile format ["mk4_fLoadout_%1 = compile (preprocessFileLineNumbers 'mk4\l\%1.sqf')", _fileName]; }; // now call the cached loadout function if ( (call compile format["[_unit, _loadout] call mk4_fLoadout_%1", _fileName]) ) then { // succesfully gave a loadout if ( mk4_debugMode == 3 ) then { [__FILE__, __LINE__, format["'%1' was given loadout '%2 - %3'", _unit, _fileName, _loadout]] call mk4_fEcho; }; _handled = true; } else { // failed giving a loadout [format["<< ERROR >> '%1' was given undefined loadout '%2 - %3'", _unit, _fileName, _loadout]] call mk4_fEcho; _handled = false; }; _handled // ret private ["_unit", "_weapon", "_muzzles"]; _unit = _this select 0; _weapon = primaryWeapon _unit; _handled = false; if ( _weapon != "" ) then { _muzzles = getArray(configFile >> "cfgWeapons" >> _weapon >> "muzzles"); if ( (_muzzles select 0) == "this" ) then { _unit selectWeapon _weapon; } else { _unit selectWeapon (_muzzles select 0); }; _handled = true; }; _handled // ret private ["_unit", "_magazines", "_handled"]; _unit = _this select 0; if ( local _unit ) then { // first remove all magazines on the unit { _unit removeMagazine _x; } forEach (magazines _unit); // and now add all given magazines _magazines = _this - [_unit]; { _magazine = _x select 0; _amount = _x select 1; for "_i" from 1 to _amount do { _unit addMagazine _magazine; }; } forEach _magazines; _handled = true; } else { _handled = false; }; _handled // ret private ["_unit", "_magazines", "_handled"]; _unit = _this select 0; _magazines = _this - [_unit]; _handled = false; if ( !isNull(unitBackpack _unit) ) then // dealing with a BIS backpack { if ( local _unit ) then { clearMagazineCargoGlobal (unitBackpack _unit); { (unitBackpack _unit) addMagazineCargoGlobal _x; } forEach _magazines; _handled = true; }; } else // dealing with a ACE backpack { if ( MK4_ACE ) then { _unit setVariable ["ACE_RuckMagContents", _magazines]; _handled = true; } else { [__FILE__, __LINE__, "<< ERROR >> No backpack found", _unit] call mk4_fEcho; }; }; _handled // ret private ["_unit", "_weapons", "_handled"]; _unit = _this select 0; _weapons = _this - [_unit]; _handled = false; if ( !isNull(unitBackpack _unit) ) then // dealing with a BIS backpack { if ( local _unit ) then { clearWeaponCargoGlobal (unitBackpack _unit); { (unitBackpack _unit) addWeaponCargoGlobal _x; } forEach _weapons; _handled = true; }; } else // dealing with a ACE backpack { if ( MK4_ACE ) then { _unit setVariable ["ACE_RuckWepContents", _weapons]; _handled = true; } else { [__FILE__, __LINE__, "<< ERROR >> No backpack found", _unit] call mk4_fEcho; }; }; _handled // ret private ["_unit", "_weapon" , "_handled", "_weaponOnBack"]; _unit = _this select 0; _weapon = _this select 1; _handled = false; _weaponOnBack = _unit getVariable ["ACE_weaponOnBack", ""]; if ( _weaponOnBack == "" ) then { _unit setVariable ["ACE_weaponOnBack", _weapon]; _handled = true; } else { [__FILE__, __LINE__, "<< ERROR >> Can't add weapon to back, back already occupied", [_unit, _weapon]] call mk4_fEcho; }; _handled // retprivate ["_unit", "_weapons", "_handled"]; _unit = _this select 0; if ( local _unit ) then { // first remove all weapons { _unit removeWeapon _x; } forEach (weapons _unit); //then nick the poor sod's backpack like the evil git you are. Yes you...you know who you are! removeBackPack _unit; // and now add the weapons _weapons = _this select 1; { _unit addWeapon _x; } forEach _weapons; _handled = true; } else { _handled = false; }; _handled // ret private["_cmdScope", "_cmd", "_cmdArray", "_execute"]; _cmdScope = _this select 0; _cmd = _this select 1; // if an arg array was sent with, grab it, otherwise make an empty one _cmdArray = if ( count _this > 2 ) then { _this select 2 } else { [] }; _execute = switch ( _cmdScope ) do { case 0: { isServer }; // 0 = server only case 1: { !isDedicated };// 1 = all clients case 2: { true }; // 2 = all clients + server }; if ( _execute ) then { _cmdArray call _cmd; if ( mk4_debugMode == 3 ) then { [__FILE__, __LINE__, "executing a received command:", _this] call mk4_fEcho }; }; _execute // ret mk4_network_cmd = _this; publicVariable "mk4_network_cmd"; _this spawn mk4_network_fExec; if ( mk4_debugMode == 3 ) then { [__FILE__, __LINE__, "sending command over network", mk4_network_cmd] call mk4_fEcho }; true // ret switch ( typeName _this ) do { case "STRING": { "" + _this + "" }; case "ARRAY": { "" + _this + "" }; default { [__FILE__, __LINE__, "<< ERROR >> Unsupported data type", (typeName _this)] call mk4_fEcho; "<< ERROR >>" }; }; switch ( typeName _this ) do { case "STRING": { "" + _this + "" }; case "ARRAY": { "" + _this + "" }; default { [__FILE__, __LINE__, "<< ERROR >> Unsupported data type", (typeName _this)] call mk4_fEcho; "<< ERROR >>" }; }; switch ( typeName _this ) do { case "STRING": { "" + _this + "" }; case "ARRAY": { "" + _this + "" }; default { [__FILE__, __LINE__, "<< ERROR >> Unsupported data type", (typeName _this)] call mk4_fEcho; "<< ERROR >>" }; }; switch ( typeName _this ) do { case "STRING": { "" + _this + "" }; case "ARRAY": { "" + _this + "" }; default { [__FILE__, __LINE__, "<< ERROR >> Unsupported data type", (typeName _this)] call mk4_fEcho; "<< ERROR >>" }; }; switch ( typeName _this ) do { case "STRING": { "" + _this + "" }; case "ARRAY": { "" + _this + "" }; default { [__FILE__, __LINE__, "<< ERROR >> Unsupported data type", (typeName _this)] call mk4_fEcho; "<< ERROR >>" }; }; switch ( typeName _this ) do { case "STRING": { "" + _this + "" }; case "ARRAY": { "" + _this + "" }; default { [__FILE__, __LINE__, "<< ERROR >> Unsupported data type", (typeName _this)] call mk4_fEcho; "<< ERROR >>" }; }; private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "SL": // Section Leader { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["SmokeShellRed", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_ACOG", "NVGoggles", "Binocular_Vector", "ItemWatch", "ItemCompass", "ACRE_PRC343", "ItemMap", "ACRE_PRC119"] } else { ["BAF_L85A2_RIS_ACOG", "NVGoggles", "Binocular_Vector", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "RIFLE": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L85A2_RIS_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; case "GRN": // Grenadier { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["BAF_L109A1_HE", 2], ["1Rnd_HE_M203", 8] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_UGL_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L85A2_UGL_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemWatch"] } ] call mk4_fSetWeapons; _unit addBackpack "BAF_AssaultPack_RifleAmmo"; }; case "MED": // Medic { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["SmokeShellRed", 2], ["SmokeShellGreen", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_Holo","ACE_Rucksack_MOLLE_WMARPAT_Medic","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L85A2_RIS_Holo","ACE_Rucksack_MOLLE_WMARPAT_Medic","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemWatch"] } ] call mk4_fSetWeapons; }; case "TL": // Team Leader { [_unit, ["30Rnd_556x45_Stanag", 8], ["SmokeShell", 2], ["SmokeShellRed", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_Holo","NVGoggles","Binocular_Vector","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L85A2_RIS_Holo","NVGoggles","Binocular_Vector","ItemMap","ItemCompass","ItemWatch","ItemWatch"] } ] call mk4_fSetWeapons; _unit addBackpack "BAF_AssaultPack_RifleAmmo"; }; case "AR": // Automatic Rifleman { [_unit, ["200Rnd_556x45_L110A1", 5], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L110A1_Aim","ACE_Earplugs", "NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L110A1_Aim","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; case "AAR": // Assistant Automatic Rifleman { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_Holo","ACE_Earplugs","NVGoggles","Binocular_Vector","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L85A2_RIS_Holo","NVGoggles","Binocular_Vector","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; _unit addBackpack "BAF_AssaultPack_ARAmmo"; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "SL": // Squad Leader { [_unit, ["10x_303", 6], ["HandGrenade_East", 3] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["LeeEnfield", "Binocular", "ItemWatch", "ItemCompass", "ItemMap", "ACRE_PRC343"] } else { ["LeeEnfield", "Binocular", "ItemWatch", "ItemCompass", "ItemMap", "ItemRadio"] } ] call mk4_fSetWeapons; }; case "MED": // Medic { [_unit, ["30Rnd_762x39_AK47", 5], ["HandGrenade_East", 3] ] call mk4_fSetMagazines; [_unit, ["AK_47_M", "ItemWatch", "ItemCompass", "ItemMap"] ] call mk4_fSetWeapons; }; case "RPG": // RPG gunner { [_unit, ["30Rnd_762x39_AK47", 4], ["PG7V", 3] ] call mk4_fSetMagazines; [_unit, ["AK_47_S", "RPG7V", "ItemWatch", "ItemCompass", "ItemMap"] ] call mk4_fSetWeapons; }; case "MG": // Machinegunner { [_unit, ["100Rnd_762x54_PK", 5] ] call mk4_fSetMagazines; [_unit, ["PK", "ItemWatch", "ItemCompass", "ItemMap"] ] call mk4_fSetWeapons; }; case "IED": // Bomber { [_unit, ["10x_303", 4], ["PipeBomb", 4] ] call mk4_fSetMagazines; [_unit, ["LeeEnfield", "ItemWatch", "ItemCompass", "ItemMap"] ] call mk4_fSetWeapons; removeBackpack _unit; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "PL": // Platoon Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellBlue", 6] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74_U", "Binocular", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AKS_74_U", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "PSG": // Platoon Sergeant { [_unit, ["30Rnd_762x39_AK47", 6], ["SmokeShellBlue", 6] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_47_M", "Binocular", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AK_47_M", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "RTO": // Platoon RTO { [_unit, ["30Rnd_762x39_AK47", 8] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_47_M", "Binocular", "ItemWatch", "ItemCompass", "ACRE_PRC343", "ACRE_PRC119", "ItemMap"] } else { ["AK_47_M", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "HM": // Medic { [_unit, ["30Rnd_545x39_AK", 4], ["SmokeShellBlue", 4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74_U", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AKS_74_U", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "SL": // Squad Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellGreen", 2], ["SmokeShellRed", 2], ["Handgrenade_East", 2], ["1Rnd_HE_GP25", 6], ["FlareRed_GP25", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ACRE_PRC148", "ItemMap"] } else { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "TL": // Team Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellGreen", 2], ["SmokeShellRed", 2], ["Handgrenade_East", 2], ["1Rnd_HE_GP25", 6], ["FlareGreen_GP25", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "AR": // Automatic Rifleman { [_unit, ["75Rnd_545x39_RPK", 5], ["SmokeShellGreen", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["RPK_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["RPK_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; removeBackpack _unit; }; case "AAR": // Assistant Automatic Rifleman { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellRed", 2], ["75Rnd_545x39_RPK", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AKS_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "GRN": // Grenadier { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellRed", 2], ["PG7V", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74", "RPG7V", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AKS_74", "RPG7V", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "AGRN": // Grenadier { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellRed", 2], ["PG7V", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AK_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "MG": // Machinegunner { [_unit, ["100Rnd_762x54_PK", 6] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["PK", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["PK", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "R": // Rifleman { [_unit, ["30Rnd_545x39_AK", 7], ["SmokeShell", 2], ["Handgrenade_East", 3] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AK_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "DM": // Designated Marksman { [_unit, ["10Rnd_762x54_SVD", 7], ["SmokeShell", 2] ] call mk4_fSetMagazines; [_unit, ["SVD", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; case "DEM": // Demolitions Specialist { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShell", 2], ["Handgrenade_East", 2], ["PipeBomb", 1] ] call mk4_fSetMagazines; [_unit, ["AK_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; case "BODY": // Bodyguard { [_unit, ["30Rnd_762x39_AK47", 6], ["SmokeShell", 2], ["Handgrenade_East", 2] ] call mk4_fSetMagazines; [_unit, ["AK_47_S", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; case "CREW": // Crew { [_unit, ["30Rnd_545x39_AK", 5], ["SmokeShell", 2] ] call mk4_fSetMagazines; [_unit, ["AKS_74_U", "NVGoggles", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; case "CREW_COM": // Crew { [_unit, ["30Rnd_545x39_AK", 5], ["SmokeShell", 2] ] call mk4_fSetMagazines; [_unit, ["AKS_74_U", "Binocular", "NVGoggles", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "FTL": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 8], ["SmokeShell", 2], ["HandGrenade_West", 2], ["1rnd_HE_M203", 4], ["ACE_15Rnd_9x19_P226",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["ACE_m16a2gl_scope","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch", "ACRE_PRC148","ACRE_PRC343","ACE_BackPack_ACR_DDPM"] } else { ["ACE_m16a2gl_scope","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ItemRadio","ACE_BackPack_ACR_DDPM"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 4],["ACE_30Rnd_556x45_T_Stanag", 4],["HandGrenade_West", 4],["SmokeShell", 4],["1rnd_HE_M203", 6],["100Rnd_556x45_M249",1]] call mk4_fSetRuckMagazines; //[_unit, ["ACE_M72", 1]] call mk4_fSetRuckWeapons; [_unit, "ACE_M72"] call mk4_fSetWeaponOnBack; }; case "AR": // Rifleman Backpack { [_unit, ["200Rnd_556x45_M249", 2], ["ACE_200Rnd_556x45_T_M249", 2], ["SmokeShell", 2], ["HandGrenade_West", 2], ["ACE_15Rnd_9x19_P226",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["M249","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ACRE_PRC343","ACE_BackPack_ACR_DDPM"] } else { ["M249","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ItemRadio","ACE_BackPack_ACR_DDPM"] } ] call mk4_fSetWeapons; [_unit, ["100Rnd_556x45_M249", 2],["ACE_100Rnd_556x45_T_M249", 2],["HandGrenade_West", 4],["SmokeShell", 4]] call mk4_fSetRuckMagazines; //[_unit, ["AKS_74_U", 1]] call mk4_fSetRuckWeapons; //[_unit, "AKS_74_U"] call mk4_fSetWeaponOnBack; }; case "RF": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 8], ["SmokeShell", 2], ["HandGrenade_West", 2], ["1rnd_HE_M203", 4], ["ACE_15Rnd_9x19_P226",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["M16A2GL","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ACRE_PRC343","ACE_BackPack_ACR_DDPM"] } else { ["M16A2GL","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ItemRadio","ACE_BackPack_ACR_DDPM"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 4],["ACE_30Rnd_556x45_T_Stanag", 4],["HandGrenade_West", 4],["SmokeShell", 4],["1rnd_HE_M203", 6],["100Rnd_556x45_M249",1]] call mk4_fSetRuckMagazines; //[_unit, ["ACE_M72", 1]] call mk4_fSetRuckWeapons; [_unit, "ACE_M72"] call mk4_fSetWeaponOnBack; }; case "DM": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 7], ["PipeBomb", 2], ["SmokeShell", 1], ["HandGrenade_West", 2], ["1rnd_HE_M203", 4], ["ACE_15Rnd_9x19_P226",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["M16A2GL","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ACRE_PRC343","ACE_BackPack_ACR_DDPM"] } else { ["M16A2GL","ACE_P226","Binocular","ACE_DAGR","ACE_Earplugs","ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ItemRadio","ACE_BackPack_ACR_DDPM"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 5],["ACE_30Rnd_556x45_T_Stanag", 4],["1rnd_HE_M203", 4],["PipeBomb", 1],["HandGrenade_West", 3],["SmokeShell", 3],["100Rnd_556x45_M249",1]] call mk4_fSetRuckMagazines; //[_unit, ["AKS_74_U", 1]] call mk4_fSetRuckWeapons; //[_unit, "AKS_74_U"] call mk4_fSetWeaponOnBack; }; case "ME": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["SmokeShellGreen", 2], ["HandGrenade_West", 2], ["ACE_15Rnd_9x19_P226",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["M16A2","ACE_P226","Binocular","ACE_Earplugs","ACE_GlassesLHD_glasses""ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ACRE_PRC343","ACE_BackPack_ACR_DDPM"] } else { ["M16A2","ACE_P226","Binocular","ACE_Earplugs","ACE_GlassesLHD_glasses""ACE_GlassesLHD_glasses","ItemCompass","ItemWatch","ItemRadio","ACE_BackPack_ACR_DDPM"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 5],["ACE_30Rnd_556x45_T_Stanag", 4],["SmokeShellGreen", 2],["SmokeShell", 2],["HandGrenade_West", 2],["100Rnd_556x45_M249",1]] call mk4_fSetRuckMagazines; //[_unit, ["AKS_74_U", 1]] call mk4_fSetRuckWeapons; //[_unit, "AKS_74_U"] call mk4_fSetWeaponOnBack; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "RIFLE": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["BAF_L85A2_RIS_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; _unit addBackpack "TK_Assault_Pack_EP1"; [_unit, ["30Rnd_545x39_AK", 5],["30Rnd_556x45_Stanag", 1]] call mk4_fSetRuckMagazines; [_unit, "AKS_74_U"] call mk4_fSetWeaponOnBack; }; case "RIFLE2": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["BAF_L85A2_RIS_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343","ACE_CharliePack_ACU"] } else { ["BAF_L85A2_RIS_ACOG","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_545x39_AK", 5],["30Rnd_556x45_Stanag", 1]] call mk4_fSetRuckMagazines; [_unit, ["AKS_74_U", 1]] call mk4_fSetRuckWeapons; [_unit, "AKS_74_U"] call mk4_fSetWeaponOnBack; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "PL": // Platoon Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellBlue", 6] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74_U", "Binocular", "ItemWatch", "ItemCompass", "ItemMap", "ACRE_PRC343", "ACRE_PRC148"] } else { ["AKS_74_U", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "PSG": // Platoon Sergeant { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellBlue", 6] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74_U", "Binocular", "ItemWatch", "ItemCompass", "ACRE_PRC343", "ItemMap"] } else { ["AKS_74_U", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; removeBackpack _unit; _unit addBackpack "TKG_ALICE_Pack_AmmoAK74_EP1"; }; case "HM": // Medic { [_unit, ["30Rnd_545x39_AK", 4], ["SmokeShellBlue", 4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74_U", "ItemWatch", "ItemCompass", "ACRE_PRC343", "ItemMap"] } else { ["AKS_74_U", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "SL": // Squad Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellGreen", 2], ["SmokeShellRed", 2], ["Handgrenade_East", 2], ["1Rnd_HE_GP25", 6], ["FlareRed_GP25", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ACRE_PRC343", "ACRE_PRC148", "ItemMap"] } else { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; _unit addBackpack "TKG_ALICE_Pack_AmmoAK74_EP1"; }; case "TL": // Team Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellGreen", 2], ["SmokeShellRed", 2], ["Handgrenade_East", 2], ["1Rnd_HE_GP25", 6], ["FlareGreen_GP25", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ACRE_PRC343", "ItemMap"] } else { ["AK_74_GL", "Binocular", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; _unit addBackpack "TKG_ALICE_Pack_AmmoAK74_EP1"; }; case "AR": // Automatic Rifleman { [_unit, ["75Rnd_545x39_RPK", 6], ["SmokeShellGreen", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["RPK_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["RPK_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; removeBackpack _unit; }; case "AAR": // Assistant Automatic Rifleman { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellRed", 2], ["75Rnd_545x39_RPK", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AKS_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; _unit addBackpack "TK_Assault_Pack_RPK_EP1"; }; case "GRN": // Grenadier { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellRed", 2], ["PG7V", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74", "RPG7V", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AKS_74", "RPG7V", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "AGRN": // Grenadier { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShellRed", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74", "ItemWatch", "ItemCompass", "ItemMap"] } else { ["AK_74", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] } ] call mk4_fSetWeapons; }; case "BODY": // Bodyguard { [_unit, ["30Rnd_762x39_AK47", 6], ["SmokeShell", 2], ["Handgrenade_East", 2] ] call mk4_fSetMagazines; [_unit, ["AK_47_S", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; case "CREW": // Crew { [_unit, ["30Rnd_545x39_AK", 5], ["SmokeShell", 2] ] call mk4_fSetMagazines; [_unit, ["AKS_74_U", "NVGoggles", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; case "CREW_COM": // Crew { [_unit, ["30Rnd_545x39_AK", 5], ["SmokeShell", 2] ] call mk4_fSetMagazines; [_unit, ["AKS_74_U", "Binocular", "NVGoggles", "ItemWatch", "ItemCompass", "ItemRadio", "ItemMap"] ] call mk4_fSetWeapons; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "SL": // Section Leader { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShell", 2], ["SmokeShellRed", 2], ["8Rnd_9x18_Makarov", 4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74_pso","Makarov","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["AKS_74_pso","Makarov","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; case "RIFLE": // Rifleman Backpack { [_unit, ["30Rnd_545x39_AK", 8], ["SmokeShell", 2], ["HandGrenade_East", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["AK_74","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; case "MED": // Medic { [_unit, ["30Rnd_556x45_Stanag", 6], ["SmokeShell", 2], ["BAF_L109A1_HE", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AKS_74","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343"] } else { ["AKS_74","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; case "FAC": // FAC { [_unit, ["30Rnd_545x39_AK", 6], ["SmokeShell", 2], ["SmokeShellRed", 2], ["SmokeShellGreen", 2], ["1Rnd_SmokeRed_GP25", 16] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["AK_74_GL","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343","ACRE_PRC148"] } else { ["AK_74_GL","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; case "PILOT": // Pilot { [_unit, ["8Rnd_9x18_Makarov", 4], ["SmokeShell", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["Makarov","ItemMap","ItemCompass","ItemWatch","ACRE_PRC148"] } else { ["Makarov","ItemMap","ItemCompass","ItemWatch","ItemRadio"] } ] call mk4_fSetWeapons; }; default { _handled = false } }; _handled // ret private ["_unit", "_loadout", "_handled"]; _unit = _this select 0; _loadout = _this select 1; _handled = true; // grab the correct loadout (should be in UPPERCASE) switch ( _loadout ) do { case "SL": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 8], ["SmokeShell", 2], ["HandGrenade_West", 2], ["ACE_15Rnd_9x19_P226",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["M16A4_ACG","ACE_P226","Binocular","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch", "ACRE_PRC148","ACRE_PRC343","ACE_Rucksack_MOLLE_DMARPAT"] } else { ["M16A4_ACG","ACE_P226","Binocular","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio","ACE_Rucksack_MOLLE_DMARPAT"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 3],["ACE_30Rnd_556x45_T_Stanag", 3],["HandGrenade_West", 3],["SmokeShell", 3]] call mk4_fSetRuckMagazines; //[_unit, ["ACE_M72", 1]] call mk4_fSetRuckWeapons; //[_unit, "ACE_M72"] call mk4_fSetWeaponOnBack; }; case "FTL": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 8], ["SmokeShell", 2], ["HandGrenade_West", 2], ["ACE_15Rnd_9x19_P226",4], ["1Rnd_HE_M203",4] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["M16A4_ACG_GL","ACE_P226","Binocular","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch", "ACRE_PRC148","ACRE_PRC343","ACE_Rucksack_MOLLE_DMARPAT"] } else { ["M16A4_ACG_GL","ACE_P226","Binocular","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio","ACE_Rucksack_MOLLE_DMARPAT"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 3],["ACE_30Rnd_556x45_T_Stanag", 3],["HandGrenade_West", 3],["SmokeShell", 3],["1Rnd_HE_M203",8]] call mk4_fSetRuckMagazines; //[_unit, ["ACE_M72", 1]] call mk4_fSetRuckWeapons; //[_unit, "ACE_M72"] call mk4_fSetWeaponOnBack; }; case "AR": // Rifleman Backpack { [_unit, ["200Rnd_556x45_M249", 3], ["ACE_200Rnd_556x45_T_M249",1], ["SmokeShell", 2], ["HandGrenade_West", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["ACE_M249_PIP_ACOG","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343","ACE_Rucksack_MOLLE_DMARPAT"] } else { ["ACE_M249_PIP_ACOG","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio","ACE_Rucksack_MOLLE_DMARPAT"] } ] call mk4_fSetWeapons; [_unit, ["200Rnd_556x45_M249", 2],["ACE_200Rnd_556x45_T_M249", 2],["HandGrenade_West", 4],["SmokeShell", 4]] call mk4_fSetRuckMagazines; //[_unit, ["AKS_74_U", 1]] call mk4_fSetRuckWeapons; //[_unit, "AKS_74_U"] call mk4_fSetWeaponOnBack; }; case "RF": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 7], ["SmokeShell", 2], ["HandGrenade_West", 3] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["m16a4","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343","ACE_Rucksack_MOLLE_DMARPAT"] } else { ["m16a4","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio","ACE_Rucksack_MOLLE_DMARPAT"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 3],["ACE_30Rnd_556x45_T_Stanag", 3],["HandGrenade_West", 3],["SmokeShell", 3]] call mk4_fSetRuckMagazines; //[_unit, ["ACE_M72", 1]] call mk4_fSetRuckWeapons; [_unit, "ACE_M72"] call mk4_fSetWeaponOnBack; }; case "AT": // Rifleman Backpack { [_unit, ["30Rnd_556x45_Stanag", 8], ["SMAW_HEDP", 2] ] call mk4_fSetMagazines; [_unit, if ( MK4_ACRE ) then { ["ACE_M16A4_Iron","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ACRE_PRC343","SMAW"] } else { ["ACE_M16A4_Iron","ACE_Earplugs","NVGoggles","ItemMap","ItemCompass","ItemWatch","ItemRadio","SMAW"] } ] call mk4_fSetWeapons; [_unit, ["30Rnd_556x45_Stanag", 2],["ACE_30Rnd_556x45_T_Stanag", 3],["HandGrenade_West", 5],["SmokeShell", 5]] call mk4_fSetRuckMagazines; //[_unit, ["AKS_74_U", 1]] call mk4_fSetRuckWeapons; [_unit, "ACE_Rucksack_MOLLE_DMARPAT"] call mk4_fSetWeaponOnBack; }; default { _handled = false } }; _handled // ret #define PRIORITY -35 #define THIS_FILE "mk4\s\adminMenu.sqf" private["_obj", "_caller", "_id", "_arg"]; switch (count _this) do { case 1: { // if called from script _arg = _this select 0; }; case 4: { // called from addAction _obj = _this select 0; _caller = _this select 1; _id = _this select 2; _arg = _this select 3; }; }; waitUntil { MK4_INIT }; switch (_arg) do { case "init": { if ( isServer ) then { mk4_fShowCasrates = { private ["_stats", "_westStats", "_eastStats", "_resStats", "_civStats"]; _stats = "
CasRates

"; _westStats = format["West: %1 out of %2 (%3%4)
", WCasNum, WStartNum, WCasRate, "%"]; _eastStats = format["East: %1 out of %2 (%3%4)
", ECasNum, EStartNum, ECasRate, "%"]; _resStats = format["Res: %1 out of %2 (%3%4)
", RCasNum, RStartNum, RCasRate, "%"]; _civStats = format["Civ: %1 out of %2 (%3%4)
", CCasNum, CStartNum, CCasRate, "%"]; _stats = _stats + _westStats + _eastStats + _resStats + _civStats + "
"; [1, {if (isAdmin) then {hint parseText(_this)} }, _stats] call mk4_network_fSend; }; }; if ( !isDedicated ) then { mk4_showAdminMenu = false; ["==== Admin Menu ====" call mk4_fGoldText, THIS_FILE, "showAdminMenu", PRIORITY, false, false, "", "isAdmin"] call mk4_fAddPersistentAction; ["Spectator Script" call mk4_fGoldText, THIS_FILE, "spectateMode", PRIORITY - 1, false, false, "", "mk4_showAdminMenu"] call mk4_fAddPersistentAction; ["Show Player Ratings" call mk4_fGoldText, THIS_FILE, "playerRatings", PRIORITY - 2, false, false, "", "mk4_showAdminMenu"] call mk4_fAddPersistentAction; ["View CasRates" call mk4_fGoldText, THIS_FILE, "casrates", PRIORITY - 3, false, false, "", "mk4_showAdminMenu"] call mk4_fAddPersistentAction; ["End Mission" call mk4_fGoldText, THIS_FILE, "endMission", PRIORITY - 4, false, false, "", "mk4_showAdminMenu"] call mk4_fAddPersistentAction; ["===================" call mk4_fGoldText, THIS_FILE, "", PRIORITY - 5, false, false, "", "mk4_showAdminMenu"] call mk4_fAddPersistentAction; }; }; case "spectateMode": { //[player, player, "null"] execVM "mk4\s\spect\specta.sqf"; ace_sys_spectator_no_butterfly_mode = false; ace_sys_spectator_can_exit_spectator = true; [player, player, "null"] call ace_fnc_startSpectator }; case "showAdminMenu": { mk4_showAdminMenu = !mk4_showAdminMenu; }; case "playerRatings": { _msg = "
Player Ratings

"; _players = []; { if ( isPlayer _x ) then { _players set [count _players, _x]; }; } forEach ( if (isMultiplayer) then {playableUnits} else {switchableUnits} ); { if ( rating _x >= 0 ) then { _msg = _msg + format["%1 %2
", ((name _x) call mk4_fGreenText), rating _x]; } else { _msg = _msg + format["%1 %2
", ((name _x) call mk4_fRedText), rating _x]; }; } forEach _players; _msg = _msg + "
"; hint (parseText _msg); }; case "casrates": { [0, { call mk4_fShowCasrates }] call mk4_network_fSend; }; case "endMission": { mk4_adminEndex = true; publicVariable "mk4_adminEndex"; }; case "": { }; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; // wait until template is initialized waitUntil { MK4_INIT }; _vehicle = _this select 0; _authorizedCrew = _this select 1; // the server doesnt need to be running this / check if auth crew is an array if ( isDedicated ) exitWith { }; if ( (typeName _authorizedCrew) != "ARRAY" ) exitWith { [__FILE__,__LINE__,"invalid parameters", _this] call mk4_fEcho}; // add the getIn EH which will check if the unit is authorized _eh = _vehicle addEventHandler ["getIn", { _vehicle = _this select 0; _vehicleRole = _this select 1; _unit = _this select 2; _authorizedCrew = _vehicle getVariable "mk4_authorizedCrew"; _authorized = false; // don't proceed if this unit isn't even local to you if ( !(local _unit) ) exitWith { }; // don't proceed any further if unit is cargo if ( _vehicleRole == "CARGO" ) exitWith { }; // check if unit is in the mixed array _authorized = [_unit, _authorizedCrew] call mk4_fInMixedArray; // now kick the non-authorized people out if ( !_authorized ) exitWith { _unit action ["getout", _vehicle]; hint "\nYou are not authorized to crew this vehicle\n\n"; }; }]; // save the authorized crew values on the vehicle itself _vehicle setVariable ["mk4_authorizedCrew", _authorizedCrew]; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; // Create a trigger with the following settings: // - Repeatedly // - Activation by (side you wish to impose the LOA on) // - Cond: (vehicle player in thisList) // - On Act: nul = [] execVM "mk4\s\borderControl.sqf"; // - On Deact: // // To exclude a player or a vehicle from the LOA, put this in its init line: // this setVariable ["mk4_LOA", false]; _vehicle = vehicle player; _distance = 4; // preferred bumping distance if ( format["%1",_vehicle getVariable "mk4_LOA"] != "false" ) then { // send the player a message (standard msg when none was given) _msg = if (count _this > 0) then { _this select 0 } else { format["%1, you were leaving the area of operations. Check your map.", toUpper(name player)] }; titleText [_msg, "PLAIN"]; // no need for multiple people to do this if ( player == driver _vehicle ) then { // get the velocity vector _vel = velocity _vehicle; _velX = _vel select 0; _velY = _vel select 1; _velZ = _vel select 2; // get the direction of movement (could be different from the direction of the unit) _dir = [[0,0,0], _vel] call mk4_fDirTo; // turn 180 _dir = _dir + 180; _vehicle setDir _dir; // place unit a few meters forward _pos = getPosATL _vehicle; _posX = _pos select 0; _posY = _pos select 1; _posZ = _pos select 2; _vehicle setPosATL [(_posX + sin(_dir) * _distance), (_posY + cos(_dir) * _distance), _posZ]; // reverse the velocity vector _vehicle setVelocity [-_velX, -_velY, -_velZ]; // if it was a footmobile, freeze userinput for a second // - needed because the LOA will be checked every 0.5 sec // - workaround for buggy disableUserInput if ( player == _vehicle ) then { mk4_fDisableMovementKeys = { _key = _this select 1; _disabledKeys = (actionKeys "moveForward") + (actionKeys "moveBack") + (actionKeys "MoveLeft") + (actionKeys "MoveRight"); if ( _key in _disabledKeys ) then { true } else { false }; }; _eh = (findDisplay 46) displayAddEventhandler ["keyDown", "_this call mk4_fDisableMovementKeys"]; uisleep 1; (findDisplay 46) displayRemoveEventHandler ["keyDown", _eh]; }; }; }; // end //------------------------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------------------------- class mk4_template_debugger { idd = -1; movingEnable = 1; onLoad = "['load'] spawn compile preprocessFileLineNumbers 'mk4\s\debugger\init.sqf';"; onUnload = "['unload'] call compile preprocessFileLineNumbers 'mk4\s\debugger\init.sqf';"; class RscText; class RscButton_small; class RscEdit; class Controls { class RscGroupBox2 { x=0.100; y=0.070; w=0.800; h=0.830; type = 0; idc = -1; style = 112; text = ""; colorBackground[] = {1, 1, 1, 0.6}; colorText[] = {0, 0, 0, 0}; font = "BitStream"; sizeEx = 0.02; }; class Drag: RscGroupBox2 { x=0.100; y=0.070; w=0.800; h=0.830; colorbackground[] = {0,0,0,0.8}; colortext[] = {0,0,0,0}; moving = 1; }; class Header : RscText { type=0; // colorBackground[] = {0,0,0,0}; font = "Zeppelin32"; IDC = 531010; style=2; x=0.100; y=0.070; w=0.800; h=0.04; text="Debug Console"; sizeEx = 0.04; colortext[]={1,1,1,1}; }; class SubBackground1 : RscGroupBox2 { x=0.110; y=0.115; w=0.780; h=0.410; style=128; colorBackground[] = {0.709,0.972,0.384,0.2}; }; class SubBackground2 : RscGroupBox2 { x=0.110; y=0.535; w=0.780; h=0.350; style=128; colorBackground[] = {0.709,0.972,0.384,0.2/*0.25, 0.25, 0.25, 1.55*/}; }; //----- Value check ----- class ValueInput1 : RscEdit { IDC = 531011; style = 64; // colorText[] = {0.95,0.95,0.95,1}; // colorSelection[] = {0.543,0.5742,0.4102,1}; // font = "Zeppelin32"; // sizeEx = 0.03921; // text = ""; // type=2; // x = 0.120; y = 0.125; w = 0.760; h = 0.04; autocomplete = "scripting"; }; class ValueOutput1 : RscEdit { IDC = 531012; style = 64; // colorText[] = {0.95,0.95,0.95,1}; // colorSelection[] = {0.543,0.5742,0.4102,1}; // font = "Zeppelin32"; // sizeEx = 0.03921; // text = ""; // type=2; // x = 0.120; y = 0.165-0.001; w = 0.760; h = 0.04; autocomplete = ""; }; class ValueInput2 : ValueInput1 { IDC = 531021; y = 0.225; }; class ValueOutput2 : ValueOutput1 { IDC = 531022; y = 0.265-0.001; }; class ValueInput3 : ValueInput1 { IDC = 531031; y = 0.325; }; class ValueOutput3 : ValueOutput1 { IDC = 531032; y = 0.365-0.001; }; class ValueInput4 : ValueInput1 { IDC = 531041; y = 0.425; }; class ValueOutput4 : ValueOutput1 { IDC = 531042; y = 0.465-0.001; }; //----- Command lines ----- class CommandInput1 : RscEdit { IDC = 531101; style = 64; // colorText[] = {0.95,0.95,0.95,1}; // colorSelection[] = {0.543,0.5742,0.4102,1}; // font = "Zeppelin32"; // sizeEx = 0.03921; // text = ""; // type=2; // x = 0.120; y = 0.550; w = 0.695; h = 0.04; autocomplete = "scripting"; }; class CommandButton1 : RscButton_small { idc = -1; type=1; // style = 258; // colorDisabled[] = {0.4,0.4,0.4,1}; // font = "Zeppelin32"; // sizeEx = 0.02674; // colorBackgroundActive[] = {1,0.537,0,1}; // colorBackgroundDisabled[] = {0.95,0.95,0.95,1}; // colorFocused[] = {1,0.537,0,1}; // offsetX = 0.003; // offsetY = 0.003; // offsetPressedX = 0.002; // offsetPressedY = 0.002; // colorShadow[] = {0.023529,0,0.0313725,1}; // colorBorder[] = {0.023529,0,0.0313725,1}; // borderSize = 0; // soundEnter[] = { "", 0, 1 }; // soundPush[] = { "", 0, 1 }; // soundClick[] = { "", 0, 1 }; // soundEscape[] = { "", 0, 1 }; // x = 0.820; y = 0.550; w = 0.060; h = 0.04; colorText[] = {0.75, 0.75, 0.75, 1}; colorBackground[] = {0.709/2,0.972/2,0.384/2,1}; text = "Exec"; action = "call compile (ctrlText 531101);"; default = 1; }; class CommandInput2 : CommandInput1 { IDC = 531102; y = 0.600; }; class CommandButton2 : CommandButton1 { y = 0.600; action = "call compile (ctrlText 531102);"; }; class CommandInput3 : CommandInput1 { IDC = 531103; y = 0.650; }; class CommandButton3 : CommandButton1 { y = 0.650; action = "call compile (ctrlText 531103);"; }; class CommandInput4 : CommandInput1 { IDC = 531104; y = 0.700; }; class CommandButton4 : CommandButton1 { y = 0.700; action = "call compile (ctrlText 531104);"; }; class CommandInput5 : CommandInput1 { IDC = 531105; y = 0.750; }; class CommandButton5 : CommandButton1 { y = 0.750; action = "call compile (ctrlText 531105);"; }; class CommandInput6 : CommandInput1 { IDC = 531106; y = 0.800; }; class CommandButton6 : CommandButton1 { y = 0.800; action = "call compile (ctrlText 531106);"; default = true; }; }; }; _arg = _this select 0; switch ( _arg ) do { case "load": { mk4_debugger_run = true; // check if this is the first session we're running this mission, if so blank out all the text box values if ( format['%1', (uiNamespace getVariable "mk4_debugger_session")] != missionName ) then { uiNamespace setVariable ["mk4_debugger_session", missionName]; uiNamespace setVariable ["mk4_debugger_var1", ""]; uiNamespace setVariable ["mk4_debugger_var2", ""]; uiNamespace setVariable ["mk4_debugger_var3", ""]; uiNamespace setVariable ["mk4_debugger_var4", ""]; uiNamespace setVariable ["mk4_debugger_cmd1", ""]; uiNamespace setVariable ["mk4_debugger_cmd2", ""]; uiNamespace setVariable ["mk4_debugger_cmd3", ""]; uiNamespace setVariable ["mk4_debugger_cmd4", ""]; uiNamespace setVariable ["mk4_debugger_cmd5", ""]; uiNamespace setVariable ["mk4_debugger_cmd6", ""]; }; ctrlSetText [531011, (uiNamespace getVariable "mk4_debugger_var1")]; ctrlSetText [531021, (uiNamespace getVariable "mk4_debugger_var2")]; ctrlSetText [531031, (uiNamespace getVariable "mk4_debugger_var3")]; ctrlSetText [531041, (uiNamespace getVariable "mk4_debugger_var4")]; ctrlSetText [531101, (uiNamespace getVariable "mk4_debugger_cmd1")]; ctrlSetText [531102, (uiNamespace getVariable "mk4_debugger_cmd2")]; ctrlSetText [531103, (uiNamespace getVariable "mk4_debugger_cmd3")]; ctrlSetText [531104, (uiNamespace getVariable "mk4_debugger_cmd4")]; ctrlSetText [531105, (uiNamespace getVariable "mk4_debugger_cmd5")]; ctrlSetText [531106, (uiNamespace getVariable "mk4_debugger_cmd6")]; while { mk4_debugger_run } do { if ( (ctrlText 531011) != "" ) then { ctrlSetText [531012, format ["%1", call compile (ctrlText 531011)]] }; if ( (ctrlText 531021) != "" ) then { ctrlSetText [531022, format ["%1", call compile (ctrlText 531021)]] }; if ( (ctrlText 531031) != "" ) then { ctrlSetText [531032, format ["%1", call compile (ctrlText 531031)]] }; if ( (ctrlText 531041) != "" ) then { ctrlSetText [531042, format ["%1", call compile (ctrlText 531041)]] }; sleep 0.1; }; }; case "unload": { mk4_debugger_run = false; uiNamespace setVariable ["mk4_debugger_var1", (ctrlText 531011)]; uiNamespace setVariable ["mk4_debugger_var2", (ctrlText 531021)]; uiNamespace setVariable ["mk4_debugger_var3", (ctrlText 531031)]; uiNamespace setVariable ["mk4_debugger_var4", (ctrlText 531041)]; uiNamespace setVariable ["mk4_debugger_cmd1", (ctrlText 531101)]; uiNamespace setVariable ["mk4_debugger_cmd2", (ctrlText 531102)]; uiNamespace setVariable ["mk4_debugger_cmd3", (ctrlText 531103)]; uiNamespace setVariable ["mk4_debugger_cmd4", (ctrlText 531104)]; uiNamespace setVariable ["mk4_debugger_cmd5", (ctrlText 531105)]; uiNamespace setVariable ["mk4_debugger_cmd6", (ctrlText 531106)]; }; }; #define PRIORITY -15 #define THIS_FILE "mk4\s\debugMenu.sqf" private["_obj", "_caller", "_id", "_arg"]; switch (count _this) do { case 1: { // if called from script _arg = _this select 0; }; case 4: { // called from addAction _obj = _this select 0; _caller = _this select 1; _id = _this select 2; _arg = _this select 3; }; }; waitUntil { MK4_INIT }; switch (_arg) do { case "init": // debug true { // initialize important variables mk4_showDebugMenu = false; mk4_godMode = false; mk4_showingStats = false; // let the server send stats in debugging mode if (isServer) then { [] spawn { // grab a list of values, and broadcast it over the network while {true} do { // server specific mk4_serverUptime = diag_tickTime; mk4_serverTime = serverTime; mk4_serverMissionTime = time; mk4_serverFPS = diag_fps; { publicVariable _x } forEach ["mk4_serverUptime", "mk4_serverTime", "mk4_serverMissionTime", "mk4_serverFPS"]; // server environment mk4_serverDayTime = dayTime; mk4_serverDate = date; mk4_serverOverCast = overCast; mk4_serverRain = rain; mk4_serverFog = fog; { publicVariable _x } forEach ["mk4_serverDayTime", "mk4_serverDate", "mk4_serverOverCast", "mk4_serverRain", "mk4_serverFog"]; // server mission stats { publicVariable _x } forEach ["WCasNum", "WStartNum", "WCasRate"]; { publicVariable _x } forEach ["ECasNum", "EStartNum", "ECasRate"]; { publicVariable _x } forEach ["RCasNum", "RStartNum", "RCasRate"]; { publicVariable _x } forEach ["CCasNum", "CStartNum", "CCasRate"]; sleep 2; }; }; }; // start the debuggin action menu on all clients if (!isDedicated) then { [] spawn { ["==== Debug Menu ====" call mk4_fGoldText, THIS_FILE, "showDebugMenu", PRIORITY, false, false, ""] call mk4_fAddPersistentAction; ["Dump Pos (fCreateStaticUnit)" call mk4_fGoldText, THIS_FILE, "fCreateStaticUnit", PRIORITY - 1, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Debugger" call mk4_fGoldText, THIS_FILE, "debugger", PRIORITY - 2, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Teleport to ..." call mk4_fGoldText, THIS_FILE, "teleport", PRIORITY - 3, false, true, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Recompile Functions" call mk4_fGoldText, THIS_FILE, "recompile", PRIORITY - 4, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Show Running Scripts" call mk4_fGoldText, THIS_FILE, "runningScripts", PRIORITY - 5, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Show Loadout" call mk4_fGoldText, THIS_FILE, "showLoadout", PRIORITY - 6, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Camera Mode" call mk4_fGoldText, THIS_FILE, "camera", PRIORITY - 7, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Toggle Server Stats" call mk4_fGoldText, THIS_FILE, "statistics", PRIORITY - 8, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Toggle setCaptive" call mk4_fGoldText, THIS_FILE, "setCaptive", PRIORITY - 9, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Toggle God Mode" call mk4_fGoldText, THIS_FILE, "godMode", PRIORITY - 10, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["Spectator Script" call mk4_fGoldText, THIS_FILE, "spectateMode", PRIORITY - 11, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; ["===================" call mk4_fGoldText, THIS_FILE, "", PRIORITY - 12, false, false, "", "mk4_showDebugMenu"] call mk4_fAddPersistentAction; [__FILE__, __LINE__, "Debugging Menu Enabled"] call mk4_fEcho; }; }; }; case "showDebugMenu": { mk4_showDebugMenu = !mk4_showDebugMenu; }; case "debugger": { createDialog "mk4_template_debugger"; }; case "fCreateStaticUnit": { //_className = typeOf player; _pos = getPosATL player; _dir = round(getDir player); _unitPos = [player] call mk4_fUnitPos; _marker = "Sign_sphere25cm_EP1" createVehicle [0,0,0]; _markerZ = switch ( _unitPos ) do { case "UP": { 1.3 }; case "MIDDLE": { 0.7 }; case "DOWN": { 0.2 }; }; _marker setPosATL [_pos select 0, _pos select 1, (_pos select 2) + _markerZ]; _dump = format['[_classes, "", %2, %3, "%4", _probability] call mk4_fCreateStaticUnit; ', _className, _pos, _dir, _unitPos]; diag_log text _dump; copyToClipboard _dump; mk4 globalChat "Dumped to RPT"; }; case "teleport": { hint "\nClick on your destination.\n\n\nThe map will close automagically.\n\n"; onMapSingleClick "openMap [false, false]; (vehicle player) setPosATL [_pos select 0, _pos select 1, (getPosATL (vehicle player)) select 2]; true; hintSilent ''; onMapSingleClick ''; "; openMap [true,false]; }; case "showLoadout": { hintSilent format["\nUnit: \n%1 \n\nWeapons and Items: \n%2 \n\nMagazines: \n%3 \n\n", typeOf (vehicle player), weapons (vehicle player), magazines (vehicle player)]; }; case "camera": { hint "\nRight mouse-click to exit camera mode\n\n"; sleep 1.5; player exec "camera.sqs"; }; case "setCaptive": { player setCaptive !(captive player); _msg = format["player setCaptive = ""%1""", (captive player)]; [__FILE__, __LINE__, _msg] call mk4_fEcho; }; case "godMode": { mk4_godMode = !mk4_godMode; [2, { (_this select 0) allowDammage (_this select 1) }, [(vehicle player), !mk4_godMode]] call mk4_network_fSend; _msg = format["God Mode %1", (["Disabled", "Enabled"] select mk4_godMode)]; [__FILE__, __LINE__, _msg] call mk4_fEcho; }; case "spectateMode": { //[player, player, "null"] execVM "mk4\s\spect\specta.sqf"; ace_sys_spectator_no_butterfly_mode = false; ace_sys_spectator_can_exit_spectator = true; [player, player, "null"] call ace_fnc_startSpectator }; case "recompile": { _beginTime = diag_tickTime; call compile (preprocessFileLineNumbers "mk4\f\init.sqf"); _endTime = diag_tickTime; [__FILE__, __LINE__, format["All functions recompiled succesfully in %1 seconds", (_endTime - _beginTime)]] call mk4_fEcho; }; case "statistics": { mk4_showingStats = !mk4_showingStats; if ( mk4_showingStats ) then { [] spawn { while { mk4_showingStats } do { _serverData = format ["Server Data: \nUptime: %1 \nserverTime: %2 \ntime: %3 \nFPS: %4\n", mk4_serverUptime, mk4_serverTime, mk4_serverMissionTime, mk4_serverFPS]; _serverEnvData = format ["Server Env Data: \ndayTime: %1 \ndate: %2 \noverCast: %3 \nrain: %4 \nfog: %5\n", mk4_serverDayTime, mk4_serverDate, mk4_serverOverCast, mk4_serverRain, mk4_serverFog]; _serverWStats = format["West: %1 out of %2 (%3%4)\n", WCasNum, WStartNum, WCasRate, "%"]; _serverEStats = format["East: %1 out of %2 (%3%4)\n", ECasNum, EStartNum, ECasRate, "%"]; _serverRStats = format["Res: %1 out of %2 (%3%4)\n", RCasNum, RStartNum, RCasRate, "%"]; _serverCStats = format["Civ: %1 out of %2 (%3%4)\n", CCasNum, CStartNum, CCasRate, "%"]; _serverStats = "Server Casualty Stats: \n" + _serverWStats + _serverEStats + _serverRStats + _serverCStats; hintSilent format ["\n%1 \n%2 \n%3\n", _serverData, _serverEnvData, _serverStats]; sleep 2; }; }; } else { hintSilent ""; }; [__FILE__, __LINE__, format["Showing Stats set to %1", (["Disabled", "Enabled"] select mk4_showingStats)]] call mk4_fEcho; }; case "runningScripts": { _runningScripts = ""; { _runningScripts = format["%1 \n%2", _runningScripts, _x]; } forEach mk4_runningScripts; hint format["\nRunning Scripts: \n%1 \n\n", _runningScripts]; }; case "": { }; }; #define EAST 0 #define WEST 1 #define RESISTANCE 2 #define CIVILIAN 3 #define PARAM(TITLE) { title = TITLE; values[] = {""}; texts[] = {""}; default = 0; } if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; // wait until the template is initialized waitUntil { MK4_INIT }; mk4_fAdminMarkerDeletion = { private ["_deleter", "_uid", "_msg"]; _deleter = _this select 0; _uid = _this select 1; // only admins need to see the msg (dedi server can record it to the rpt) // if ( isAdmin || isAvailableAdmin || isDedicated ) then // { _msg = format['<< ADMIN MSG >> User "%1" (UID: %2) deleted map markers', _deleter, _uid]; mk4 globalChat _msg; diag_log text _msg; // record it in the rpt as well // }; }; // the following things are only needed on clients if ( !isDedicated ) then { mk4_fMapMarkerDeletion = { private ["_dikCode"]; _dikCode = _this select 1; // trigger when the delete key was pressed if ( _dikCode == 211 ) then { // dont increment when player is admin or part of the admin group // if ( !(isAdmin || isAvailableAdmin) ) then // { mk4_markerDeleteAttempts = mk4_markerDeleteAttempts + 1; // }; }; false // let the game engine process the key }; // spawn a thread that will wait for the displays and add the EH's [] spawn { if ( time == 0 ) then // mission is still in briefing phase, add EH's to 52 and 53 { if ( isServer ) then { waitUntil { !isNull(findDisplay 52) }; // serverGetReady (findDisplay 52) displayAddEventHandler ["KeyDown","_this call mk4_fMapMarkerDeletion"]; } else { waitUntil { !isNull(findDisplay 53) }; // clientGetReady (findDisplay 53) displayAddEventHandler ["KeyDown","_this call mk4_fMapMarkerDeletion"]; }; }; waitUntil { !isNull(findDisplay 12) }; // in-game map (findDisplay 12) displayAddEventHandler ["KeyDown","_this call mk4_fMapMarkerDeletion"]; }; // now start checking every 5 seconds if the player has deleted markers mk4_markerDeleteAttempts = 0; while { true } do { if ( mk4_markerDeleteAttempts > 0 ) then { // tell admins the user has been deleting markers [2, { _this call mk4_fAdminMarkerDeletion }, [name player, getPlayerUID player]] call mk4_network_fSend; // reset it to 0 mk4_markerDeleteAttempts = 0; }; uisleep 5; }; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; // wait a while after mission start before running the script waitUntil { MK4_INIT }; sleep 2; // the server will add the killed EH to all units, and humans add it to all their team members (because of locality in mp) _scope = []; _scope = if (isServer) then { allUnits } else { (units player) }; { _eh = _x addEventHandler["killed", { _victim = _this select 0; _killer = _this select 1; // first grab the player names before the object becomes null _victimName = [_victim] call mk4_fUnitName; _killerName = [_killer] call mk4_fUnitName; // get the true object name (reset vehVarName temporarily) _victimObjName = [_victim] call mk4_fObjectName; _killerObjName = [_killer] call mk4_fObjectName; // get the side indicator from the object name (side command doesnt work, all dead units become CIVs) _sideVictim = toString[(toArray(_victimObjName) select 0)]; _sideKiller = toString[(toArray(_killerObjName) select 0)]; // trigger if killer was on the same side, prevent triggering by suicide, and prevent TK msg if the vehicle just blew up if ( (_sideVictim == _sideKiller) && !(_victim == _killer) && !(_victim in vehicle _killer)) then { [2, { _this call mk4_fAdminTeamKill }, [[_victim, _victimName], [_killer, _killerName]] ] call mk4_network_fSend; }; }]; } forEach _scope; mk4_fAdminTeamKill = { private ["_victim", "_victimName", "_killer", "_killerName", "_msg"]; if ( !(isAdmin || isAvailableAdmin || isDedicated) ) exitWith { }; // only admins need to see the msg _victim = (_this select 0) select 0; _victimName = (_this select 0) select 1; _killer = (_this select 1) select 0; _killerName = (_this select 1) select 1; _msg = if ( (isPlayer _killer) && isMultiplayer ) then // only show UID if it's a player if this is a MP session { format["<< ADMIN MSG >> %1 got teamkilled by %2 (UID = %3)", _victimName, _killerName, getPlayerUID _killer]; } else { format["<< ADMIN MSG >> %1 got teamkilled by %2", _victimName, _killerName]; }; mk4 globalChat _msg; // show msg on screen diag_log text _msg; // record it in the rpt as well }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; // wait until template is initialized waitUntil { MK4_INIT }; // if the param was not defined, assume default viewdistance if ( isNil "mk4_defaultVD" ) then { mk4_defaultVD = viewDistance }; if ( isNil "mk4_heliVD" ) then { mk4_heliVD = mk4_defaultVD }; if ( isNil "mk4_planeVD" ) then { mk4_planeVD = mk4_defaultVD }; if ( isNil "mk4_armorVD" ) then { mk4_armorVD = mk4_defaultVD }; while { true } do { waitUntil { alive player }; switch ( true ) do { case ( (vehicle player) isKindOf "Man" ): { setViewDistance mk4_defaultVD }; case ( (vehicle player) isKindOf "Helicopter" ): { setViewDistance mk4_heliVD }; case ( (vehicle player) isKindOf "Plane" ): { setViewDistance mk4_planeVD }; case ( (vehicle player) isKindOf "Wheeled_APC" ): { setViewDistance mk4_armorVD }; case ( (vehicle player) isKindOf "Tank" ): { setViewDistance mk4_armorVD }; default { setViewDistance mk4_defaultVD } }; if ( mk4_debugMode > 0 ) then { [__FILE__, __LINE__, "Setting view distance to", viewDistance] call mk4_fEcho }; _playerVehicle = vehicle player; waitUntil { _playerVehicle != (vehicle player) }; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };#define SEPERATING_DISTANCE_X 5 #define SEPERATING_DISTANCE_Y 9 #define IN_VEHICLE_ALPHA 0.35 #define IN_VEHICLE_SIZE 0.75 #define UPDATE_DELAY 1 if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; mk4_HighLightedForces = []; // maybe in future we should do something with multiple groups? [] spawn { waitUntil { !isNull(findDisplay 12) }; (findDisplay 12) displayAddEventHandler ["MouseButtonDown","_this call mk4_fMapClickEvent"]; (findDisplay 12) displayAddEventHandler ["keyDown","_this call mk4_fMapKeyDownEvent"]; waitUntil { visibleMap }; hint format["\nmk4_forceTracker \n----------------------- \n\nPress Alt + LMB on a force marker see information about the force being tracked.\n\n"]; }; // start the group tracking loop while { true } do { { _alpha = 1; // default alpha value _sizeMultiplier = 1; // number to multiply the size with (1 if not in Veh, 0.7 if in Veh) _markerSize = (_x getVariable "_markerSize"); // default size _forcePos = [1,1,1]; // figure out if object/group is still alive _alive = switch ( typeName _x ) do { case "GROUP": { (({alive _x} count (units _x)) > 0) }; case "OBJECT": { (alive _x) }; }; if ( _alive ) then { _forceLeader = switch ( typeName _x ) do { case "GROUP": { leader _x }; case "OBJECT": { _x }; }; _forcePos = getPos _forceLeader; // if the group leader/object is in a vehicle, create an offset for the force marker if ( _forceLeader != vehicle _forceLeader ) then { // this stuff goes through the cargo of the vehicle, and gets the leader index of the group leader scopeName "offsetFinder"; _grpIndex = 0; { if ( _x == leader _x ) then // if _x is a group leader { _grpIndex = _grpIndex + 1; // inc the group index if ( _x == _forceLeader ) then { breakTo "offsetFinder" }; // but only continue counting until we've found our own leader }; } forEach (crew (vehicle _forceLeader)); // multiply that index with a seperating distance, and create the offset we need if ( _grpIndex > 0 ) then { _forcePos = [(getPos (leader (vehicle _forceLeader)) select 0) + SEPERATING_DISTANCE_X , (getPos (leader (vehicle _forceLeader)) select 1) - (SEPERATING_DISTANCE_Y * _grpIndex), 0]; _alpha = IN_VEHICLE_ALPHA; _sizeMultiplier = IN_VEHICLE_SIZE; }; }; } else { // if ded mk4_forcesToTrack = mk4_forcesToTrack - [_x]; // remove the group/object from the tracker if no one is alive in the group deleteVehicle (_x getVariable "_logic"); // delete the logic attached to the group/object }; if ( _x in mk4_forcesToTrack ) then // if _x is still alive, update all markers { { _x setMarkerPosLocal _forcePos; _x setMarkerSizeLocal [_markerSize * _sizeMultiplier, _markerSize * _sizeMultiplier]; if ( !hcShownBar ) then // dont show markers when HC is up { _x setMarkerAlphaLocal _alpha; } else { _x setMarkerAlphaLocal 0; }; } forEach (_x getVariable "_markers"); (_x getVariable "_logic") setPos _forcePos; }; } forEach mk4_forcesToTrack; uisleep UPDATE_DELAY; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };/* =================================================================== Random House Patrol Script v1.1 for Arma 2 by Tophe of stgta Ops [OOPS] =================================================================== Contact & bugreport: harlechin@hotmail.com ==================================================================== HOW TO USE: * Just put this: guard = [this] execVM "HousePatrol.sqf" in the init field of a unit and put it next to or on a house. OPTIONAL SETTINGS: * You may also set the behaviour of the unit by putting the prefered behaviour in the array. Like this: guard = [this,"COMBAT"] execVM "HousePatrol.sqf" You may put any of these five: * "CARELESS" * "SAFE" * "AWARE" * "COMBAT" * "STEALTH". If you don't put anything the default "SAFE" will be set. * There is also an option to set the maximum amount of time (in seconds) that the unit will wait before moving to the next waypoint. To use this option the behaviour option must be set too. Example: guard = [this,"SAFE",50] execVM "HousePatrol.sqf" If you don't put anything the default value of 30 will be set Use 0 as value if you want the guard to patrol continuesly. ==================================================================== */ sleep 0.5; if (!isServer) exitWith {}; // Setting variables _unit = _this select 0; _beh = if (count _this > 1) then {_this select 1} else {"SAFE"}; _wtime = if (count _this > 2) then {_this select 2} else {30}; if (_wtime < 0) then {_wtime = 30}; _position = getPos _unit; _house = nearestBuilding _unit; _x = 0; _y = 0; _t = 0; _timeout = 0; _notbugged = true; _name = vehicleVarName _unit; if (isNil _name) then {_name = "guard"}; // Set the behaviour of the unit if (_beh == "CARELESS" or _beh == "SAFE" or _beh == "AWARE" or _beh == "COMBAT" or _beh == "STEALTH") then {_unit setBehaviour _beh} else {_unit setBehaviour "SAFE"}; // Find out the number of positions available in the building // and put the unit at a random starting position while { format ["%1", _house buildingPos _x] != "[0,0,0]" } do {_x = _x + 1}; _x = _x - 1; _unit setPos (_house buildingPos (random _x)); if ((getPos _unit select 0 == 0) and (getPos _unit select 1 == 0)) then {_unit setPos _position; _notbugged = false; _unit globalChat format ["%1 can't patrol that building, due to game bug. Choose a different building",_name]; }; // Have the unit patrol inside the house while {alive _unit and _notbugged} do { _y = random _x; _t = random (_wtime); _unit doMove (_house buildingPos _y); sleep 0.5; _timeout = time + 80; waitUntil {moveToCompleted _unit or moveToFailed _unit or !alive _unit or _timeout < time}; sleep _t; }; //#include "spect\spectating.hpp" #include "debugger\dialog.hpp" //#include "unitTracker\overlay.hpp" if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; waitUntil { MK4_INIT }; if ( !isDedicated ) then { // black out the screen and say hello 0 fadeSound 0; 1001 cutText ["", "BLACK OUT", 0.001]; // start the intro once the textures around the player are loaded waitUntil {preloadCamera (getPosATL player)}; 1002 cutText [format["Welcome %1", name player], "PLAIN", 3]; }; sleep 3; if ( !isDedicated ) then { // compile an array of people in the group, and keep track how long the longest string is _groupListArr = []; _longestString = 0; _unitCount = count(units player); for [ {_i = 0}, {_i < _unitCount}, {_i = _i + 1}] do { _unitString = format["%1. %2 (%3)", (_i + 1), [((units player) select _i)] call mk4_fUnitName, [((units player) select _i)] call mk4_fDisplayName ]; _unitStrLen = count(toArray(_unitString)); _longestString = if ( _unitStrLen > _longestString ) then { _unitStrLen } else { _longestString }; _groupListArr = _groupListArr + [_unitString]; }; // add spaces to all the short names, so that in the intro everything is neatly aligned _groupListStr = ""; { for [ { _i = count(toArray(_x)) }, { _i <= _longestString }, { _i = _i + 1 }] do { _x = _x + toString[0xA0]; // normal space didnt work, so I used a unicode "no-break space" }; _groupListStr = _groupListStr + (_x + "\n"); } forEach _groupListArr; _groupName = [player] call mk4_fGroupName; // get the trimmed group name // now that we've collected all the info needed, show it on screen if ( vehicle player == player ) then { 1002 cutText [format["Your group's callsign: %1 \n\nYour group's organization: \n\n%2", _groupName, _groupListStr], "PLAIN", 3]; } else { 1002 cutText [format["Your vehicle's callsign: %1 \n\nYour vehicle's organization: \n\n%2", _groupName, _groupListStr], "PLAIN", 3]; }; }; sleep 5.5; if ( !isDedicated ) then { 1001 cutText ["", "BLACK IN", 3]; 1002 cutText ["", "BLACK IN", 3]; 3 fadeSound 1; }; // the end if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; waitUntil { MK4_INIT }; if ( !isDedicated ) then { // black out the screen and say hello 0 fadeSound 0; 1001 cutText ["", "BLACK OUT", 0.001]; // start the intro once the textures around the player are loaded waitUntil {preloadCamera (getPosATL player)}; 1002 cutText [format["Welcome %1", name player], "PLAIN", 3]; }; sleep 3; if ( !isDedicated ) then { // compile an array of people in the group, and keep track how long the longest string is _groupListArr = []; _longestString = 0; _unitCount = count(units player); for [ {_i = 0}, {_i < _unitCount}, {_i = _i + 1}] do { _unitString = format["%1. %2", (_i + 1), [((units player) select _i)] call mk4_fUnitName]; _unitStrLen = count(toArray(_unitString)); _longestString = if ( _unitStrLen > _longestString ) then { _unitStrLen } else { _longestString }; _groupListArr = _groupListArr + [_unitString]; }; // add spaces to all the short names, so that in the intro everything is neatly aligned _groupListStr = ""; { for [ { _i = count(toArray(_x)) }, { _i <= _longestString }, { _i = _i + 1 }] do { _x = _x + toString[0xA0]; // normal space didnt work, so I used a unicode "no-break space" }; _groupListStr = _groupListStr + (_x + "\n"); } forEach _groupListArr; _groupName = [player] call mk4_fGroupName; // get the trimmed group name // now that we've collected all the info needed, show it on screen if ( vehicle player == player ) then { 1002 cutText [format["Your group's callsign: %1 \n\nYour group's organization: \n\n%2", _groupName, _groupListStr], "PLAIN", 3]; } else { 1002 cutText [format["Your vehicle's callsign: %1 \n\nYour vehicle's organization: \n\n%2", _groupName, _groupListStr], "PLAIN", 3]; }; }; sleep 5.5; if ( !isDedicated ) then { 1001 cutText ["", "BLACK IN", 3]; 1002 cutText ["", "BLACK IN", 3]; 3 fadeSound 1; }; // the end if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; ///////////////////////////////////////////////////////////////////// // This script will initialize all major functions of the mk4 mission template // // // // DO NOT MODIFY // ///////////////////////////////////////////////////////////////////// if (!isNil "MK4_INIT" ) exitWith {}; MK4_INIT = false; // Place a mission info header in the RPT diag_log text ""; diag_log text format["|============================= %1 @ %2 =============================|", missionName, worldName]; diag_log text ""; diag_log text " mk4 template 0.27"; diag_log text format[" init method: %1", _this select 0]; diag_log text ""; diag_log text "|======================================================================================|"; diag_log text ""; // Initialize important variables MK4_ACRE = isClass(configFile >> "CfgPatches" >> "ACRE_Main"); MK4_ACE = isClass(configFile >> "CfgPatches" >> "ACE_Main"); MK4_Settings = (missionConfigFile >> "MK4_Settings"); mk4_debugMode = 0; mk4_missionFilePathLength = (count(toArray(__FILE__)) - 18); mk4_runningScripts = []; mk4_forcesToTrack = []; mk4_adminEndex = false; mk4_requireVersion = 3; // the required version of the description.ext WCasRate = 0; WCasNum = 0; WStartNum = 0; ECasRate = 0; ECasNum = 0; EStartNum = 0; RCasRate = 0; RCasNum = 0; RStartNum = 0; CCasRate = 0; CCasNum = 0; CStartNum = 0; // Discover what this node is [] spawn compile (preprocessFileLineNumbers "mk4\s\nodeDiscovery.sqf"); // Initialize all functions call compile (preprocessFileLineNumbers "mk4\f\init.sqf"); // Run the user defined pre_init call compile (preprocessFileLineNumbers "pre_init.sqf"); // put the mk4 logic back on sideLogic (it's put on EAST by default) if ( isServer ) then { private ["_center", "_group"]; { createCenter _x } forEach [EAST, WEST, RESISTANCE, CIVILIAN, sideLogic]; _group = createGroup sideLogic; mk4 joinAs [_group, 1]; }; ///////////////////////////////////////////////////////// // Start going through the settings and start the chosen scripts // ///////////////////////////////////////////////////////// // check if the description.ext version is supported by this version of the template if ( mk4_requireVersion != getNumber(MK4_Settings >> "version") ) then { [] spawn { waitUntil { time > 0 }; hintC format["Your description.ext version is incompatible with the current version of the template. \n\nYour version: %1 \nRequired version: %2", getNumber(MK4_Settings >> "General" >> "version"), mk4_requireVersion]; }; }; // run the code field in the parameters if ( getNumber(MK4_Settings >> "General" >> "processParams") == 1 ) then { call compile (preprocessFileLineNumbers "mk4\s\processParams.sqf"); }; // Weather sync was enabled/disabled? if ( getNumber(MK4_Settings >> "General" >> "weatherSync") == 1 ) then { [] execVM "mk4\s\weatherSync.sqf"; }; // Conversations were enabled/disabled? if ( (getNumber(MK4_Settings >> "General" >> "noConversations") == 1) && !isDedicated ) then { { _x setVariable ["BIS_noCoreConversations", true] } forEach allUnits; }; // Disable saving in the MP editor? if ( (getNumber(MK4_Settings >> "General" >> "enableSaving") == 0) && !isDedicated ) then { enableSaving [false, false]; }; // Enable Admin menu for the logged in admin? if ( getNumber(MK4_Settings >> "General" >> "adminMenu") == 1 ) then { ['init'] execVM "mk4\s\adminMenu.sqf"; }; // Enable detection of marker deletion if ( getNumber(MK4_Settings >> "Admin" >> "detectMarkerDeletion") == 1 ) then { [] execVM "mk4\s\detectMarkerDeletion.sqf"; }; // Enable detection of team killing if ( getNumber(MK4_Settings >> "Admin" >> "detectTeamKilling") == 1 ) then { [] execVM "mk4\s\detectTeamKilling.sqf"; }; // Enable the unit tracker? if ( (getNumber(MK4_Settings >> "General" >> "unitTracker") == 1) && !isDedicated ) then { [] execVM "mk4\s\unitTracker\init.sqf"; }; // Enable mission monitor? if ( (getNumber(MK4_Settings >> "General" >> "missionMonitor") == 1) && isServer ) then { [] execVM "mk4\s\monitor.sqf"; }; // grab mission endings and monitor their conditions if ( isServer ) then { [] execVM "mk4\s\processEndings.sqf"; }; // Set the hotkey for the debugger if debugging mode is enabled if ( (mk4_debugMode > 0) && !isDedicated ) then { [] spawn { _hotKey = getNumber(MK4_Settings >> "General" >> "debuggerHotkey"); waitUntil { !isNull (findDisplay 46) }; (findDisplay 46) displayAddEventHandler ["KeyDown", format["if (_this select 1 == %1) then {createDialog 'mk4_template_debugger'}", _hotKey]]; }; }; // Start an intro? if ( (getNumber(MK4_Settings >> "General" >> "intro") == 1) ) then { [] spawn { waitUntil { MK4_INIT }; if ( (time == 0) || (getNumber(MK4_Settings >> "General" >> "introJIP" ) == 1) ) then { [] execVM (getText(MK4_Settings >> "General" >> "introScript" )); }; }; }; // Start the force tracker? if ( (getNumber(MK4_Settings >> "General" >> "forceTracker") == 1) && !isDedicated ) then { [] execVM "mk4\s\forceTracker.sqf"; }; // Start dynamic View Distance? if ( getNumber(MK4_Settings >> "Admin" >> "detectTeamKilling") == 1 ) then { [] execVM "mk4\s\dynamicViewDistance.sqf"; }; //////////////// // ACE settings // //////////////// ace_sys_tracking_markers_enabled = if ( getNumber(MK4_Settings >> "ACE" >> "tracking") == 1 ) then { true } else { false }; ace_sys_spectator_playable_only = if ( getNumber(MK4_Settings >> "ACE" >> "spectatePlayable") == 1 ) then { true } else { false }; ace_sys_spectator_no_butterfly_mode = if ( getNumber(MK4_Settings >> "ACE" >> "spectateNoButterfly") == 1 ) then { true } else { false }; ACE_NoStaminaEffects = if ( getNumber(MK4_Settings >> "ACE" >> "noStaminaEffects") == 1 ) then { true } else { false }; ACE_NO_RECOGNIZE = if ( getNumber(MK4_Settings >> "ACE" >> "noRecognize") == 1 ) then { true } else { false }; // Select primary muzzle and put the unit in a safe stance [] spawn { waitUntil { MK4_INIT }; [player] call mk4_fSelectPrimaryMuzzle; if ( player == vehicle player ) then // if player is on foot { player switchMove "amovpercmstpslowwrfldnon_player_idlesteady03"; // no need to broadcast over network }; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; // wait until template is initialized waitUntil { MK4_INIT }; _initDelay = getNumber(MK4_Settings >> "MissionMonitor" >> "initDelay"); _updateDelay = getNumber(MK4_Settings >> "MissionMonitor" >> "updateDelay"); _source = getArray(MK4_Settings >> "MissionMonitor" >> "source") call mk4_fEnumMixedArray; mk4_source = _source; // dbg sleep _initDelay; // Units which were available at start _WArray = []; _EArray = []; _RArray = []; _CArray = []; // Updated unit array, dead units get removed _WArrayUpd = []; _EArrayUpd = []; _RArrayUpd = []; _CArrayUpd = []; // populate the arrays { switch (side _x) do { case WEST: { _WArray set [count _WArray, _x] }; case EAST: { _EArray set [count _EArray, _x] }; case RESISTANCE: { _RArray set [count _RArray, _x] }; case CIVILIAN: { _CArray set [count _CArray, _x] }; default { } } } forEach _source; // save the number of units at start WStartNum = count(_WArray); EStartNum = count(_EArray); RStartNum = count(_RArray); CStartNum = count(_CArray); // from now on we only work with the updated array, // so we have a snapshot of when the mission started _WArrayUpd =+ _WArray; _EArrayUpd =+ _EArray; _RArrayUpd =+ _RArray; _CArrayUpd =+ _CArray; // start checking the numbers while { true } do { { _arrLen = count _x; for [{_i = 0}, {_i < _arrLen}, {_i = _i + 1}] do { if ( !alive (_x select _i) ) then { if ( mk4_debugMode > 2 ) then { [__FILE__, __LINE__, "Marking dead unit for deletion:", (_x select _i)] call mk4_fEcho }; _x set [_i, objNull]; }; }; } forEach [_WArrayUpd, _EArrayUpd, _RArrayUpd, _CArrayUpd]; // remove marked objects _WArrayUpd = _WArrayUpd - [objNull]; _EArrayUpd = _EArrayUpd - [objNull]; _RArrayUpd = _RArrayUpd - [objNull]; _CArrayUpd = _CArrayUpd - [objNull]; // if side had any units, calculate the cas rate and number if ( WStartNum > 0) then { WCasNum = WStartNum - (count _WArrayUpd); WCasRate = ( WCasNum / WStartNum ) * 100; }; if ( EStartNum > 0) then { ECasNum = EStartNum - (count _EArrayUpd); ECasRate = ( ECasNum / EStartNum ) * 100; }; if ( RStartNum > 0) then { RCasNum = RStartNum - (count _RArrayUpd); RCasRate = ( RCasNum / RStartNum ) * 100; }; if ( CStartNum > 0) then { CCasNum = CStartNum - (count _CArrayUpd); CCasRate = ( CCasNum / CStartNum ) * 100; }; if (isNil "MK4_MONITOR_INIT") then { MK4_MONITOR_INIT = true ; [__FILE__, __LINE__, "Monitor Initialized"] call mk4_fEcho; }; sleep _updateDelay; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; /////////////////////////////////////// // Detect the environment this node is in, // // and what kind of node this is. // /////////////////////////////////////// switch ( isDedicated ) do { case true: { isClient = false; isJIP = false; isAdmin = false; isAvailableAdmin = false; }; case false: { isClient = true; isJIP = if ( isNull player ) then { waitUntil { !(isNull player) }; true } else { false }; isAdmin = if ( isMultiplayer ) then { (serverCommandAvailable "#kick jinef") } else { true }; isAvailableAdmin= if ( isMultiplayer ) then { (parseNumber(getPlayerUID player) in (getArray (MK4_Settings >> "Admin" >> "adminUIDs"))) } else { true }; // keep checking if this node is a logged-in admin [] spawn { while { true } do { sleep 10; isAdmin = (serverCommandAvailable "#kick jinef") || !isMultiplayer; }; }; }; }; MK4_INIT = true; // Output what was discovered to the RPT diag_log text ""; diag_log text "Node Info:"; diag_log text format["isDedicated = %1", isDedicated]; diag_log text format["isServer = %1", isServer]; diag_log text format["isClient = %1", isClient]; diag_log text format["isMultiplayer = %1", isMultiplayer]; diag_log text format["isAdmin = %1", isAdmin]; diag_log text format["isAvailableAdmin = %1", isAvailableAdmin]; diag_log text format["isJIP = %1", isJIP]; diag_log text ""; // endif ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; _reason = _this; // wait until we've received all the statistics waitUntil { !isNil "WCasNum" && !isNil "WStartNum" && !isNil "WCasRate" }; waitUntil { !isNil "ECasNum" && !isNil "EStartNum" && !isNil "ECasRate" }; waitUntil { !isNil "RCasNum" && !isNil "RStartNum" && !isNil "RCasRate" }; waitUntil { !isNil "CCasNum" && !isNil "CStartNum" && !isNil "CCasRate" }; _statsArr = []; // only show stats for a side if there were actually any units on that side if (WStartNum > 0) then { _statsArr = _statsArr + [format["West Casualties: %1 out of %2 (%3%4)", WCasNum, WStartNum, round(WCasRate), "%"]] }; if (EStartNum > 0) then { _statsArr = _statsArr + [format["East Casualties: %1 out of %2 (%3%4)", ECasNum, EStartNum, round(ECasRate), "%"]] }; if (RStartNum > 0) then { _statsArr = _statsArr + [format["Resistance Casualties: %1 out of %2 (%3%4)", RCasNum, RStartNum, round(RCasRate), "%"]] }; if (CStartNum > 0) then { _statsArr = _statsArr + [format["Civilian Casualties: %1 out of %2 (%3%4)", CCasNum, CStartNum, round(CCasRate), "%"]] }; // find how long the longest string is _longestString = 0; { _statsStrLen = count(toArray(_x)); _longestString = if ( _statsStrLen > _longestString ) then { _statsStrLen } else { _longestString }; } forEach _statsArr; // add spaces to all the short strings, so that in the outro everything is neatly aligned _statsStr = ""; { for [ { _i = count(toArray(_x)) }, { _i <= _longestString }, { _i = _i + 1 }] do { _x = _x + toString[0xA0]; // normal space didnt work, so I used a unicode "no-break space" }; _statsStr = _statsStr + (_x + "\n\n"); } forEach _statsArr; if ( !isDedicated ) then { closeDialog 0; }; sleep 1; if ( !isDedicated ) then { // black out the screen and say hello 2 fadeSound 0; 1002 cutText ["MISSION OVER", "PLAIN", 2]; }; sleep 2; if ( !isDedicated ) then { 1001 cutText ["", "BLACK OUT", 2]; }; sleep 3; if ( !isDedicated ) then { 1002 cutText [format[" %1 \n\n\n\n %2 ", _reason, _statsStr], "PLAIN", 3]; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; _endType = ""; _endMessage = ""; _endings = (MK4_Settings >> "MissionEndings"); _endingsCount = count _endings; _loop = true; scopeName "main"; // keep checking each ending until one of the conditions becomes true while { true } do { sleep 2; for [ { _i = 0 }, { _i < _endingsCount }, { _i = _i + 1 } ] do { _ending = getArray(_endings select _i); // a valid ending has 2 elements if ( count _ending == 2 ) then { // now check the condition _condition = _ending select 0; if ( call compile _condition ) then { _endType = configName(_endings select _i); _endMessage = _ending select 1; breakTo "main"; }; }; sleep .1; }; }; sleep 1; // if an outro was enabled, send mission statistics and call the desired outro script if ( (getNumber(MK4_Settings >> "General" >> "outro") == 1) ) then { _outroScript = getText(MK4_Settings >> "General" >> "outroScript"); _outroDuration = getNumber(MK4_Settings >> "General" >> "outroDuration"); publicVariable "WCasNum"; publicVariable "WStartNum"; publicVariable "WCasRate"; // west stats publicVariable "ECasNum"; publicVariable "EStartNum"; publicVariable "ECasRate"; // east stats publicVariable "RCasNum"; publicVariable "RStartNum"; publicVariable "RCasRate"; // resistance stats publicVariable "CCasNum"; publicVariable "CStartNum"; publicVariable "CCasRate"; // civ stats // send the call to the outro over the network [2,{ (_this select 1) execVM (_this select 0) }, [_outroScript, _endMessage]] call mk4_network_fSend; // wait a while so everyone can read the outro, and then end the mission sleep _outroDuration; }; // let the mission end [2, { endMission _this }, _endType] call mk4_network_fSend; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };private ["_params", "_paramCount", "_paramName", "_paramValue", "_paramCode", "_i"]; // make a paramsarray if in single-player if ( !isMultiplayer ) then { paramsArray = [] }; _params = (missionConfigFile >> "Params"); _paramCount = count _params; for [ { _i = 0 }, { _i < _paramCount }, { _i = _i + 1 } ] do { _paramName =(configName (_params select _i)); if ( isMultiplayer ) then { _paramValue = (paramsArray select _i); } else { // in singleplayer, grab the default param value, and put it in the paramsArray ourselves _paramValue = getNumber (_params >> _paramName >> "default"); paramsArray set [_i, _paramValue]; }; // n00b check if ( (isText (_params >> _paramName >> "code")) ) then { // compile the parameter code together with the param value(s) _paramCode = format[(getText (_params >> _paramName >> "code")), _paramValue]; call compile _paramCode; [__FILE__, __LINE__, format["Executing code field for param '%1'", _paramName], _paramCode] call mk4_fEcho; } else { //[__FILE__, __LINE__, format["<< ERROR >> code field for param '%1' is missing!", paramName]] call mk4_fEcho; }; }; true // ret _side = _this select 0; _skill = _this select 1; if ( !isServer ) exitWith { }; waitUntil { MK4_INIT && time > 0 }; if ( _skill > 1 ) then { _skill = _skill / 10 }; { if ( side _x == _side ) then { _x setSkill _skill; }; } forEach allUnits; private ["_timeParam", "_hours", "_minutes"]; _timeParam = _this select 0; if ( _timeParam == 9999 ) then { _hours = floor(random(24)); _minutes = floor(random(60)); } else { _hours = floor(_timeParam / 100); _minutes = _timeParam % 100; }; setDate[(date select 0),(date select 1),(date select 2), _hours, _minutes]; true // ret if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; _weatherParam = _this select 0; if ( isServer ) then { mk4_weather = if ( _weatherParam == 99 ) then // if random weather was chosen { _overcast = random(1); _rain = if (_overcast >= 0.6) then { random(0.6) } else { 0 }; _fog = if (_rain >= 0.25) then { (random(0.4) + 0.4) } else { 0 }; [_overcast, _rain, _fog] } else { switch ( (_this select 0) ) do { // syntax: [overCast, rain, fog] case 0: { [0, 0, 0] }; // Clear case 1: { [0.6, 0, 0.1] }; // Cloudy case 2: { [0.85, 0.4, 0.35] }; // Light Rain case 3: { [0.95, 0.9, 0.6] }; // Heavy Rain case 4: { [0.6, 0, 0.8] }; // Light Fog case 5: { [0.6, 0, 0.95] }; // Heavy fog default { [0, 0, 0] } } }; publicVariable "mk4_weather"; } else { waitUntil { !(isNil "mk4_weather") }; // wait until clients received the weather values from the server }; 0 setOvercast (mk4_weather select 0); 0 setRain (mk4_weather select 1); 0 setFog (mk4_weather select 2); sleep 2; // this will make sure the weather doesnt change immediately from the chosen weather params 900 setOvercast (mk4_weather select 0); 900 setRain (mk4_weather select 1); 900 setFog (mk4_weather select 2); // every 5 to 15 minutes, reset the weather back to chosen values on the server if ( isServer ) then { [] spawn { while { true } do { _changeTime = 240 + random(600); sleep _changeTime; _changeTime setOvercast (mk4_weather select 0); _changeTime setRain (mk4_weather select 1); _changeTime setFog (mk4_weather select 2); }; }; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript };if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; if ( !isServer ) exitWith { }; _timeLimit = _this select 0; if ( count _this > 1 ) then { _warningTimes = _this - [_timeLimit]; waitUntil { time > 0 }; { waitUntil { time > (_timeLimit + _x) }; [2, { hint format["%1 minutes left", _this] }, (abs(_x) / 60)] call mk4_network_fSend; } forEach _warningTimes; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; // wait until template is initialized waitUntil { MK4_INIT }; _trackedUnits = []; _markers = []; // grab the settings for the unit tracker _myType = getText(MK4_Settings >> "UnitTracker" >> "myType"); _mySize = getArray(MK4_Settings >> "UnitTracker" >> "mySize"); _myAlpha = getNumber(MK4_Settings >> "UnitTracker" >> "myAlpha"); _myColor = getText(MK4_Settings >> "UnitTracker" >> "myColor"); _otherType = getText(MK4_Settings >> "UnitTracker" >> "otherType"); _otherSize = getArray(MK4_Settings >> "UnitTracker" >> "otherSize"); _otherAlpha = getNumber(MK4_Settings >> "UnitTracker" >> "otherAlpha"); _otherColor = getText(MK4_Settings >> "UnitTracker" >> "otherColor"); _updateDelay = getNumber(MK4_Settings >> "UnitTracker" >> "updateDelay"); _showName = (getNumber(MK4_Settings >> "UnitTracker" >> "showName") > 0); // if ( _showName ) then // { // [] spawn { // disableSerialization; // waitUntil { !isNull(findDisplay 12) }; // wait until map screen is init // ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseMoving", "mk4_mapMouseCoords set [0, _this select 1]; mk4_mapMouseCoords set [1, _this select 2]; hint str(_this); false"]; // mk4_mapMouseCoords = [0.5,0.5]; // diag_log "map"; // 10009 cutRsc["ACE_SpectRecogOverlay","PLAIN"]; // _ctrloverlay = (uiNamespace getVariable "ACE_SpectRecogOverlay") displayCtrl 1; // _ctrloverlay ctrlShow false; // _ctrloverlay ctrlCommit 0; // while { true } do // { // if ( visibleMap ) then // { // // get nearest units // _pos = ((findDisplay 12) displayCtrl 51) posScreenToWorld mk4_mapMouseCoords; // _objs = nearestObjects [_pos, ["CAManBase"], 5]; // _unit = objNull; // player globalChat str(_pos); // player globalChat str(_objs); // { // if ( !isNil{_x getVariable "mk4_unitMarker"} ) exitWith // { // hint (name _x); // _unit = _x; // }; // } forEach _objs; // if ( !(isNull _unit) ) then // { // _ctrloverlay ctrlSetText (name _unit); // _ctrloverlay ctrlShow true; // _ctrloverlay ctrlSetPosition [mk4_mapMouseCoords select 0, (mk4_mapMouseCoords select 1) - .035, 0.4, 0.15]; // _ctrloverlay ctrlCommit 0; // }; // uisleep 0.041; // 24 fps // } else // { // // hide the textbox // _ctrloverlay ctrlSetText ""; // _ctrloverlay ctrlCommit 0; // // keep checking every fps when the map is visible again // waitUntil { visibleMap }; // // map is up again // }; // player globalChat "loop"; // }; // }; // }; while { true } do { waitUntil { alive player }; _units = units player; // get a current list of group members _markerCount = count _markers; for [{_i = 0}, {_i < _markerCount}, {_i = _i + 1}] do { _currentUnit = (_trackedUnits select _i); _currentMarker = (_markers select _i); // remove current unit from the _units array _units = _units - [_currentUnit]; // only track alive units that are currently in your group if ( alive _currentUnit && (group player == group _currentUnit) ) then { // update marker pos and stuff _currentMarker setMarkerPosLocal (getPosASL _currentUnit); _currentMarker setMarkerDirLocal (getDir _currentUnit); _currentMarker setMarkerTypeLocal (if (_currentUnit == player) then { _myType } else { _otherType } ); _currentMarker setMarkerSizeLocal (if (_currentUnit == player) then { _mySize } else { _otherSize } ); _currentMarker setMarkerAlphaLocal (if (_currentUnit == player) then { _myAlpha } else { _otherAlpha } ); _color = _currentUnit getVariable "mk4_assignedTeam"; if ( isNil "_color" ) then { _color = (if (_currentUnit == player) then { _myColor } else { _otherColor } ); } else { _color = switch ( _color ) do { case "RED": { "ColorRed" }; case "GREEN": { "ColorGreen" }; case "BLUE": { "ColorBlue" }; case "YELLOW": { "ColorYellow" }; default { "ColorWhite" } }; }; _currentMarker setMarkerColorLocal _color; } else { // delete the marker, undefine the var, and mark the unit and marker references for deletion deleteMarkerLocal _currentMarker; _currentUnit setVariable ["mk4_unitMarker", nil]; _trackedUnits set [_i, objNull]; _markers set [_i, objNull]; }; }; // remove array elements marked for deletion _trackedUnits = _trackedUnits - [objNull]; _markers = _markers - [objNull]; // if there are group members not being tracked, start tracking them { if ( alive _x ) then // a unit can be dead and be in the units array, so check { // create marker _marker = [(getPosASL _x), "ICON", _otherType , _otherColor, [0,0]] call mk4_fCreateMarkerLocal; // add the marker and the unit to the tracked units and marker arrays _trackedUnits set [count _trackedUnits, _x]; _markers set [count _markers, _marker]; // save the marker ref to the unit itself _x setVariable ["mk4_unitMarker", _marker]; }; } forEach _units; uisleep _updateDelay; // use uisleep instead }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; // class RscTitles // { // class ACE_SpectRecogOverlay // { // idd = -1; // movingEnable = 1; // duration = 10e10; // fadein = 0.3; // fadeout = 0.3; // name = "ACE_SpectRecogOverlay"; // onLoad = "with uiNameSpace do {ACE_SpectRecogOverlay = _this select 0}"; // class controls // { // class ACE_SpectRecogOverlay_Text : RscText // { // idc = 1; // type = 0; // colorBackground[] = {0, 0, 0, 0}; // colorText[] = {1, 1, 1, 0.75}; // text = ""; // style = 0; // font = "Zeppelin32"; // sizeEx = 0.023; // x = 0; y = 0; // w = 0; h = 0; // }; // }; // }; // }; // ========================================================================================================= // Urban Patrol Script // Version: 2.1.0 // Author: Kronzky (www.kronzky.info / kronzky@gmail.com) // --------------------------------------------------------------------------------------------------------- // Required parameters: // unit = Unit to patrol area (1st argument) // markername = Name of marker that covers the active area. (2nd argument) // (e.g. nul=[this,"town"] execVM "mk4\s\ups.sqf") // // Optional parameters: // random = Place unit at random start position. // randomdn = Only use random positions on ground level. // randomup = Only use random positions at top building positions. // min:n/max:n = Create a random number (between min and max) of 'clones'. // init:string = Cloned units' init string. // prefix:string = Cloned units' names will start with this prefix. // nomove = Unit will stay at start position until enemy is spotted. // nofollow = Unit will only follow an enemy within the marker area. // delete:n = Delete dead units after 'n' seconds. // nowait = Do not wait at patrol end points. // noslow = Keep default behaviour of unit (don't change to "safe" and "limited"). // noai = Don't use enhanced AI for evasive and flanking maneuvers. // showmarker = Display the area marker. // trigger = Display a message when no more units are left in sector. // empty:n = Consider area empty, even if 'n' units are left. // track = Display a position and destination marker for each unit. // // ========================================================================================================= if (!isServer) exitWith {}; // how far opfors should move away if they're under attack // set this to 200-300, when using the script in open areas (rural surroundings) #define SAFEDIST 75 // how close unit has to be to target to generate a new one #define CLOSEENOUGH 10 // how close units have to be to each other to share information #define SHAREDIST 100 // how long AI units should be in alert mode after initially spotting an enemy #define ALERTTIME 180 // --------------------------------------------------------------------------------------------------------- //echo format["[K] %1",_this]; // convert argument list to uppercase _UCthis = []; for [{_i=0},{_i=0} do {_bp = _bld BuildingPos _bi;if ((_bp select 0)==0) then {_bi=-99} else {_bz=_bp select 2; _higher = ((_bz>_maxZ) || ((abs(_bz-_maxZ)<.5) && (random 1>.5))); if ((_bz>4) && _higher) then {_maxZ=_bz; _bldpos=_bi}};_bi=_bi+1};_bldpos}; KRON_OnRoad = {private["_pos","_car","_tries","_lst"];_pos=_this select 0; _car=_this select 1; _tries=_this select 2; _lst=_pos nearRoads 4; if ((count _lst!=0) && (_car || !(surfaceIsWater _pos))) then {_tries=99}; (_tries+1)}; KRON_getDirPos = {private["_a","_b","_from","_to","_return"]; _from = _this select 0; _to = _this select 1; _return = 0; _a = ((_to select 0) - (_from select 0)); _b = ((_to select 1) - (_from select 1)); if (_a != 0 || _b != 0) then {_return = _a atan2 _b}; if ( _return < 0 ) then { _return = _return + 360 }; _return}; KRON_distancePosSqr = {(((_this select 0) select 0)-((_this select 1) select 0))^2 + (((_this select 0) select 1)-((_this select 1) select 1))^2}; KRON_relPos = {private["_p","_d","_a","_x","_y","_xout","_yout"];_p=_this select 0; _x=_p select 0; _y=_p select 1; _d=_this select 1; _a=_this select 2; _xout=_x + sin(_a)*_d; _yout=_y + cos(_a)*_d;[_xout,_yout,0]}; KRON_rotpoint = {private["_cp","_a","_tx","_ty","_cd","_sd","_cx","_cy","_xout","_yout"];_cp=_this select 0; _cx=_cp select 0; _cy=_cp select 1; _a=_this select 1; _cd=cos(_a*-1); _sd=sin(_a*-1); _tx=_this select 2; _ty=_this select 3; _xout=if (_a!=0) then {_cx+ (_cd*_tx - _sd*_ty)} else {_cx+_tx}; _yout=if (_a!=0) then {_cy+ (_sd*_tx + _cd*_ty)} else {_cy+_ty}; [_xout,_yout,0]}; KRON_stayInside = { private["_np","_nx","_ny","_cp","_cx","_cy","_rx","_ry","_d","_tp","_tx","_ty","_fx","_fy"]; _np=_this select 0; _nx=_np select 0; _ny=_np select 1; _cp=_this select 1; _cx=_cp select 0; _cy=_cp select 1; _rx=_this select 2; _ry=_this select 3; _d=_this select 4; _tp = [_cp,_d,(_nx-_cx),(_ny-_cy)] call KRON_rotpoint; _tx = _tp select 0; _fx=_tx; _ty = _tp select 1; _fy=_ty; if (_tx<(_cx-_rx)) then {_fx=_cx-_rx}; if (_tx>(_cx+_rx)) then {_fx=_cx+_rx}; if (_ty<(_cy-_ry)) then {_fy=_cy-_ry}; if (_ty>(_cy+_ry)) then {_fy=_cy+_ry}; if ((_fx!=_tx) || (_fy!=_ty)) then {_np = [_cp,_d*-1,(_fx-_cx),(_fy-_cy)] call KRON_rotpoint}; _np; }; // Misc KRON_getArg = {private["_cmd","_arg","_list","_a","_v"]; _cmd=_this select 0; _arg=_this select 1; _list=_this select 2; _a=-1; {_a=_a+1; _v=format["%1",_list select _a]; if (_v==_cmd) then {_arg=(_list select _a+1)}} foreach _list; _arg}; KRON_deleteDead = {private["_u","_s"];_u=_this select 0; _s= _this select 1; _u removeAllEventHandlers "killed"; sleep _s; deletevehicle _u}; KRON_AllWest=[]; KRON_AllEast=[]; KRON_AllRes=[]; KRON_KnownEnemy=[objNull,objNull]; // find all units in mission { _s = side _x; switch (_s) do { case west: { KRON_AllWest=KRON_AllWest+[_x]; }; case east: { KRON_AllEast=KRON_AllEast+[_x]; }; case resistance: { KRON_AllRes=KRON_AllRes+[_x]; }; }; }forEach allUnits; if (isNil("KRON_UPS_Debug")) then {KRON_UPS_Debug=0}; KRON_HQ="Logic" createVehicle [0,0]; KRON_UPS_Instances=0; KRON_UPS_Total=0; KRON_UPS_Exited=0; KRON_UPS_INIT=1; }; if ((count _this)<2) exitWith { if (format["%1",_this]!="INIT") then {hint "UPS: Unit and marker name have to be defined!"}; }; _exit = false; _onroof = false; // --------------------------------------------------------------------------------------------------------- waitUntil {KRON_UPS_INIT==1}; sleep (random 1); KRON_UPS_Instances = KRON_UPS_Instances + 1; // get name of area marker _areamarker = _this select 1; if (isNil ("_areamarker")) exitWith { hint "UPS: Area marker not defined.\n(Typo, or name not enclosed in quotation marks?)"; }; _centerpos = []; _centerX = []; _centerY = []; _rangeX = 0; _rangeY = 0; _areadir = 0; _areaname = ""; _areatrigger = objNull; _showmarker = "HIDEMARKER"; _getAreaInfo = { if (typeName _areamarker=="String") then { // remember center position of area marker _centerpos = getMarkerPos _areamarker; _centerX = abs(_centerpos select 0); _centerY = abs(_centerpos select 1); // X/Y range of target area _areasize = getMarkerSize _areamarker; _rangeX = _areasize select 0; _rangeY = _areasize select 1; // marker orientation (needed as negative value!) _areadir = (markerDir _areamarker) * -1; _areaname = _areamarker; // show area marker _showmarker = if ("SHOWMARKER" in _UCthis) then {"SHOWMARKER"} else {"HIDEMARKER"}; if (_showmarker=="HIDEMARKER") then { _areamarker setMarkerPos [-abs(_centerX),-abs(_centerY)]; }; } else { _centerpos = getPos _areamarker; _centerX = abs(_centerpos select 0); _centerY = abs(_centerpos select 1); // X/Y range of target area _rangeX = triggerArea _areamarker select 0; _rangeY = triggerArea _areamarker select 1; // marker orientation (needed as negative value!) _areadir = (getDir _areamarker) * -1; _areaname = vehicleVarName _areamarker; }; // update trigger position if !(isNull _areatrigger) then { _areatrigger setPos [_centerX,_centerY]; }; }; [] call _getAreaInfo; sleep .01; // unit that's moving _obj = _this select 0; _npc = _obj; // is anybody alive in the group? _exit = true; if (typename _obj=="OBJECT") then { if (alive _npc) then {_exit = false;} } else { if (count _obj>0) then { {if (alive _x) then {_npc = _x; _exit = false;}} forEach _obj; }; }; // give this group a unique index _grpidx = format["%1",KRON_UPS_Instances]; _grpname = format["%1_%2",(side _npc),_grpidx]; // remember the original group members, so we can later find a new leader, in case he dies _members = units _npc; KRON_UPS_Total = KRON_UPS_Total + (count _members); // what type of "vehicle" is unit ? _isman = _npc isKindOf "Man"; _iscar = _npc isKindOf "vbs2_LandVehicles"; _isboat = _npc isKindOf "Ship"; _isplane = _npc isKindOf "Air"; // check to see whether group is an enemy of the player (for attack and avoidance maneuvers) // since countenemy doesn't count vehicles, and also only counts enemies if they're known, // we just have to brute-force it for now, and declare *everyone* an enemy who isn't a civilian _issoldier = side _npc != civilian; _friends=[]; _enemies=[]; _sharedenemy=0; //TODO: FIND A WAY TO DETERMINE ASSOCIATION OF RESISTANCE UNITS if (_issoldier) then { switch (side _npc) do { case west: { _friends=_friends+KRON_AllWest; _enemies=_enemies+KRON_AllEast+KRON_AllRes; _sharedenemy=0; }; case east: { _friends=_friends+KRON_AllEast; _enemies=_enemies+KRON_AllWest+KRON_AllRes; _sharedenemy=1; }; case resistance: { _enemies=_enemies+KRON_AllEast+KRON_AllWest; _sharedenemy=2; }; }; { _friends=_friends-[_x]; _x disableAI "autotarget"; } forEach _members; }; sleep .01; // global unit variable to externally influence script _named = false; _npcname = str(side _npc); if ("NAMED" in _UCthis) then { _named = true; _npcname = format["%1",_npc]; _grpidx = _npcname; }; // create global variable for this group call compile format ["KRON_UPS_%1=1",_npcname]; // store some trig calculations _cosdir=cos(_areadir); _sindir=sin(_areadir); // minimum distance of new target position if (_rangeX==0) exitWith { hint format["UPS: Cannot patrol Sector: %1\nArea Marker doesn't exist",_areaname]; }; _mindist=(_rangeX^2+_rangeY^2)/4; // remember the original mode & speed _orgMode = behaviour _npc; _orgSpeed = speedmode _npc; _speedmode = _orgSpeed; // set first target to current position (so we'll generate a new one right away) _currPos = getpos _npc; _orgPos = _currPos; _orgWatch=[_currPos,50,getDir _npc] call KRON_relPos; _orgDir = getDir _npc; _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0]; _dist = 0; _lastdist = 0; _lastmove1 = 0; _lastmove2 = 0; _maxmove=0; _moved=0; _damm=0; _dammchg=0; _lastdamm = 0; _timeontarget = 0; _fightmode = "walk"; _fm=0; _gothit = false; _hitPos=[0,0,0]; _react = 99; _lastdamage = 0; _lastknown = 0; _opfknowval = 0; _sin90=1; _cos90=0; _sin270=-1; _cos270=0; // set target tolerance high for choppers & planes _closeenough=CLOSEENOUGH*CLOSEENOUGH; if (_isplane) then {_closeenough=5000}; sleep .01; // ***************************************** optional arguments ***************************************** // wait at patrol end points _pause = if ("NOWAIT" in _UCthis) then {"NOWAIT"} else {"WAIT"}; // don't move until an enemy is spotted _nomove = if ("NOMOVE" in _UCthis) then {"NOMOVE"} else {"MOVE"}; // don't follow outside of marker area _nofollow = if ("NOFOLLOW" in _UCthis) then {"NOFOLLOW"} else {"FOLLOW"}; // share enemy info _shareinfo = if ("NOSHARE" in _UCthis) then {"NOSHARE"} else {"SHARE"}; // "area cleared" trigger activator _usetrigger = if ("TRIGGER" in _UCthis) then {"TRIGGER"} else {if ("NOTRIGGER" in _UCthis) then {"NOTRIGGER"} else {"SILENTTRIGGER"}}; // suppress fight behaviour if ("NOAI" in _UCthis) then {_issoldier=false}; // adjust cycle delay _cycle = ["CYCLE:",5,_UCthis] call KRON_getArg; // drop units at random positions _initpos = "ORIGINAL"; if ("RANDOM" in _UCthis) then {_initpos = "RANDOM"}; if ("RANDOMUP" in _UCthis) then {_initpos = "RANDOMUP"}; if ("RANDOMDN" in _UCthis) then {_initpos = "RANDOMDN"}; // don't position groups or vehicles on rooftops if ((_initpos!="ORIGINAL") && ((!_isman) || (count _members)>1)) then {_initpos="RANDOMDN"}; // set behaviour modes (or not) _noslow = if ("NOSLOW" in _UCthis) then {"NOSLOW"} else {"SLOW"}; if (_noslow!="NOSLOW") then { _npc setbehaviour "safe"; _npc setSpeedMode "limited"; _speedmode = "limited"; }; // make start position random if (_initpos!="ORIGINAL") then { // find a random position (try a max of 20 positions) _try=0; _bld=0; _bldpos=0; while {_try<20} do { _currPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; if ((_initpos=="RANDOMUP") || ((_initpos=="RANDOM") && (random 1>.75))) then { _posinfo=[_currPos] call KRON_PosInfo; // _posinfo: [0,0]=no house near, [obj,-1]=house near, but no roof positions, [obj,pos]=house near, with roof pos _bld=_posinfo select 0; _bldpos=_posinfo select 1; }; if (_isplane || _isboat || !(surfaceiswater _currPos)) then { if (((_initpos=="RANDOM") || (_initpos=="RANDOMUP")) && (_bldpos>0)) then {_try=99}; if (((_initpos=="RANDOM") || (_initpos=="RANDOMDN")) && (_bldpos==0)) then {_try=99}; }; _try=_try+1; }; if (_bldpos==0) then { if (_isman) then { {_x setPos _currPos} foreach units _npc; } else { _npc setPos _currPos; }; } else { // put the unit on top of a building _npc setPos (_bld buildingPos _bldpos); _npc setUnitPos "up"; _currPos = getPos _npc; _onroof = true; _exit=true; // don't patrol if on roof }; }; sleep .01; // track unit _track = if (("TRACK" in _UCthis) || (KRON_UPS_Debug>0)) then {"TRACK"} else {"NOTRACK"}; _trackername = ""; _destname = ""; if (_track=="TRACK") then { _track = "TRACK"; _trackername=format["trk_%1",_grpidx]; _markerobj = createMarker[_trackername,[0,0]]; _markerobj setMarkerShape "ICON"; _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Dot")) then {"WTF_DOT"} else {"DOT"}; _trackername setMarkerType _markertype; _markercolor = switch (side _npc) do { case west: {"ColorGreen"}; case east: {"ColorRed"}; case resistance: {"ColorBlue"}; default {"ColorBlack"}; }; _trackername setMarkerColor _markercolor; _trackername setMarkerText format["%1",_grpidx]; _trackername setmarkerpos _currPos; _trackername setMarkerSize [.5,.5]; _destname=format["dest_%1",_grpidx]; _markerobj = createMarker[_destname,[0,0]]; _markerobj setMarkerShape "ICON"; _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Flag")) then {"WTF_FLAG"} else {"FLAG"}; _destname setMarkerType _markertype; _destname setMarkerColor _markercolor; _destname setMarkerText format["%1",_grpidx]; _destname setMarkerSize [.5,.5]; }; sleep .01; // delete dead units _deletedead = ["DELETE:",0,_UCthis] call KRON_getArg; if (_deletedead>0) then { {_x addEventHandler['killed',format["[_this select 0,%1] spawn KRON_deleteDead",_deletedead]]}forEach _members; }; // how many group clones? // TBD: add to global side arrays? _mincopies = ["MIN:",0,_UCthis] call KRON_getArg; _maxcopies = ["MAX:",0,_UCthis] call KRON_getArg; if (_mincopies>_maxcopies) then {_maxcopies=_mincopies}; if (_maxcopies>140) exitWith {hint "Cannot create more than 140 groups!"}; if (_maxcopies>0) then { if !(_isMan) exitWith {hint "Vehicles cannot be cloned."}; _copies=_mincopies+round(random (_maxcopies-_mincopies)); // any init strings? _initstr = ["INIT:","",_UCthis] call KRON_getArg; // name of clones _nameprefix = ["PREFIX:","UPSCLONE",_UCthis] call KRON_getArg; // create the clones for "_grpcnt" from 1 to _copies do { // group leader _unittype=typeof _npc; // copy groups if (isNil ("KRON_cloneindex")) then { KRON_cloneindex = 0; }; // make the clones civilians // use random Civilian models for single unit groups if ((_unittype=="Civilian") && (count _members==1)) then {_rnd=1+round(random 20); if (_rnd>1) then {_unittype=format["Civilian%1",_rnd]}}; _grp=createGroup side _npc; _lead = _grp createUnit [_unittype, getpos _npc, [], 0, "form"]; KRON_cloneindex = KRON_cloneindex+1; _lead setVehicleVarName format["%1%2",_nameprefix,KRON_cloneindex]; call compile format["%1%2=_lead",_nameprefix,KRON_cloneindex]; _lead setBehaviour _orgMode; _lead setSpeedMode _orgSpeed; _lead setSkill skill _npc; _lead setVehicleInit _initstr; [_lead] join _grp; _grp selectLeader _lead; // copy team members (skip the leader) _c=0; { _c=_c+1; if (_c>1) then { _newunit = _grp createUnit [typeof _x, getpos _x, [],0,"form"]; KRON_cloneindex = KRON_cloneindex+1; _newunit setVehicleVarName format["%1%2",_nameprefix,KRON_cloneindex]; call compile format["%1%2=_newunit",_nameprefix,KRON_cloneindex]; _newunit setBehaviour _orgMode; _newunit setSpeedMode _orgSpeed; _newunit setSkill skill _x; _newunit setVehicleInit _initstr; [_newunit] join _grp; }; } foreach _members; _nul=[_lead,_areamarker,_pause,_noslow,_nomove,_nofollow,_initpos,_track,_showmarker,_shareinfo,"DELETE:",_deletedead] execVM "ups.sqf"; sleep .05; }; processInitCommands; }; sleep .01; // units that can be left for area to be "cleared" _zoneempty = ["EMPTY:",0,_UCthis] call KRON_getArg; // create area trigger if (_usetrigger!="NOTRIGGER") then { _trgside = switch (side _npc) do { case west: {"WEST"}; case east: {"EAST"}; case resistance: {"GUER"}; case civilian: {"CIV"};}; _trgname="KRON_Trig_"+_trgside+"_"+_areaname; _flgname="KRON_Cleared_"+_areaname; // has the trigger been created already? KRON_TRGFlag=-1; call compile format["%1=false",_flgname]; call compile format["KRON_TRGFlag=%1",_trgname]; if (isNil ("KRON_TRGFlag")) then { // trigger doesn't exist yet, so create one (make it a bit bigger than the marker, to catch path finding 'excursions' and flanking moves) call compile format["%1=createTrigger['EmptyDetector',[_centerX,_centerY]];",_trgname]; call compile format["_areatrigger = %1",_trgname]; call compile format["%1 setTriggerArea[_rangeX*1.5,_rangeY*1.5,markerDir _areaname,true]",_trgname]; call compile format["%1 setTriggerActivation[_trgside,'PRESENT',true]",_trgname]; call compile format["%1 setEffectCondition 'true'",_trgname]; call compile format["%1 setTriggerTimeout [5,7,10,true]",_trgname]; if (_usetrigger!="SILENTTRIGGER") then { _markerhide = [-_centerX,-_centerY]; _markershow = [_centerX,_centerY]; if (_showmarker=="HIDEMARKER") then { _markershow = [-_centerX,-_centerY]; }; call compile format["%1 setTriggerStatements['count thislist<=%6', 'titletext [''SECTOR <%2> CLEARED'',''PLAIN''];''%2'' setmarkerpos %4;%3=true;', 'titletext [''SECTOR <%2> HAS BEEN RE-OCCUPIED'',''PLAIN''];''%2'' setmarkerpos %5;%3=false;']", _trgname,_areaname,_flgname,_markerhide,_markershow,_zoneempty]; } else { call compile format["%1 setTriggerStatements['count thislist<=%3', '%2=true;', '%2=false;']", _trgname,_flgname,_zoneempty]; }; }; sleep .01; }; // init done _makenewtarget=true; _newpos=false; _targetPos = _currPos; _swimming = false; _waiting = if (_nomove=="NOMOVE") then {9999} else {0}; // exit if something went wrong during initialization (or if unit is on roof) if (_exit) exitWith { if ((KRON_UPS_DEBUG>0) && !_onroof) then {hint "Initialization aborted"}; }; // *********************************************************************************************************** // ************************************************ MAIN LOOP ************************************************ _loop=true; _currcycle=_cycle; while {_loop} do { sleep .01; // keep track of how long we've been moving towards a destination _timeontarget=_timeontarget+_currcycle; _react=_react+_currcycle; // did anybody in the group got hit? _newdamage=0; { if((damage _x)>0.2) then { _newdamage=_newdamage+(damage _x); // damage has increased since last round if (_newdamage>_lastdamage) then { _lastdamage=_newdamage; _gothit=true; }; _hitPos=getpos _x; if (!alive _x) then { _members=_members-[_x]; _friends=_friends-[_x]; }; }; } foreach _members; sleep .01; // nobody left alive, exit routine if (count _members==0) then { _exit=true; } else { // did the leader die? if (!alive _npc) then { _npc = _members select 0; group _npc selectLeader _npc; if (isPlayer _npc) then {_exit=true}; }; }; // current position _currPos = getpos _npc; _currX = _currPos select 0; _currY = _currPos select 1; if (_track=="TRACK") then { _trackername setmarkerpos _currPos; }; // if the AI is a civilian we don't have to bother checking for enemy encounters if ((_issoldier) && ((count _enemies)>0) && !(_exit)) then { // if the leader comes across another unit that's either injured or dead, go into combat mode as well. // If the other person is still alive, share enemy information. if ((_shareinfo=="SHARE") && (behaviour _npc=="SAFE")) then { _others=_friends-_members; { if ((!(isNull _x) && (_npc distance _x.5) || (behaviour _x in ["AWARE","COMBAT"]))) exitWith { _npc setBehaviour "aware"; _gothit=true; if ((_hitPos select 0)==0) then {_hitPos = getPos _x}; if (_npc knowsabout _x>3) then { if (alive _x) then {_npc reveal (KRON_KnownEnemy select _sharedenemy)}; }; }; }forEach _others; }; sleep .01; // did the group spot an enemy? _lastknown=_opfknowval; _opfknowval=0; _maxknowledge=0; { _knows=_npc knowsabout _x; if ((alive _x) && (_knows>0.2) && (_knows>_maxknowledge)) then { KRON_KnownEnemy set [_sharedenemy,_x]; _opfknowval=_opfknowval+_knows; _maxknowledge=_knows; }; if (!alive _x) then {_enemies=_enemies-[_x]}; if (_maxknowledge==4) exitWith {}; }forEach _enemies; sleep .01; _pursue=false; _accuracy=100; // opfor spotted an enemy or got shot, so start pursuit if (_opfknowval>_lastknown || _gothit) then { _npc setbehaviour "combat"; _pursue=true; // make the exactness of the target dependent on the knowledge about the shooter _accuracy=21-(_maxknowledge*5); }; if (isNull (KRON_KnownEnemy select _sharedenemy)) then { _pursue=false; }; // don't react to new fatalities if less than 60 seconds have passed since the last one if ((_react<60) && (_fightmode!="walk")) then {_pursue=false}; if (_pursue) then { // get position of spotted unit in player group, and watch that spot _offsx=_accuracy/2-random _accuracy; _offsY=_accuracy/2-random _accuracy; _targetPos = getpos (KRON_KnownEnemy select _sharedenemy); _targetPos = [(_targetPos select 0) + _offsX, (_targetPos select 1) + _offsY]; _targetX = _targetPos select 0; _targetY = _targetPos select 1; {_x dowatch _targetPos} foreach units _npc; sleep .01; // also go into "combat mode" _npc setSpeedMode "full"; _speedmode = "full"; _npc setbehaviour "combat"; _pause="NOWAIT"; _waiting=0; // angle from unit to target _dir1 = [_currPos,_targetPos] call KRON_getDirPos; // angle from target to unit (reverse direction) _dir2 = (_dir1+180) mod 360; // angle from fatality to target _dir3 = if (_hitPos select 0!=0) then {[_hitPos,_targetPos] call KRON_getDirPos} else {_dir1}; _dd=(_dir1-_dir3); // unit position offset straight towards target _relUX = sin(_dir1)*SAFEDIST; _relUY = cos(_dir1)*SAFEDIST; // target position offset straight towards unit _relTX = sin(_dir2)*SAFEDIST; _relTY = cos(_dir2)*SAFEDIST; // go either left or right (depending on location of fatality - or randomly if no fatality) _sinU=_sin90; _cosU=_cos90; _sinT=_sin270; _cosT=_cos270; if ((_dd<0) || (_dd==0 && (random 1)>.5)) then {_sinU=_sin270; _cosU=_cos270; _sinT=_sin90; _cosT=_cos90}; // avoidance position (right or left of unit) _avoidX = _currX + _cosU*_relUX - _sinU*_relUY; _avoidY = _currY + _sinU*_relUX + _cosU*_relUY; _avoidPos = [_avoidX,_avoidY]; // flanking position (right or left of target) _flankX = _targetX + _cosT*_relTX - _sinT*_relTY; _flankY = _targetY + _sinT*_relTX + _cosT*_relTY; _flankPos = [_flankX,_flankY]; // final target position _attackPos = _targetPos; // for now we're stepping a bit to the side _targetPos = _avoidPos; if (_nofollow=="NOFOLLOW") then { _avoidPos = [_avoidPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _flankPos = [_flankPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _attackPos = [_attackPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _targetPos = [_targetPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; }; _react=0; _fightmode="fight"; _timeontarget=0; _fm=1; if (KRON_UPS_Debug!=0) then { "dead" setmarkerpos _hitPos; "avoid" setmarkerpos _avoidPos; "flank" setmarkerpos _flankPos; "target" setmarkerpos _attackPos; }; _newpos=true; // speed up the cycle duration after an incident if (_currcycle>=_cycle) then {_currcycle=1}; }; }; sleep .01; if !(_newpos) then { // calculate new distance // if we're waiting at a waypoint, no calculating necessary if (_waiting<=0) then { // distance to target _dist = [_currPos,_targetPos] call KRON_distancePosSqr; if (_lastdist==0) then {_lastdist=_dist}; _moved = abs(_dist-_lastdist); // adjust the target tolerance for fast moving vehicles if (_moved>_maxmove) then {_maxmove=_moved; if ((_maxmove/40) > _closeenough) then {_closeenough=_maxmove/40}}; // how much did we move in the last three cycles? _totmove=_moved+_lastmove1+_lastmove2; _damm = damage _npc; // is our damage changing (increasing)? _dammchg = abs(_damm - _lastdamm); // we're either close enough, seem to be stuck, or are getting damaged, so find a new target if ((!_swimming) && ((_dist<=_closeenough) || (_totmove<.2) || (_dammchg>0.01) || (_timeontarget>ALERTTIME))) then {_makenewtarget=true;}; // in 'attack (approach) mode', so follow the flanking path (don't make it too predictable though) if ((_fightmode!="walk") && (_dist<=_closeenough)) then { if ((random 1)<.95) then { if (_flankPos select 0!=0) then { _targetPos=_flankPos; _flankPos=[0,0]; _makenewtarget=false; _newpos=true; _fm=1; } else { if (_attackPos select 0!=0) then { _targetPos=_attackPos; _attackPos=[0,0]; _makenewtarget=false; _newpos=true; _fm=2; }; }; }; }; sleep .01; // make new target if (_makenewtarget) then { if ((_nomove=="NOMOVE") && (_timeontarget>ALERTTIME)) then { if (([_currPos,_orgPos] call KRON_distancePosSqr)<_closeenough) then { _newpos = false; } else { _targetPos=_orgPos; }; } else { // re-read marker position/size [] call _getAreaInfo; // find a new target that's not too close to the current position _targetPos=_currPos; _tries=0; while {((([_currPos,_targetPos] call KRON_distancePosSqr) < _mindist)) && (_tries<20)} do { _tries=_tries+1; // generate new target position (on the road) _tries=0; while {_tries<20} do { _targetPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; if (_iscar) then { _roadlist = _targetPos nearRoads 100; if (count _roadlist>0) then { _targetPos = getPos (_roadlist select 0); _tries=99; }; } else { _tries=99; }; //_road=[_targetPos,(_isplane||_isboat),_road] call KRON_OnRoad; sleep .01; }; }; }; _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0]; _gothit=false; _hitPos=[0,0,0]; _fm=0; _npc setSpeedMode _orgSpeed; _newpos=true; // if we're waiting at patrol end points then don't create a new target right away. Keep cycling though to check for enemy encounters if ((_pause!="NOWAIT") && (_waiting<0)) then {_waiting = (15 + random 20)}; }; }; }; sleep .01; // if in water, get right back out of it again if (surfaceIsWater _currPos) then { if (_isman && !_swimming) then { _drydist=999; // look around, to find a dry spot for [{_a=0}, {_a<=270}, {_a=_a+90}] do { _dp=[_currPos,30,_a] call KRON_relPos; if !(surfaceIsWater _dp) then {_targetPos=_dp}; }; _newpos=true; _swimming=true; }; } else { _swimming=false; }; _waiting = _waiting - _currcycle; if ((_waiting<=0) && _newpos) then { // tell unit about new target position if (_fightmode!="walk") then { // reset patrol speed after following enemy for a while if (_timeontarget>ALERTTIME) then { _fightmode="walk"; _speedmode = _orgSpeed; { _x setSpeedMode _speedmode; _x setBehaviour _orgMode; }forEach _members; }; // use individual doMoves if pursuing enemy, // as otherwise the group breaks up too much {_x doMove _targetPos}forEach _members; } else { (group _npc) move _targetPos; (group _npc) setSpeedMode _speedmode; }; if (_track=="TRACK") then { switch (_fm) do { case 1: {_destname setmarkerSize [.4,.4]}; case 2: {_destname setmarkerSize [.6,.6]}; default {_destname setmarkerSize [.5,.5]}; }; _destname setMarkerPos _targetPos; }; _dist=0; _moved=0; _lastmove1=10; _waiting=-1; _newpos=false; _swimming=false; _timeontarget = 0; }; // move on _lastdist = _dist; _lastmove2 = _lastmove1; _lastmove1 = _moved; _lastdamm = _damm; // check external loop switch _cont = (call compile format ["KRON_UPS_%1",_npcname]); if (_cont==0) then {_exit=true}; _makenewtarget=false; if ((_exit) || (isNil("_npc"))) then { _loop=false; } else { // slowly increase the cycle duration after an incident if (_currcycle<_cycle) then {_currcycle=_currcycle+.5}; sleep _currcycle; }; }; if !(isNil("_npc")) then { {doStop _x; _x domove getPos _x; _x move getPos _x} forEach _members; }; KRON_UPS_Exited=KRON_UPS_Exited+1; if (_track=="TRACK") then { _trackername setMarkerType "Dot"; _destname setMarkerType "Empty"; }; _friends=nil; _enemies=nil; #define CHANGETIME 10 if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fRegisterScript }; sleep CHANGETIME; "mk4_weather" addPublicVariableEventHandler { _overcast = (_this select 1) select 0; _rain = (_this select 1) select 1; _fog = (_this select 1) select 2; if ( mk4_debugMode == 3 ) then { // if debug is high [__FILE__, __LINE__, "received new weather values", (_this select 1)] call mk4_fEcho; }; CHANGETIME setOvercast _overcast; CHANGETIME setRain _rain; CHANGETIME setFog _fog; }; if (isServer) then { while { true } do { mk4_weather = [overcast, rain, fog]; publicVariable "mk4_weather"; if ( mk4_debugMode == 3 ) then { // if debug is high [__FILE__, __LINE__, "sending new weather values over network", mk4_weather] call mk4_fEcho; }; sleep 10; }; }; if ( mk4_debugMode == 3 ) then { [__FILE__] call mk4_fUnregisterScript }; if ( getNumber(MK4_Settings >> "ACE" >> "spectator") == 1 ) then { _this call ace_fnc_startSpectator }; /////////////////////////////////////////// // The purpose of this file is to set variables // // or run code before the init.sqf is run. // // // // !! DO NOT DELETE THIS FILE !! // ////////////////////////////////////////// //Init UPSMON scritp (must be run on all clients) //call compile preprocessFileLineNumbers "scripts\Init_UPSMON.sqf"; //KRON_UPS_sharedist = 50; scud1 = false; scud2 = false; scud3 = false; objAllDone = false; if (isDedicated) then {setViewDistance 75; mk4_defaultVD = 75;};// ========================================================================================================= // UPSMON - Urban Patrol Script Mon // Version: 5.0.9 // Author: Monsada (chs.monsada@gmail.com) // // Wiki: http://dev-heaven.net/projects/upsmon/wiki // Forum: http://forums.bistudio.com/showthread.php?t=91696 // Share your missions with upsmon: http://dev-heaven.net/projects/upsmon/boards/86 // --------------------------------------------------------------------------------------------------------- // Based on Urban Patrol Script // Version: 2.0.3 // Author: Kronzky (www.kronzky.info / kronzky@gmail.com) // --------------------------------------------------------------------------------------------------------- // Some little fixes: !Rafalsky (v5.0.8 - 5.0.9) // --------------------------------------------------------------------------------------------------------- //Adding eventhandlers "KRON_UPS_EAST_SURRENDED" addPublicVariableEventHandler { if (_this select 1) then { nul=[east] execvm "scripts\UPSMON\MON_surrended.sqf";};}; "KRON_UPS_WEST_SURRENDED" addPublicVariableEventHandler { if (_this select 1) then { nul=[west] execvm "scripts\UPSMON\MON_surrended.sqf";};}; "KRON_UPS_GUER_SURRENDED" addPublicVariableEventHandler { if (_this select 1) then { nul=[resistance] execvm "scripts\UPSMON\MON_surrended.sqf";};}; "MON_LOCAL_EXEC" addPublicVariableEventHandler { if (local ((_this select 1)select 0)) then { call ( compile format[(_this select 1)select 1,(_this select 1)select 0] ); }; }; if (!isServer) exitWith {}; //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // These Variables should be checked and set as required, to make the mission runs properly. //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // ACE Wounds System for AI (set TRUE to On, set FALSE to Off) ! ace_sys_wounds_noai = false; // set it as required //1=Enable or 0=disable debug. In debug could see a mark positioning de leader and another mark of the destination of movement, very useful for editing mission KRON_UPS_Debug = 0; //1=Enable or 0=disable. In game display global chat info about who just killed a civilian. //numbers of Civilians killed by players could be read from array 'KILLED_CIV_COUNTER' -> [Total, by West, by East, by Res, The killer] R_WHO_IS_CIV_KILLER_INFO = 1; // if you are spotted by AI group, how close the other AI group have to be to You , to be informed about your present position. over this, will lose target KRON_UPS_sharedist = 250; // If enabled IA communication between them with radio defined sharedist distance, 0/2 // (must be set to 2 in order to use reinforcement !R) KRON_UPS_comradio = 2; //Sides that are enemies of resistance KRON_UPS_Res_enemy = [west]; // Distance from destination for searching vehicles. (Search area is about 200m), // If your destination point is further than KRON_UPS_searchVehicledist, AI will try to find a vehicle to go there. KRON_UPS_searchVehicledist = 600; // 700, 900 //Enables or disables AI to use static weapons KRON_UPS_useStatics = true; //Enables or disables AI to put mines if armoured enemies near KRON_UPS_useMines = false; //------------------------------------------------------------------------------------------------------------------------------ // These Variables can be changed if needed but it is not necessary. //------------------------------------------------------------------------------------------------------------------------------ //% of chanse to use smoke by team members when someone wounded or killed in the group in %(default 13 & 35). // set both to 0 -> to switch off this function R_USE_SMOKE_wounded = 10; R_USE_SMOKE_killed = 25; //Height that heli will fly this input will be randomised in a 10% KRON_UPS_flyInHeight = 80; //Percentage of units to surrender. KRON_UPS_EAST_SURRENDER = 5; KRON_UPS_WEST_SURRENDER = 10; KRON_UPS_GUER_SURRENDER = 5; // knowsAbout 0.5 1.03 , 1.49 to add this enemy to "target list" (1-4) the higher number the less detect ability (original in 5.0.7 was 0.5) // it does not mean the AI will not shoot at you. This means: what must be knowsAbout you to UPSMON adds you to the list of targets (UPSMON list of target) R_knowsAboutEnemy = 1.49; // --------------------------------------------------------------------------------------------------------------------- // Better do not change these variables if you aren't sure !R // --------------------------------------------------------------------------------------------------------------------- //Efective distance for doing perfect ambush (max distance is this x2) KRON_UPS_ambushdist = 50; //Max distance to target for doing para-drop, will be randomised between 0 and 100% of this value. KRON_UPS_paradropdist = 250; //Frequency for doing calculations for each squad. KRON_UPS_Cycle = 10; //org 20 //Time that lider wait until doing another movement, this time reduced dynamically under fire, and on new targets KRON_UPS_react = 60; //Min time to wait for doing another reaction KRON_UPS_minreact = 20; // org 30 //Max waiting is the maximum time patrol groups will wait when arrived to target for doing another target. KRON_UPS_maxwaiting = 30; // how long AI units should be in alert mode after initially spotting an enemy KRON_UPS_alerttime = 90; // how far opfors should move away if they're under attack KRON_UPS_safedist = 100; //org 300 // how close unit has to be to target to generate a new one target or to enter stealth mode KRON_UPS_closeenough = 300; //Enable it to send reinforcements, better done it in a trigger inside your mission. KRON_UPS_reinforcement = false; //Artillery support, better control if set in trigger KRON_UPS_ARTILLERY_EAST_FIRE = false; //set to true for doing east to fire KRON_UPS_ARTILLERY_WEST_FIRE = false; //set to true for doing west to fire KRON_UPS_ARTILLERY_GUER_FIRE = false; //set to true for doing resistance to fire //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Do not touch these variables !!!! !R //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- R_GOTHIT_ARRAY =[0]; AcePresent = isClass(configFile/"CfgPatches"/"ace_main"); UPSMON_Version = "UPSMON 5.0.9"; KILLED_CIV_COUNTER = [0,0,0,0,0]; KRON_UPS_flankAngle = 45; //Angulo de flanqueo KRON_UPS_INIT = 0; //Variable que indica que ha sido inicializado KRON_UPS_EAST_SURRENDED = false; KRON_UPS_WEST_SURRENDED = false; KRON_UPS_GUER_SURRENDED = false; KRON_AllWest=[]; //All west AI KRON_AllEast=[]; //All east AI KRON_AllRes=[]; //All resistance AI KRON_UPS_East_enemies = []; KRON_UPS_West_enemies = []; KRON_UPS_Guer_enemies = []; KRON_UPS_East_friends = []; KRON_UPS_West_friends = []; KRON_UPS_Guer_friends = []; KRON_targets0 =[];//objetivos west KRON_targets1 =[];//objetivos east KRON_targets2 =[];//resistence KRON_targetsPos =[];//Posiciones de destino actuales. KRON_NPCs = []; //Lideres de los grupos actuales KRON_UPS_Instances=0; KRON_UPS_Total=0; KRON_UPS_Exited=0; KRON_UPS_East_Total = 0; KRON_UPS_West_Total = 0; KRON_UPS_Guer_Total = 0; KRON_UPS_ARTILLERY_UNITS = []; KRON_UPS_ARTILLERY_WEST_TARGET = objnull; KRON_UPS_ARTILLERY_EAST_TARGET = objnull; KRON_UPS_ARTILLERY_GUER_TARGET = objnull; KRON_UPS_TEMPLATES = []; KRON_UPS_MG_WEAPONS = ["MG36","M249","M240","MK_48","PK","PKm","Pecheneg","M249 Para","M249 Para M145","M240G M145","M60"]; //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // ***************************************** SERVER INITIALIZATION ***************************************** if (isNil("KRON_UPS_INIT") || KRON_UPS_INIT == 0) then { //Init library function, Required Version: 5.0 of mon_functions call compile preprocessFileLineNumbers "scripts\UPSMON\common\MON_functions.sqf"; //init !R functions call compile preprocessFileLineNumbers "scripts\UPSMON\!R\R_functions.sqf"; if (isNil "RE") then {[] execVM "\ca\Modules\MP\data\scripts\MPframework.sqf"}; //scripts initialization UPSMON = compile preprocessFile "scripts\UPSMON.sqf"; UPSMON_surrended = compile preprocessFile "scripts\UPSMON\MON_surrended.sqf"; // declaracin de variables privadas private["_obj","_trg","_l","_pos"]; // global functions KRON_randomPos = {private["_cx","_cy","_rx","_ry","_cd","_sd","_ad","_tx","_ty","_xout","_yout"];_cx=_this select 0; _cy=_this select 1; _rx=_this select 2; _ry=_this select 3; _cd=_this select 4; _sd=_this select 5; _ad=_this select 6; _tx=random (_rx*2)-_rx; _ty=random (_ry*2)-_ry; _xout=if (_ad!=0) then {_cx+ (_cd*_tx - _sd*_ty)} else {_cx+_tx}; _yout=if (_ad!=0) then {_cy+ (_sd*_tx + _cd*_ty)} else {_cy+_ty}; [_xout,_yout]}; KRON_PosInfo = {private["_pos","_lst","_bld","_bldpos"];_pos=_this select 0; _lst=_pos nearObjects ["House",12]; if (count _lst==0) then {_bld=0;_bldpos=0} else {_bld=_lst select 0; _bldpos=[_bld] call KRON_BldPos}; [_bld,_bldpos]}; KRON_PosInfo3 = {private["_pos","_lst","_bld","_bldpos"];_pos=_this select 0; _lst= nearestObjects [_pos, [], 3]; if (count _lst==0) then {_bld=objnull;_bldpos=0} else {_bld = nearestbuilding (_lst select 0); _bldpos=[_bld] call KRON_BldPos2}; [_bld,_bldpos]}; KRON_BldPos = {private ["_bld","_bldpos","_posZ","_maxZ"];_bld=_this select 0;_maxZ=0;_bi=0;_bldpos=0;while {_bi>=0} do {if (((_bld BuildingPos _bi) select 0)==0) then {_bi=-99} else {_bz=((_bld BuildingPos _bi) select 2); if (((_bz)>4) && ((_bz>_maxZ) || ((_bz==_maxZ) && (random 1>.8)))) then {_maxZ=_bz; _bldpos=_bi}};_bi=_bi+1};_bldpos}; KRON_BldPos2 = {private ["_bld","_bldpos"]; _bld=_this select 0; _bldpos = 1; while {format ["%1", _bld buildingPos _bldpos] != "[0,0,0]"} do {_bldpos = _bldpos + 1;}; _bldpos = _bldpos - 1; _bldpos;}; KRON_getDirPos = {private["_a","_b","_from","_to","_return"]; _from = _this select 0; _to = _this select 1; _return = 0; _a = ((_to select 0) - (_from select 0)); _b = ((_to select 1) - (_from select 1)); if (_a != 0 || _b != 0) then {_return = _a atan2 _b}; if ( _return < 0 ) then { _return = _return + 360 }; _return}; KRON_distancePosSqr = {round(((((_this select 0) select 0)-((_this select 1) select 0))^2 + (((_this select 0) select 1)-((_this select 1) select 1))^2)^0.5)}; KRON_relPos = {private["_p","_d","_a","_x","_y","_xout","_yout"];_p=_this select 0; _x=_p select 0; _y=_p select 1; _d=_this select 1; _a=_this select 2; _xout=_x + sin(_a)*_d; _yout=_y + cos(_a)*_d;[_xout,_yout,0]}; KRON_rotpoint = {private["_cp","_a","_tx","_ty","_cd","_sd","_cx","_cy","_xout","_yout"];_cp=_this select 0; _cx=_cp select 0; _cy=_cp select 1; _a=_this select 1; _cd=cos(_a*-1); _sd=sin(_a*-1); _tx=_this select 2; _ty=_this select 3; _xout=if (_a!=0) then {_cx+ (_cd*_tx - _sd*_ty)} else {_cx+_tx}; _yout=if (_a!=0) then {_cy+ (_sd*_tx + _cd*_ty)} else {_cy+_ty}; [_xout,_yout,0]}; KRON_stayInside = { private["_np","_nx","_ny","_cp","_cx","_cy","_rx","_ry","_d","_tp","_tx","_ty","_fx","_fy"]; _np=_this select 0; _nx=_np select 0; _ny=_np select 1; _cp=_this select 1; _cx=_cp select 0; _cy=_cp select 1; _rx=_this select 2; _ry=_this select 3; _d=_this select 4; _tp = [_cp,_d,(_nx-_cx),(_ny-_cy)] call KRON_rotpoint; _tx = _tp select 0; _fx=_tx; _ty = _tp select 1; _fy=_ty; if (_tx<(_cx-_rx)) then {_fx=_cx-_rx}; if (_tx>(_cx+_rx)) then {_fx=_cx+_rx}; if (_ty<(_cy-_ry)) then {_fy=_cy-_ry}; if (_ty>(_cy+_ry)) then {_fy=_cy+_ry}; if ((_fx!=_tx) || (_fy!=_ty)) then {_np = [_cp,_d*-1,(_fx-_cx),(_fy-_cy)] call KRON_rotpoint}; _np; }; // Misc KRON_UPSgetArg = {private["_cmd","_arg","_list","_a","_v"]; _cmd=_this select 0; _arg=_this select 1; _list=_this select 2; _a=-1; {_a=_a+1; _v=format["%1",_list select _a]; if (_v==_cmd) then {_arg=(_list select _a+1)}} foreach _list; _arg}; KRON_UPSsetArg = {private["_cmd","_arg","_list","_a","_v"]; _cmd=_this select 0; _arg=_this select 1; _list=_this select 2; _a=-1; { _a=_a+1; _v= format ["%1", _list select _a]; if (_v==_cmd) then { _a=_a+1; _list set [_a,_arg]; }; } foreach _list; _list}; KRON_deleteDead = {private["_u","_s"];_u=_this select 0; _s= _this select 1; _u removeAllEventHandlers "killed"; sleep _s; deletevehicle _u}; // *********************************************************************************************************** // MAIN UPSMON SERVER FUNCTION // *********************************************************************************************************** MON_MAIN_server = { private["_obj","_trg","_l","_pos","_countWestSur","_countEastSur","_countResSur","_WestSur","_EastSur","_ResSur","_target","_targets","_targets0","_targets1","_targets2","_npc","_cycle" ,"_arti","_side","_range","_rounds","_area","_maxcadence","_mincadence","_bullet","_fire","_knownpos","_sharedenemy","_enemyside","_timeout"]; _cycle = 10; //Time to do a call to commander _arti = objnull; _side = ""; _range = 0; _rounds = 0; _area = 0; _maxcadence = 0; _mincadence = 0; _bullet = ""; _fire = false; _target = objnull; _knownpos =[0,0,0]; _enemyside = []; _WestSur = KRON_UPS_WEST_SURRENDED; _EastSur = KRON_UPS_EAST_SURRENDED; _ResSur = KRON_UPS_GUER_SURRENDED; //Main loop while {true} do { _countWestSur = round ( KRON_UPS_West_Total * KRON_UPS_WEST_SURRENDER / 100); _countEastSur = round ( KRON_UPS_East_Total * KRON_UPS_EAST_SURRENDER / 100); _countResSur = round ( KRON_UPS_Guer_Total * KRON_UPS_GUER_SURRENDER / 100); //Checks for WEST surrender if (KRON_UPS_WEST_SURRENDER > 0 && !KRON_UPS_WEST_SURRENDED ) then { { if (!alive _x || !canmove _x) then {KRON_AllWest = KRON_AllWest-[_x]}; }foreach KRON_AllWest; if ( count KRON_AllWest <= _countWestSur ) then { KRON_UPS_WEST_SURRENDED = true; publicvariable "KRON_AllWest"; publicvariable "KRON_UPS_WEST_SURRENDED"; }; }; //Checks for EAST surrender if (KRON_UPS_EAST_SURRENDER > 0 && !KRON_UPS_EAST_SURRENDED ) then { { if (!alive _x || !canmove _x) then {KRON_AllEast = KRON_AllEast-[_x]}; }foreach KRON_AllEast; if ( count KRON_AllEast <= _countEastSur ) then { KRON_UPS_EAST_SURRENDED = true; publicvariable "KRON_AllEast"; publicvariable "KRON_UPS_EAST_SURRENDED"; }; }; //Checks for RESISTANCE surrender if (KRON_UPS_GUER_SURRENDER > 0 && !KRON_UPS_GUER_SURRENDED ) then { { if (!alive _x || !canmove _x) then {KRON_AllRes = KRON_AllRes-[_x]}; }foreach KRON_AllRes; if ( count KRON_AllRes <= _countResSur ) then { KRON_UPS_GUER_SURRENDED = true; publicvariable "KRON_AllRes"; publicvariable "KRON_UPS_GUER_SURRENDED"; }; }; //Exec surrended script if (KRON_UPS_WEST_SURRENDED && !_WestSur ) then { _WestSur = true; [west] spawn UPSMON_surrended; }; if (KRON_UPS_EAST_SURRENDED && !_EastSur ) then { _EastSur = true; [east] spawn UPSMON_surrended; }; if (KRON_UPS_GUER_SURRENDED && !_ResSur ) then { _ResSur = true; [Resistance] spawn UPSMON_surrended; }; sleep 0.5; _sharedenemy = 0; _targets0 = []; _targets1 = []; _targets2 = []; { if (!isnull _x && alive _x && !captive _x ) then { _npc = _x; _targets = []; switch (side _npc) do { //West targets case west: { _sharedenemy = 0; _enemyside = [east]; }; //East targets case east: { _sharedenemy = 1; _enemyside = [west]; }; //Resistance targets case resistance: { _sharedenemy = 2; _enemyside = KRON_UPS_Res_enemy; }; }; if (side _npc in KRON_UPS_Res_enemy) then { _enemyside = _enemyside + [resistance]; }; //Gets known targets on each leader for comunicating enemy position //Has better performance with targetsquery //_targets = _npc nearTargets KRON_UPS_sharedist; _targets = _npc targetsQuery ["","","","",""]; { //_target = _x select 4; //Neartargets _target = _x select 1; //Targetsquery if ( side _target in _enemyside ) then { // if (KRON_UPS_Debug>0) then {player globalchat format["%1: knows about %2, enemies=%3",_npc getVariable ("UPSMON_grpid"),_npc knowsabout _target, _npc countEnemy _targets ]}; if (!isnull _target && alive _target && canmove _target && !captive _target && _npc knowsabout _target > R_knowsAboutEnemy && ( _target iskindof "Land" || _target iskindof "Air" || _target iskindof "Ship" ) && !( _target iskindof "Animal") && ( _target emptyPositions "Gunner" == 0 && _target emptyPositions "Driver" == 0 || (!isnull (gunner _target) && canmove (gunner _target)) || (!isnull (driver _target) && canmove (driver _target))) ) then { //Saves last known position //_knownpos = _x select 0; //Neartargets _knownpos = _x select 4;//Targetsquery _target setvariable ["UPSMON_lastknownpos", _knownpos, false]; // _npc setVariable ["R_knowsAboutTarget", true, false]; // !R call (compile format ["_targets%1 = _targets%1 - [_target]",_sharedenemy]); call (compile format ["_targets%1 = _targets%1 + [_target]",_sharedenemy]); }; }; sleep 0.01; }foreach _targets; }; sleep 0.01; }foreach KRON_NPCs; //Share targets KRON_targets0 = _targets0; KRON_targets1 = _targets1; KRON_targets2 = _targets2; //Target debug console if (KRON_UPS_Debug>0) then {hintsilent parseText format["%1
--------------------------
West(A=%2 C=%3 T=%4)
East(A=%5 C=%6 T=%7)
Res(A=%8 C=%9 T=%10)
" ,UPSMON_Version ,KRON_UPS_West_Total, count KRON_AllWest, count KRON_targets0 ,KRON_UPS_East_Total, count KRON_AllEast, count KRON_targets1 ,KRON_UPS_Guer_Total, count KRON_AllRes, count KRON_targets2 ]}; sleep 0.5; //Artillery module control { _arti = _x select 0; _rounds = _x select 1; _range = _x select 2; _area = _x select 3; _maxcadence = _x select 4; _mincadence = _x select 5; _bullet = _x select 6; _salvobreak = _x select 7; if (isnil{_arti getVariable ("timeout")}) then { _arti setVariable ["timeout", time, false]; sleep 0.1; }; _timeout = _arti getVariable ("timeout"); if (!isnull (gunner _arti) && canmove (gunner _arti) && (time >= _timeout)) then { _side = side gunner _arti; _fire = call (compile format ["KRON_UPS_ARTILLERY_%1_FIRE",_side]); //If fire enabled gets a known target pos for doing fire if no friendly squads near. if (_fire) then { _target = call (compile format ["KRON_UPS_ARTILLERY_%1_TARGET",_side]); if (isnil "_target" ) then {_target = objnull;}; switch (_side) do { //West targets case west: { _targets = KRON_targets0; }; //East targets case east: { _targets = KRON_targets1; }; //Resistance targets case resistance: { _targets = KRON_targets2; }; }; //Check if has a target if (!(_target in _targets ) || isnull _target || !alive _target) then { _target = objnull; { _auxtarget = _x; _targetPos = _auxtarget getvariable ("UPSMON_lastknownpos"); if (!isnil "_targetPos") then { //If target in range check no friendly squad near if (alive _auxtarget && !(_auxtarget iskindof "Air") && (round([position _arti,_targetPos] call KRON_distancePosSqr)) <= _range) then { _target = _auxtarget; //Must check if no friendly squad near fire position { if (!isnull _x && _side == side _x) then { if ((round([position _x,_targetPos] call KRON_distancePosSqr)) < (KRON_UPS_safedist * 0.7)) exitwith {_target = objnull;}; }; } foreach KRON_NPCs; }; }; //If target found exit if (!isnull _target) exitwith {}; } foreach _targets; }; //If target fires artillery if (!isnull _target) then { //Fix current target call (compile format ["KRON_UPS_ARTILLERY_%1_TARGET = _target",_side]); _targetPos = _target getvariable ("UPSMON_lastknownpos"); if (!isnil "_targetPos") then { _arti removeAllEventHandlers "fired"; sleep 0.01; // chatch the bullet in the air and delete it _arti addeventhandler["fired", {deletevehicle (nearestobject[_this select 0, _this select 4])}]; [_arti,_targetPos,_rounds,_area,_maxcadence,_mincadence,_bullet,_salvobreak] spawn MON_artillery_dofire; }; }; }; }; sleep 0.5; } foreach KRON_UPS_ARTILLERY_UNITS; // if (KRON_UPS_Debug>0) then {player globalchat format["Init_upsmon artillery=%1",count KRON_UPS_ARTILLERY_UNITS]}; sleep _cycle; }; }; }; // *********************************************************************************************************** // INITIALIZATION OF UPSMON // *********************************************************************************************************** _l = allunits + vehicles; { if ((_x iskindof "AllVehicles") && (side _x != civilian)) then { _s = side _x; switch (_s) do { case west: { KRON_AllWest=KRON_AllWest+[_x]; }; case east: { KRON_AllEast=KRON_AllEast+[_x]; }; case resistance: { KRON_AllRes=KRON_AllRes+[_x]; }; }; }; } forEach _l; _l = nil; if (isNil("KRON_UPS_Debug")) then {KRON_UPS_Debug=0}; KRON_UPS_East_enemies = KRON_AllWest; KRON_UPS_West_enemies = KRON_AllEast; if (east in KRON_UPS_Res_enemy ) then { KRON_UPS_East_enemies = KRON_UPS_East_enemies+KRON_AllRes; KRON_UPS_Guer_enemies = KRON_AllEast; } else { KRON_UPS_East_friends = KRON_UPS_East_friends+KRON_AllRes; KRON_UPS_Guer_friends = KRON_AllEast; }; if (west in KRON_UPS_Res_enemy ) then { KRON_UPS_West_enemies = KRON_UPS_West_enemies+KRON_AllRes; KRON_UPS_Guer_enemies = KRON_UPS_Guer_enemies+KRON_AllWest; } else { KRON_UPS_West_friends = KRON_UPS_West_friends+KRON_AllRes; KRON_UPS_Guer_friends = KRON_UPS_Guer_friends+KRON_AllWest; }; KRON_UPS_West_Total = count KRON_AllWest; KRON_UPS_East_Total = count KRON_AllEast; KRON_UPS_Guer_Total = count KRON_AllRes; //Initialization done KRON_UPS_INIT=1; //killciv EH _l = allunits; { if (side _x == civilian) then { _x AddEventHandler ["firedNear", {nul = _this spawn R_SN_EHFIREDNEAR}]; sleep 0.01; _x AddEventHandler ["killed", {nul = _this spawn R_SN_EHKILLEDCIV}]; sleep 0.01; }; } forEach _l; _l = nil; // --------------------------------------------------------------------------------------------------------- processInitCommands; //Executes de main process of server [] SPAWN MON_MAIN_server; diag_log "--------------------------------"; diag_log (format["UPSMON started"]); if(true) exitWith {}; /* ============================================= !R Hide area markers. create Game Logic Object put in initialization field: nul = call compile preprocessFile "scripts\UPSMON\!R\markerAlpha.sqf"; all markers area must be named area0, area1...area13 ================================================= */ { _x setmarkeralpha 0; } foreach ["area0", "area1", "area2","area3","area4","area5","area6","area7","area8","area9","area10","area11","area12","area13"]; /* autor: !R 5.0.8 R3 */ // get new position [x,y,x] from pos in distance and angle. // [_pos, _distance, _angle] call R_relPos3D; // [newX,newY,Z] R_relPos3D = { private["_p","_d","_a","_x","_y","_z","_xout","_yout"]; _p=_this select 0; _x=_p select 0; _y=_p select 1; _z=_p select 2; _d=_this select 1; _a=_this select 2; _xout=_x + sin(_a)*_d; _yout=_y + cos(_a)*_d; [_xout,_yout,_z] }; // [_unit] spawn R_ThrowSmoke; R_ThrowSmoke = { private ["_unit","_shell", "_moves","_unitPos","_pos","_flare","_direction"]; /* _stanThrow = ["AwopPercMstpSgthWrflDnon_Start1", "AwopPercMstpSgthWrflDnon_Throw1","AwopPercMstpSgthWrflDnon_End1"]; _kneeThrow = ["AwopPknlMstpSgthWrflDnon_Start", "AwopPknlMstpSgthWrflDnon_Throw" ,"AwopPknlMstpSgthWrflDnon_End"]; _proneThrow= ["AwopPpneMstpSgthWrflDnon_Start", "AwopPpneMstpSgthWrflDnon_Throw" ,"AwopPpneMstpSgthWrflDnon_End"]; */ _moves = ["AwopPercMstpSgthWrflDnon_Start1","AwopPknlMstpSgthWrflDnon_Start","AwopPpneMstpSgthWrflDnon_Start"]; _unit = _this select 0; _shell = "SmokeShell"; _unitPos = unitPos _unit; //Animation switch (_unitPos) do { case "Auto": { _unit playMove (_moves select 1); }; case "Up": { _unit playMove (_moves select 0); }; case "Middle": { _unit playMove (_moves select 1); }; case "Down": { _unit playMove (_moves select 2); }; }; sleep 4; _direction = direction _unit; // use such bypass as setvelocity does not work in MP _pos = position _unit; _pos = [(_pos select 0),(_pos select 1),(_pos select 2)+1.5]; _pos = [_pos, 18, _direction] call R_relPos3D; if (alive _unit && canmove _unit) then { _flare = _shell createVehicle _pos; }; // setvelocity does not work in MP http://dev-heaven.net/issues/17949 /* _vector = [18,direction _unit,0] call C B A_fnc_polar2vect; _pos=position _unit; _pos=[(_pos select 0),(_pos select 1),(_pos select 2)+2]; _flare = _shell createVehicle _pos; _flare setPos _pos; _flare setvelocity _vector; */ }; // [_unit] call R_FN_deleteObsoleteWaypoints; // leave only the last way point R_FN_deleteObsoleteWaypoints = { private ["_unit","_grp"]; _unit = _this select 0; _grp = group _unit; while {(count (waypoints _grp)) > 1} do { deleteWaypoint ((waypoints _grp) select 0); }; }; // array = [_npc] call R_FN_vehiclesUsedByGroup; // return array of vehicles used by group R_FN_vehiclesUsedByGroup = { private ["_npc","_vehicles"]; _npc = _this select 0; _vehicles = []; if (!alive _npc) exitwith {}; { if (( vehicle _x != _x || !(_x iskindof "Man")) && !((vehicle _x) in _vehicles)) then { _vehicles = _vehicles + [vehicle _x]; }; } foreach units _npc; _vehicles }; // array = [_vehicle] call R_FN_unitsInCargo; // array of units in cargo of the vehicle (in vehicle and assigned as cargo) R_FN_unitsInCargo = { private ["_vehicle","_x","_unitsInCargo"]; _vehicle = _this select 0; _unitsInCargo = []; { if( (assignedVehicleRole _x) select 0 == "Cargo") then { _unitsInCargo = _unitsInCargo + [_x]; }; } forEach crew _vehicle; _unitsInCargo }; // array = [_npc] call R_FN_allUnitsInCargo; // array of all units in cargo of the group (not driver, commander or gunner) R_FN_allUnitsInCargo = { private ["_npc","_vehicles","_unitsInCargo","_allUnitsInCargo"]; _npc = _this select 0; if (!alive _npc) exitwith {}; _allUnitsInCargo =[]; _vehicles = [_npc] call R_FN_vehiclesUsedByGroup; { _unitsInCargo = [_x] call R_FN_unitsInCargo; _allUnitsInCargo = _allUnitsInCargo + _unitsInCargo; } foreach _vehicles; _allUnitsInCargo }; // old MON_GetOutDist // <- _npc // <- _targetPos: position for exiting(if no waypoint used) // <- _atdist: minimal dist to the _targetpos do getout // -> nothing // nul = [_npc,_targetpos,_atdist] spawn R_SN_GetOutDist; R_SN_GetOutDist = { private["_vehicle","_npc","_target","_atdist","_getout","_dogetout","_driver","_commander","_targetpos","_dist","_vehpos","_vehicles"]; _npc = _this select 0; _targetpos = _this select 1; _atdist = _this select 2; // minimal dist to the target to do getOut _dogetout = []; // units to do getout _vehicles = []; // vehs used by the group if (!alive _npc) exitwith{}; _vehicle = vehicle _npc; _vehpos = getpos _vehicle; _dist = round([_vehpos,_targetpos] call KRON_distancePosSqr); // dist to the target // if (KRON_UPS_Debug>0) then {player sidechat format["%1: Getoutdist dist=%2 atdist=%3 ",typeof _vehicle,_dist, _atdist]}; // if _npc is in vehicle if ( _vehicle != _npc || !(_npc iskindof "Man")) then { if ( (_dist) <= _atdist ) then { _vehicles = [_npc] call R_FN_vehiclesUsedByGroup; // vehicles use by the group { _dogetout = [_x] call R_FN_unitsInCargo; // units cargo in the vehicle _driver = driver _x; if ( count _dogetout > 0 ) then { //Stop the veh for 5.5 sek nul = [_vehicle,5] spawn MON_doStop; sleep 0.8; // give time to actualy stop { _x spawn MON_GetOut; sleep 0.3; } foreach _dogetout; //We removed the id to the vehicle so it can be reused _x setVariable ["UPSMON_grpid", 0, false]; _x setVariable ["UPSMON_cargo", [], false]; [_npc,_x, _driver] spawn MON_checkleaveVehicle; // if every one outside, make sure driver can walk sleep 0.01; }; } foreach _vehicles; }; }; }; // #define GOTHIT(X) ([X] call R_FN_GOTHIT) // nul = [_grpId] call R_FN_GOTHIT; R_FN_GOTHIT = { _grpId = _this select 0; if ((R_GOTHIT_ARRAY select _grpId) != 0) then { true } else { false } }; // use in gothit proces // nul = [_unit, _shooter] spawn R_SN_EHHIT; R_SN_EHHIT = { private ["_unit","_shooter","_grpId"]; _unit = _this select 0; _shooter = _this select 1; _grpId = _unit getVariable ("UPSMON_grpid"); if ((side _unit != side _shooter) && (R_GOTHIT_ARRAY select _grpId) == 0) then { R_GOTHIT_ARRAY set [_grpId, 1]; // if (KRON_UPS_Debug > 0) then {player globalchat format["UNIT: %1, SHOOTER :%2 %3",_unit,_shooter,side _shooter]}; }; }; // use in gothit proces // nul = [_unit, _shooter] spawn R_SN_EHKILLED; R_SN_EHKILLED = { private ["_unit","_shooter","_grpId"]; _unit = _this select 0; _shooter = _this select 1; _grpId = _unit getVariable ("UPSMON_grpid"); if ((side _unit != side _shooter) && (R_GOTHIT_ARRAY select _grpId) == 0) then { R_GOTHIT_ARRAY set [_grpId, 2]; // if (KRON_UPS_Debug > 0) then {player globalchat format["UNIT: %1, SHOOTER :%2 %3",_unit,_shooter,side _shooter]}; }; }; // logic is needed to display rGlobalChat private ["_center","_group"]; _center = createCenter sideLogic; _group = createGroup _center; R_Logic_civkill = _group createUnit ["LOGIC", [1,1,1], [], 0, "NONE"]; _group = nil; _center = nil; // use in gothit proces // nul = [_unit, _shooter] spawn R_SN_EHKILLEDCIV; R_SN_EHKILLEDCIV = { private ["_killer","_side"]; _killer = _this select 1; //only if player killed a civilian if (isPlayer _killer) then { KILLED_CIV_COUNTER set [0,(KILLED_CIV_COUNTER select 0) + 1]; // if (KRON_UPS_Debug > 0) then {player globalchat format["KILLER: %1, %2", side _killer,KILLED_CIV_COUNTER ]}; switch (side _killer) do { case west: { KILLED_CIV_COUNTER set [1,(KILLED_CIV_COUNTER select 1) + 1]; }; case east: { KILLED_CIV_COUNTER set [2,(KILLED_CIV_COUNTER select 2) + 1]; }; case resistance: { KILLED_CIV_COUNTER set [3,(KILLED_CIV_COUNTER select 3) + 1]; }; }; KILLED_CIV_COUNTER set [4,_killer]; //if (KRON_UPS_Debug > 0) then {player globalchat format["KILLER: %1", side _killer ]}; if (KRON_UPS_Debug > 0) then {player globalchat format["KILLED_CIV_COUNTER: %1",KILLED_CIV_COUNTER]}; if (R_WHO_IS_CIV_KILLER_INFO > 0) then { [R_Logic_civkill, nil , rglobalChat, format [" A CIVILIAN WAS KILLED BY %1",_killer]] call RE; }; }; }; //firedNear R_SN_EHFIREDNEAR = { private ["_civ"]; _civ = leader (_this select 0); _civ setspeedmode "FULL"; }; // ========================================================================================================= // Script for action follow me when surrended, adds the soldier to player squad in a random choice. // Version: 1.0 // Author: Monsada (smirall@hotmail.com) // --------------------------------------------------------------------------------------------------------- private ["_obj","_caller","_id","_objtype","_rnd","_join","_direction"]; _npc = _this select 0; _caller = _this select 1; _id = _this select 2; _rnd = 0; _join=true; _npc switchmove ""; _direction = ((getpos _caller select 0) - (getpos _npc select 0)) atan2 ((getpos _caller select 1) - (getpos _npc select 1)); //If positive values are needed then use: if(_direction < 0) then {_direction = _direction + 360}; _npc setdir _direction; _npc dowatch _caller; _npc setSpeedMode "LIMITED"; _npc domove position _caller; sleep 0.5; _rnd = random 100; _npc setmimic "Sad"; if (_rnd <= 30 ) then { _npc globalchat "Ok"; }; if (_rnd > 30 && _rnd <= 50) then { _npc globalchat "Yes"; }; if (_rnd > 50 && _rnd <= 100) then { _join=false; _rnd = random 100; if (_rnd < 20) then { _npc setmimic "angry"; _npc switchmove "CtsPercMstpSnonWnonDnon_idle31rejpaniVnose"; _npc globalchat "Kiss my ass"; }; if (_rnd > 20 && _rnd <= 40) then { _npc setmimic "Agresive"; _npc switchmove "CtsPercMstpSnonWnonDnon_idle33rejpaniVzadku"; sleep 3; _npc globalchat "Que te den"; }; if (_rnd > 40 && _rnd <= 60) then { _npc setmimic "Agresive"; _npc switchmove "CtsPercMstpSnonWnonDnon_idle33rejpaniVzadku"; sleep 1; _npc globalchat "Fuck you"; }; if (_rnd > 60 && _rnd <= 80) then { _npc setmimic "Agresive"; _npc switchmove "CtsPercMstpSnonWnonDnon_idle32podrbaniNanose"; sleep 0.5; _npc globalchat "Follow your mother"; }; if (_rnd > 80 && _rnd <= 100) then { _npc setmimic "angry"; sleep 0.1; _npc switchmove "CtsPercMstpSnonWnonDnon_idle32podrbaniNanose"; _npc globalchat "Fuck you"; }; }; if (_join) then { // remove the action once it is activated _npc stop false; if (_npc == leader _npc) then { _npc globalchat "All follow that man"; { _x switchmove ""; [_x] joinSilent _caller; }foreach units _npc; } else { _npc removeAction _id; [_npc] joinSilent _caller; }; }; if (true) exitWith {}; // ========================================================================================================= // Biblioteca de funciones comunes // Version: 5.0.7 // Author: Monsada (smirall@hotmail.com) // http://www.simulacion-esp.com/ // Comunidad Hispana de Simulacin // ========================================================================================================= MON_bugged_vehicles = ["BIS_alice_emptydoor","ACE_Grenade_Geometry"]; // in Vanilia extra bugged vehicle if !(AcePresent) then { MON_bugged_vehicles = MON_bugged_vehicles + ["HMMWV_M998A2_SOV_DES_EP1"]; }; // --------------------------------------------------------------------------------------------------------- //Funcin que permite posicionar objetos a la altura definida //param1: objeto //param2: altura MON_subir = { if (!isserver) exitwith{}; private ["_object","_altura","_pos","_x","_y","_z","_bld","_bldpos"]; _object = _this select 0; _altura = _this select 1; _x = 0; _y = 0; _z = 0; _pos =0; _bld = objnull; _bldpos =0; _pos = getposasl _object; _x = _pos select 0; _y = ( _pos select 1 ); _z = ( _pos select 2 ) + _altura; _object setposasl [_x,_y ,_z]; }; //Retorna la direccin entre dos posiciones MON_getDirPos = {private["_a","_b","_from","_to","_return"]; _from = _this select 0; _to = _this select 1; _return = 0; _a = ((_to select 0) - (_from select 0)); _b = ((_to select 1) - (_from select 1)); if (_a != 0 || _b != 0) then {_return = _a atan2 _b}; if ( _return < 0 ) then { _return = _return + 360 }; _return}; // --------------------------------------------------------------------------------------------------------- //Funcin de borra unidades que han sido matadas //param1: objeto a borrar cuando muera //param2: tiempo a esperar antes de borrar el objeto MON_deleteDead = {private["_u","_s"];_u=_this select 0; _s= _this select 1; _u removeAllEventHandlers "killed"; sleep _s; deletevehicle _u}; MON_deleteDeadDist = {private["_u","_s","_dist","_OCercanos","_cicle","_deleted","_isplayer"]; _i = 0; _cicle = 10; _deleted = false; _isplayer = false; _u = _this select 0; _s = _this select 1; _dist = _this select 2; _u removeAllEventHandlers "killed"; sleep _s; while {!_deleted} do { _isplayer = false; //Buscamos objetos cercanos _OCercanos = nearestObjects [_u, ["Man"] , _dist]; //Validamos si alguno de los soldados cerca es un jugador y est vivo {if (isplayer _x && alive _x) exitwith {_isplayer = true;}}foreach _OCercanos; if (!_isplayer) then { deletevehicle _u; _deleted = true; }; sleep _cicle; }; }; // --------------------------------------------------------------------------------------------------------- //Funcin tomada de UPS, busca el comando en la lista y devuelve el siguiente elemento //param1: comando a buscar //param2: valor por defecto del comando //param3: array con los comandos //Retorna valor del comando encontrado o valor por defecto MON_getArg = {private["_cmd","_arg","_list","_a","_v"]; _cmd=_this select 0; _arg=_this select 1; _list=_this select 2; _a=-1; {_a=_a+1; _v=format["%1",_list select _a]; if (_v==_cmd) then {_arg=(_list select _a+1)}} foreach _list; _arg}; // --------------------------------------------------------------------------------------------------------- //Funcin que devuelve una posicin en 3D a partir de otra, una direccin y una distancia //param1: posicin //param2: direccin //param3: distancia //Retorna vector de posicion en 3D [0,0,0] MON_GetPos = { private ["_pos","_dir","_dist","_cosU","_cosT","_relTX","_sinU","_sinT","_relTY","_newPos","_newPosX","_newPosY", "_targetZ" ]; _pos = _this select 0; _dir = _this select 1; _dist = _this select 2; _targetX = _pos select 0; _targetY = _pos select 1; _targetZ = _pos select 2; //Calculamos posicin _cosU = [_dir] call MON_GetCOS; _sinU = [_dir] call MON_GetSIN; _cosT = abs cos(_dir); _sinT = abs sin(_dir); _relTX = _sinT * _dist * _cosU; _relTY = _cosT * _dist * _sinU; _newPosX = _targetX + _relTX; _newPosY = _targetY + _relTY; _newPos = [_newPosX,_newPosY,_targetZ]; _newPos; }; // --------------------------------------------------------------------------------------------------------- //Funcin que devuelve una posicin en 2D a partir de otra, una direccin y una distancia //param1: posicin //param2: direccin //param3: distancia //Retorna vector de posicion en 2D [0,0] MON_GetPos2D = { private ["_pos","_dir","_dist","_cosU","_cosT","_relTX","_sinU","_sinT","_relTY","_newPos","_newPosX","_newPosY" ]; _pos = _this select 0; _dir = _this select 1; _dist = _this select 2; _targetX = _pos select 0; _targetY = _pos select 1; //Calculamos posicin _cosU = [_dir] call MON_GetCOS; _sinU = [_dir] call MON_GetSIN; _cosT = abs cos(_dir); _sinT = abs sin(_dir); _relTX = _sinT * _dist * _cosU; _relTY = _cosT * _dist * _sinU; _newPosX = _targetX + _relTX; _newPosY = _targetY + _relTY; _newPos = [_newPosX,_newPosY]; _newPos; }; // --------------------------------------------------------------------------------------------------------- //Funcin que devuelve las posiciones que se pueden ocupar dentro de un edificio //param1: objeto location //Retorna numero de posiciones que tiene el edificio MON_BldPos = {private ["_bld","_bldpos"]; _bld=_this; _bldpos = 1; while {format ["%1", _bld buildingPos _bldpos] != "[0,0,0]"} do {_bldpos = _bldpos + 1;}; _bldpos = _bldpos - 1; _bldpos;}; // --------------------------------------------------------------------------------------------------------- //Funcin que devuelve la casa que hay ms cerca del objeto param1 y las posiciones que se pueden ocupar dentro de ella. //param1: objeto //Retorna vector con [objeto location, posiciones que tiene] MON_PosInfo = { private["_obj","_bld","_bldpos"]; _obj=_this; _bld = nearestbuilding _obj; _bldpos= _bld call MON_BldPos; [_bld,_bldpos]; }; // --------------------------------------------------------------------------------------------------------- //Funcin que devuelve el valor negativo o positivo del seno en base a un angulo MON_GetSIN = { private["_dir","_sin","_cos"]; _dir=_this select 0; if (_dir<90) then { _sin=1; } else { if (_dir<180) then { _sin=-1; } else { if (_dir<270) then { _sin=-1; } else { _sin=1; }; }; }; _sin }; // --------------------------------------------------------------------------------------------------------- //Funcin que devuelve el valor negativo o positivo del coseno en base a un angulo MON_GetCOS = { private["_dir","_cos"]; _dir=_this select 0; if (_dir<90) then { _cos=1; } else { if (_dir<180) then { _cos=1; } else { if (_dir<270) then { _cos=-1; } else { _cos=-1; }; }; }; _cos }; //Funcin que busca vehiculos cercanos y hace entrar a las unidades del lider //Parmeters: [_grpid,_npc] // <- _grpid: id of group to assign to vehicle // <- _npc: lider // -> _getin: true if any getin MON_GetIn_NearestVehicles = { private["_vehicles","_npc","_units","_unitsIn","_grpid","_getin"]; _grpid = _this select 0; _npc = _this select 1; _vehicles=[[]]; _air=[[]]; _units = []; _unitsIn = []; _getin=false; if (leader _npc == _npc) then { _units = units _npc; } else { _units = _units + [_npc]; }; { if ( (_x!= vehicle _x && !((vehicle _x) iskindof "StaticWeapon" )) || !(_x iskindof "Man") || !alive _x || !canmove _x || !canstand _x) then {_units = _units-[_x];}; }foreach _units; _unitsIn = _units; //First catch combat vehicles if ( (count _units) > 0) then { _air = [_npc,200] call MON_NearestsAirTransports; {if (_npc knowsabout (_x select 0) <= 0.5) then{ _air = _air - [_x]};}foreach _air; _units = [_grpid, _units, _air, false] call MON_selectvehicles; }; sleep 0.05; if ( (count _units) > 1) then { _vehicles = [_npc,200,true] call MON_NearestsLandCombat; {if (_npc knowsabout(_x select 0) <= 0.5) then{ _vehicles = _vehicles - [_x]};}foreach _vehicles; _units = [_grpid, _units, _vehicles, false] call MON_selectvehicles; }; sleep 0.05; if ( (count _units) > 0) then { _vehicles = [_npc,200] call MON_NearestsLandTransports; {if (_npc knowsabout (_x select 0) <= 0.5) then{ _vehicles = _vehicles - [_x]};}foreach _vehicles; _units = [_grpid, _units, _vehicles, false] call MON_selectvehicles; }; sleep 0.05; if ( (count _units) > 0 && (count _vehicles) > 0) then { sleep 1; _vehicles = _vehicles + _air; _units = [_grpid, _units, _vehicles, true] call MON_selectvehicles; }; sleep 0.05; _unitsIn = _unitsIn - _units; _unitsIn; //sleep 0.05; }; //Funcin que busca vehiculos cercanos y hace entrar a las unidades del lider //Parmeters: [_grpid,_npc] // <- _grpid: id of group to assign to vehicle // <- _npc: lider // -> _getin: true if any getin MON_GetIn_NearestCombat = { private["_vehicles","_npc","_units","_unitsIn","_grpid","_getin","_dist","_all"]; _grpid = _this select 0; _npc = _this select 1; _dist = _this select 2; _all = _this select 3; _vehicles=[[]]; _units = []; _unitsIn = []; _getin=false; if (leader _npc == _npc) then { _units = units _npc; } else { _units = _units + [_npc]; }; { if ( (_x!= vehicle _x && !((vehicle _x) iskindof "StaticWeapon" )) || !(_x iskindof "Man") || !alive _x || !canmove _x || !canstand _x) then {_units = _units-[_x];}; }foreach _units; //If suficient units leader will not get in if (!all) then { if (count _units > 2 ) then {_units = _units - [leader _npc]}; }; _unitsIn = _units; //We need 2 units available if not any leave vehicle to another squad if ( (count _units) > 1) then { _vehicles = [_npc,_dist,_all] call MON_NearestsAirCombat; {if (_npc knowsabout (_x select 0) <= 0.5) then{ _vehicles = _vehicles - [_x]};}foreach _vehicles; _units = [_grpid, _units, _vehicles, false] call MON_selectvehicles; }; sleep 0.05; if ( (count _units) > 1) then { _vehicles = [_npc,_dist,_all] call MON_NearestsLandCombat; {if (_npc knowsabout(_x select 0) <= 0.5) then{ _vehicles = _vehicles - [_x]};}foreach _vehicles; _units = [_grpid, _units, _vehicles, false] call MON_selectvehicles; }; _unitsIn = _unitsIn - _units; _unitsIn; }; //Funcin que busca vehiculos cercanos y hace entrar a las unidades del lider //Parmeters: [_grpid,_npc] // <- _grpid: id of group to assign to vehicle // <- _npc: lider // -> _getin: true if any getin MON_GetIn_NearestBoat = { private["_vehicles","_npc","_units","_unitsIn","_grpid","_getin","_dist"]; _grpid = _this select 0; _npc = _this select 1; _dist = _this select 2; _vehicles=[[]]; _units = []; _unitsIn = []; _getin=false; if (leader _npc == _npc) then { _units = units _npc; } else { _units = _units + [_npc]; }; { if ( (_x!= vehicle _x && !((vehicle _x) iskindof "StaticWeapon" )) || !(_x iskindof "Man") || !alive _x || !canmove _x || !canstand _x) then {_units = _units-[_x];}; }foreach _units; _unitsIn = _units; //We need 2 units available if not any leave vehicle to another squad if ( (count _units) > 0) then { _vehicles = [_npc,_dist] call MON_Nearestsboats; {if (_npc knowsabout (_x select 0) <= 0.5) then{ _vehicles = _vehicles - [_x]};}foreach _vehicles; _units = [_grpid, _units, _vehicles, false] call MON_selectvehicles; }; if ( (count _units) > 1 && (count _vehicles) > 0) then { sleep 1; _units = [_grpid, _units, _vehicles, true] call MON_selectvehicles; }; _unitsIn = _unitsIn - _units; _unitsIn; }; //Funcin que busca staticos cercanos y hace entrar a las unidades del lider //Parmeters: [_grpid,_npc] // <- _grpid: id of group to assign to vehicle // <- _npc: lider // -> _getin: true if any getin MON_GetIn_NearestStatic = { private["_vehicles","_npc","_units","_unitsIn","_grpid","_getin","_count"]; _grpid = _this select 0; _npc = _this select 1; _count = 0; _distance = 100; if ((count _this) > 2) then {_distance = _this select 2;}; _vehicles=[]; _units = []; _unitsIn = []; _getin=false; //Buscamos staticos cerca _vehicles = [_npc,_distance] call MON_NearestsStaticWeapons; if ( count _vehicles == 0) exitwith {_unitsIn;}; if (leader _npc == _npc) then { _units = (units _npc) - [_npc]; } else { _units = _units + [_npc]; }; //Solo tomamos las unidades vivas y que no estn en vehiculo { if ( (_x iskindof "Man") && _x == vehicle _x && alive _x && canmove _x && canstand _x) then { _unitsIn = _unitsIn + [_x]; }; }foreach _units; //Intentamos tomar solo las que estn disponibles _units = []; { if (unitready _x) then { _units = _units + [_x]; }; }foreach _unitsin; //Si hay unidades disponibles las usamos if (count _units > 0) then { _unitsIn = _units; }; //if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: Found %2 estatic weapons %3 men available",_grpid,count _vehicles, count _unitsIn]}; _units = _unitsIn; if ( count _unitsIn > 0) then { _units = [_grpid, _units, _vehicles, true] call MON_selectvehicles; }; _unitsIn = _unitsIn - _units; _unitsIn; }; //Function to assign units to vehicles //Parmeters: [_grpid,_unitsin,_vehicle] // <- _grpid: id of group to assign to vehicle // <- _units: array of units to getin // <- _vehicles: array of vehicles to use // -> _untis: array of units getin MON_selectvehicles = { private["_vehicles","_emptypositions","_units","_unitsIn","_i","_grpid","_vehgrpid","_unit","_wp","_any","_index","_cargo"]; _grpid = _this select 0; _units = _this select 1; _vehicles = _this select 2; _any = _this select 3; //meter en cualquier vehiculo _wp = []; _vehicle = []; _unitsIn = []; _emptypositions = 0; _i = 0; _vehgrpid = 0; _unit = objnull; _index = 0; _cargo = []; { if ((count _units) == 0 ) exitwith {}; _vehicle = _x select 0 ; _emptypositions = _x select 1; _unitsIn = []; _i = 0; _vehgrpid = _vehicle getvariable ("UPSMON_grpid"); _cargo = _vehicle getvariable ("UPSMON_cargo"); if ( isNil("_vehgrpid") ) then {_vehgrpid = 0;}; if ( isNil("_cargo") ) then {_cargo = [];}; //Asignamos el vehiculo a a la escuadra si contiene las posiciones justas if (_vehgrpid == 0) then { _vehicle setVariable ["UPSMON_grpid", _grpid, false]; _vehicle setVariable ["UPSMON_cargo", _unitsIn, false]; _vehgrpid = _grpid; }; { if (!alive _x || !canmove _x) then {_cargo = _cargo - [_x]; }; }foreach _cargo; _emptypositions = _emptypositions - (count _cargo - count ( crew _vehicle) ); //if (KRON_UPS_Debug>0) then {player sidechat format["%1 %2 positions=%3 cargo=%4 crew=%5",_grpid, typeof _vehicle, _emptypositions, count _cargo,count (crew _vehicle)]}; //ahora buscamos en cualquier vehiculo if ( _vehgrpid == _grpid || (_emptypositions > 0 && _any)) then { while {_i < _emptypositions && _i < count _units} do { _unit = _units select _i; _unitsIn = _unitsIn + [_unit]; _i = _i + 1; }; _units = _units - _unitsIn; if ( (count _unitsIn) > 0) then { //Metemos las unidades en el vehiculo [_grpid,_unitsIn,_vehicle] spawn MON_UnitsGetIn; if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: Get in %2 %3 units of %4 available",_grpid,typeof _vehicle,count _unitsIn,_emptypositions]}; //if (KRON_UPS_Debug>0 ) then {diag_log format["%1: Moving %3 units into %2 with %4 positions",_grpid,typeof _vehicle,count _unitsIn,_emptypositions]}; }; }; _index = _index + 1; sleep 0.05; } foreach _vehicles; _units; }; //Funcion que mete la tropa en el vehiculo //Parmeters: [_grpid,_unitsin,_vehicle] // <- _grpid: id of group to assign to vehicle // <- _unitsin: array of units to getin // <- _vehicle MON_UnitsGetIn = { private["_grpid","_vehicle","_npc","_driver","_gunner", "_unitsin", "_units" , "_Commandercount","_Drivercount","_Gunnercount","_cargo", "_Cargocount","_emptypositions","_commander","_vehgrpid","_cargo"]; _grpid = _this select 0; _unitsin = _this select 1; _vehicle = _this select 2; _units = _unitsin; _driver = objnull; _gunner = objnull; _commander = objnull; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; _cargo = []; _Cargocount = (_vehicle) emptyPositions "Cargo"; _Gunnercount = (_vehicle) emptyPositions "Gunner"; _Commandercount = (_vehicle) emptyPositions "Commander"; _Drivercount = (_vehicle) emptyPositions "Driver"; //Obtenemos el identificador del vehiculo _vehgrpid = _vehicle getvariable ("UPSMON_grpid"); _cargo = _vehicle getvariable ("UPSMON_cargo"); if ( isNil("_vehgrpid") ) then {_vehgrpid = 0;}; if ( isNil("_cargo") ) then {_cargo = [];}; _cargo = _cargo - _unitsin; //Para evitar duplicados _cargo = _cargo + _unitsin; //Aadimos a la carga _vehicle setVariable ["UPSMON_cargo", _cargo, false]; //Hablitamos a la IA para entrar en el vehiculo { [_x,0] call MON_dostop; if ("StaticWeapon" countType [vehicle (_x)]>0) then { _x spawn MON_doGetOut; }; unassignVehicle _x; _x spawn MON_Allowgetin; }foreach _units; //Assigned to the leader as commander or cargo { if ( _vehgrpid == _grpid && _x == leader _x && _Commandercount > 0 ) exitwith { _Commandercount = 0; _commander = _x; _commander assignAsCommander _vehicle; _units = _units - [_x]; [_x] orderGetIn true; }; if ( _x == leader _x && _Cargocount > 0 ) exitwith { _x assignAsCargo _vehicle; _units = _units - [_x]; _Cargocount = _Cargocount - 1; [_x] orderGetIn true; }; }foreach _units; //if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: _vehgrpid %2 ,_Gunnercount %3, %4",_grpid,_vehgrpid,_Gunnercount,count _units]}; //Si el vehiculo pertenece al grupo asignamos posiciones de piloto, sin solo de carga if ( _vehgrpid == _grpid ) then { //Asignamos el conductor if ( _Drivercount > 0 && count (_units) > 0 ) then { _driver = _units select (count _units - 1); [_driver,_vehicle,0] spawn MON_assignasdriver; _units = _units - [_driver]; }; //Asignamos el artillero if ( _Gunnercount > 0 && count (_units) > 0 ) then { _gunner = [_vehicle,_units] call MON_getNearestSoldier; [_gunner,_vehicle] spawn MON_assignasgunner; _units = _units - [_gunner]; }; }; //if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: _vehgrpid=%2 units=%4",_grpid,_vehgrpid,_cargocount,count _units]}; //Movemos el resto como carga if ( _Cargocount > 0 && count (_units) > 0 ) then { { _x assignAsCargo _vehicle; [_x] orderGetIn true; sleep 0.05; } forEach _units; }; { [_x] spawn MON_avoidDissembark; } forEach _unitsin - [_driver] - [_gunner] -[_commander]; }; MON_getNearestSoldier = { private["_units","_obj","_near"]; _obj = _this select 0; _units = _this select 1; _near = objnull; { if (isnull _near) then { _near = _x; } else { if ( _x distance _obj < _near distance _obj ) then {_near = _x;}; }; }foreach _units; _near; }; MON_avoidDissembark = { private["_npc","_vehicle","_timeout"]; _npc = _this select 0; _vehicle = vehicle _npc ; _timeout = 120; _timeout = time + _timeout; while {_npc == vehicle _npc && alive _npc && canmove _npc && time < _timeout} do { sleep 1; }; if (!alive _npc || !canmove _npc || time >= _timeout || driver vehicle _npc == _npc) exitwith{}; _npc stop true; while {_npc != vehicle _npc && alive _npc && canmove _npc} do {sleep 1;}; _npc stop false; sleep 0.5; if (!alive _npc || !canmove _npc) exitwith{}; }; //Funcin que devuelve un vehiculo de transporte cercano //Parmeters: [_npc] // <- _npc: object for position search // -> _vehicle: vehicle MON_NearestLandTransport = { private["_vehicle","_npc","_transportSoldier","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount"]; _npc = _this; _OCercanos = []; _transportSoldier = 0; _vehicle = objnull; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Car","TANK","Truck","Motorcycle"] , 150]; { _Cargocount = (_x) emptyPositions "Cargo"; _Gunnercount = (_x) emptyPositions "Gunner"; _Commandercount = (_x) emptyPositions "Commander"; _Drivercount = (_x) emptyPositions "Driver"; _transportSoldier = _Cargocount + _Gunnercount + _Commandercount + _Drivercount; if (!locked _x && canMove _x && _transportSoldier >= count (units _npc) && !(typeof _x in MON_bugged_vehicles) && (_drivercount > 0 || side _npc == side _x )) exitwith {_vehicle = _x;}; }foreach _OCercanos; _vehicle; }; //Funcin que devuelve un array con los vehiculos terrestres ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_NearestsLandTransports = { private["_vehicles","_npc","_emptypositions","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount","_distance"]; _npc = _this select 0; _distance = _this select 1; _OCercanos = []; _emptypositions = 0; _vehicles = []; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Car","TANK","Truck","Motorcycle"] , _distance]; { _Cargocount = (_x) emptyPositions "Cargo"; _Gunnercount = (_x) emptyPositions "Gunner"; _Commandercount = (_x) emptyPositions "Commander"; _Drivercount = (_x) emptyPositions "Driver"; _emptypositions = _Cargocount + _Gunnercount + _Commandercount + _Drivercount; if (!locked _x && _emptypositions > 0 && canMove _x && !(typeof _x in MON_bugged_vehicles) && (_drivercount > 0 || side _npc == side _x )) then { _vehicles = _vehicles + [[_x,_emptypositions]];}; }foreach _OCercanos; _vehicles; }; //Funcin que devuelve un array con los vehiculos terrestres ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_NearestsLandCombat = { private["_vehicles","_npc","_emptypositions","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount","_distance","_all"]; _npc = _this select 0; _distance = _this select 1; _all = _this select 2; _OCercanos = []; _emptypositions = 0; _vehicles = []; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Car","TANK","Truck","Motorcycle"] , _distance]; { if (_all) then { _Cargocount = (_x) emptyPositions "Cargo"; }; _Gunnercount = (_x) emptyPositions "Gunner"; _Drivercount = (_x) emptyPositions "Driver"; _Commandercount = (_x) emptyPositions "Commander"; _emptypositions = _Cargocount + _Gunnercount + _Commandercount + _Drivercount; if (!locked _x && _Gunnercount > 0 && canMove _x && !(typeof _x in MON_bugged_vehicles) && (_drivercount > 0 || side _npc == side _x )) then { _vehicles = _vehicles + [[_x,_emptypositions]];}; }foreach _OCercanos; _vehicles; }; //Funcin que devuelve un array con los vehiculos aereos ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_NearestsAirTransports = { private["_vehicles","_npc","_emptypositions","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount","_distance"]; _npc = _this select 0; _distance = _this select 1; _OCercanos = []; _emptypositions = 0; _vehicles = []; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Helicopter"] , _distance]; { _Cargocount = (_x) emptyPositions "Cargo"; _Gunnercount = (_x) emptyPositions "Gunner"; _Commandercount = (_x) emptyPositions "Commander"; _Drivercount = (_x) emptyPositions "Driver"; _emptypositions = _Cargocount + _Gunnercount + _Commandercount + _Drivercount; if (!locked _x && _emptypositions > 0 && canMove _x && !(typeof _x in MON_bugged_vehicles) && (_drivercount > 0 || side _npc == side _x )) then { _vehicles = _vehicles + [[_x,_emptypositions]];}; }foreach _OCercanos; _vehicles; }; //Function that returns an array with the closest air vehicles //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_NearestsAirCombat = { private["_vehicles","_npc","_emptypositions","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount","_distance","_all"]; _npc = _this select 0; _distance = _this select 1; _all = _this select 2; _OCercanos = []; _emptypositions = 0; _vehicles = []; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Helicopter"] , _distance]; { if (_all) then { _Cargocount = (_x) emptyPositions "Cargo"; }; // _Gunnercount = [_x] call RAF_numberOfTurrets; _Gunnercount = (_x) emptyPositions "Gunner"; _Drivercount = (_x) emptyPositions "Driver"; _Commandercount = (_x) emptyPositions "Commander"; _emptypositions = _Cargocount + _Gunnercount + _Commandercount + _Drivercount; if (!locked _x && _Gunnercount > 0 && canMove _x && !(typeof _x in MON_bugged_vehicles) && (_drivercount > 0 || side _npc == side _x )) then { _vehicles = _vehicles + [[_x,_emptypositions]];}; }foreach _OCercanos; _vehicles //return }; //Funcin que devuelve un array con los vehiculos staticos ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_NearestsStaticWeapons = { private["_vehicles","_npc","_emptypositions","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount","_distance"]; _npc = _this select 0; _distance = _this select 1; _OCercanos = []; _emptypositions = 0; _vehicles = []; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["StaticWeapon"] , _distance]; { _Gunnercount = (_x) emptyPositions "Gunner"; _emptypositions = _Gunnercount; if (!locked _x && alive _x && _emptypositions > 0 && !(typeof _x in MON_bugged_vehicles) ) then { _vehicles = _vehicles + [[_x,_emptypositions]];}; }foreach _OCercanos; _vehicles //return }; //Funcin que devuelve un array con los vehiculos marinos ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_Nearestsboats = { private["_vehicles","_npc","_emptypositions","_OCercanos","_driver", "_Commandercount","_Drivercount","_Gunnercount","_Cargocount","_distance"]; _npc = _this select 0; _distance = _this select 1; _OCercanos = []; _emptypositions = 0; _vehicles = []; _Cargocount = 0; _Gunnercount = 0; _Commandercount = 0; _Drivercount = 0; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Ship"] , _distance]; { _Cargocount = (_x) emptyPositions "Cargo"; _Gunnercount = (_x) emptyPositions "Gunner"; _Commandercount = (_x) emptyPositions "Commander"; _Drivercount = (_x) emptyPositions "Driver"; _emptypositions = _Cargocount + _Gunnercount + _Commandercount + _Drivercount; if (!locked _x && _emptypositions > 0 && canMove _x && (_drivercount > 0 || side _npc == side _x )) then { _vehicles = _vehicles + [[_x,_emptypositions]];}; }foreach _OCercanos; _vehicles //return }; //Function to delay the taking of the steering wheel and the vehicle will not have time to rise and MON_assignasdriver = { private["_vehicle","_driver","_wait"]; _driver = _this select 0; _vehicle = _this select 1; _wait = _this select 2; [_driver,_wait] spawn MON_dostop; sleep _wait; unassignVehicle _driver; _driver assignasdriver _vehicle; [_driver] orderGetIn true; //if (KRON_UPS_Debug>0) then {player sidechat format["%1: assigning to driver of %2 ",_driver, typeof _vehicle]}; }; MON_assignasgunner = { private["_vehicle","_gunner","_dist"]; _gunner = _this select 0; _vehicle = _this select 1; _dist=0; _gunner assignasgunner _vehicle; [_gunner] orderGetIn true; waituntil { _gunner != vehicle _gunner || !alive _gunner || !canmove _gunner ||!alive _vehicle || !canfire _vehicle}; if ( alive _gunner && alive _vehicle && canmove _gunner && canfire _vehicle) then { _dist = _gunner distance _vehicle; if (_dist < 3) then { _gunner moveInTurret [_vehicle, [0]] ; }; }; }; //Allow getin MON_Allowgetin = { //Hablitamos a la IA para entrar en el vehiculo [_this] allowGetIn true; }; //If every on is outside, make sure driver can move MON_checkleaveVehicle={ _npc = _this select 0; _vehicle = _this select 1; _driver = _this select 2; _in = false; //Take time to go all units sleep 5; { if (_x != vehicle _x) then {_in = true}; }foreach units _npc; // if no one is inside if (!_in) then { _driver enableAI "MOVE"; sleep 1; _driver stop false; sleep 1; _driver leaveVehicle _vehicle; sleep 1; }; }; //Function for order a unit to exit if no gunner //Parmeters: [_npc] // <- _npc: MON_GetOut = { private["_vehicle","_npc","_getout" ,"_gunner"]; _npc = _this; _vehicle = vehicle (_npc); _gunner = objnull; _gunner = gunner _vehicle; sleep 0.05; if (!alive _npc) exitwith{}; //If no leave the vehicle gunner if ( isnull _gunner || !alive _gunner || !canmove _gunner || (_gunner != _npc && driver _vehicle != _npc && commander _vehicle != _npc) ) then { [_npc] allowGetIn false; _npc spawn MON_doGetOut; unassignVehicle _npc; //sleep 0.2; }; }; //Function for order a unit to exit //Parmeters: [_npc] // <- _npc: MON_doGetOut = { private["_vehicle","_npc","_getout" ,"_gunner","_groupOne","_timeout","_dir"]; _npc = _this; _vehicle = vehicle (_npc); sleep 0.05; if (_vehicle == _npc) exitwith{}; //Wait until vehicle is stopped waituntil {!alive _npc || !canmove _npc || !alive _vehicle || ( (abs(velocity _vehicle select 0)) <= 0.1 && (abs(velocity _vehicle select 1)) <= 0.1 ) || ( _vehicle iskindof "Air" && ((position _vehicle) select 2) <= 1)}; if (!alive _npc || !canmove _npc) exitwith{}; unassignVehicle _npc; _npc action ["getOut", _vehicle]; doGetOut _npc; [_npc] allowGetIn false; nul = [_npc] spawn MON_cancelstop; waituntil {!alive _npc || !canmove _npc || vehicle _npc == _npc}; if (!alive _npc || !canmove _npc) exitwith{}; if (leader _npc != _npc) then { //Moves out with dispersion of 45 _dir = getDir _npc; _dir = _dir + 45 - (random 90); nul = [_npc,25,_dir] spawn MON_domove; //if (KRON_UPS_Debug>0 ) then { player globalchat format["%1 Moving away from %2 %2",_npc, typeof _vehicle,_dir];}; }; }; //Function for exiting of heli //Parmeters: [_heli,_targetPos,_atdist] // <- _heli: // <- _targetPos: position for exiting(if no waypoint used) // <- _atdist: distance for doing paradrop or landing MON_doParadrop = { if (KRON_UPS_Debug>0 ) then { player globalchat format["Mon_doParadrop started"];}; private["_heli","_npc","_getout" ,"_gunner","_targetpos","_helipos","_dist","_index","_grp","_wp","_targetPosWp","_targetP","_units","_crew","_timeout","_jumpers"]; _heli = _this select 0; _targetPos = [0,0]; _atdist = 250; _flyingheigh = KRON_UPS_flyInHeight; _landonBeh = ["CARELESS","SAFE"]; _timeout=0; //Gets optional parameters if ((count _this) > 1) then {_targetPos = _this select 1;}; if ((count _this) > 2) then {_atdist = _this select 2;}; if ((count _this) > 3) then {_flyingheigh = _this select 3;}; _helipos = [0,0]; _targetposWp = [0,0]; _gunner = objnull; _gunner = gunner _heli; _dist = 1000000; _index = 0; _grp = GRPNULL; _wp = []; _units =[]; _crew =[]; waituntil {count crew _heli > 0 || !alive _heli || !canmove _heli}; _grp = group ((crew _heli) select 0); _npc = leader ((crew _heli) select 0); _units = units _npc; while { (_dist >= _atdist || _dist < 10) && alive _heli && canmove _heli && count crew _heli > 0} do { _heli flyInHeight _flyingheigh; /* //Take last waypoint _index = (count waypoints _grp) - 1; _wp = [_grp,_index]; _targetPosWp = waypointPosition _wp; if (format ["%1", _targetPosWp] == "[0,0,0]") then {_targetPosWp = _targetPos}; */ _targetPosWp = _targetPos; _helipos = position _heli; _dist = round([_helipos,_targetPosWp] call KRON_distancePosSqr); //if (KRON_UPS_Debug>0 ) then {player globalchat format["Goiing to drop zone _dist=%1, _atdist=%2", _dist, _atdist ];}; sleep 1; }; if (!alive _heli || count crew _heli == 0) exitwith{}; _crew = crew _heli; //Jump if (((position _heli) select 2) >= 90 && !surfaceIsWater position _heli && (!(toupper (behaviour _npc) IN _landonBeh) || (random 100) < 20)) then { //moving hely for avoiding stuck if (KRON_UPS_Debug>0 ) then {_heli globalchat format["doing paradrop high %1 dist=%2",(position _heli) select 2,_dist,_atdist];}; _jumpers = [_heli] call R_FN_unitsInCargo; //Do paradrop { if( (assignedVehicleRole _x) select 0 == "Cargo")then { unassignVehicle _x; _x action ["EJECT", _heli] ; _x stop false; [_x] allowGetIn false; [_x] spawn MON_ACE_Watersurvival; }; sleep 0.5; } forEach crew _heli; [_heli,700] spawn MON_domove; //Clear Hely vars _heli setVariable ["UPSMON_grpid", 0, false]; _heli setVariable ["UPSMON_cargo", [], false]; // set orginal fly hight // _flyingheigh = KRON_UPS_flyInHeight; // _heli flyInHeight _flyingheigh; //Waits until all units are down _timeout = time + 60; { waituntil {(_x == vehicle _x ) || !alive _x || !canmove _x || isnull _x || time > _timeout}; //Fix bug of ACE that sometimes AI gets in stand animation //_x switchMove "AmovPercMsprSlowWrflDf_AmovPpneMstpSrasWrflDnon_2"; } foreach _jumpers; if ( _npc == vehicle _npc) then { { if (alive _x && canmove _x) then { [_x] dofollow _npc; }; } foreach units _npc; }; //if (KRON_UPS_Debug>0) then {player globalchat format["%1 after paradrop",_npc]}; if (alive _npc && canmove _npc) then { _npc move _targetPosWp; }else{ {if (alive _x && canmove _x) exitwith { _x move _targetPosWp;}}foreach _crew; }; //If only pilot land heli if (count crew _heli <=1) then { [_heli] spawn MON_landHely; }; } else { //land if ( ((position _heli) select 2) >= 60 && !surfaceIsWater _helipos && ((random 100)<20 || !canmove _heli || (toupper (behaviour _npc) IN _landonBeh))) then { [_heli] spawn MON_landHely; } else { If (alive _heli && canmove _heli && count crew _heli > 0) then { if (KRON_UPS_Debug>0 ) then {_heli globalchat format["%1 failed paradrop, trying another time",typeof _heli];}; //Try another time _heli flyInHeight _flyingheigh; sleep 3; [_heli, _targetPos, _atdist*1.5,_flyingheigh] spawn MON_doParadrop; }; }; }; }; //Lands hely MON_landHely = { private["_heli","_npc","_crew","_NearestEnemy","_timeout","_landing","_targetpos","_jumpers"]; _heli = _this select 0; _crew =[]; _targetpos=[0,0]; _timeout = 0; _landing = false; sleep 0.05; if (!alive _heli || !canmove _heli ) exitwith{}; _crew = crew _heli; _npc = leader (_crew select 0); //Checks hely is already landing _landing = _heli getVariable "UPSMON_landing"; if (isnil ("_landing")) then {_landing=false; _heli setVariable ["UPSMON_landing", false, false];}; if (_landing) exitwith {}; //Orders to land heli _heli land "LAND"; if (KRON_UPS_Debug>0 ) then {player globalchat format["%1 is landing",typeof _heli];}; //Puts a mark for knowing hely is landing _heli setVariable ["UPSMON_landing", true, false]; //Waits for land position waituntil {!alive _heli || toUpper(landResult _heli) != "NOTREADY" }; if (alive _heli && (toUpper(landResult _heli) == "NOTFOUND")) exitwith { if (KRON_UPS_Debug>0 ) then { player globalchat format["%1 no landing zone, doing paradrop",typeof _heli];}; _heli setVariable ["UPSMON_landing", false, false]; [_heli] spawn MON_doparadrop; }; //1rt try-Waits until velocity and heigh are good for getting out _timeout = 60 + time; waituntil {!alive _heli || time > _timeout || ((abs(velocity _heli select 2)) <= 1 && ((position _heli) select 2) <= 0.7)}; //2nd try-Waits until velocity and heigh are good for getting out if (((position _heli) select 2) > 2 && ((position _heli) select 2) < 30 && !surfaceiswater position _heli) then { _heli land "LAND"; _timeout = 30 + time; waituntil {!alive _heli || time > _timeout || ((position _heli) select 2) > 30 || ( (abs(velocity _heli select 2)) <= 1 && ((position _heli) select 2) <= 0.7)}; //Failed landing doing paradrop if ( ((position _heli) select 2) > 30) exitwith { if (KRON_UPS_Debug>0 ) then { player globalchat format["%1 landing timeout, doing paradrop",typeof _heli];}; _heli setVariable ["UPSMON_landing", false, false]; sleep 5; [_heli] spawn MON_doparadrop; }; }; //Chechs if alive before continuing if (!alive _heli) exitwith{}; //If there is pilot and gunner, get out only cargo if ((!isnull gunner _heli) && (!isnull driver _heli)) then { _jumpers = [_heli] call R_FN_unitsInCargo; } else { _jumpers = crew _heli; }; //dogetout each of _jumpers { _x spawn MON_doGetOut; sleep 0.5; } forEach _jumpers; _timeout = 20 + time; //Waits until all getout of heli { waituntil {vehicle _x == _x || !canmove _x || !alive _x || movetofailed _x || time > _timeout }; } forEach _jumpers; sleep 1; _heli land "NONE"; sleep 1; [_heli,700] spawn MON_domove; // If leader alive sets combat mode if (alive _npc && canmove _npc) then { //Gets nearest known enemy for putting in combat mode _NearestEnemy = _npc findNearestEnemy _npc; if (!isnull _NearestEnemy ) then { _npc setBehaviour "AWARE"; _groupOne = group _npc; _groupOne setFormation "DIAMOND"; }; //Moves to current target Position _grpid = _npc getvariable "UPSMON_grpid"; if !(isnil "_grpid") then { _targetpos =(KRON_targetsPos select _grpid); _npc move _targetpos; if (KRON_UPS_Debug>0 ) then { player globalchat format["%1 landed, moving to %2 %3",_grpid,_targetpos,count KRON_targetsPos];}; }; }; //Quitamos el id al vehiculo para que pueda ser reutilizado _heli setVariable ["UPSMON_grpid", 0, false]; _heli setVariable ["UPSMON_cargo", [], false]; _heli setVariable ["UPSMON_landing", false, false]; }; //Controls that heli not stoped flying MON_HeliStuckcontrol = { private["_heli","_landing","_stuckcontrol","_dir1","_targetPos","_lastpos"]; _heli = _this select 0; _landing = false; _stuckcontrol = false; _targetPos=[0,0,0]; _dir1 = 0; sleep 0.05; if ( !alive _heli || !canmove _heli ) exitwith{}; //Checks stuckcontrol not active _stuckcontrol = _heli getVariable "UPSMON_stuckcontrol"; if (isnil ("_stuckcontrol")) then {_stuckcontrol=false}; if (_stuckcontrol) exitwith {}; _heli setVariable ["UPSMON_stuckcontrol", true, false]; //if (KRON_UPS_Debug>0 ) then {player globalchat format["%1 stuck control begins",typeof _heli];}; //Stuck loop control while {(alive _heli) && (count crew _heli) > 0 } do { sleep 5; if ((abs(velocity _heli select 0)) <= 5 && (abs(velocity _heli select 1)) <= 5 && (abs(velocity _heli select 2)) <= 5 && ((position _heli) select 2) >= 30) then { _landing = _heli getVariable "UPSMON_landing"; if (isnil ("_landing")) then {_landing=false;}; if (!_landing) then { //moving hely for avoiding stuck [_heli,800] spawn MON_domove; if (KRON_UPS_Debug>0 ) then {player GLOBALCHAT format["%1 stucked at %2m height, moving",typeof _heli,(position _heli) select 2];}; sleep 25; }; }; }; //if (KRON_UPS_Debug>0 ) then {player globalchat format["%1 exits from stuck control",typeof _heli];}; _heli setVariable ["UPSMON_stuckcontrol", false, false]; }; //Function that checks is gunner is alive, if not moves a cargo MON_Gunnercontrol = { private["_vehicle","_gunnercontrol","_hasgunner","_crew","_crew2"]; _vehicle = _this select 0; _targetPos=[0,0,0]; _dir1 = 0; _gunnercontrol = false; _hasgunner = (_vehicle) emptyPositions "Gunner" > 0 || !isnull gunner _vehicle; _crew = []; _crew2 = []; //Without driver and gunner sleep 0.05; if ( !alive _vehicle || !canmove _vehicle ) exitwith{}; //Checks stuckcontrol not active _gunnercontrol = _vehicle getVariable "UPSMON_gunnercontrol"; if (isnil ("_gunnercontrol")) then {_gunnercontrol=false}; if (_gunnercontrol) exitwith {}; _vehicle setVariable ["UPSMON_gunnercontrol", true, false]; _crew = crew _vehicle; //gunner and driver loop control while { alive _vehicle && canmove _vehicle && count _crew > 0} do { _crew = crew _vehicle; { if (!canmove _x || !alive _x) then {_crew = _crew -[_x];}; }foreach _crew; //Driver control if ((isnull (driver _vehicle) || !alive (driver _vehicle) || !canmove (driver _vehicle)) && count _crew > 0) then { _crew2 = _crew - [gunner _vehicle]; if (count _crew2 > 0) then { (_crew2 select (count _crew2 - 1)) spawn MON_movetodriver; }; }; //Gunner control if ( _hasgunner && (isnull (gunner _vehicle) || !alive (gunner _vehicle) || !canmove (gunner _vehicle)) && count _crew > 1) then { _crew2 = _crew - [driver _vehicle]; if (count _crew2 > 0) then { (_crew2 select (count _crew2 - 1)) spawn MON_movetogunner; }else{ (_crew select 0) spawn MON_movetogunner; }; }; sleep 20; //if (KRON_UPS_Debug>0 ) then {player globalchat format["%1 crew=%2",typeof _vehicle, count _crew];}; }; //if (KRON_UPS_Debug>0 ) then {player globalchat format["%1 exits from gunner control",typeof _vehicle];}; _vehicle setVariable ["UPSMON_gunnercontrol", false, false]; }; //Mueve a todo el grupo adelante MON_move = { private["_npc","_dir1","_targetPos","_dist"]; _npc = _this select 0; _dist = _this select 1; sleep 0.05; if (!alive _npc || !canmove _npc ) exitwith{}; _dir1 = getDir _npc; _targetPos = [position _npc,_dir1, _dist] call MON_GetPos2D; _npc move _targetPos; }; //Mueve al soldado adelante MON_domove = { private["_npc","_dir1","_targetPos","_dist"]; _npc = _this select 0; _dist = _this select 1; if ((count _this) > 2) then {_dir1 = _this select 2;} else{_dir1 = getDir _npc;}; sleep 0.05; if (!alive _npc || !canmove _npc ) exitwith{}; _targetPos = [position _npc,_dir1, _dist] call MON_GetPos2D; //If position water and not boat not go if (surfaceIsWater _targetPos && !(_npc iskindof "boat" || _npc iskindof "air") ) exitwith {}; _npc domove _targetPos; }; //Funcin que detiene al soldado y lo hace esperar x segundos MON_doStop = { private["_sleep","_npc"]; _npc = _this select 0; _sleep = _this select 1; sleep 0.05; if (!alive _npc || !canmove _npc ) exitwith{}; if ( _sleep == 0 ) then {_sleep = 0.1}; //Restauramos valores por defecto de movimiento //_npc disableAI "MOVE"; dostop _npc ; sleep _sleep; [_npc] spawn MON_cancelstop; }; //Funcin que detiene al soldado y lo hace esperar x segundos MON_cancelstop = { private["_npc"]; _npc = _this select 0; _npc stop false; }; //Make grenade dodge animation MON_evadeGrenade = { if (!alive _this || (vehicle _this) != _this || !canmove _this) exitwith{}; _this playmovenow "AmovPercMstpSlowWrflDnon_ActsPpneMstpSlowWrflDr_GrenadeEscape"; sleep 8; if (!alive _this || (vehicle _this) != _this || !canmove _this) exitwith{}; _this switchmove "AmovPpneMstpSrasWrflDnon_AmovPpneMevaSlowWrflDr"; //croqueta _this playmovenow "AmovPpneMstpSrasWrflDnon"; //prone }; //Realiza la animacin de la croqueta MON_animCroqueta = { if (!alive _this || (vehicle _this) != _this || !canmove _this || !(_this iskindof "Man")) exitwith{}; if ((random 1)<=.50) then { _this switchmove "AmovPpneMstpSrasWrflDnon_AmovPpneMevaSlowWrflDl"; //croqueta } else { _this switchmove "AmovPpneMstpSrasWrflDnon_AmovPpneMevaSlowWrflDr"; //croqueta }; }; //Throw a grenade MON_throw_grenade = { private["_target","_npc"]; _npc = _this select 0; _target = _this select 1; sleep random 1.5; if (!alive _npc || (vehicle _npc) != _npc || !canmove _npc) exitwith{}; [_npc,_target] spawn MON_dowatch; sleep 0.1; // R_Functions [_npc] spawn R_ThrowSmoke; /* _npc addMagazine "SmokeShell"; _npc selectWeapon "throw"; sleep .1; _npc fire ["SmokeShellMuzzle","SmokeShellMuzzle","SmokeShell"]; */ }; //Establece el tipo de posicin MON_setUnitPos = { private["_pos","_npc"]; _npc = _this select 0; _pos = _this select 1; sleep 0.5; if (!alive _npc || !canmove _npc || _npc != vehicle _npc || !(_npc iskindof "Man")) exitwith{}; _npc setUnitPos _pos; sleep 1; }; //Establece el tipo de posicin MON_setUnitPosTime = { private["_pos","_npc"]; _npc = _this select 0; _pos = _this select 1; _time = _this select 2; if (!alive _npc || !canmove _npc) exitwith{}; _npc setUnitPos _pos; sleep _time; _npc setUnitPos "AUTO"; sleep 1; }; // Funcin para mirar en una direccin MON_dowatch = { private["_target","_npc"]; _npc = _this select 0; _target = _this select 1; if (!alive _npc) exitwith{}; _npc dowatch _target; sleep 1; }; //Funcin que mueve al soldado a la posicin de conductor //Parmeters: [_npc,_vehicle] // <- _npc: unit to move to driver pos // <- _vehicle MON_movetoDriver = { private["_vehicle","_npc"]; _npc = _this ; _vehicle = vehicle _npc; //Si est muerto if (vehicle _npc == _npc || !alive _npc || !canmove _npc || !(_npc iskindof "Man")) exitwith{}; if (isnull(driver _vehicle) || !alive(driver _vehicle) || !canmove(driver _vehicle)) then { //if (KRON_UPS_Debug>0) then {player sidechat format["%1: Moving to driver of %2 ",_npc,typeof _vehicle]}; _npc action ["getOut", _vehicle]; doGetOut _npc; WaitUntil {vehicle _npc==_npc || !alive _npc || !canmove _npc}; //Si est muerto if (!alive _npc || !canmove _npc) exitwith{}; unassignVehicle _npc; _npc assignasdriver _vehicle; _npc moveindriver _vehicle; }; }; //Funcin que mueve al soldado a la posicin de conductor //Parmeters: [_npc,_vehicle] // <- _npc: unit to move to driver pos // <- _vehicle MON_movetogunner = { private["_vehicle","_npc"]; _npc = _this ; _vehicle = vehicle _npc; sleep 0.05; //Si est muerto if (vehicle _npc == _npc || !alive _npc || !canmove _npc || !(_npc iskindof "Man")) exitwith{}; if (isnull(gunner _vehicle) || !alive(gunner _vehicle) || !canmove(gunner _vehicle)) then { if (KRON_UPS_Debug>0) then {player sidechat format["%1: Moving to gunner of %2 ",_npc,typeof _vehicle]}; _npc action ["getOut", _vehicle]; doGetOut _npc; WaitUntil {vehicle _npc==_npc || !alive _npc || !canmove _npc}; //Si est muerto if (!alive _npc || !canmove _npc) exitwith{}; unassignVehicle _npc; _npc assignasgunner _vehicle; _npc moveingunner _vehicle; }; }; //Funcin que retorna array de arrays con edificios y sus plantas //Parmeters: [_object,(_distance,_minfloors)] // <- _object: soldier to get near buildings // <- _distance: distance to search buildings (optional, 25 by default) // <- _minfloors: min floors of building (optional) if not especified min floors is 2 // -> [_bld,_bldpos] MON_GetNearestBuildings = { private ["_object","_altura","_pos","_bld","_bldpos","_posinfo","_minfloors","_OCercanos","_distance","_blds"]; _distance = 25; _minfloors = 2; _altura = 0; _blds = []; _object = _this select 0; if ((count _this) > 1) then {_distance = _this select 1;}; if ((count _this) > 2) then {_minfloors = _this select 2;}; _pos =0; _bld = objnull; _bldpos =0; _posinfo=[]; //La altura mnima es 2 porque hay muchos edificios q devuelven 2 de altura pero no se puede entrar en ellos. if ( minfloors == 0 ) then { minfloors = 2; }; // _posinfo: [0,0]=no house near, [obj,0]=house near, but no roof positions, [obj,pos]=house near, with roof pos //_posinfo= _object call MON_PosInfo; _OCercanos = nearestObjects [_object, ["house","building"] , _distance]; { _bldpos = _x call MON_BldPos; if ( _bldpos >= _minfloors && damage _x <= 0 ) then { _blds = _blds + [[_x,_bldpos]];}; //player sidechat format["%1 cerca de edificio con %2 plantas %5",typeof _object,_bldpos]; }foreach _OCercanos; _blds; }; //Function to move al units of squad to near buildings //Parmeters: [_npc,(_patrol,_minfloors)] // <- _npc: lider // <- _distance: distance to search buildings (optional, 25 by default) // <- _patrol: wheter must patrol or not MON_moveNearestBuildings = { private ["_npc","_altura","_pos","_bld","_bldpos","_posinfo","_blds","_distance","_cntobjs1","_bldunitin","_blddist","_patrol","_wait","_all"]; _distance = 30; _altura = 0; _patrol = false; _wait=60; _all = false; _npc = _this select 0; if ((count _this) > 1) then {_distance = _this select 1;}; if ((count _this) > 2) then {_patrol = _this select 2;}; if ((count _this) > 3) then {_wait = _this select 3;}; if ((count _this) > 4) then {_all = _this select 4;}; _pos =0; _bld = objnull; _bldpos =0; _cntobjs1=0; _bldunitsin=[]; _units=[]; _blds=[]; //If all soldiers move leader too if (_all) then { _units = (units _npc); }else{ _units = (units _npc) - [_npc]; }; sleep 0.05; { if (_x iskindof "Man" && unitReady _x && _x == vehicle _x && canmove _x && alive _x && canstand _x) then {_bldunitsin = _bldunitsin + [_x]} }foreach _units; if (count _bldunitsin == 0) exitwith {}; //Obtenemos los edificios cercanos al lider _blds = [_npc,_distance] call MON_GetNearestBuildings; if (count _blds==0) exitwith {}; //Movemos a la unidades a los edificios cercanos. [_bldunitsin, _blds, _patrol,_wait,_all] spawn MON_moveBuildings; }; //Function to move al units of squad to near buildings //Parmeters: [_npc,(_patrol,_minfloors)] // <- _units: array of units // <- _blds: array of buildingsinfo [_bld,pos] // <- _patrol: wheter must patrol or not // -> _bldunitsin: array of units moved to builidings MON_moveBuildings = { private ["_npc","_altura","_pos","_bld","_bldpos","_posinfo","_blds","_cntobjs1","_bldunitin","_blddist","_i","_patrol","_wait","_all","_minpos","_blds2"]; _patrol = false; _wait = 60; _minpos = 2; _all = false; _units = _this select 0; _blds = _this select 1; if ((count _this) > 2) then {_patrol = _this select 2;}; if ((count _this) > 3) then {_wait = _this select 3;}; if ((count _this) > 4) then {_all = _this select 4;}; if ((count _this) > 5) then {_minpos = _this select 5;}; _altura = 0; _pos =0; _bld = objnull; _bldpos =0; _cntobjs1=0; _bldunitsin=[]; _movein=[]; _blds2 =[]; //if (KRON_UPS_Debug>0) then {player globalchat format["MON_moveBuildings _units=%1 _blds=%2",count _units, count _blds]; }; //if (KRON_UPS_Debug>0) then {diag_log format["MON_moveBuildings _units=%1 _blds=%2",count _units, count _blds];}; { _bld = _x select 0; _bldpos = _x select 1; if ( _bldpos >= _minpos ) then { _cntobjs1 = 1; _movein = []; _i = 0; if (_patrol) then { if (_bldpos >= 8) then { _cntobjs1 = 2 }; } else { if (_bldpos >= 8) then { _cntobjs1 = round(random 3) + 1;}; }; //Buscamos una unidad cercana para recorrerlo { if (_x iskindof "Man" && unitReady _x && canmove _x && alive _x && vehicle _x == _x && _i < _cntobjs1) then{ _movein = _movein + [_x]; _i = _i + 1; }; } foreach _units; //if (KRON_UPS_Debug>0) then {player globalchat format["_units=%3 _bldunitsin %4 _movein=%1",_movein, typeof _bld, count _units, count _bldunitsin];} //if (KRON_UPS_Debug>0) then {diag_log format["_units=%3 _bldunitsin %4 _movein=%1 %2 %5",_movein, typeof _bld, count _units, count _bldunitsin,_x];}; if (count _movein > 0) then { _bldunitsin = _bldunitsin + _movein; _units = _units - _bldunitsin; if (_patrol) then { { [_x,_bld,_bldpos] spawn MON_patrolBuilding; }foreach _movein; } else { { _altura = floor(random(_bldpos)); if (_altura<2) then {_altura = _minpos}; [_x,_bld,_altura,_wait] spawn MON_movetoBuilding; }foreach _movein; }; }; }; if (count _units == 0) exitwith {}; }foreach _blds; //If need to enter all units in building and rest try with a superior lvl if ( _all && count _units > 0 ) then { _blds2 = []; _minpos = _minpos + 3; { if ( (_x select 1) >= _minpos) then { _blds2 = _blds2 + [_x]; }; }foreach _blds; //if (KRON_UPS_Debug>0) then {player globalchat format["MON_moveBuildings exit _units=%1 _blds=%2",count _units, count _blds2]; }; //if (KRON_UPS_Debug>0) then {diag_log format["MON_moveBuildings exit _units=%1 _blds=%2",count _units, count _blds2];}; if (count _blds2 > 0 ) then { [_units, _blds2, _patrol,_wait,_all,_minpos] call MON_moveBuildings; }; _bldunitsin = _bldunitsin + _units; }; _bldunitsin; }; //Function to move a unit to a position in a building //Parmeters: [_npc,(_patrol,_minfloors)] // <- _npc: soldier // <- _bld: building // <- _altura: building // <- _wait: time to wait in position MON_movetoBuilding = { private ["_npc","_altura","_bld","_wait","_dist","_retry","_soldiers"]; _wait = 60; _timeout = 120; _dist = 0; _retry = false; _npc = _this select 0; _bld = _this select 1; _altura = _this select 2; if ((count _this) > 3) then {_wait = _this select 3;}; //Si est en un vehiculo ignoramos la orden if (vehicle _npc != _npc || !alive _npc || !canmove _npc) exitwith{}; //Si ya est en un edificio ignoramos la orden _inbuilding = _npc getvariable ("UPSMON_inbuilding"); if ( isNil("_inbuilding") ) then {_inbuilding = false;}; if (_inbuilding) exitwith{}; _npc domove (_bld buildingPos _altura); _npc setVariable ["UPSMON_inbuilding", _inbuilding, false]; _npc setvariable ["UPSMON_buildingpos", nil, false]; _timeout = time + _timeout; //if (KRON_UPS_Debug>0) then {player globalchat format["%4|_bld=%1 | %2 | %3",typeof _bld, _npc, typeof _npc ,_altura];}; //if (KRON_UPS_Debug>0) then {diag_log format["%4|_bld=%1 | %2 | %3",typeof _bld, _npc, typeof _npc ,_altura];}; waitUntil {moveToCompleted _npc || moveToFailed _npc || !alive _npc || !canmove _npc || _timeout < time}; if (moveToCompleted _npc && alive _npc && canmove _npc) then { _dist = [position _npc,_bld buildingPos _altura] call KRON_distancePosSqr; _soldiers = [_npc,1] call MON_nearestSoldiers; //If more soldiers in same floor see to keep or goout. if (count _soldiers > 0) then { { if (!isnil{_x getvariable ("UPSMON_buildingpos")}) exitwith {_retry = true}; }foreach _soldiers; }; if (!_retry && _dist <= 2) then { _npc setvariable ["UPSMON_buildingpos", _altura, false]; sleep 0.1; [_npc,_wait] spawn MON_dostop; }; }; if (!alive _npc || !canmove _npc) exitwith{}; _npc setVariable ["UPSMON_inbuilding", false, false]; //Down one position. if (_retry ) then { _altura = _altura + 1; _bldpos = _bld call MON_BldPos; if (_altura <= _bldpos) then { [_npc,_bld,_altura] spawn MON_movetoBuilding; }; }; }; //Funcin para mover a una unidad al edificio ms cercano //Parmeters: [_npc,_bld,(_BldPos)] // <- _npc: soldier to move // <- _bld:building to patrol // <- _BldPos: positions of builiding (optional) MON_patrolBuilding = { private ["_npc","_bld","_bldpos","_posinfo","_minfloors","_OCercanos","_distance","_timeout","_pos","_inbuilding","_rnd","_NearestEnemy","_patrolto","_time"]; _bldpos = 0; _pos = 0; _timeout = 0; _i = 1; _inbuilding = false; _rnd = 0; _patrolto = 0; _NearestEnemy = objnull; _time = 0; _npc = _this select 0; _bld = _this select 1; if ((count _this) > 2) then {_bldpos = _this select 2;} else {_bldpos = _x call MON_BldPos;}; if (_i > _bldpos) then {_i = _bldpos}; _patrolto = round ( 10 + random (_bldpos) ); if (_patrolto > _bldpos) then {_patrolto = _bldpos}; //Si ya est muerto o no se puede mover se ignora if (!(_npc iskindof "Man") || !alive _npc || !canmove _npc) exitwith{}; //Si ya est en un edificio ignoramos la orden _inbuilding = _npc getvariable ("UPSMON_inbuilding"); if ( isNil("_inbuilding") ) then {_inbuilding = false;}; //Asignamos el vehiculo a a la escuadra si contiene las posiciones justas if (!_inbuilding) then { _inbuilding = true; _npc setVariable ["UPSMON_inbuilding", _inbuilding, false]; [_npc,"Middle"] spawn MON_setUnitPos; _timeout = time + 60; //player sidechat format["%1 patrol building %2 from %3 to %4",typeof _npc, typeof _bld,_i, _patrolto]; while { _i <= _patrolto && alive _npc && canmove _npc} do{ _npc domove (_bld buildingPos _i); _time = time + 30; waitUntil {moveToCompleted _npc or moveToFailed _npc or !alive _npc or _time < time}; if (moveToCompleted _npc) then { _timeout = time + 60; _i = _i + 1; } else { if (moveToFailed _npc || !canmove _npc || !alive _npc || _timeout < time) then { //player sidechat format["%1 Cancelando patrulla en %2",_npc, typeof _bld]; _i = _patrolto + 1; }; }; sleep 0.05; }; //Si est en un vehiculo ignoramos la orden if (!alive _npc || !canmove _npc) exitwith{}; //Volvemos con el lider _npc domove (position leader _npc); //Marcamos que ya hemos finalizado sleep 60; //Damos tiempo para salir del edificio _npc setVariable ["UPSMON_inbuilding", false, false]; }; }; //Function to put a mine //Parmeters: [_npc,(_position)] // <- _npc: leader // <- _position:location for mine (optional) MON_CreateMine = { private ["_npc","_rnd","_soldier","_mine","_dir","_position"]; _soldier = _this select 0; if ((count _this) > 1) then {_position = _this select 1;} else {_position = [0,0];}; _mine = objnull; _rnd = 0; _dir = 0; _npc = leader _soldier; if (_soldier == _npc ) then { _rnd = round (random ( count ((units _npc)))); _soldier = (units _npc) select _rnd; }; //leader only control not work //Si est en un vehiculo ignoramos la orden if (!(_soldier iskindof "Man" ) || _soldier == _npc || _soldier!=vehicle _soldier || !alive _soldier || !canmove _soldier) exitwith {false}; //Animacin para montar el arma if ((count _this) > 1) then { [_soldier,_position] spawn MON_doCreateMine; }else{ [_soldier] spawn MON_doCreateMine; }; true; }; MON_doCreateMine = { private ["_npc","_rnd","_soldier","_mine","_dir","_position"]; _position = [0,0]; _soldier = _this select 0; if ((count _this) > 1) then {_position = _this select 1;}; //If not is Man or dead exit if (!(_x iskindof "Man" ) || _soldier!=vehicle _soldier || !alive _soldier || !canmove _soldier) exitwith {false}; _soldier stop false; [_soldier,"AUTO"] spawn MON_setUnitPos; if ((count _this) > 1) then { _soldier domove _position; waituntil {unitReady _soldier || moveToCompleted _soldier || moveToFailed _soldier || !alive _soldier || !canmove _soldier}; }; if (moveToFailed _soldier || !alive _soldier || _soldier != vehicle _soldier || !canmove _soldier) exitwith {false}; //Crouche _soldier playMovenow "ainvpknlmstpslaywrfldnon_1"; sleep 1; if (!alive _soldier || !canmove _soldier) exitwith{}; _dir = getdir _soldier; _position = [position _soldier,_dir, 0.5] call MON_GetPos2D; _mine = createMine ["MineMine", _position , [], 0]; //Prepare mine _soldier playMoveNow "AinvPknlMstpSlayWrflDnon_medic"; sleep 5; //Return to formation _soldier domove position ( leader _soldier ); }; //Function to surrender AI soldier //Parmeters: [_npc] // <- _npc: soldier to surrender MON_surrender = { private ["_npc","_vehicle"]; _npc = _this select 0; if (!alive _npc || !canmove _npc) exitwith {}; _npc addrating -1000; _npc setcaptive true; sleep 0.5; _vehicle = vehicle _npc; if ( _npc != _vehicle || !(_npc iskindof "Man" )) then { _vehicle setcaptive true; if ( "Air" countType [_vehicle]>0) then { //Si acaba de entrar en el heli se define punto de aterrizaje if (_npc == driver _vehicle ) then { [_vehicle] call MON_landHely; }; } else { _npc spawn MON_doGetOut; }; //Esperamos a que est parado waituntil {_npc == vehicle _npc || !alive _npc}; }; if (!alive _npc || !canmove _npc) exitwith {}; _npc setcaptive true; _npc stop true; [_npc,"UP"] call MON_setUnitPos; removeAllWeapons _npc; sleep 1; _npc playMoveNow "AmovPercMstpSnonWnonDnon_AmovPercMstpSsurWnonDnon"; }; //Returns leader if was dead MON_getleader = { private ["_npc","_members"]; _npc = _this select 0; _members = _this select 1; sleep 0.05; if (!alive _npc ) then { //takes commder a soldier not in vehicle { if (alive _x && canmove _x && _x == vehicle _x && !isplayer _x) exitwith { _npc = _x; }; } foreach _members; //if no soldier out of vehicle takes any if (!alive _npc ) then { { if (alive _x && canmove _x) exitwith {_npc = _x;}; } foreach _members; }; //If not alive or already leader or is player exits if (isPlayer _npc || !alive _npc || !canmove _npc ) then { { if (alive _x && !isPlayer _x) exitwith {_npc = [_npc, _members] call MON_getleader;}; }foreach _members; }; if (leader _npc == _npc) exitwith {_npc}; //Set new _npc as leader group _npc selectLeader _npc; }; _npc // return }; MON_ACE_Watersurvival = { private ["_lb","_pos","_ejector","_in","_grpid","_rnd"]; _in =[]; _rnd = 0; _ejector = _this select 0; //if (KRON_UPS_Debug>0) then {player globalchat format["MON_ACE_Watersurvival %1",typeof _ejector]}; waitUntil { !canmove _ejector || !alive _ejector || isnull (_ejector) || ((getPos vehicle _ejector) select 2 < 1) }; if ( !surfaceIsWater (getpos _ejector) || !canmove _ejector || !alive _ejector || isnull (_ejector) ) exitWith {}; //Miramos de entrar en un barco cercano _grpid = _ejector getvariable "UPSMON_grpid"; if (isnil "_grpid") then {_grpid = 0}; _in = [_grpid,_ejector,30] call MON_GetIn_NearestBoat; //If no boat near creates a zodiac if (count _in <= 0) then { if (!(isNil "ace_main")) then { _lb = "ACE_Lifeboat_US" createVehicle getposASL _ejector; }else{ _lb = "Zodiac" createVehicle getposASL _ejector; }; _pos = getposASL _ejector; _pos set [0, ((_pos select 0) + 2)]; _pos set [1, ((_pos select 1) + 2)]; //_pos set [2, 0]; _lb setPos _pos; //Moves in boat if !(isPlayer _ejector) then { [_ejector,_lb,0] call MON_assignasdriver; }; }; //Wait until reached eart waitUntil { !canmove _ejector || !alive _ejector || isnull (_ejector) || !surfaceIsWater (position _ejector) }; if (KRON_UPS_Debug>0) then {player globalchat format["Exit from boat%1",typeof _lb]}; _ejector spawn MON_dogetout; }; //=============================================================Changed by Shay_gman======================================================================================== //Function to do artillery //Parmeters: [_position,(_rounds,_area,_cadence,_mincadence)] // <- _arti: // <- _position: center of fire create artillery // <- _rounds: rounds of fire // <- _area: Dispersion area // <- _maxcadence: Cadence of fire, is random between min // <- _mincadence: Minimum cadence // <- _bullet: class of bullet to fire, default ARTY_Sh_81_HE MON_artillery_dofire = { if (!isserver) exitWith {}; private ["_smoke1","_i","_area","_position","_maxcadence","_mincadence","_sleep","_rounds","_arti","_timeout","_salvo_break"]; _area = 150; _maxcadence = 10; _mincadence = 5; _sleep = 0; _rounds = 5; _bullet = "ARTY_Sh_81_HE"; _position =[]; _salvo_break = 10; _arti = _this select 0; _position = _this select 1; if ((count _this) > 2) then {_rounds = _this select 2;}; if ((count _this) > 3) then {_area = _this select 3;}; if ((count _this) > 4) then {_maxcadence = _this select 4;}; if ((count _this) > 5) then {_mincadence = _this select 5;}; if ((count _this) > 6) then {_bullet = _this select 6;}; if ((count _this) > 7) then {_salvo_break = _this select 7;}; // set reload time for 1000 make do not fire untill this salvo finish _timeout = time + 1000; _arti setVariable ["timeout", _timeout, false]; _area2 = _area * 2; if (KRON_UPS_Debug>0) then { player globalchat format["artillery doing fire on %1",_position] }; for [{_i=0}, {_i<_rounds}, {_i=_i+1}] do { _arti fire (weapons _arti select 0); _sleep = random _maxcadence; if (_sleep < _mincadence) then {_sleep = _mincadence}; sleep _sleep; _smoke1 = _bullet createVehicle [(_position select 0)+ random _area2 - _area, (_position select 1)+ random _area2 - _area, (_position select 2)+ 100]; _arti setVehicleAmmo 1; }; // set reload time for next salvo _timeout = time + _salvo_break; _arti setVariable ["timeout", _timeout, false]; }; //Funcin que devuelve un array con los vehiculos terrestres ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_deadbodies = { private["_vehicles","_npc","_bodies","_OCercanos","_distance","_side"]; _npc = _this select 0; _distance = _this select 1; //_side = _this select 2; _OCercanos = []; _bodies = []; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Man"] , _distance]; { if (_npc knowsabout _x >0.5 && (!canmove _x || !alive _x)) then { _bodies = _bodies + [_x];}; }foreach _OCercanos; _bodies; }; //Funcin que devuelve un array con los vehiculos terrestres ms cercanos //Parmeters: [_npc,_distance] // <- _npc: object for position search // <- _distance: max distance from npc // -> _vehicles: array of vehicles MON_nearestSoldiers = { private["_vehicles","_npc","_soldiers","_OCercanos","_distance","_side"]; _npc = _this select 0; _distance = _this select 1; if (isnull _npc) exitwith {}; _OCercanos = []; _soldiers = []; //Buscamos objetos cercanos _OCercanos = nearestObjects [_npc, ["Man"] , _distance]; _OCercanos = _OCercanos - [_npc]; { if ( alive _x && canmove _x ) then { _soldiers = _soldiers + [_x];}; }foreach _OCercanos; _soldiers; }; /* ===================================================================================================== MON_spawn.sqf Author: Monsada (chs.monsada@gmail.com) Comunidad Hispana de Simulacin: http://www.simulacion-esp.com ===================================================================================================== Parmeters: [_artillery,(_range,_rounds,_area,_cadence,_mincadence)] execvm "scripts\UPSMON\MON_artillery_add.sqf"; <- _artillery object to attach artillery script, must be an object with gunner. <- ( _rounds ) rounds to fire each time, default 1 <- ( _range ) range of artillery, default 800 <- ( _area ) Dispersion area, 150m by default <- ( _maxcadence ) Cadence of fire, is random between min, default 10s <- ( _mincadence ) Minimum cadence, default 5s <- ( _bullet ) Class of bullet to fire, default ARTY_Sh_81_HE ===================================================================================================== 1. Place a static weapon on map. 2. Exec module in int of static weapon nul=[this] execVM "scripts\UPSMON\MON_artillery_add.sqf"; 1. Be sure static weapon has a gunner or place a "fortify" squad near, this will make squad to take static weapon. 2. Create a trigger in your mission for setting when to fire. Set side artillery variable to true: KRON_UPS_ARTILLERY_EAST_FIRE = true; This sample will do east artilleries to fire on known enemies position, when you want to stop fire set to false. For more info: http://dev-heaven.net/projects/upsmon/wiki/Artillery_module =====================================================================================================*/ if (!isserver) exitWith {}; //Waits until UPSMON is init waitUntil {!isNil("KRON_UPS_INIT")}; waitUntil {KRON_UPS_INIT==1}; private ["_artillery","_smoke1","_i","_area","_position","_maxcadence","_mincadence","_sleep","_rounds","_dummypos","_salvobreak"]; _range = 800; _area = 150; _maxcadence = 10; _mincadence = 5; _sleep = 0; _rounds = 1; _bullet = "ARTY_Sh_81_HE"; _vector =[]; _salvobreak = 10; _artillery = _this select 0; //if (KRON_UPS_Debug>0) then {player globalchat format["MON_artillery_add before %1 %2 %3",isnull _artillery,alive _artillery]}; if (isnull _artillery || !alive _artillery) exitwith{}; if ((count _this) > 1) then {_rounds = _this select 1;}; if ((count _this) > 2) then {_range = _this select 2;}; if ((count _this) > 3) then {_area = _this select 3;}; if ((count _this) > 4) then {_maxcadence = _this select 4;}; if ((count _this) > 5) then {_mincadence = _this select 5;}; if ((count _this) > 6) then {_bullet = _this select 6;}; if ((count _this) > 7) then {_salvobreak = _this select 7;}; //Add artillery to array of artilleries _vector = [_artillery,_rounds,_range,_area,_maxcadence,_mincadence,_bullet,_salvobreak]; if (isnil "KRON_UPS_ARTILLERY_UNITS" ) then {KRON_UPS_ARTILLERY_UNITS = []}; KRON_UPS_ARTILLERY_UNITS = KRON_UPS_ARTILLERY_UNITS + [_vector]; _dummypos = [getpos _artillery, 50, getdir _artillery] call R_relPos3D; (gunner _artillery) lookAt [_dummypos select 0, _dummypos select 1,(_dummypos select 2)+100]; /* ===================================================================================================== MON_spawn.sqf Author: Monsada (chs.monsada@gmail.com) Comunidad Hispana de Simulacin: http://www.simulacion-esp.com ===================================================================================================== Parmeters: [Param1,Param2,Param3,[Param4]] EXECVM "SCRIPTS\UPSMON\MON_SPAWN.SQF"; <- Param1 Id of the template to copy. <- Param2 Position to create new squad. <- Param3 N of squads to create <- Param4 Array of parameters of UPSMON, first must be name of marc to patrol ===================================================================================================== Function that allows to spawn UPSMON squads. 1- create a squad in editor. Exec UPSMON and set TEMPLATE id, this will save members of squad, not equipement. nul = [this,"town","TEMPLATE:",1] execVM "scripts\upsmon.sqf"; 2- Exec MON_spawn on trigger or where you want telling the copy of the template to create and the position. nul = [1,[0,0,0],3,[mark, upsmon optional params]] EXECVM "SCRIPTS\UPSMON\MON_SPAWN.SQF"; =====================================================================================================*/ if (!isserver) exitWith {}; //Waits until UPSMON is init waitUntil {!isNil("KRON_UPS_INIT")}; waitUntil {KRON_UPS_INIT==1}; private ["_template","_position","_params","_copies","_membertypes","_unittype","_side","_UCthis","_initstr","_grp","_lead","_newunit","_i","_newpos","_vehicle","_initlstr"]; //Parameter reading _template = _this select 0; _position = _this select 1; _copies = _this select 2; _params = _this select 3; //Initialization _membertypes = []; _side = ""; _UCthis = []; _initstr = ""; _initlstr = ""; _grp = grpnull; _lead = objnull; _newunit = objnull; _newpos=[]; _vehicle=[]; //Gets parameters of UPSMON for [{_i=0},{_i0) then {player globalchat format["Spawning %3 copies of template %1",_template,_position,_copies,count KRON_UPS_TEMPLATES]}; //if (KRON_UPS_Debug>0) then {diag_log format["Spawning %3 copies of template %1 on %2 templates %4",_template,_position,_copies,count KRON_UPS_TEMPLATES]}; //Search if any template { if ((_x select 0) == _template) then { _side = _x select 1; _membertypes = _x select 2; _vehicletypes = _x select 3; //Gets leader type _unittype= _membertypes select 0; //if (KRON_UPS_Debug>0) then {player globalchat format["template %1:%2 ",_template,_membertypes]}; for [{_i=1},{_i<=_copies},{_i=_i+1}] do { // make the clones civilians // use random Civilian models for single unit groups if ((_unittype=="Civilian") && (count _members==1)) then {_rnd=1+round(random 20); if (_rnd>1) then {_unittype=format["Civilian%1",_rnd]}}; _grp=createGroup _side; _lead = _grp createUnit [_unittype, _position, [], 0, "form"]; _lead setVehicleInit _initlstr; [_lead] join _grp; _grp selectLeader _lead; sleep 1; // copy team members (skip the leader) _c=0; { _c=_c+1; if (_c>1) then { _newpos = _position findEmptyPosition [10, 200]; sleep .4; if (count _newpos <= 0) then {_newpos = _position}; _newunit = _grp createUnit [_x, _newpos, [],0,"form"]; _newunit setVehicleInit _initstr; [_newunit] join _grp; }; } foreach _membertypes; { _newpos = _position findEmptyPosition [10, 200]; sleep .4; if (count _newpos <= 0) then {_newpos = _position}; _newunit = _x createvehicle (_newpos); } foreach _vehicletypes; //Set new parameters _params = [_lead] + _UCthis; //Exec UPSMON script _params SPAWN UPSMON; processInitCommands; }; }; }foreach KRON_UPS_TEMPLATES; if (true) exitwith{}; // ========================================================================================================= // Script for adding the action of follow player. // Version: 1.0 // Author: Monsada (smirall@hotmail.com) // --------------------------------------------------------------------------------------------------------- private ["_side","_soldiers"]; _side = _this select 0; _soldiers = switch (_side) do { case west: {KRON_AllWest}; case east: {KRON_AllEast}; case resistance: {KRON_AllRes}; }; { if ( leader _x == _x ) then { _x addaction ["Order your men to follow me", "scripts\UPSMON\actions\followme.sqf", [], 1, false]; } else { _x addaction ["Follow me", "scripts\UPSMON\actions\followme.sqf", [], 1, false]; }; }foreach _soldiers; if (true) exitWith {}; [EN] ============================================================================================== === 5.0.9 ==================================================================================== Added: - "noveh" - the group will not search for vehicles (untill in fight and only for combat vehicles). (code improved by: Nordin) - Counter of civilians killed by players (array): KILLED_CIV_COUNTER [Total, by West, by East, by Resistance, the Killer] (works with civilians placed in editor or spawned by UPSMON) - When player kills a civilian display globalchat info WHO (Player) did it. In "Init_UPSMON.sqf" R_WHO_IS_CIV_KILLER_INFO = 1, Set O to disable this feature. - Add UPSMON version info in DEBUG display. Modified: - CBA is NOT required any more ! - Turning off ACE Wounds is now optional. (see Init_UPSMON.sqf to set it ON or OFF) - Solved bug: Self wounds or friendly fire is treated as damages made by the enemy forces. (NOTE: If the killer is not recognize, AI will use smoke) - Solved bug: MON_HeliStuckcontrol runs too often as bad speed read. - Improved: Combat behaviour (now in close distance AI often in COMBAT mode) - Improved: Stuck control for vehicles and units. - Improved: Respawn for vehicles (multiple times vehicle respawn allowed) - First parameter coud be Unit or Group. (Make sure when the script starts such GROUP's leader or the UNIT is present 100%). - Improved Artillery module (code improved by: shay_gman) http://dev-heaven.net/projects/upsmon/wiki/Artillery_module - Change: armor vehicles using limited speed no matter range when placed directly from editor with default crew. Now the speed depends on the distance to the new targetpos (r.by Demonized) - Fixed small code bugs: ex: {exit=true;}; should be: {_exit=true;}; - Solved bug: Respawn for vehicles not working. (r.by Demonized) - Solved bug 99%: reinforcement AI after getting out of the combat vehicle, often the vehicle did not move. (r.by seba1976) Misc: - HMMWV_M998A2_SOV_DES_EP1 added to bugged vehicles for Vanilia players. http://dev-heaven.net/issues/18314 ============================================================================================ === 5.0.8 ================================================================================ Added: CBA is now required !!! UPSMON switches off "ACE wounds system for AI". "nosmoke" - the group will not use the smoke at all. "onroad" - targetpos will be generated only on roads (unless unit in fight). Civilians do not take vehicles or static weapons (no more stealing). Modified: New targetpos depend on the type of the unit (air, water, land) - (water unit only on water etc) Detection of new target/(generate new target) is longer just a bit. (R_knowsAboutEnemy) AI use smokes when s/o hit or KIA. (R_USE_SMOKE_wounded, R_USE_SMOKE_killed). Solved bug: AI reinforcement have problem to get into helicopters. Solved bug: group "nowp" have problem to generate target when no other groups around Solved bug: AI do not paradrop around positions of the enemy. (stuck) Solved bug: Helicopters paradrop and fly too low. =============================================================================================== // ----------------------------------------------------------------------------- //Version: 5.0.6 // ----------------------------------------------------------------------------- // Added: // Parameter "RESPAWN" for alowing respawn UPSMON squads when all are dead // "aware","combat","stealth" and "careless" added as a parameter so you can define default behaviour of squad // Added AI stuff for water // AI aware if find dead bodies // Added fixed positions for reinforcement squads, those squads that have a reinforcement ID can be set reinforcement position by seting KRON_UPS_reinforcement"x"_pos = position; sample // reinforcement: http://dev-heaven.net/projects/upsmon/wiki/Reinforcement // Added Artillery module: http://dev-heaven.net/projects/upsmon/wiki/Artillery_module // Added spawn module: http://dev-heaven.net/projects/upsmon/wiki/MON_spawn // Modified: // Solved bug in SPAWNED that not refreshed correctly army counters // If in walk mode and safe will land hely. // When Hely in squad column formation can not be used, last member assigned as driver // Detected bug with VEE formation, some times AI don't change vehaviour, changed to wedge // Folder estructure modified to gather upsmon scripts this will no affect already missions. // Improved AI response under Supress fire in combat situation // Avoid hurt soldiers than can not stand to get in vehicles and buildings // Avoid to patrol in damaged buildings // avoid bugged clases such as "BIS_alice_emptydoor"; // AI try to get in combat vehicles // Performance optimization. // Realistic reaction of squads depending on distance to target // ----------------------------------------------------------------------------- //Version: 5.0.5 // ----------------------------------------------------------------------------- // Added // Parameter "AMBUSH:",3000 you can set max time to wait for ambush // Modified: // Ambush squads exits if called for reinforcement so you can force exit creating a especific reinforcement group for this ex: setting "reinforcement:",100 // you can force exit ambush setting KRON_UPS_reinforcement100 = true // you can put 0 seconds for putting mines and go away if combined with "move" for example // Solved bug that sets reinforcement to false on init of scritp // Improved getout and landheli algoritm // Improved target debug console A=all units C=current alive units T=targets knonw by this side // Improved movement with vehicles, now they go in safe until near known enemies // adjusted flanking algorithm // ----------------------------------------------------------------------------- //Version: 5.0.4 // Added // Implemented: It also would be great if they use smoke-grenades when ai is under fire by targets they dont see well. One example: I lay on a moutain with my squad and shoot with sniperrifles from the hill down at the ai in a village. The ai should throw smoke and try to get cover. That would be great. // Feature #9559: parameter "spawned" = use only with squads created in runtime, this feature will add squad to UPSMON correctly. // Feature #9558 parameter "nowp" = No waypoints will be created for this squad, so this squad will comunicate enemies but will not be moved, so you can do what you want with them using waypoints. // Feature #9503 parameter "ambush" = Ambush squad will not move until in combat, will wait for incoming enemies stealth and ambush when near or discovered. // Parameter "RFLOCK", if especified when reinforcement is called, target position is locked until reached reinforcement point // Added surrended client control so now is no necesary create any trigger in mission to launch surrended.sqf // Added stuck control to avoid that helis stopping flying // New target sistem control based in last known positions instead of real position of targets // Modified: // Bug #9666 fixed:AI Cheats with UPSMON - Groups always Flank Real Position instead of last known // Bug #9662 fixed: Reinforcement Group returning home, does not get out of Vehicles (if used) // Bug #9639 fixed: Reinforcement Group can get stuck if Transportvehicle back to Patrolmarker gets destroyed// // Set DIAMOND formation when exiting vehicle // bug with NOSLOW solved. // solved other bugs such as no patrol without enemies. // --------------------------------------------------------------------------------------------------------- //Version: 5.0.3 // Added // KRON_UPS_searchVehicledist = 800 // KRON_UPS_EAST_SURRENDER, KRON_UPS_WEST_SURRENDER,KRON_UPS_GUER_SURRENDER // Set percentaje of forces for surrender. // Main control for all squads, doing comon proceses and saving performance. // sample followme.sqf script for enabling AI surrended to join your squad, must // be executed in each client when KRON_UPS_EAST_SURRENDED or KRON_UPS_WEST_SURRENDED // or KRON_UPS_GUER_SURRENDED // Modified: // Fixed Bug with resistance forces detected as enemies when not parametriced as enemy // Fixed bug check if dead leader before moving. // Fixed bug, "alive" not always returns someone is dead instanctly so controlled with canmove. // Fixed bug, error _vehicle object expected. // Controled not doing paradroop on water. //------------------------------------------------------------------------------------------------------------- //Version: 5.0.2 // Added // KRON_UPS_useStatics, enables AI to use Static weapons. // KRON_UPS_useMines, enables AI to put mines when enemy armored vehicles near // Now vehicles can be used for patrol, not only with target. // Modified: // Fixed Bug that do not sent reinforcement if parameter "reinforcement" // Fixed bug with random 1 ocasiolly has been returned more than 1. // Fixed bug that eventually do not change dead leader //------------------------------------------------------------------------------------------------------------- //Version: 5.0.1 // Added // Mulitiple reinforcement reinforcement:x, now you can put an id of reinforcement for calling only this groups later: // nul=[this,"town", "move","reinforcement:",1, "delete:",600] execVM "scripts\upsmon.sqf"; // nul=[this,"town", "move","reinforcement:",2, "delete:",600] execVM "scripts\upsmon.sqf"; // Modified: // Fixed fortify squads don't get defence positions until known enemys // Fortify squads leave fortify status when called for reinforcement // --------------------------------------------------------------------------------------------------------- //Version: 5.0.0 // Added // KRON_UPS_flyInHeight: Height that heli will fly this input will be randomiced in a 10% // KRON_UPS_paradropdist: Max distance to target for doing paradrop, will be randomiced between 0 and 100% of this value. // parameter "fortify" makes leader order to take positions on nearly buildings at distance 100 meters near leader, // squads with fortify will ignore "MOVE" rol. // Modified: // Fixed bug that eventually stoped hely when paradrops done. // --------------------------------------------------------------------------------------------------------- //Version: 4.2.6 // Added // // Modified: // Fixed bug that leaves a soldier in front of vehicle afte geting out. // Fixed bug that allowed AI to disenbark from heli before arriving objective. //------------------------------------------------------------------------------------------------------------- //Version: 4.2.5 // Added // Air transport // Paratroop air transported units // Improved comunications // Modificaciones: // Updated for an action radio of 1000 meters or avove. // Added some translations to english //------------------------------------------------------------------------------------------------------------- //Version: 4.2.2 // Added // Se ha aadido ataque frontal // Formaciones de combate en funcin de la situacin // La IA puede entrar en los edificios a tomar posiciones de defensa y en ataque puede patrullarlos en busca de enemigos o posiciones de fuego. // Modificaciones: // Mejorado el sistema para localizar, asignar y entrar en vehiculos,. // Optimizado el rendimiento. Se ha mejorado para que se pueda ejecutar cada 20s. // Modificada la parametrizacin, sharedist incrementado, react reducido, cycle aumentado. // Modificada la actitud e la IA en combate, se ha dado ms especializacin en funcin de la situacin. // Corregido bug que al enviar refuerzos haca que dejaran de patrullar si no tenian ningn target // Posiciones de flanqueo ms dinmicas. // Las escuadras con rol "NOMOVE" tienden a asegurar la posicin y a hacer mayor uso de los edificios del entorno. //------------------------------------------------------------------------------------------------------------- //Version: 4.1.3 // // Modificaciones: // corregidos los problemas al entrar en vehiculos, que haca que casi siempre alguno se quedara fuera // Optimizado el rendimiento. // Modificada la actitud e la IA en combate, se ha dado ms especializacin en funcin de la situacin. // //------------------------------------------------------------------------------------------------------------- //Version: 4.1.2 // // Modificaciones: // KRON_UPS_Maxwaiting pasa a ser una variable excluvia para patrullas, indica el tiempo mximo a esperar // para llegar al destino y buscar otro //------------------------------------------------------------------------------------------------------------- //Version: 4.1.0 // Added // Habilitado bsqueda y uso de vehculos de transporte, cuando la IA est lejos del objetivo busca vehiculos con capacidad cerca, ahora ya puedes definir tu base con vehiculos, que si la IA los necesita los coge. // // Modificaciones: // Adaptadas ciertas partes de cdigo para ser usadas en modo multihilo, mejorando los resultados y el rendimiento en general. //------------------------------------------------------------------------------------------------------------- //Version: 4.0.0 // Added // Control de movimiento de la IA, ahora gestionan mejor los tiempos, hacen coverturas de movimiento, avanzan con ms precaucin cuando estn cerca del enemigo. // Aadidas algunas animaciones para darle pinceladas de dramatismo a los movimientos de la IA // // Modificaciones: // Modificacin control de deteccin de movimientos de otros grupos ahora no requiere la lectura de objetos, con lo que mejora el rendimiento. // Adaptado sistema de scripts para poder controlar los grupos de IA y aadir mejoras que requieran la interaccin de los grupos. //------------------------------------------------------------------------------- //Version: 3.0.8 // Modificaciones: // Corregido el bug de los buildings, se ha vuelto a implementar el uso de edificios // Mejorada la velocidad de iniciacin del script. //------------------------------------------------------------------------------------------------------------- //Version: 3.0.7 // Added // // Modificaciones: // Corregido bud que en dedicado fijaba el objetivo siempre en lugar de los flancos //------------------------------------------------------------------------------------------------------------- //Version: 3.0.6 // Added // // Modificaciones // Corregidos bugs varios, entre ellos uno que ralentizaba la accin de los grupos // Set de parmetros modificados para un comportamiento ms ptimo y realista // deshabilitado KRON_UPS_intowndist por comportamientos extraos con algunos objetos builiding // Ahora la IA selecciona los caminos con ms cobertura, a ser posible //------------------------------------------------------------------------------------------------------------- //Version: 3.0.5 // Added // // Modificaciones // Corregido bug que evitaba enviar los refuerzos // La distancia de comunicacin de objetivos aumenta en funcin del rol, los nomove * 1.5 // //------------------------------------------------------------------------------------------------------------- //Version: 3.0.4 // Added // Aadidos parmetros para asignar enemigos y aliados a la resistencia // Aadido control anti snipers, si la IA se ve atacada y no sabe de donde se mueve de sitio // Modificaciones // Se ajusta el ngulo de flanqueo en funcin de la distancia al objetivo // //------------------------------------------------------------------------------------------------------------- // // Modified: Monsada (SMM) 03.11.2009 //Version: 3.0.3 // Added // Multiple targets, now IA can have multiple open targets // La IA ahora usa tamien los edificios para buscar enemigos, protegerse dentro o atacar desde all. // Modificaciones // La IA pierde el objetivo si lo pierde de vista y est a ms de la distancia KRON_UPS_sharedist // //------------------------------------------------------------------------------------------------------------- //Version: 3.0.2 // Added // Se ha aadido la opcin de Refuerzos, ahora se pueden definir unas unidades de refuerzos alejados de la zona que se enviarn al detectar enemigos enemigos // si KRON_UPS_reinforcement es true, se puede usar un marcador a modo de alarma para alimentar esta variable cuando se desee. // Las unidades tendrn una predisposicin a mantener la posicin si tienen el rol NOMOVE // Modificaciones // Se ha corregido la formula par definir los puntos de flanqueo tx = sin x * dist * (signo cos x). // Las unidades con rol NOMOVE tienden a mantener la posicin cuanto ms alejados estn del enemigo // Se ha mejorado el rendimiento. // //------------------------------------------------------------------------------------------------------------- //Version: 3.0.1 // Added // Sistema de combate urbano. La Ia ajusta el flanjeo y sus movimientos al tipo de superficie. // Modificaciones // Ahora los pelotones verifican la presencia de aliados para determinar otras rutas de flanqueo. // Se ha substituido el algoritmo de determinacin de posiciones de flanqueo por un bug con las funciones cos y sin // que retornan aleatoriamente valores positivos o negativos con el mismo ngulo. // //------------------------------------------------------------------------------------------------------------- // Version: 3.0.0 // Added: // Improved IA flanking possitions // Improved IA movements in combat // Now IA can be supressed by fire // IA may use smoke grenades when in fire // Improved performance (this script now runs every 15s and do not need to stress to 1 second) // Implemented comunications simulating radio to know enemy position //Errores corregidos y modificaciones // Corregida la funcin KRON_distancePosSqr que no devolvia la distancia correcta entre dos puntos // Corregido bug que no alimentaba correctamente el objetivocompartido cuando este fallecia // Corregido control de la distancia al objetivo que hacia que la IA no flanquera // Algoritmo de control de accin y movimiento modificado // ======================================================================================================================================================================================================== KNOWN PROBLEMS: 1) Pilots are very stupid if they have to land, sometimes they crash the helicopter (trees). 2) Sometimes a vehicle stops and wait for something (driver switches off the engine)? In the end (~2min) stuck control makes it move but I do not know if the problem is UPSMON or Arma. Difficult to reproduce cause it happens at random times and very rarely. Expecialy when reinforcement AI use combat vehicle. Possible explanation: targetpos in the forest, AI lost the way, no radio contact etc :) 3) Too much smoke might cause drop in Fps. (change parameters: R_USE_SMOKE_wounded = 13; R_USE_SMOKE_killed = 35;) =============================================================================================== HINTS & TIPS : ------------------- 0) To get rid of the debug information set (in Init_UPSMON.sqf) KRON_UPS_Debug = 0; ------------------- 1) note for MissionMakers : UPSMON patrol vehicles after some time use up all fuel and stop. Use a script to refuel the vehicles. ------------------ 2) - Hide area markers before briefing. - create Game Logic Object put in initialization field: nul = call compile preprocessFile "scripts\UPSMON\!R\markerAlpha.sqf"; (all markers area must be named area0, area1...area13) ------------------ 3) If you use civilians, always set their skill to 0 (save CPU). ------------------ 4) in init.sqf do not use: if (isServer) then { //Init UPSMON scritp call compile preprocessFileLineNumbers "scripts\Init_UPSMON.sqf"; }; use: //Init UPSMON scritp call compile preprocessFileLineNumbers "scripts\Init_UPSMON.sqf"; as Init_UPSMON.sqf has got part of the code which should be run on all clients. ---------------- 5) If you fight on the small area think about lowering the "KRON_UPS_sharedist". example: If the fight area is a town (600x600) and "KRON_UPS_sharedist = 700;", in the moment you are spotted at the edge of the town all AI units in the 700m from you gets info about your position, and if they are not busy you can expect attack of all units. 6) Only one init per Group, if you init in the unit INIT (make sure this unit is 100% possibility of present) 7) if the leader is vehicle -> the group follows the vehicle (fast), if the leader is outside vehicle -> the vehicle follow the foot leader. (slow) 8) to count civilians killed by players use (array): KILLED_CIV_COUNTER [Total,by West,by East,by Resistance, the Killer] example: total_number_civilians_killed_by_any_players = KILLED_CIV_COUNTER select 0; number_civilians_killed_by_any_east_players = KILLED_CIV_COUNTER select 2; the_killer = KILLED_CIV_COUNTER select 4; (Note: if the player becomes ENEMY to all is not side anymore. Kills by ENEMY are only counted in Total) ================================================================================================ Hello UPSMON users, I'm currently run the project but I'm not very good at creating new function to the UPSMON as I'm not good script writer. I feel much better as a person who can adjust existing code to work with UPSMON well. 95% of the functions in UPSMON were there (created by Kronzky or Monsada). I just make some of them work more smooth, and fixed some bugs. The aim is reliability, performance and make all end user friendly. So if you found a bug or had improved part of the code... let me know. Any new code that could make UPSMON runs better or add new functions is very welcome. :) forum: http://forums.bistudio.com/showthread.php?t=91696 report bug: http://dev-heaven.net/projects/upsmon/issues (do not forget to attach simple mission to reproduce problem) Thank you !R// ========================================================================================================= // UPSMON - Urban Patrol Script // version 5.0.9 // // Author: Monsada (chs.monsada@gmail.com) // Comunidad Hispana de Simulacin: // // Wiki: http://dev-heaven.net/projects/upsmon/wiki // Forum: http://forums.bistudio.com/showthread.php?t=91696 // Share your missions with upsmon: http://dev-heaven.net/projects/upsmon/boards/86 // --------------------------------------------------------------------------------------------------------- // Based on Urban Patrol Script v2.0.3 // Author: Kronzky (www.kronzky.info / kronzky@gmail.com) // --------------------------------------------------------------------------------------------------------- // Some little fixes: !Rafalsky (v5.0.8 - 5.0.9) // Code improvements: shay_gman(Artillery), Nordin("noveh") // --------------------------------------------------------------------------------------------------------- // Required parameters: // unit = Unit to patrol area (1st argument) // markername = Name of marker that covers the active area. (2nd argument) // // Patrol squad samples: (put in the leader's init field) // nul=[this,"area0"] execVM "scripts\upsmon.sqf"; // // Defensive squad samples: // nul=[this,"area0","nomove"] execVM "scripts\upsmon.sqf"; // // Reinforcement // nul=[this,"area0","reinforcement:",1] execVM "scripts\UPSMON.sqf"; // (in trigger call: KRON_UPS_reinforcement1 = true; // (call pos marker mkr1): KRON_UPS_reinforcement1_pos = getMarkerPos "mkr1"; // // // Optional parameters: _ // random = Place unit at random start position. // randomdn = Only use random positions on ground level. // randomup = Only use random positions at top building positions. // min:n/max:n = Create a random number (between min and max) of 'clones'. // init:string = Custom init string for created clones. // nomove = Unit will stay or hide in the near buildings until enemy is spotted. // nofollow = Unit will only follow an enemy within the marker area.(When fight sometimes can go outside) // onroad = Unit will get target destination only on the roads // nosmoke = Units will not use smoke when s/o wounded or die. // delete:n = Delete dead units after 'n' seconds. // nowait = Do not wait at patrol end points. // noslow = Keep default behaviour of unit (don't change to "safe" and "limited"). // noai = Don't use enhanced AI for evasive and flanking maneuvers. // trigger = Display a message when no more units are left in sector. // empty:n = Consider area empty, even if 'n' units are left. // reinforcement = Makes squad as reinforcement, when alarm KRON_UPS_reinforcement==true this squad will go where enemy were. // reinforcement:x = Makes squad as reinforcement id, when alarm KRON_UPS_reinforcementx==true this squad will go where enemy were. // fortify = makes leader order to take positions on nearly buildings at distance 200 meters, squad fortified moves less than "nomove" // aware,combat,stealth,careless defines default behaviour of squad // noveh = the group will not search for transport vehicles (unless in fight and only combat vehicles) // nowp = No waypoints will be created for this squad UNTIL ENEMY DETECTED, this squad will comunicate enemies but will not be moved by UPSMON until enemy detected, after that upsmon takes control of squad // nowp2 = No waypoints will be created for this squad UNTIL ENEMY DETECTED and damaged, this squad will comunicate enemies but will not be moved by UPSMON until enemy detected and damaged, after that upsmon takes control of squad // nowp3 = No waypoints will be created for this squad in any way, this squad will comunicate enemies but will not be moved by UPSMON. // ambush = Ambush squad will not move until in combat, will lay mines if enabled and wait for incoming enemies stealth and ambush when near or discovered. // ambush2 = Ambush squad will not move until in combat, will NOT LAY MINES and wait for incoming enemies stealth and ambush when near or discovered. // ambush:n = Creates an anbush and wait maximun the especified time n in seconds. you can put 0 seconds for putting mines and go away if combined with "move" for example // ambush2:n = Same as ambush:n but without laying mines. // respawn = allow squad to respawn when all members are dead and no targets near // respawn:x = allows to define the number of times squad may respawn. // showmarker = Display the area marker. // track = Display a position and destination marker for each unit. // spawned = use only with squads created in runtime, this feature will add squad to UPSMON correctly. // aware,combat,stealth,careless defines default behaviour of squad // numbers of Civilians killed by players could be read from the array 'KILLED_CIV_COUNTER' -> [Total, by West, by East, by Res, The Killer] if (!isServer) exitWith {}; if (isNil("KRON_UPS_INIT")) then { KRON_UPS_INIT=0; }; waitUntil {KRON_UPS_INIT==1}; // convert argument list to uppercase _UCthis = []; for [{_i=0},{_i0) then {player sidechat format["%1: New instance %2 %3 %4",_grpidx,_npc getVariable ("UPSMON_grpid")]}; // == get the name of area marker ============================================== _areamarker = _this select 1; if (isNil ("_areamarker")) exitWith { hint "UPS: Area marker not defined.\n(Typo, or name not enclosed in quotation marks?)"; }; // remember center position of area marker _centerpos = getMarkerPos _areamarker; _centerX = abs(_centerpos select 0); _centerY = abs(_centerpos select 1); _centerpos = [_centerX,_centerY]; // show/hide area marker _showmarker = if ("SHOWMARKER" in _UCthis) then {"SHOWMARKER"} else {"HIDEMARKER"}; if (_showmarker=="HIDEMARKER") then { //_areamarker setMarkerCondition "false"; // VBS2 _areamarker setMarkerPos [-abs(_centerX),-abs(_centerY)]; }; // is anybody alive in the group? _exit = true; if (typename _npc=="OBJECT") then { if (!isnull group _npc) then { _npc = [_npc,units (group _npc)] call MON_getleader; }else{ _vehicles = [_npc,2] call MON_nearestSoldiers; if (count _vehicles>0) then { _npc = [_vehicles select 0,units (_vehicles select 0)] call MON_getleader; }; }; } else { if (count _obj>0) then { _npc = [_obj,count _obj] call MON_getleader; }; }; // set the leader in the vehilce if (!(_npc iskindof "Man")) then { if (!isnull(commander _npc) ) then { _npc = commander _npc; }else{ if (!isnull(driver _npc) ) then { _npc = driver _npc; }else{ _npc = gunner _npc; }; }; group _npc selectLeader _npc; }; // =============================================== if (alive _npc) then {_exit = false;}; if (KRON_UPS_Debug>0 && _exit) then {player sidechat format["%1 There is no alive members %1 %2 %3",_grpidx,typename _npc,typeof _npc, count units _npc]}; // exit if something went wrong during initialization (or if unit is on roof) if (_exit) exitWith { if (KRON_UPS_DEBUG>0) then {hint "Initialization aborted"}; }; // remember the original group members, so we can later find a new leader, in case he dies _members = units _npc; KRON_UPS_Total = KRON_UPS_Total + (count _members); //Fills member soldier types _vehicles = []; { if (vehicle _x != _x ) then { _vehicles = _vehicles - [vehicle _x]; _vehicles = _vehicles + [vehicle _x]; }; _membertypes = _membertypes + [typeof _x]; } foreach _members; //Fills member vehicle types { _vehicletypes = _vehicletypes + [typeof _x]; } foreach _vehicles; // what type of "vehicle" is _npc ? _isman = "Man" countType [ vehicle _npc]>0; _iscar = "LandVehicle" countType [vehicle _npc]>0; _isboat = "Ship" countType [vehicle _npc]>0; _isplane = "Air" countType [vehicle _npc]>0; // we just have to brute-force it for now, and declare *everyone* an enemy who isn't a civilian _isSoldier = _side != civilian; _friends=[]; _enemies=[]; _sharedenemy=0; if (_isSoldier) then { switch (_side) do { case west: { _sharedenemy=0; _friendside = [west]; _enemyside = [east]; }; case east: { _sharedenemy=1; _friendside = [east]; _enemyside = [west]; }; case resistance: { _sharedenemy=2; _enemyside = KRON_UPS_Res_enemy; if (!(east in _enemyside)) then { _friendside = [east]; }; if (!(west in _enemyside)) then { _friendside = [west]; }; }; }; }; if (_side in KRON_UPS_Res_enemy) then { _enemyside = _enemyside + [resistance]; }else { _friendside = _friendside + [resistance]; }; sleep .05; //Sets min units alive for surrender _surrender = call (compile format ["KRON_UPS_%1_SURRENDER",_side]); // Tanks friendlys are contabiliced { if ( side _x in _friendside && ( _x iskindof "Tank" || _x iskindof "Wheeled_APC" )) then { _friendlytanks = _friendlytanks + [_x]; }; }foreach vehicles; // global unit variable to externally influence script //call compile format ["KRON_UPS_%1=1",_npcname]; // X/Y range of target area _areasize = getMarkerSize _areamarker; _rangeX = _areasize select 0; _rangeY = _areasize select 1; _area = abs((_rangeX * _rangeY) ^ 0.5); // marker orientation (needed as negative value!) _areadir = (markerDir _areamarker) * -1; // store some trig calculations _cosdir=cos(_areadir); _sindir=sin(_areadir); // minimum distance of new target position _mindist=(_rangeX^2+_rangeY^2)/3; if (_rangeX==0) exitWith { hint format["UPS: Cannot patrol Sector: %1\nArea Marker doesn't exist",_areamarker]; }; // remember the original mode & speed _orgMode = behaviour _npc; _orgSpeed = speedmode _npc; // set first target to current position (so we'll generate a new one right away) _currPos = getpos _npc; _orgPos = _currPos; _orgDir = getDir _npc; _orgWatch=[_currPos,50,_orgDir] call KRON_relPos; _lastpos = _currPos; _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0]; _newattackPos = [0,0]; _fixedtargetpos = [0,0]; _frontPos = [0,0]; _dirf1 = 0;_dirf2=0;_flankPos2=[0,0]; _dist = 10000; _lastdist = 0; _lastmove1 = 0; _lastmove2 = 0; _maxmove=0; _moved=0; _damm=0; _dammchg=0; _lastdamm = 0; _timeontarget = 0; _fightmode = "walk"; _fm=0; _gothit = false; _pursue = false; _hitPos=[0,0,0]; _react = 0; _lastknown = 0; _opfknowval = 0; _sin0=1; _sin90=1; _cos90=0; _sin270=-1; _cos270=0; _targetX =0; _targetY=0; _relTX=0;_relTY=0; _relUX=0;_relUY=0; _supressed = false; _flankdist=0; _nBuilding=nil; _nBuildingt =nil; _speedmode="Limited"; _distnbuid = 0; _distnbuidt = 0; _objsflankPos1 = []; _cntobjs1 = 0; _objsflankPos2 = []; _cntobjs2 = 0; _targettext =""; _dir1 =0;_dir2=0;_dir3=0;_dd=0; _timeontarget=0; _reinforcement =""; _reinforcementsent = false; _target = objnull; _newtarget=objnull; _flankdir=0; //1 tendencia a flankpos1, 2 tendencia a flankpos2 _prov=0; _targets=[]; _planta=0; //Indice de plantas en edificios _newflankAngle = 0; _closeenough = KRON_UPS_closeenough; _gunner = objnull; _driver = objnull; _fortify = false; _buildingdist= 60;//Distance to search buildings near _Behaviour = "SAFE"; _grp = grpnull; _grp = group _npc; _template = 0; _nowpType = 1; _ambushtype = 1; _rstuckControl = 0; _makenewtarget=true; // set target tolerance high for choppers & planes if (_isplane) then {_closeenough = KRON_UPS_closeenough * 2}; // ***************************************** optional arguments ***************************************** // wait at patrol end points _pause = if ("NOWAIT" in _UCthis) then {"NOWAIT"} else {"WAIT"}; // don't move until an enemy is spotted _nomove = if ("NOMOVE" in _UCthis) then {"NOMOVE"} else {"MOVE"}; //fortify group in near places _fortify= if ("FORTIFY" in _UCthis) then {true} else {false}; _fortifyorig = _fortify; if (_fortify) then { _nomove="NOMOVE"; _minreact = KRON_UPS_minreact * 3; _buildingdist = _buildingdist * 2; _makenewtarget = false; _wait = 3000; }; // create _targerpoint on the roads only (by this group) _onroad = if ("ONROAD" in _UCthis) then {true} else {false}; // do not use smoke (by this group) _nosmoke = if ("NOSMOKE" in _UCthis) then {true} else {false}; // do not search for vehicles (unless in fight and combat vehicles) _noveh = if ("NOVEH" in _UCthis) then {true} else {false}; // don't make waypoints _nowp = if ("NOWP" in _UCthis) then {true} else {false}; _nowp = if ("NOWP2" in _UCthis) then {true} else {_nowp}; _nowp = if ("NOWP3" in _UCthis) then {true} else {_nowp}; _nowpType = if ("NOWP2" in _UCthis) then {2} else {_nowpType}; _nowpType = if ("NOWP3" in _UCthis) then {3} else {_nowpType}; //Ambush squad will no move until in combat or so close enemy _ambush= if ("AMBUSH" in _UCthis) then {true} else {false}; _ambush= if ("AMBUSH:" in _UCthis) then {true} else {_ambush}; _ambush= if ("AMBUSH2" in _UCthis) then {true} else {_ambush}; _ambushwait = ["AMBUSH:",_ambushwait,_UCthis] call KRON_UPSgetArg; _ambushwait = ["AMBUSH2:",_ambushwait,_UCthis] call KRON_UPSgetArg; _ambushType = if ("AMBUSH2" in _UCthis) then {2} else {_ambushType}; _ambushType = if ("AMBUSH2:" in _UCthis) then {2} else {_ambushType}; // respawn _respawn = if ("RESPAWN" in _UCthis) then {true} else {false}; _respawn = if ("RESPAWN:" in _UCthis) then {true} else {_respawn}; _respawnmax = ["RESPAWN:",_respawnmax,_UCthis] call KRON_UPSgetArg; if (!_respawn) then {_respawnmax = 0}; // any init strings? _initstr = ["INIT:","",_UCthis] call KRON_UPSgetArg; // don't follow outside of marker area _nofollow = if ("NOFOLLOW" in _UCthis) then {"NOFOLLOW"} else {"FOLLOW"}; // share enemy info _shareinfo = if ("NOSHARE" in _UCthis) then {"NOSHARE"} else {"SHARE"}; // "area cleared" trigger activator _areatrigger = if ("TRIGGER" in _UCthis) then {"TRIGGER"} else {if ("NOTRIGGER" in _UCthis) then {"NOTRIGGER"} else {"SILENTTRIGGER"}}; // suppress fight behaviour if ("NOAI" in _UCthis) then {_isSoldier=false}; // adjust cycle delay _cycle = ["CYCLE:",KRON_UPS_Cycle,_UCthis] call KRON_UPSgetArg; _currcycle=_cycle; //spawned for squads created in runtime _spawned= if ("SPAWNED" in _UCthis) then {true} else {false}; if (_spawned) then { if (KRON_UPS_Debug>0) then {player sidechat format["%1: squad has been spawned, respawns %2",_grpidx,_respawnmax]}; switch (side _npc) do { case west: { KRON_AllWest=KRON_AllWest + units _npc; }; case east: { KRON_AllEast=KRON_AllEast + units _npc; }; case resistance: { KRON_AllRes=KRON_AllRes + units _npc; if (east in KRON_UPS_Res_enemy ) then { KRON_UPS_East_enemies = KRON_UPS_East_enemies+units _npc; } else { KRON_UPS_East_friends = KRON_UPS_East_friends+units _npc; }; if (west in KRON_UPS_Res_enemy ) then { KRON_UPS_West_enemies = KRON_UPS_West_enemies+units _npc; } else { KRON_UPS_West_friends = KRON_UPS_West_friends+units _npc; }; }; }; call (compile format ["KRON_UPS_%1_Total = KRON_UPS_%1_Total + count (units _npc)",side _npc]); _vehicletypes = ["VEHTYPE:",_vehicletypes,_UCthis] call KRON_UPSgetArg; //!R }; // set drop units at random positions _initpos = "ORIGINAL"; if ("RANDOM" in _UCthis) then {_initpos = "RANDOM"}; if ("RANDOMUP" in _UCthis) then {_initpos = "RANDOMUP"}; if ("RANDOMDN" in _UCthis) then {_initpos = "RANDOMDN"}; // don't position groups or vehicles on rooftops if ((_initpos!="ORIGINAL") && ((!_isman) || (count _members)>1)) then {_initpos="RANDOMDN"}; // set behaviour modes (or not) _orgMode = "SAFE"; if ("CARELESS" in _UCthis) then {_orgMode = "CARELESS"}; if ("AWARE" in _UCthis) then {_orgMode = "AWARE"}; if ("COMBAT" in _UCthis) then {_orgMode = "COMBAT"}; if ("STEALTH" in _UCthis) then {_orgMode = "STEALTH"}; // set original beahviour if (!_isSoldier) then { _Behaviour = "CARELESS"; } else { _Behaviour = _orgMode; }; _npc setbehaviour _Behaviour; // set initial speed _noslow = if ("NOSLOW" in _UCthis) then {"NOSLOW"} else {"SLOW"}; if (_noslow!="NOSLOW") then { _orgSpeed = "limited"; } else { _orgSpeed = "FULL"; }; _speedmode = _orgSpeed; _npc setspeedmode _speedmode; // set If enemy detected reinforcements will be sent REIN1 _reinforcement= if ("REINFORCEMENT" in _UCthis) then {"REINFORCEMENT"} else {"NOREINFORCEMENT"}; //rein_yes _rfid = ["REINFORCEMENT:",0,_UCthis] call KRON_UPSgetArg; // rein_# if (_rfid>0) then { _reinforcement="REINFORCEMENT"; //if (KRON_UPS_Debug>0) then {hintsilent format["%1: reinforcement group %2",_grpidx,_rfid,_rfidcalled,_reinforcement]}; }; //set Is a template for spawn module? _template = ["TEMPLATE:",_template,_UCthis] call KRON_UPSgetArg; //Fills template array for spawn if (_template > 0 && !_spawned) then { KRON_UPS_TEMPLATES = KRON_UPS_TEMPLATES + ( [[_template]+[_side]+[_membertypes]+[_vehicletypes]] ); //if (KRON_UPS_Debug>0) then {diag_log format["%1 Adding TEMPLATE %2 _spawned %3",_grpidx,_template,_spawned]}; //if (KRON_UPS_Debug>0) then {player globalchat format["KRON_UPS_TEMPLATES %1",count KRON_UPS_TEMPLATES]}; }; // make start position random if (_initpos!="ORIGINAL") then { // find a random position (try a max of 20 positions) _try=0; _bld=0; _bldpos=0; while {_try<20} do { _currPos=[_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; _posinfo=[_currPos] call KRON_PosInfo3; // _posinfo: [0,0]=no house near, [obj,-1]=house near, but no roof positions, [obj,pos]=house near, with roof pos _bld=_posinfo select 0; _bldpos=_posinfo select 1; if (_isplane || _isboat || !(surfaceiswater _currPos)) then { if (((_initpos=="RANDOM") || (_initpos=="RANDOMUP")) && (_bldpos>0)) then {_try=99}; if (((_initpos=="RANDOM") || (_initpos=="RANDOMDN")) && (_bldpos==0)) then {_try=99}; }; _try=_try+1; sleep .01; }; if (_bldpos==0) then { if (_isman) then { {_x setpos _currPos} foreach units _npc; } else { _npc setpos _currPos; }; } else { // put the unit on top of a building _npc setPos (_bld buildingPos _bldpos); _currPos = getPos _npc; _nowp=true; // don't move if on roof }; }; // track unit ====================================================================================== _track = if (("TRACK" in _UCthis) || (KRON_UPS_Debug>0)) then {"TRACK"} else {"NOTRACK"}; _trackername = ""; _destname = ""; if (_track=="TRACK") then { _track = "TRACK"; _trackername=format["trk_%1",_grpidx]; _markerobj = createMarker[_trackername,[0,0]]; _markerobj setMarkerShape "ICON"; _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Dot")) then {"WTF_DOT"} else {"DOT"}; _trackername setMarkerType _markertype; _markercolor = switch (side _npc) do { case west: {"ColorGreen"}; case east: {"ColorRed"}; case resistance: {"ColorBlue"}; default {"ColorBlack"}; }; _trackername setMarkerColor _markercolor; _trackername setMarkerText format["%1",_grpidx]; _trackername setmarkerpos _currPos; _destname=format["dest_%1",_grpidx]; _markerobj = createMarker[_destname,[0,0]]; _markerobj setMarkerShape "ICON"; _markertype = if (isClass(configFile >> "cfgMarkers" >> "WTF_Flag")) then {"WTF_FLAG"} else {"FLAG"}; _destname setMarkerType _markertype; _destname setMarkerColor _markercolor; _destname setMarkerText format["%1",_grpidx]; _destname setMarkerSize [.5,.5]; }; // delete dead units ============================================================================== _deletedead = ["DELETE:",0,_UCthis] call KRON_UPSgetArg; if (_deletedead>0) then { { _x addEventHandler['killed',format["[_this select 0,%1] spawn KRON_deleteDead",_deletedead]]; sleep 0.01; }forEach _members; }; // how many group clones? ========================================================================= // TBD: add to global side arrays? _mincopies = ["MIN:",0,_UCthis] call KRON_UPSgetArg; _maxcopies = ["MAX:",0,_UCthis] call KRON_UPSgetArg; if (_mincopies>_maxcopies) then {_maxcopies=_mincopies}; if (_maxcopies>140) exitWith {hint "Cannot create more than 140 groups!"}; if (_maxcopies>0) then { _copies=_mincopies+random (_maxcopies-_mincopies); // create the clones for "_grpcnt" from 1 to _copies do { // copy groups if (isNil ("KRON_grpindex")) then {KRON_grpindex = 0}; KRON_grpindex = KRON_grpindex+1; // copy group leader _unittype = typeof _npc; // make the clones civilians // use random Civilian models for single unit groups if ((_unittype=="Civilian") && (count _members==1)) then {_rnd=1+round(random 20); if (_rnd>1) then {_unittype=format["Civilian%1",_rnd]}}; _grp=createGroup side _npc; _lead = _grp createUnit [_unittype, getpos _npc, [], 0, "form"]; _lead setVehicleVarName format["l%1",KRON_grpindex]; call compile format["l%1=_lead",KRON_grpindex]; _lead setBehaviour _orgMode; _lead setSpeedmode _orgSpeed; _lead setSkill skill _npc; _lead setVehicleInit _initstr; [_lead] join _grp; _grp selectLeader _lead; // copy team members (skip the leader) _i=0; { _i=_i+1; if (_i>1) then { _newunit = _grp createUnit [typeof _x, getpos _x, [],0,"form"]; _newunit setBehaviour _orgMode; _newunit setSpeedMode _orgSpeed; _newunit setSkill skill _x; _newunit setVehicleInit _initstr; [_newunit] join _grp; }; } foreach _members; nul=[_lead,_areamarker,_pause,_noslow,_nomove,_nofollow,_initpos,_track,_showmarker,_shareinfo,"DELETE:",_dead] execVM "scripts\upsmon.sqf"; //sleep .05; }; processInitCommands; sleep .05; }; // units that can be left for area to be "cleared" ============================================================================================= _zoneempty = ["EMPTY:",0,_UCthis] call KRON_UPSgetArg; // create area trigger ========================================================================================================================= if (_areatrigger!="NOTRIGGER") then { _trgside = switch (side _npc) do { case west: {"WEST"}; case east: {"EAST"}; case resistance: {"GUER"}; case civilian: {"CIV"};}; //_trgside = switch (side _npc) do { case west: {"EAST"}; case east: {"WEST"}; case resistance: {"ANY"}; case civilian: {"ANY"};}; _trgname="KRON_Trig_"+_trgside+"_"+_areamarker; _flgname="KRON_Cleared_"+_areamarker; // has the trigger been created already? KRON_TRGFlag=-1; call compile format["%1=false",_flgname]; call compile format["KRON_TRGFlag=%1",_trgname]; if (isNil ("KRON_TRGFlag")) then { // trigger doesn't exist yet, so create one (make it a bit bigger than the marker, to catch path finding 'excursions' and flanking moves) call compile format["%1=createTrigger['EmptyDetector',_centerpos]",_trgname]; call compile format["%1 setTriggerArea[_rangeX*1.5,_rangeY*1.5,markerDir _areamarker,true]",_trgname]; call compile format["%1 setTriggerActivation[_trgside,'PRESENT',true]",_trgname]; call compile format["%1 setEffectCondition 'true'",_trgname]; call compile format["%1 setTriggerTimeout [5,7,10,true]",_trgname]; if (_areatrigger!="SILENTTRIGGER") then { call compile format["%1 setTriggerStatements['count thislist<=%6', 'titletext [''SECTOR <%2> LIMPIO'',''PLAIN''];''%2'' setmarkerpos [-%4,-%5];%3=true;', 'titletext [''SECTOR <%2> HA SIDO REOCUPADO'',''PLAIN''];''%2'' setmarkerpos [%4,%5];%3=false;']", _trgname,_areamarker,_flgname,_centerX,_centerY,_zoneempty]; } else { call compile format["%1 setTriggerStatements['count thislist<=%3', '%2=true;', '%2=false;']", _trgname,_flgname,_zoneempty]; }; }; sleep .05; }; //If a soldier has a useful building takes about ====================================================================================================================== if ( _nomove=="NOMOVE" ) then { sleep 10; _unitsIn = [_grpid,_npc,150] call MON_GetIn_NearestStatic; if ( count _unitsIn > 0 ) then { sleep 10}; [_npc, _buildingdist,false,_wait,true] spawn MON_moveNearestBuildings; }; // init done _newpos = false; _targetPos = [0,0,0];//_currPos; _targettext ="_currPos"; _swimming = false; _waiting = if (_nomove=="NOMOVE") then {9999} else {0}; _sharedist = if (_nomove=="NOMOVE") then {KRON_UPS_sharedist} else {KRON_UPS_sharedist*1.5}; //Gets position of waypoint if no targetpos if (format ["%1", _targetPos] == "[0,0,0]") then { _index = (count waypoints _grp) - 1; _wp = [_grp,_index]; _targetPos = waypointPosition _wp; if (([_currpos,_targetPos] call KRON_distancePosSqr)<= 20) then {_targetPos = [0,0,0];}; }; // *********************************************************************************************************** // ************************************************ MAIN LOOP ************************************************ // *********************************************************************************************************** _loop=true; scopeName "main"; while {_loop} do { //if (KRON_UPS_Debug>0) then {player sidechat format["%1: _cycle=%2 _currcycle=%3 _react=%4 _waiting=%5",_grpidx,_cycle,_currcycle,_react,_waiting]}; _timeontarget=_timeontarget+_currcycle; _react=_react+_currcycle; _waiting = _waiting - _currcycle; _lastreact = _lastreact + _currcycle; _newpos = false; _sokilled = false; _sowounded = false; // CHECK IF did anybody in the group got hit or die? if ((R_GOTHIT_ARRAY select _grpId) != 0) then { _gothit = true; if ((R_GOTHIT_ARRAY select _grpId) == 1) then { _sowounded = true; } else { _sokilled = true; }; sleep 0.01; R_GOTHIT_ARRAY set [_grpId, 0]; }; // nobody left alive, exit routine if (count _members==0) then { _exit=true; } else { // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; }; //exits from loop if (_exit) exitwith {}; //Checks if surrender is enabled if ( _surrender > 0 ) then { _surrended = call (compile format ["KRON_UPS_%1_SURRENDED",_side]); }; //If surrended exits from script if (_surrended) exitwith { { [_x] spawn MON_surrender; }foreach _members; if (KRON_UPS_Debug>0) then {_npc globalchat format["%1: %2 SURRENDED",_grpidx,_side]}; }; //Assign the current leader of the group in the array of group leaders KRON_NPCs set [_grpid,_npc]; // current position _currPos = getpos _npc; _currX = _currPos select 0; _currY = _currPos select 1; if (_track=="TRACK" || KRON_UPS_Debug>0) then { _trackername setmarkerpos _currPos; }; // if the AI is a civilian we don't have to bother checking for enemy encounters if ( _isSoldier && !_exit) then { _pursue=false; //_Behaviour = Behaviour _npc; //Variables to see if the leader is in a vehicle _incar = "LandVehicle" countType [vehicle (_npc)]>0; _inheli = "Air" countType [vehicle (_npc)]>0; _inboat = "Ship" countType [vehicle (_npc)]>0; //If the group is strengthened and the enemies have been detected are sent to target if (_rfid > 0 ) then { _rfidcalled = call (compile format ["KRON_UPS_reinforcement%1",_rfid]); // will be TRUE when variable in triger will be true. if (isnil "_rfidcalled") then {_rfidcalled=false}; _fixedtargetPos = call (compile format ["KRON_UPS_reinforcement%1_pos",_rfid]); // will be position os setfix target of sending reinforcement if (isnil "_fixedtargetPos") then { _fixedtargetPos=[0,0]; }else{ _fixedtargetPos = [abs(_fixedtargetPos select 0),abs(_fixedtargetPos select 1)]; _target = objnull; }; }; sleep .01; //Reinforcement control if (_reinforcement=="REINFORCEMENT") then { // (global call OR id call) AND !send yet if ( (KRON_UPS_reinforcement || _rfidcalled) && (!_reinforcementsent)) then { _reinforcementsent=true; _fortify = false; _minreact = KRON_UPS_minreact; _buildingdist = 60; _react = _react + 100; _waiting = -1; if (KRON_UPS_Debug>0) then {player sidechat format["%1 called for reinforcement %2",_grpidx,_fixedtargetPos]}; } else { // !(global or id call) AND send if ( !(KRON_UPS_reinforcement || _rfidcalled) && (_reinforcementsent)) then { _fixedtargetPos = [0,0]; _attackPos = [0,0]; _fortify = _fortifyorig; _reinforcementsent=false; if (_rfid > 0 ) then { call (compile format ["KRON_UPS_reinforcement%1_pos = [0,0]",_rfid]); call (compile format ["KRON_UPS_reinforcement%1 = false",_rfid]); }; if (KRON_UPS_Debug>0) then {player sidechat format["%1 reinforcement canceled",_grpidx]}; }; }; }; //Gets targets from radio _targets = call (compile format ["KRON_targets%1",_sharedenemy]); // if (KRON_UPS_Debug>0) then {player globalchat format["targets from global upsmon: %1",_targets]}; //!R //Reveal targets found by members to leader { //_NearestEnemy = assignedTarget _x; //if (KRON_UPS_Debug>0) then {player globalchat format["Nearest Enemy %1, know about %2",_NearestEnemy,_x knowsabout _NearestEnemy]}; //!R _NearestEnemy = _x findnearestenemy _x; if (_x knowsabout _NearestEnemy > R_knowsAboutEnemy && (_npc knowsabout _NearestEnemy <= R_knowsAboutEnemy || count _targets <= 0 )) then { if (_npc knowsabout _NearestEnemy <= R_knowsAboutEnemy ) then { _npc reveal _NearestEnemy; if (KRON_UPS_Debug>0) then {player globalchat format["%1: %2 reveals target %3 to leader",_grpidx,typeof _x, typeof _NearestEnemy]}; }; //If no targets adds this if (count _targets <= 0) then { //_target = _NearestEnemy; _targets = _targets + [_NearestEnemy]; _NearestEnemy setvariable ["UPSMON_lastknownpos", position _NearestEnemy, false]; //if (KRON_UPS_Debug>0) then {player globalchat format["%1: %3 added to targets",_grpidx,typeof _x, typeof _target]}; }; }; } foreach units _npc; //if no target but _npc knows enemy then this is _target if (isNull (_target)) then { { if ((_npc knowsabout _x > R_knowsAboutEnemy) && (alive _x) && (canmove _x)) then { _target =_x; if (!isNull (_target)) exitWith{}; }; } foreach _targets; }; //Resets distance to target _dist = 10000; //Gets current known position of target and distance if ( !isNull (_target) && alive _target ) then { _newattackPos = _target getvariable ("UPSMON_lastknownpos"); if ( !isnil "_newattackPos" ) then { _attackPos=_newattackPos; //Gets distance to target known pos _dist = ([_currpos,_attackPos] call KRON_distancePosSqr); }; }; //Initialization for geting new targets //If the current target is dead or no prior knowledge is cleaned if (isNull (_target) || !alive _target || !canmove _target ) then { _lastknown = 0; _opfknowval = 0; _target = objnull; }; _newtarget = _target; if ((_shareinfo=="SHARE")) then { //Requests for radio the enemy's position, if it is within the range of acts if ((KRON_UPS_comradio == 2)) then { _targetsnear = false; //I we have a close target alive do not search another if (!alive _target || !canmove _target || _dist > _closeenough) then { { if ( !isnull _x && canmove _x && alive _x ) then { _newattackPos = _x getvariable ("UPSMON_lastknownpos"); if ( !isnil "_newattackPos" ) then { _dist3 = ([_currpos,_newattackPos] call KRON_distancePosSqr); //Sets if near targets to begin warning IF ( _dist3 <= (_closeenough + KRON_UPS_safedist)) then { _targetsnear = true }; //Sets new target if ( ( isnull (_newtarget) || captive _newtarget|| !alive _newtarget|| !canmove _newtarget || _dist3 < _dist ) && ( _dist3 <= _sharedist || _reinforcementsent ) && ( !(_x iskindof "Air") || (_x iskindof "Air" && _isplane )) && ( !(_x iskindof "Ship") || (_x iskindof "Ship" && _isboat )) && ( _x emptyPositions "Gunner" == 0 && _x emptyPositions "Driver" == 0 || (!isnull (gunner _x) && canmove (gunner _x)) || (!isnull (driver _x) && canmove (driver _x))) ) then { _newtarget = _x; _opfknowval = _npc knowsabout _x; _dist = _dist3; if (_dist < _closeenough) exitWith {}; }; }; }; } foreach _targets; sleep 0.5; }; }; //If you change the target changed direction flanking initialize if ( !isNull (_newtarget) && alive _newtarget && canmove _newtarget && (_newtarget != _target || isNull (_target)) ) then { _timeontarget = 0; _targetdead = false; _flankdir= if (random 100 <= 10) then {0} else {_flankdir}; _target = _newtarget; }; }; // use smoke when hit or s/o killed if !_nosmoke then { { //when hit if (_sowounded && random 100 < R_USE_SMOKE_wounded) then { nul = [_x,_target] spawn MON_throw_grenade; // if (KRON_UPS_Debug>0) then {player sidechat format["%1: We got wounded smoking!",_grpidx]}; }; //when die if (_sokilled && random 100 < R_USE_SMOKE_killed) then { nul = [_x,_target] spawn MON_throw_grenade; //if (KRON_UPS_Debug>0) then {player sidechat format["%1: We got killed one, smoking!",_grpidx]}; }; sleep 0.1; } foreach _members; }; //Gets current known position of target and distance if ( !isNull (_target) && alive _target ) then { //Enemy detected if (_fightmode != "fight" ) then { _fightmode = "fight"; _npc setCombatMode "YELLOW"; // !R _react = KRON_UPS_react; if (KRON_UPS_Debug>0) then {player sidechat format["%1: Enemy detected %2",_grpidx, typeof _target]}; if (_nowpType == 1) then { nul = [_npc] call R_FN_deleteObsoleteWaypoints; _nowp = false; }; }; _newattackPos = _target getvariable ("UPSMON_lastknownpos"); if ( !isnil "_newattackPos" ) then { _attackPos=_newattackPos; //Gets distance to target known pos _dist = ([_currpos,_attackPos] call KRON_distancePosSqr); //Looks at target known pos _members lookat _attackPos; }; }; //If the enemy has moved away from the radio coverage is not a reinforcement sent we will have lost track if ( _fightmode != "walk" && !isnull(_target) && _dist < 15 && _npc knowsabout _target < R_knowsAboutEnemy ) then { //If squad is near last position and no target clear position of target if (KRON_UPS_Debug>0) then {player sidechat format["%1: Target lost",_grpidx]}; _fightmode="walk"; _speedmode = _orgSpeed; _target = objnull; _Behaviour = _orgMode; _waiting = -1; _unitpos = "AUTO"; _pursue=false; _targetdead = true; _makenewtarget = true; //Go back to the original position }; //If knowledge of the target increases accelerate the reaction if (_opfknowval>_lastknown ) then { _react = _react + 20; }; // if spotted an enemy or got shot, so start pursuit, if in combat and exceed time to react or movecompleted if (_fightmode != "walk" && ((_react >= KRON_UPS_react && _lastreact >=_minreact) || moveToCompleted _npc )) then { _pursue=true; }; //Ambush ========================================================================================================== if (_ambush && !_ambushed) then { _ambushed = true; _nowp = true; _currcycle = 2; _grp setFormation "LINE"; _npc setBehaviour "STEALTH"; _npc setSpeedMode "FULL"; sleep 10; { [_x,"DOWN"] spawn MON_setUnitPos; _x stop true; }foreach units _npc; //Puts a mine if near road if ( KRON_UPS_useMines && _ambushType == 1 ) then { if (KRON_UPS_Debug>0) then {player sidechat format["%1: Puting mine for ambush",_grpidx]}; _npc setBehaviour "careless"; _dir1 = getDir _npc; _mineposition = [position _npc,_dir1, 25] call MON_GetPos2D; _roads = _mineposition nearroads KRON_UPS_ambushdist; if (count _roads > 0) then { _mineposition = position (_roads select 0); if (_Mines > 0 && [_npc,_mineposition] call MON_CreateMine) then {_Mines = _Mines -1;}; if (count _roads > 3) then { _mineposition = position (_roads select 3); if (_Mines > 0 && [_npc,_mineposition] call MON_CreateMine) then {_Mines = _Mines -1;}; }; } else { _mineposition = [position _npc,(_dir1-30)mod 360, KRON_UPS_ambushdist + random 15] call MON_GetPos2D; if (_Mines > 0 && [_npc,_mineposition] call MON_CreateMine) then {_Mines = _Mines -1;}; _mineposition = [position _npc,(_dir1+30)mod 360, KRON_UPS_ambushdist + random 15] call MON_GetPos2D; if (_Mines > 0 && [_npc,_mineposition] call MON_CreateMine) then {_Mines = _Mines -1;}; }; _mineposition = [position _npc,_dir1, KRON_UPS_ambushdist + random 20] call MON_GetPos2D; if ([_npc,_mineposition] call MON_CreateMine) then {_Mines = _Mines -1;}; _mineposition = [position _npc,_dir1-15, KRON_UPS_ambushdist + random 10] call MON_GetPos2D; if ([_npc,_mineposition] call MON_CreateMine) then {_Mines = _Mines -1;}; _npc setBehaviour "carelesscareless"; sleep 30; { if (!stopped _x) then { _x domove position _npc; waituntil {moveToCompleted _x || moveToFailed _x || !alive _x || !canmove _x || _x distance _npc <= 5}; }; }foreach units _npc; }; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; _npc setBehaviour "STEALTH"; _grp setFormation "LINE"; sleep 10; { [_x,"DOWN"] spawn MON_setUnitPos; _x stop true; _x setUnitPos "DOWN"; }foreach units _npc; }; // end of ambush mine //Ambus enemy is nearly aproach //_ambushdist = 50; if (_ambush) then { _prov = ((_ambushdist*2 - (_npc distance _target))*3) - 40; //if (KRON_UPS_Debug>0) then {player sidechat format["%1:%6 _ambushdist=%5 last=%2 dist=%3 prov=%4",_grpidx,_lastdist,_npc distance _target,_prov,_ambushdist,typeof _target]}; if (_gothit || _reinforcementsent || time > _ambushwait || ( "Air" countType [_target]<=0 && ( _npc distance _target <= _ambushdist + random 10 || (!isNull (_target) && (( random 100 <= _prov && _npc distance _target > _lastdist) || _npc distance _target > _ambushdist*3 && _lastdist < _ambushdist*3 && _lastdist > 0)) )) ) then { if (KRON_UPS_Debug>0) then {player sidechat format["%1: FIREEEEEEEEE!!!",_grpidx]}; _nowp = false; _ambush = false; _ambushed = false; _currcycle = _cycle; { _x stop false; _x setUnitPos "Middle"; } foreach _members; //No engage yet _pursue = false; }; //Sets distance to target _lastdist = _npc distance _target; }; // end of ambush //if (KRON_UPS_Debug>0) then {player sidechat format["%1: _nowp=%2 in vehicle=%3 _inheli=%4 _npc=%5",_grpidx,_nowp,vehicle (_npc) ,_inheli,typeof _npc ]}; //If in vehicle take driver if not controlled by user if (alive _npc && !_nowp) then { if (!_isman || (vehicle (_npc) != _npc && !_inboat && !(vehicle (_npc) iskindof "StaticWeapon"))) then { //If new target is close enough getout vehicle (not heli) _unitsin = []; if (!_inheli) then { if (_fightmode == "walk") then { _GetOutDist = _area / 20; }else{ _GetOutDist = _closeenough * ((random .4) + 0.6); }; //If near target or stuck getout of vehicle and lock or gothit exits inmediately if (_gothit || _dist <= _closeenough * 1.5 || (_lastcurrpos select 0 == _currpos select 0 && _lastcurrpos select 1 == _currpos select 1 && moveToFailed (vehicle (_npc))) || moveTocompleted (vehicle (_npc))) then { _GetOutDist = 10000; }; //if (KRON_UPS_Debug>0) then {player sidechat format["%1: vehicle=%2 _npc=%3",_grpidx,vehicle (_npc) ,typeof _npc ]}; _unitsin = [_npc] call R_FN_allUnitsInCargo; // return units in cargo in all vehs used by the group private ["_handle1"]; _handle1 = [_npc,_targetpos,_GetOutDist] spawn R_SN_GetOutDist; // getout if as close as _GetOutDist to the target _timeout = time + 10; waitUntil {scriptDone _handle1 || time > _timeout}; } else { _GetOutDist = 0; }; // if there was getout of the cargo if (count _unitsin > 0) then { //if (KRON_UPS_Debug>0) then {player sidechat format["%1: Geting out of vehicle, dist=%2 atdist=%3 _area=%4",_grpidx,([_currpos,_targetpos] call KRON_distancePosSqr),_GetOutDist,_area]}; _timeout = time + 7; { waituntil {vehicle _x == _x || !canmove _x || !alive _x || time > _timeout || movetofailed _x }; } foreach _unitsin; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; if (_fightmode == "fight" || _gothit) then { _npc setBehaviour "COMBAT"; // AWARE _groupOne = group _npc; _groupOne setFormation "DIAMOND"; nul = [_npc,30] spawn MON_move; }; sleep 0.2; // select leader outside of vehicle { if (alive _x && canmove _x) exitwith {group _x selectLeader _x; _npc = _x}; } foreach _unitsin; if (_fightmode == "fight") then { _pursue = true; }else { _pursue = false; _makenewtarget=true; }; }; }; }; //If under attack or increasing knowledge speeds up the response and regain control of the AI if (_gothit) then { _react = if (!_supressed) then {_react + 30}; if (_fightmode != "walk") then { if (_nowpType != 3) then { nul = [_npc] call R_FN_deleteObsoleteWaypoints; _nowp = false; }; }; }; //If there is no objective order is canceled persecution if ((isNull (_target) || !alive _target )) then { _pursue=false; if (_gothit && !_fortify && !_nowp) then { if ((_fightmode == "walk")) then { //It could be a sniper, better be alert and move in case _Behaviour = "COMBAT"; _speedmode = "FULL"; _unitpos = "AUTO"; _gothit = false; _makenewtarget = true; _waiting = -1; if ((random 100 < 20) && !_nosmoke) then { nul= [_npc,_target] spawn MON_throw_grenade; }; if (KRON_UPS_Debug>0) then {player sidechat format["%1: Have been damaged moving",_grpidx,_makenewtarget]}; } else { if ((_react >= KRON_UPS_react && _lastreact >=_minreact && count _targets <= 0) || _sowounded) then { //We shoot and we have no target, we move from position if (KRON_UPS_Debug>0) then {player sidechat format["%1: Under fire by unkown target, moving to newpos",_grpidx]}; //Covers the group with a smoke grenade if (!_supressed && (random 100 < 80) && !_nosmoke) then { nul= [_npc,_target] spawn MON_throw_grenade; }; _gothit = false; _makenewtarget = true; _waiting = -1; _pause="NOWAIT"; _speedmode = "FULL"; _unitpos = "middle"; _Behaviour = "AWARE"; } else { if (_lastreact >=_minreact && !_targetdead) then { _targetdead = true; _pursue = true; //We have run out of targets continue to search if (KRON_UPS_Debug>0) then {player sidechat format["%1: Target defeated, searching",_grpidx]}; }; }; }; }; }; //If no fixed target check if current target is available if (format ["%1",_fixedtargetPos] != "[0,0]") then { //If fixed target check if close enough or near enemy and gothit if (([_currpos,_fixedtargetpos] call KRON_distancePosSqr) <= _closeenough || (_dist <= _closeenough && _gothit)) then { _fixedtargetPos = [0,0]; } else { _pursue = false; _attackPos=_fixedtargetPos; if (_react >= KRON_UPS_react && _lastreact >=_minreact) then { _makenewtarget = true; _unitpos = "AUTO"; _speed = "FULL"; }; }; }; //If captive or surrended do not pursue if ( isnil "_attackPos") then {_pursue = false;}; if ( captive _target || format ["%1", _attackPos] == "[0,0]") then {_pursue = false;}; //If no waypoint do not move if (_nowp) then { _makenewtarget = false; _pursue = false; }; if (_inheli) then { _landing = _heli getVariable "UPSMON_landing"; if (isnil ("_landing")) then {_landing=false;}; if (_landing) then { _pursue = false; }; }; sleep 0.5; // ********************************************************************************************************************** // PURSUE: CHASE BEGINS THE LENS // ********************************************************************************************************************** if (_pursue) then { // if (KRON_UPS_Debug>0) then {player sidechat format["%1: is in pursure",_grpidx]}; _pursue = false; _newpos = true; _react = 0; _lastreact = 0; _timeontarget = 0; _makenewtarget = false; _fm = 1; //Cancel supress effect when reaction time _supressed = false; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; // get position of spotted unit in player group, and watch that spot _targetPos = _attackPos; _targetX = _targetPos select 0; _targetY = _targetPos select 1; _currPos = getpos _npc; // also go into "combat mode" _pause="NOWAIT"; _waiting=0; // angle from unit to target _dir1 = [_currPos,_targetPos] call KRON_getDirPos; // angle from target to unit (reverse direction) _dir2 = (_dir1+180) mod 360; //Establecemos una distancia de flanqueo _flankdist = ((random 0.5)+0.7)*KRON_UPS_safedist; //La distancia de flanqueo no puede ser superior a la distancia del objetivo o nos pordra pillar por la espalda _flankdist = if ((_flankdist*1.40) >= _dist) then {_dist*.65} else {_flankdist}; if (_inheli) then {_flankdist = _flankdist / 2;}; // avoidance position (right or left of unit) _avoidPos = [_currPos,_dir2, KRON_UPS_safedist] call MON_GetPos2D; //Calculamos posicin de avance frontal _frontPos = [_targetPos,_dir2, _flankdist] call MON_GetPos2D; //Adaptamos el ngulo de flanqueo a la distancia _newflankAngle = ((random(KRON_UPS_flankAngle)+1) * 2 * (_flankdist / KRON_UPS_safedist )) + (KRON_UPS_flankAngle/1.4) ; if (_newflankAngle > KRON_UPS_flankAngle) then {_newflankAngle = KRON_UPS_flankAngle}; //Calculamos posicin de flanqueo 1 45 _dirf1 = (_dir2+_newflankAngle) mod 360; _flankPos = [_targetPos,_dirf1, _flankdist] call MON_GetPos2D; //Calculamos posicin de flanqueo 2 -45 _dirf2 = (_dir2-_newflankAngle+360) mod 360; _flankPos2 = [_targetPos,_dirf2, _flankdist] call MON_GetPos2D; if (KRON_UPS_Debug>0) then { "flank1" setmarkerpos _flankPos; "flank2" setmarkerpos _flankPos2; "target" setmarkerpos _attackPos; }; //Decidir por el mejor punto de flanqueo //Contamos las posiciones de destino de otros grupos ms alejadas _fldest = 0; _fldest2 = 0; _fldestfront = 0; _i = 0; { if (_i != _grpid && format ["%1", _x] != "[0,0]") then { _dist1 = [_x,_flankPos] call KRON_distancePosSqr; _dist2 = [_x,_flankPos2] call KRON_distancePosSqr; _dist3 = [_x,_frontPos] call KRON_distancePosSqr; if (_dist1 <= _flankdist/1.5 || _dist2 <= _flankdist/1.5 || _dist3 <= _flankdist/1.5) then { if (_dist1 < _dist2 && _dist1 < _dist3) then {_fldest = _fldest + 1;}; if (_dist2 < _dist1 && _dist2 < _dist3) then {_fldest2 = _fldest2 + 1;}; if (_dist3 < _dist1 && _dist3 < _dist2) then {_fldestfront = _fldestfront + 1;}; }; }; _i = _i + 1; sleep 0.01; } foreach KRON_targetsPos; //We have the positions of other groups more distant _i = 0; { if (_i != _grpid && !isnull(_x)) then { _dist1 = [getpos(_x),_flankPos] call KRON_distancePosSqr; _dist2 = [getpos(_x),_flankPos2] call KRON_distancePosSqr; _dist3 = [getpos(_x),_frontPos] call KRON_distancePosSqr; if (_dist1 <= _flankdist/1.5 || _dist2 <= _flankdist/1.5 || _dist3 <= _flankdist/1.5) then { if (_dist1 < _dist2 && _dist1 < _dist3) then {_fldest = _fldest + 1;}; if (_dist2 < _dist1 && _dist2 < _dist3) then {_fldest2 = _fldest2 + 1;}; if (_dist3 < _dist1 && _dist3 < _dist2) then {_fldestfront = _fldestfront + 1;}; }; }; _i = _i + 1; sleep 0.01; } foreach KRON_NPCs; //La preferencia es la eleccin inicial de direccin switch (_flankdir) do { case 1: {_prov = 125}; case 2: {_prov = -25}; default {_prov = 50}; }; //Si es positivo significa que hay ms destinos existentes lejanos a la posicion de flanqueo1, tomamos primariamente este if (_fldest<_fldest2) then {_prov = _prov + 50;}; if (_fldest2<_fldest) then {_prov = _prov - 50;}; //Si la provablilidad es negativa indica que tomar el flank2 por lo tanto la provabilidad de coger 1 es 0 if (_prov<0) then {_prov = 0;}; //Evaluamos la direccin en base a la provablilidad calculada if ((random 100) <= _prov) then { _flankdir =1; _flankPos = _flankPos; _targettext = "_flankPos"; } else { _flankdir =2; _flankPos = _flankPos2; _targettext = "_flankPos2"; }; //Posicin de ataque por defecto el flanco _targetPos = _flankPos; _targettext = "_flankPos"; if ((surfaceIsWater _flankPos && !(_isplane || _isboat)) ) then { _targetPos = _attackPos;_targettext ="_attackPos"; _flankdir =0; } else { if (_fldestfront < _fldest && _fldestfront < _fldest2) then { _targetPos = _frontPos;_targettext ="_frontPos"; }; }; //Establish the type of waypoint //DESTROY has worse behavior with and sometimes do not move _wptype = "MOVE"; //Set speed and combat mode _rnd = random 100; if ( _dist <= _closeenough ) then { //If we are so close we prioritize discretion fire if ( _dist <= _closeenough/2 ) then { //Close combat modeo _speedmode = "LIMITED"; _wpformation = "LINE"; _unitpos = "Middle"; _react = _react + KRON_UPS_react / 2; _minreact = KRON_UPS_minreact / 2; if ((_nomove == "NOMOVE" && _rnd < 25) && !_reinforcementsent) then { //Defensive combat _Behaviour = "STEALTH"; _wptype = "HOLD"; } else { if (_rnd < 80) then { _Behaviour = "COMBAT"; } else { _Behaviour = "STEALTH"; }; _wptype = "MOVE"; } } else { //If the troop has the role of not moving tend to keep the position _speedmode = "NORMAL"; _wpformation = "VEE"; //or WEDGE _unitpos = "Middle"; _minreact = KRON_UPS_minreact / 1.5; if ((_nomove == "NOMOVE" && _rnd < 50) && !_reinforcementsent) then { //Combate defensivo _Behaviour = "COMBAT"; _wptype = "HOLD"; } else { if (_rnd < 80) then { _Behaviour = "AWARE"; } else { _Behaviour = "COMBAT"; }; _wptype = "MOVE"; }; }; } else { if (( _dist <= (_closeenough + KRON_UPS_safedist))) then { _speedmode = "FULL"; _wpformation = "WEDGE"; _unitpos = if (_rnd < 90) then {"Middle"} else {"AUTO"}; _minreact = KRON_UPS_minreact; if ((_nomove=="NOMOVE" && _rnd < 75) && !_reinforcementsent) then { //Combate defensivo _Behaviour = "COMBAT"; //AWARE _wptype = "HOLD"; } else { //Movimiento con precaucin (ms rpido) _Behaviour = "AWARE"; _wptype = "MOVE"; }; } else { //In May distance of radio patrol act.. if (( _dist < KRON_UPS_sharedist )) then { //Platoon from the target must move fast and to the point _Behaviour = "AWARE"; _speedmode = "FULL"; _unitpos = if (_rnd < 60) then {"Middle"} else {"AUTO"}; _minreact = KRON_UPS_minreact * 2; if ((_nomove=="NOMOVE" && _rnd < 95) && !_reinforcementsent) then { _wptype = "HOLD"; _wpformation = "WEDGE"; } else { _wptype = "MOVE"; _wpformation = "WEDGE"; }; } else { //Platoon very far from the goal if not move nomove role _Behaviour = "SAFE"; _speedmode = "FULL"; _unitpos = "AUTO"; _minreact = KRON_UPS_minreact * 3; if (((_nomove=="NOMOVE") || (_nomove=="MOVE" && _rnd < 70)) && !_reinforcementsent) then { _wptype = "HOLD"; _wpformation = "WEDGE"; }else{ _wptype = "MOVE"; _wpformation = "FILE"; //COLUMN }; }; }; }; //Always keep the brackets fortified position if ( _fortify && random 100 < 99) then {_wptype = "HOLD"}; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; //If leader is in vehicle will move in anyway if (vehicle _npc != _npc || !_isman) then { _wptype = "MOVE"; _Behaviour = "AWARE"; if ( _inheli ) then { _speedmode = "FULL"; _unitpos = "AUTO"; _targetPos = _AttackPos; }; }; //Establecemos el target KRON_targetsPos set [_grpid,_targetPos]; sleep 0.01; //If use statics are enabled leader searches for static weapons near. // Tanks enemies are contabiliced if ( KRON_UPS_useMines && _Mines > 0 ) then { _enemytanksnear = false; { if ( ("Tank" countType [_x] > 0 || "Wheeled_APC" countType [_x] >0 || "Tank" countType [vehicle _x] > 0 || "Wheeled_APC" countType [vehicle _x] >0 ) && alive _x && canMove _x && _npc distance _x <= _closeenough + KRON_UPS_safedist ) exitwith { _enemytanksnear = true; _enemytanknear = _x;}; } foreach _targets; //If use mines are enabled and enemy armors near and no friendly armor put mine. if ( _enemytanksnear && !isnull _enemytanknear && alive _enemytanknear ) then { _friendlytanksnear = false; { if (!( alive _x && canMove _x)) then {_friendlytanks = _friendlytanks - [_x]}; if (alive _x && canMove _x && _npc distance _x <= _closeenough + KRON_UPS_safedist ) exitwith { _friendlytanksnear = true;}; }foreach _friendlytanks; if (!_friendlytanksnear && random(100)<30 ) then { _dir1 = [_currPos,position _enemytanknear] call KRON_getDirPos; _mineposition = [position _npc,_dir1, 25] call MON_GetPos2D; _roads = _mineposition nearroads 50; if (count _roads > 0) then {_mineposition = position (_roads select 0);}; if ([_npc,_mineposition] call MON_CreateMine) then { _Mines = _Mines -1; if (KRON_UPS_Debug>0) then {player sidechat format["%1: %3 puting mine for %2",_grpidx,typeof _enemytanknear, side _npc]}; }; }; }; }; //Si es unidad de refuerzo siempre acosar al enemigo if (_reinforcementsent) then { _wptype="MOVE"; _newpos=true; _makenewtarget = false; }; if (_nofollow=="NOFOLLOW" && _wptype != "HOLD") then { _targetPos = [_targetPos,_centerpos,_rangeX,_rangeY,_areadir] call KRON_stayInside; _targetdist = [_currPos,_targetPos] call KRON_distancePosSqr; if ( _targetdist <= 1 ) then { _wptype="HOLD"; }; }; if (_wptype == "HOLD") then { _targetPos = _currPos; _targettext ="_currPos"; }; //Is updated with the latest value, changing the target _lastknown = _opfknowval; //If for whatever reason cancels the new position should make clear the parameters that go into pursuit if (!_newpos) then { //If the unit has decided to maintain position but is being attacked is being suppressed, should have the opportunity to react _newpos = _gothit; if (!_newpos) then { _targetPos=_lastpos; if (KRON_UPS_Debug>0) then {player sidechat format["%1 Mantaining orders %2",_grpidx,_nomove]}; }; }; if (KRON_UPS_Debug>=1) then { "avoid" setmarkerpos _avoidPos; "flank" setmarkerpos _flankPos; _destname setMarkerPos _targetPos; }; }; //END PURSUE sleep 0.1; }; //((_isSoldier) && ((count _enemies)>0) // ********************************************************************************************************************** // NO NEWS // ********************************************************************************************************************** if !(_newpos) then { // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; // calculate new distance // if we're waiting at a waypoint, no calculating necessary _currpos = getpos _npc; //Sets behaviour of squad if nearly changes of target if (_targetsnear) then{ if (( toUpper(_Behaviour) IN _safemode) && _isSoldier) then { _Behaviour = "AWARE"; _npc setBehaviour _Behaviour; }; }; //If in safe mode if find dead bodies change behaviour if (toUpper(_Behaviour) IN _safemode) then { _unitsin = [_npc,_buildingdist] call MON_deadbodies; if (count _unitsin > 0) then { if !_isSoldier then { _npc setSpeedMode "FULL"; } else { if ( random 100 < 75) then { _Behaviour = "AWARE"; } else { _Behaviour = "COMBAT"; }; _react = _react + 30; _npc setBehaviour _Behaviour; if (KRON_UPS_Debug>0) then {player sidechat format["%1 dead bodies found! set %2",_grpidx,_Behaviour, count _targets]}; }; }; }; //Stuck control if (!_nowp && alive _npc && canmove _npc && _wptype == "MOVE" && _timeontarget >= 60 && _lastcurrpos select 0 == _currpos select 0 && _lastcurrpos select 1 == _currpos select 1) then { [_npc] call MON_cancelstop; _makenewtarget = true; if (KRON_UPS_Debug>0) then {player sidechat format["%1 stucked, moving",_grpidx]}; }; _lastpos = _targetPos; _lastcurrpos = _currpos; //sets last currpos for avoiding stuk if (_waiting<0) then { //Gets distance to targetpos _targetdist = [_currPos,_targetPos] call KRON_distancePosSqr; //It assesses whether it has exceeded the maximum waiting time and the objective is already shot to return to the starting position. if (_fightmode!="walk") then { if (_timeontarget > KRON_UPS_alerttime && count _targets <= 0 && ( isNull (_target) || !alive (_target) || captive _target)) then { _pursue = false; _gothit = false; _targetdead = true; _fightmode = "walk"; _speedmode = _orgSpeed; _targetPos = _currPos; _reinforcementsent = false; _target = objnull; _fixedtargetPos = [0,0]; _Behaviour = _orgMode; _waiting = -1; _unitpos = "AUTO"; _wpformation = "WEDGE"; KRON_UPS_reinforcement = false; //there is no threat if (_rfid > 0 ) then { call (compile format ["KRON_UPS_reinforcement%1 = false;",_rfid]); }; {[_x,"AUTO"] spawn MON_setUnitPos;} foreach units _npc; _npc setBehaviour _orgMode; if (KRON_UPS_Debug>0) then {player sidechat format["%1 Without objectives, leaving combat mode",_grpidx]}; }; }; //if (KRON_UPS_Debug>0) then {player globalchat format["%1 _targetdist %2 atdist=%3 dist=%4",_grpidx, _targetdist, _area/8,_dist]}; // if not in combat and we're either close enough, seem to be stuck, or are getting damaged, so find a new target if (!_nowp && (!_gothit) && (!_swimming) && (_fightmode == "walk") && (( _targetdist <= (_area/4) || moveToFailed _npc) && (_timeontarget > KRON_UPS_maxwaiting))) then { _makenewtarget=true; _unitpos = "AUTO"; _Behaviour = _orgMode; }; // make new target if (_makenewtarget) then { _gothit = false; _react = 0; _lastreact = 0; _makenewtarget = false; _timeontarget = 0; _wptype = "MOVE"; if (format ["%1",_fixedtargetPos] !="[0,0]") then { _targetPos = _fixedtargetPos; _targettext ="Reinforcement"; } else { if ((_nomove=="NOMOVE") && (_timeontarget>KRON_UPS_alerttime)) then { if (KRON_UPS_Debug>0) then {player sidechat format["nomove: %1",_nomove]}; if (([_currPos,_orgPos] call KRON_distancePosSqr)<_closeenough) then { _newpos = false; _wptype = "HOLD"; _waiting = 9999; if (_fortify) then { _minreact = KRON_UPS_minreact * 3; _buildingdist = _buildingdist * 2; _wait = 3000; }; } else { _targetPos=_orgPos; _targettext ="_orgPos"; }; } else { //rStuckControl !R _rcurrPos = getpos _npc; if (_rlastPos select 0 == _rcurrPos select 0 && _rlastPos select 1 == _rcurrPos select 1) then { if (KRON_UPS_Debug>0) then {player sidechat format["%1 !RstuckControl try to move",_grpidx]}; if (vehicle _npc != _npc) then { _rstuckControl = _rstuckControl + 1; if (_rstuckControl > 1) then { _jumpers = crew (vehicle _npc); { _x spawn MON_doGetOut; sleep 0.5; } forEach _jumpers; } else { nul = [vehicle _npc] spawn MON_domove; } } else { nul = [_npc,25] spawn MON_domove; }; } else { _rstuckControl = 0; }; _rlastPos = _rcurrPos; // re-read marker position/size _centerpos = getMarkerPos _areamarker; _centerX = abs(_centerpos select 0); _centerY = abs(_centerpos select 1); _centerpos = [_centerX,_centerY]; _areasize = getMarkerSize _areamarker; _rangeX = _areasize select 0; _rangeY = _areasize select 1; _areadir = (markerDir _areamarker) * -1; // find a new target that's not too close to the current position _targetPos=_currPos; _targettext ="newTarget"; _tries=0; while {((([_currPos,_targetPos] call KRON_distancePosSqr) < _mindist)) && (_tries<50)} do { _tries=_tries+1; // generate new target position _targetPos = [_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; _loop2=FALSE; // boat or plane // if (KRON_UPS_Debug>0) then {player sidechat format["%1, type: %2",_npc, typeOf _npc]}; sleep 4; // if (KRON_UPS_Debug>0) then {player sidechat format["%1 isplane",_isplane]}; sleep 4; if (_isplane || _isboat) then { // boat if (_isboat) then { _tries2=0; while {(!_loop2) && (_tries2 <50)} do { _tries2=_tries2+1; _targetPosTemp = [_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; if (surfaceIsWater _targetPosTemp) then { _targetPos = _targetPosTemp; _loop2 = TRUE; // if (KRON_UPS_Debug>0) then {player sidechat format["%1 Boat just got new targetPos",_grpidx]}; }; sleep 0.05; }; // plane } else { _targetPos = [_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; // if (KRON_UPS_Debug>0) then {player sidechat format["%1 Plane just got new targetPos",_grpidx]}; }; // man or car } else { // "_onroad" if _onroad then { _tries2=0; while {(!_loop2) && (_tries2 <100)} do { _tries2=_tries2+1; _targetPosTemp = [_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; _roads = (_targetPosTemp nearRoads 50); if ((count _roads) > 0) then { _targetPosTemp = getpos (_roads select 0); _targetPos = _targetPosTemp; _loop2 = TRUE; // if (KRON_UPS_Debug>0) then {player sidechat format["%1 Onroad just got new targetPos",_grpidx]}; }; sleep 0.05; }; // any place on ground } else { _tries2=0; while {(!_loop2) && (_tries2 <100)} do { _tries2=_tries2+1; _targetPosTemp = [_centerX,_centerY,_rangeX,_rangeY,_cosdir,_sindir,_areadir] call KRON_randomPos; if (!surfaceIsWater _targetPosTemp) then { _targetPos = _targetPosTemp; _loop2 = TRUE; //if (KRON_UPS_Debug>0) then {player sidechat format["%1 Man just got new TP %2, %3",_grpidx,_targetPos,_tries2]}; }; sleep 0.05; }; }; }; }; }; }; sleep 0.05; // distance to target position _avoidPos = [0,0]; _flankPos = [0,0]; _attackPos = [0,0]; _frontPos = [0,0]; _fm=0; _newpos=true; }; }; }; // if in water, get right back out of it again if (surfaceIsWater _currPos) then { if (_isman && !_swimming) then { _drydist=999; // look around, to find a dry spot for [{_a=0}, {_a<=270}, {_a=_a+90}] do { _dp=[_currPos,30,_a] call KRON_relPos; if !(surfaceIsWater _dp) then {_targetPos=_dp}; }; _newpos=true; _swimming=true; }; } else { _swimming=false; }; sleep 0.5; // ********************************************************************************************************************** // NEWPOS: SE EJECUTA LA ORDEN DE MOVIMIENTO // ********************************************************************************************************************** // if (KRON_UPS_Debug>0) then {player sidechat format["%1 rea=%2 wai=%3 tim=%4 tg=%5 %6",_grpidx,_react,_waiting,_timeontarget,typeof _target,alive _target]}; if ((_waiting<=0) && _newpos) then { // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; _currPos = getpos _npc; _newpos = false; _waiting = -1; _swimming=false; _GetIn_NearestVehicles = false; //Gets distance to targetpos _targetdist = [_currPos,_targetPos] call KRON_distancePosSqr; //If gothit and not in vehicle if (_gothit && _npc == vehicle (_npc) && alive _npc ) then { //Unidad suprimida if ((random 100) <50) then { //if (KRON_UPS_Debug>0) then {player sidechat format["%1 supressed by fire",_grpidx]}; //The unit is deleted, delete the current waypoint _supressed = true; _targetPos = _currPos; _targettext ="SUPRESSED"; _wptype = "HOLD"; //Prone { //Motion vanishes if ( _x iskindof "Man" && canmove _x && alive _x) then { if ((random 100)<40 || (primaryWeapon _x ) in KRON_UPS_MG_WEAPONS) then {[_x,"DOWN",20] spawn MON_setUnitPosTime; }else{ [_x,"Middle"] spawn MON_setUnitPos;}; }; sleep 0.01; } foreach units _npc; //All Retreat!! if ((random 100)<=60 && morale _npc < 0) then { _targetPos = _avoidPos;_targettext = "_avoidPos"; _wptype = "MOVE"; _flankdir = 0; if (!_newpos && KRON_UPS_Debug>0) then {player sidechat format["%1 All Retreat!!!",_grpidx]}; }; }; if ((random 100) < 15 && _targettext == "_avoidPos" && !_nosmoke) then { [_npc,_target] call MON_throw_grenade; }; sleep 0.5; }; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; //If you have not been removed progress continue if (alive _npc) then { _currPos = getpos _npc; if ( _wptype == "MOVE") then { //Try to avoid stucked soldiers out of vehicles if ( _npc == vehicle _npc) then { { if (alive _x && canmove _x) then { //[_x] spawn MON_cancelstop; [_x] dofollow _npc; }; } foreach _members; }; sleep 0.05; //Search for vehicle if ((!_gothit && _targetdist >= ( KRON_UPS_searchVehicledist )) && _isSoldier && !_noveh) then { if ( vehicle _npc == _npc && _dist > _closeenough ) then { _unitsIn = [_grpid,_npc] call MON_GetIn_NearestVehicles; if ( count _unitsIn > 0) then { _GetIn_NearestVehicles = true; _speedmode = "FULL"; _unitpos = "AUTO"; _npc setbehaviour "SAFE"; _npc setspeedmode "FULL"; _timeout = time + 60; _vehicle = objnull; _vehicles = []; { waituntil {vehicle _x != _x || !canmove _x || !canstand _x || !alive _x || time > _timeout || movetofailed _x}; if ( vehicle _x != _x && (isnull _vehicle || _vehicle != vehicle _x)) then { _vehicle = vehicle _x ; _vehicles = _vehicles + [_vehicle] }; }foreach _unitsIn; sleep 1; { _vehicle = _x; _cargo = _vehicle getvariable ("UPSMON_cargo"); if ( isNil("_cargo")) then {_cargo = [];}; _cargo ordergetin true; //Wait for other groups to getin { waituntil {vehicle _x != _x || !canmove _x || !canstand _x || !alive _x || time > _timeout || movetofailed _x}; } foreach _cargo; //Starts gunner control nul = [_vehicle] spawn MON_Gunnercontrol; sleep 0.1; // nul = [_x,30] spawn MON_domove; //!R just little kick to make sure it moves } foreach _vehicles; //Cheks if leader has dead until wait _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc) exitwith {_exit=true;}; if ( "Air" countType [vehicle (_npc)]>0) then { _rnd = (random 2) * 0.1; _flyInHeight = round(KRON_UPS_flyInHeight * (0.9 + _rnd)); vehicle _npc flyInHeight _flyInHeight; //If you just enter the helicopter landing site is defined if (_GetIn_NearestVehicles) then { _GetOutDist = round(((KRON_UPS_paradropdist ) * (random 100) / 100 ) + 150); [vehicle _npc, _TargetPos, _GetOutDist, 90] spawn MON_doParadrop; // org _flyInHeight sleep 1; //Execute control stuck for helys [vehicle _npc] spawn MON_HeliStuckcontrol; if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: flyingheiht=%2 paradrop at dist=%3",_grpidx, _flyInHeight, _GetOutDist,_rnd]}; }; }; }; }; }; }; sleep 0.05; //Get in combat vehicles if (!_gothit && !_GetIn_NearestVehicles && _fightmode != "walk" && _isSoldier) then { _dist2 = _dist / 4; if ( _dist2 <= 100 ) then { _unitsIn = []; _unitsIn = [_grpid,_npc,_dist2,false] call MON_GetIn_NearestCombat; _timeout = time + (_dist2/2); if ( count _unitsIn > 0) then { if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: Geting in combat vehicle targetdist=%2",_grpidx,_npc distance _target]}; _npc setbehaviour "SAFE"; _npc setspeedmode "FULL"; { waituntil {vehicle _x != _x || !canmove _x || !canstand _x || !alive _x || time > _timeout || movetofailed _x}; }foreach _unitsIn; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; //Return to combat mode _npc setbehaviour _Behaviour; _timeout = time + 150; { waituntil {vehicle _x != _x || !canmove _x || !alive _x || time > _timeout || movetofailed _x}; }foreach _unitsIn; { if ( vehicle _x iskindof "Air") then { //moving hely for avoiding stuck if (driver vehicle _x == _x) then { _vehicle = vehicle (_x); nul = [_vehicle,1000] spawn MON_domove; //Execute control stuck for helys [_vehicle] spawn MON_HeliStuckcontrol; if (KRON_UPS_Debug>0 ) then {player sidechat format["%1: Geting in combat vehicle after",_grpidx,_npc distance _target]}; }; }; if (driver vehicle _x == _x) then { //Starts gunner control nul = [vehicle _x] spawn MON_Gunnercontrol; }; sleep 0.01; }foreach _unitsIn; }; }; }; sleep 0.05; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; //If use statics are enabled leader searches for static weapons near. if ((KRON_UPS_useStatics && (vehicle _npc == _npc) && !_GetIn_NearestVehicles && _isSoldier ) && ((_wptype == "HOLD" && (random 100) < 80) || (_wptype != "HOLD" && (random 100) < 60))) then { _unitsIn = [_grpid,_npc,_buildingdist] call MON_GetIn_NearestStatic; if ( count _unitsIn > 0) then { _npc setbehaviour "SAFE"; _npc setspeedmode "FULL"; _timeout = time + 60; { waituntil {vehicle _x != _x || !canmove _x || !alive _x || time > _timeout || movetofailed _x}; }foreach _unitsIn; }; sleep 0.05; }; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; //Buildings usage. if (!_GetIn_NearestVehicles) then { if ( _wptype == "HOLD" && vehicle _npc == _npc && ( _fortify ||(random 100) < 60) ) then { //if (KRON_UPS_Debug>0) then {player sidechat format["%1: Moving to nearest buildings",_grpidx]}; [_npc,_buildingdist,false,_wait] spawn MON_moveNearestBuildings; } else { //If we are close enough patrol in buildings for searching enemies if ((( _wptype != "HOLD" && vehicle _npc == _npc && (random 100) < 90 ) && _npc == vehicle _npc && _dist <= ( _closeenough ))) then { [_npc,_buildingdist,true] spawn MON_moveNearestBuildings; }; }; sleep 0.05; }; // did the leader die? _npc = [_npc,_members] call MON_getleader; if (!alive _npc || !canmove _npc || isplayer _npc ) exitwith {_exit=true;}; if (isnull _grp || _grp != group _npc) then { _grp = group _npc; }; _index = currentWaypoint _grp; //If the waypoing is different than it has or is different from what we set hold IF (_wptype != "HOLD" || _lastwptype != _wptype) then { //Has not completed or are waypoints //_index = 1 Waypoint by default, not use. if ( _index == 1 || _index > count waypoints _grp && !isnull _grp) then { _wp = _grp addWaypoint [_targetPos, 0]; _index = _wp select 1; // if (KRON_UPS_Debug>0) then {player sidechat format["%1: created wp %2 index %3",_grpidx,_wp, _index]}; } else { _wp = [_grp,_index]; // if (KRON_UPS_Debug>0) then {player globalchat format["%1: not created wp %2 index %3 %4",_grpidx,_wp, _index,_targetPos]}; }; }; // _wp = [_grp,_index]; // if iscar the run fast if targetpost is far. if ((!_gothit && _targetdist >= (_closeenough * 1.5)) && (vehicle _npc != _npc)) then { _speedmode = "FULL"; } else { // _speedmode = _orgSpeed; }; //We define the parameters of the new waypoint _wp setWaypointType _wptype; _wp setWaypointPosition [_targetPos, 0]; _wp setWaypointFormation _wpformation; _wp setWaypointSpeed _speedmode; _lastwptype = _wptype; //If you have more than 1 waypoints delete the obsolete { if ( _x select 1 < _index ) then { deleteWaypoint _x; }; sleep 0.05; } foreach waypoints _grp; //if (KRON_UPS_Debug>0) then {diag_log format["%1: waypoints %2 %3 %4 %5",_grpidx,count waypoints _grp, _grp, group _npc, group (leader _npc)]}; //Sets behaviour if (toupper(behaviour _npc) != toupper (_Behaviour)) then { _npc setBehaviour _Behaviour; }; //Refresh position vector KRON_targetsPos set [_grpid,_targetPos]; //Although there are predefined type of movement to a small percentage will vary on an individual level { if ((random 100)<95 && _x == vehicle _x && _x iskindof "Man" && !((primaryWeapon _x ) in KRON_UPS_MG_WEAPONS)) then { nul = [_x,_unitpos] spawn MON_setUnitPos; }else{ nul = [_x,"AUTO"] spawn MON_setUnitPos; }; } foreach units _npc; //If closeenough will leave some soldiers doing supress fire if (_gothit || _dist <= _closeenough) then { { if (!canStand _x || ((primaryWeapon _x ) in KRON_UPS_MG_WEAPONS) || (vehicle _x == _x && _x iskindof "Man" && (random 100) < 50) ) then { _x suppressFor 15; }; } foreach units _npc; }; }; _gothit = false; //if (KRON_UPS_Debug>0) then {player sidechat format["%1: %2 %3 %4 %5 %6 %7 %8 %9 %10",_grpidx, _wptype, _targettext,_dist, _speedmode, _unitpos, _Behaviour, _wpformation,_fightmode,count waypoints _grp];}; }; if (_track=="TRACK") then { switch (_fm) do { case 1: {_destname setmarkerSize [.4,.4]}; case 2: {_destname setmarkerSize [.6,.6]}; default {_destname setmarkerSize [.5,.5]}; }; _destname setMarkerPos _targetPos; }; //If in hely calculations must done faster if (_isplane || _inheli) then { _currcycle = _cycle/2; _flyInHeight = KRON_UPS_flyInHeight; vehicle _npc flyInHeight _flyInHeight; }; if ((_exit) || (isNil("_npc"))) then { _loop=false; } else { // slowly increase the cycle duration after an incident sleep _currcycle; }; }; //while {_loop} if (KRON_UPS_Debug>0) then {hint format["%1 exiting mainloop",_grpidx]}; //Limpiamos variables globales de este grupo KRON_targetsPos set [_grpid,[0,0]]; KRON_NPCs set [_grpid,objnull]; KRON_UPS_Exited=KRON_UPS_Exited+1; if (_track=="TRACK") then { //_trackername setMarkerType "Dot"; _trackername setMarkerType "Empty"; _destname setMarkerType "Empty"; }; //Gets dist from orinal pos if (!isnull _target) then { _dist = ([_orgpos,position _target] call KRON_distancePosSqr); }; // if (KRON_UPS_Debug>0) then {player sidechat format["%1 _dist=%2 _closeenough=%3",_grpidx,_dist,_closeenough]}; //does respawn of group ===================================================================================================== if (_respawn && _respawnmax > 0 && !_surrended && _dist > _closeenough) then { if (KRON_UPS_Debug>0) then {player sidechat format["%1 doing respawn",_grpidx]}; // copy group leader _unittype = _membertypes select 0; // make the clones civilians // use random Civilian models for single unit groups if ((_unittype=="Civilian") && (count _members==1)) then {_rnd=1+round(random 20); if (_rnd>1) then {_unittype=format["Civilian%1",_rnd]}}; _grp=createGroup _side; _lead = _grp createUnit [_unittype, _orgpos, [], 0, "form"]; _lead setVehicleInit _initstr; [_lead] join _grp; _grp selectLeader _lead; // copy team members (skip the leader) _i=0; { _i=_i+1; if (_i>1) then { _newunit = _grp createUnit [_x, _orgpos, [],0,"form"]; _newunit setVehicleInit _initstr; [_newunit] join _grp; sleep 0.1; }; } foreach _membertypes; if ( _lead == vehicle _lead) then { { if (alive _x && canmove _x) then { [_x] dofollow _lead; }; sleep 0.1; } foreach units _lead; }; { _targetpos = _orgpos findEmptyPosition [10, 200]; sleep .4; if (count _targetpos <= 0) then {_targetpos = _orgpos}; //if (KRON_UPS_Debug>0) then {player globalchat format["%1 create vehicle _newpos %2 ",_x,_targetpos]}; _newunit = _x createvehicle (_targetpos); } foreach _vehicletypes; //if (KRON_UPS_Debug>0) then {player globalchat format["%1 _vehicletypes: %2",_grpidx, _vehicletypes]}; //Set new parameters if (!_spawned) then { _UCthis = _UCthis + ["SPAWNED"]; if ((count _vehicletypes) > 0) then { _UCthis = _UCthis + ["VEHTYPE:"] + ["dummyveh"]; }; }; _UCthis set [0,_lead]; _respawnmax = _respawnmax - 1; _UCthis = ["RESPAWN:",_respawnmax,_UCthis] call KRON_UPSsetArg; sleep 0.1; _UCthis = ["VEHTYPE:",_vehicletypes,_UCthis] call KRON_UPSsetArg; // if (KRON_UPS_Debug>0) then {player globalchat format["%1 _UCthis: %2",_grpidx,_UCthis]}; //Exec UPSMON script _UCthis SPAWN UPSMON; sleep 0.1; processInitCommands; }; _friends=nil; _enemies=nil; _enemytanks = nil; _friendlytanks = nil; _roads = nil; _targets = nil; _members = nil; _membertypes = nil; _UCthis = nil; if (!alive _npc) then { deleteGroup _grp; }; while {true} do { playSound "wind"; sleep 8; };OggS (LCvorbisDwOggS H-vorbisXiph.Org libVorbis I 20040629vorbis)BCV1L ŀАU`$)fI)(yHI)0c1c1c 4d( Ij9g'r9iN8 Q9 &cnkn)% Y@H!RH!b!b!r!r * 2 L2餓N:騣:(B -JL1Vc]|s9s9s BCV BdB!R)r 2ȀАU GI˱$O,Q53ESTMUUUUu]Wvevuv}Y[}Y[؅]aaaa}}} 4d #9)"9d ")Ifjihm˲,˲ iiiiiiifYeYeYeYeYeYeYeYeYeYeYeYeY@h*@@qq$ER$r, Y@R,r4Gs4s=Qs8cQUaʡ'p`,H6t"THփ!O^Wݩ,åQ??kjn9LxV>/6xBIQ/VF@ŵj+_NDQŒ:7_jĚI(.Sh;e\y[J9"NΟ!D s Xh@L;9t|Nf?{i\K2](N9xxtSM*UXu0\TR3w%I~nld8 т8, CEV |g*DT0Ę>+eFL4ɴqZ4 s؃N§ TOC!<|GMS\kh I8;. t@}p}I}R:SFݔpɊЛ}L%)G)6mXElIl=r;$o=!l EfF o\xTTCz|$IQ1?Ĥ^9~hG+xH]V 6'I!,[ 0c.o[f2g_5Փ; 'F (@`5*kN0ax{S.,W m.{?Km ~Q ٦q-1'TzА}e8;/k ߈1V}P ~$2_y1v>Y3b'3G#U 2,ڱ_6]q`3/ۈism "}\(17.kPڍC' Ep% 9x=&t LKi鰋ƒ,Ai#UCFu-{W؝7>X͔"aQtzͽӅ%" /E1|C \mJ( *$AgJ($I:rB 9mu%$XꫜuL5]9.HlVFH"[(vHn`֚%NyS}(KY(v.f_oɊ+ҮI %Lz$ _v@ՓCGGe*,*I@w>q˕UH;+Ľ}/gi\m ~K=ti:[~gy<̼AAd+ Ш6`Bf` 5rrM&ܽx9FjVS薼%Y@".DEJ3;@( >њ렭L hsaRS@46G]p>g5~3ɓhdEk:RTTTuWf fGHBYYne`?E"Z0% 4Lk It k^I2l%( \uոTZ (=GӻȃCRh',X+NP^,}6UA=Y񂅞]7p40-4`k'S^lV@fn*䅮B.3j3p {:YdyP Wq=:vAз60kȆhUv@% IA|vtvdj`VIM h|YTTO i!) ](1N:)c{ m+! c ! lp x709wPʜO1N e QieU⛿u˘_mv/(>pƄ7b5ɝtDg4 jI #f}&DJ3O2c`I, bq 6{a:T$Cuy׬تҖ,iMLG3W ceЦbw+U,G9ZX 1M w(JA xOPp 8RٙC aM:m#lgޱiҊ]I_ws6u݉*ZfQ=Z|T z&H Uh3PXh OggS -[MWJIU}ؐ H.C3{ٷ}8ܛn?ncᖾU?V h!TT.nSm*.Q(q,KjU=V yKMxOSCjg='$^?ֆJf"? ."7aUxzw ?@V zhBBArQ4, lu>9ulUdC- `Җ4&Ѐ 03lϻS~h|n{ʭٹvFN%N|V&SwP%e*-(TA2+-āF3]h(I:x~!kW'8a3KYNuMqSЁeJ3^u 3bk#n͆.0ϵiZgEvh h޹,ʽY/4M0A4 E@ffKտY<>D9DIV=tPSުU"%WSvCń?HZiNb۹}!S(hw׌Ofe-Y^`X p^VhUR6N48l'q̿BGSB' r@ J44Ʈ#ĆV6؊=!C{%f3 Iيs6cV"UCY"'x@̦DG(H`RaH\Zlշo.ܥ 9Xl{}O6~yM+dCD耶Cm;f o-@[{2|\(Δ\E8TqyS@KUۦjz&}GWUe~zwhZ+H#ޒ(^-#$96dVu8@/KT-'27'xB(X/^xjȔsM,AF"Jmgs!& :8rՀ%OƳ&ATknCv}"In; A%,p"JX4UHZ|Iefpt3I| 6jeݹ钗|_@OSaP00⁌l.JWv}Zh8rjw6,lB-ڀpP@Cn бc<.!ѼfţͶQsZ0pb9xJ3tٯ7r[]%a|Vx8~Yč2;;R[`~ )i!$):nW}H^:\on~Q"=l7\tRiw]>O&>uIqIM{GN`v0Fa U6NN!yjlLg缸v  \OٜXPGrVj 5Wfzp/XH4 oՀ5^6+>=m~S8LFpEݨ?r@}Ilð!>^n!W4B`.':)RI } U݀z>z._6 Rm7z3IW:@Dژ95) wwif$06}YŠfQR{0p] @U_D!,T:@JHib?Gm˜BLda]3k|ҟ kt/b© יwngZT# K`l$~;J`Gcd3X/5 JP HDWpѤ4V]oFWdT@s™m4_0#R澨~k5%䫝6T$88:m;E*(-Wφ{d` L2_$t<iN>کxO+ E0AFu@ f8I. ۈ6k!Sʦ%^P vD207cũsĭOl]D]AiV;1]JkޔR uKM1N>JWVc[I- cf`BHt4q~t͝=-չ$=j*RZZFqu)dJZ}1zﺱ"\htR ySyEAp U>26!`,"?3-6<& >In) O `> e" {dԗi86}M_FL[yejTcpyx0U}@4hyx ~*`G%W]fbJ&0+{e6X:/EWxB=)3D[ .}2U)#^U@PA@0/-OBHݶE9|8Tlt-Р2/9x<>zm;N:ԇ h[`F 'i@B')Fk/m܍uCYcTVf Y2)0׾XxUjH2?7Y2ӉHhO.BCSIHcHO+OXQM /5 !Zg&h&.^JM;}5G\` CXQLbL_CQJֳؒ]Zgd`hȒﳝ3:rR]+^ӊ US3KЮB.+Qߢn˜~lF椡 7?gj}ڽm$Q+0 vT2K`,ۛdQ81m0PSz# ,-A2 ˶~ X ` MA#/ώ;4;_x86dfT(4@)Јr1R|<@MZ{J=GM&*4!^/\tRIrx'Y[w U #X=$X2SdP\0*D^Ζ~v\\Mi;D@B>O+i*50 by~Ss6ɏw6S S+S%@mrC3Y)+9XQ! ϛNUS=j_ss- \JTYB@_^\2βhvcbBa Kj K0 ca"쯺(!\ k]h&A<%k[ԆdW HU"`ewԩ$Pm@lz =bCht$?Malb3Gں..ciq@V'dnh c; dgNE yg lG2Aƚd"OggS ľ^mWI lPpgh`m03g+nkl NmSlV$ڢ>R CĪ2-&_*|޻Z^=6Dez҃*ZmSۀia*jY3ax{<i`_Q aAQӻw[IM;cCVn:it h$YP3 n ds~# }տȸS.T8jw OvF,eYxsrq e3G{ua+ԇn}zTxp `kʠMe LĀBkH)Nw*\&aEv[:Q刣K,5b] ~7!tT:@`3dN^ix22T+q/yA{,qjRwWrMaQaq(AP4do [}QLl{!E/^]IP,@T::AZˤ'EϬDw(Ȑa-+*`>.N97P-`yՙ?Sh /H>g Oc0dj:hEɯ7??lYOTI"0j&MA?%Yot[k*fUGus/ui7y9Su΋ў7Ǒd.VeVL WP\ 'f9ܯE5š% ,I  `R0 <{?࠹$'uxJ9I@w5 8j)eATL`.Ue iGJ|z 2w<4ossԭ8~ޗ9ALբR/+6,PHEAv@Qp.aO)hH!0Ы%_լ^*I6s9`C8o7je3zJΧg R| z~Lp#& Dqk0T(.t0IH 3RH#I1Cd.9h wУh`# B5<%Op:(s?Zd3u^@u4!.!AON @`bQ~Qgqe~FMM{{WRE8jyoC .~*BW% 2DCFy1c%PxE /C鵉kM^uH@&= *кo8! XMj1nVQ*(>*Wʋ1H AИtt w}ne2&Gjly!t8dЪ)-jUZJL2mJ2Zkw[$<9a3hl([LCI:pu}`CX] X+ik4R~'fiN@ m(9z@:g<Ҩc{ƶ^ a9@<$8q'1XXo c>}5ni=o=Ƞ}1A,DPa20~9di>5erYiu<͈yr&AOz' X*lυ0`$HV1 ڕ@?: w$?f9t !x#ZfBmutRVD-h@aYpu*, Q\@S[%! Y_Ȭ<7j(zXٜPF!j-ܯΆBD?e+`+ҳݸgQ=g?l xFٟ& ò5"P@7va|:˗QE‚O> sYJۏ w:6q7ڈkǑ̮ 4ShgT&:\ ;r-J&JHfCBMh \5ڌtȐ^tqÔxE͏//V;l̩-`W"SK1XD\~1)$QSqPgS6mN/WkZZɦ$4}~qEzA(.5) -ۗ]BbB<?Zf52TBTgwjJVB֌Xޱ욨-/Wǻ^˴{oJm)#4ys'PP~!emsfNì;^p;{34ί6/SR<mEPMSF2{%V]X56%yjL̖gwĸj@l"NjV\#ԊRiXo. V&wD:2B!@ie)q 15q[,uM8. .z_d@v[R/Cb 5/bJ U65Zڅ(΁ !f\Xh &7vc?Osa[N-w&JYd  /p~>"Pa}Ȕ1QL[ܕb.6=PKy^A>."@a~YQiu-wXBV `y>Z찔[V|'2h:^F~2YfH$6 8kX1Zx,/?V-[wz0su\J ]C@uZ"Dd@+pF&9S'QqO7t[Em ?LsTu2!3׋N 1yRSomnq737f4>ju%AaFbӀ RC$kznd{Wf TT0LhT' * !@KeT6ZeZ!:$ Kͦ[ڜq~&ijlT$rKd\8A]?@3uH GEE/Hv'拍 *-'DAȝjB1s?A@s-4 mDчHè@uǜl6r1p޼p x ,ܬi'I^^h)DuyTpiʹG5Rel0p …EKm_LjE_* bMune6IFTH=Q֋9>Tdy:ƐT'5T/bB>j5qjB b_t ݌ P:f@hM蒪JT=^ryx5='}0y)vw:s p3ۗ#fa .? ίjl&h}j`u'bݵs $Eڡ 7}s@!O Jgm(YitƁ @`v{ˍ= WwSUS:\Ta LPݩo^ᨿh<VnDTmG<YOW5Rzqoz:vB5.v Bwuf/h(dk'[}CCR3 !]ͣs"#NPv]}/I{=+[tL?jYC^:uwѤ2t ì0n6'b~M0b&=tDLFewK`QB͸j15\zzc/nFMI:4_ nD{&bd8Gp1ۉBڧ/}̘߮-RH0D~uOIp}#w;@1qiCn4`–dd(}]~ _;U3$'2n D~ '0}M4WAC!~ Hj!:A7@ڗa+Wc,t+`ܵT{'Ƚ'*뇙t `!Am@1T-Wve cQ=Ab~)HjʵVpJc[(@0[ v??aό}/޵cd44?8v ׃{y*v${c?rGi-O#f\JHs1" be?6 qpj%wfXWũ^5ܯT ǜ|m8@;Je`[H)_FGH_򇌟n 燤tm^i?sP]JZFމ[XKuw4"qf7Փs507m;V"Ofto{Fd ߑP91МϪM{@&w>Yl,B8&ƪIni@=tb#NE5>s%*ģ@yD^kR6?d;~,w{*\m{.РzV:? fbE3m s4`k+ϻpzQGY_y#$=c S>ӑ4`ٸ :~:OHdP:oX3:Xl&0̊mopܷ|/C#Ѫ\/Ӿ[3n"ԵiխST(RjىM+YK[ʜ&MȰp!B@̈́F[{s=Yml M) ("s`ݘrb!ׅ xN&gw#y^|LL!m$$zfLL}#nx #TW ԏ/ށP>*qٰG|y;0; æ8}wjls4ڧ.)e8xT`)6 >h@eS~I0"CAP \wmUZ'/H '94UّCOΒS)V2[N5F0A{d3<0Ha-Q>&^z a:|d`l x3'A2{L~_BP!}`M<꧱k@0@HPHPmLmIv.Pa,Cv5b(|زOUܷ1_]~)g,# ~zϒNOHxaf{&ϟ]{߻s瓍u5U7"@ [ ̍LL zb[Bhy0?/㒃jrb=s5lNV5 sm@91|QGr$^v8U>z58z)C{Eǚ1y0i/9ޜBeJ0s:+-R0u3 Fa; E7'K}œISw6hɍO OZ;Mt\Zm-ٱA :[jư\Br?y ]Qg؍\G= nL&?>*. (=:p 0֌  PkAYKyi d. 7rbլ63,t E-"&y舀>.ٌD Q`m‚+tϰ+N$FQBq2ϱ{[qs7ٞGZQMptCX>Jsn}.јKxӻc5wLn(*M8A5ʬ%A LX8 8jqSj mZݺ}R=EdMRiv4JM2 +[_.l8oREH chkz#aZEdz~w:h2pYJ}}&SQȄŨl;]gQCf PzEPjT\%W*(jj-:kFs 8G/㽜aw薜,_mwn3<GRyh?8_fFhBًPgb\+T*7!ĉ[3Sn_t6čxC0G!@Lͪ_GI۹03}6Jb0(q }ϲ~:5)P˻8 ,׌`>Q6I݇3vil4'3~ڼ*qr@{0A_*I*p(i\b$+;-NV6<6??D sYTaKĿHbek*9t_X8|0o1E]|s&6w*OggS F#̾úzu?#pDm[ Mix<& ,3bXţYmT<|׌L-ډPLN6N "i2 = 7},=vZHЗxJF&bx89,pJ;n]m7i;2 WFJ]%'ݢA)꿁 80Ҫ95e ؄ա;<3?ޝirӺ%RE hr mwpa0Z˴^8tm=ѩZD J6>ն& xr>0렷 =K J>x`؝9U&j=&RU 𴚩sh euo:I͙nI0M^z$pfA:|@<xN 80a(`֔ե_gxԁ-N3حT,mP9//%b'u`iʼnІpW!@Z:w)ENR@TNיQ:aܶ"{Ќ^YhE( >zHXU#x/n%s 98af ppSnv-;\8&'Y < ziK^.8S nrh #0fxR+E46Q.(̔fk~e@iI?&'U2ۻ.z_HoNeV*γH,J+Zo&*eg @T o)`A4gwN>ܒsv6xd]zbo7?5Q‘XVE8IrpזxxjԺO~yk 8E0x[bfj`?Ș+0U@e.! ^IkfC:"qp]1`@ OA$%qܺ=fon6/ɯG//@Se$wL /0rc7;zK+ov*MTT4Gy";mu,N/CGCT bu];"w#;bm)~h8~*?]vV؅&@:Lj pF'lFɧg/^s3=״0<9&L~Kf,̎OY nnaG+Hlzt|꧄y8F2.9xq= br&uF6XM>6e:BYf4 ?SN_xa^h SbC2!gy6 έAgs],!>jN3,Z\T'ΰ؍2t98ffiӤ[اHN}țmTgؓua&i`( 5/A ă `?pye s<7>ftd}oe5``&_a!LꋅJ<爊} S!;L-T승 :Z?2Ԣt|P!t?cD;*D 7J> R ثߗ+i"*P-+SjKgʹ~Pa48}y6!F63^JQ@lbSұͰrOԚheQ.̃fo\`*|1R<_;_wu,<_Da٧@ŤfUJ^(Kq}EKh]j}RRl@:c6yx+t5C10=8 h[`W:\4l>q U5c9T?@)~__OȽ|vke->m jn utn-.RN/O~VŠ:5 #hݞׇpא @nHZwOm\P@ :*CQ l~zeNXG\gSr`U0Of%)Og>Lȋ_[!ohV^ C(5Fr@).4AVPIx&?'+ X$#~u8`ug )e݂T-`6@' P~ L$#z D|iWY?03dz1gEo.OÉVqfg6YkW)e~ -*1mfnZllp:9_;Px!|2}&RQp֙fo"}PJj :` CBb(H&~*e&]pef0`OQҌ6o|W?%fY3_^$b- @=G PFO>8U6ϺG4oo~u/-Dq`TDٛPVCq2-:[sC7& ,@`t`&C}Iczmƌ-l*yxvAx &n -f=}TA^-n^&I{E=;'`=QyQn|pO(4 4?`EOs5 /(JP Eq2wS6>z?Lҹm  \5&<喎ôፌw^wu8,g-Ϧ90}=ӜX*Y:%SS"%ikB[dRSlq-Ь%~tpD k*_p%yiߘy7kP n2uU鎹E?8"Hm&i`va4lfJ}m{>6 [q[gC#gF iPM~d_f[% xe6I p/Dg mzHw,"!Q%=fdCq+ 7Ssc 1rn$n?QDy2Ҙ,X}Ev]2ڑ[Z}WgpDat#-yI]hIֿ)hȁN񴶠p80<1"vhe2bu-J <>Zp{@N[%SxvBk3&/C7 ȫ8-%Ke1"zbMLPgEܰ6: ˁ,y%0<+=FQ2mÁ H -VRj:5p~Rm?B T-҈3C-z߁X~g1Ȫ Mp[P|مshzfxxF C`SL.S}.?Xcwb9i #ΚXs2 ` LClPWL|KŁ+R>!"g*dop(jJ;!d`XSV ;-qQڰ"LDHC&~mk,EH~'P~Cb=4`9X%jNp@Ұ)\Tmi`[/ֳ4}[.FYn!05Z嬠 Wkv/$f#- ^d`d{s;nukڋuFrtS'0J Z2' tdc(GDUܥ4x-ŕOlZ5Q 6)nT0iʅ{gN%^YmTle~!ЍH)=7K8n= UEkvg+i6ϒ`auE%HpQ5#rLjp\[Os~ zb֧Օ$3Zs.¶v:wmఔJJu?)h3Yi* $)`y˝-onllh'0*38q--@تb ȟi5LQ~"+{0SDB½tvv55rn>zRle|m}>[AZRmKֳCF8fAt~ie@g?S,: MiD=! Mb3.x[ML@o5j>DHENk?v`ROx CX2ӷ{Y624 :0_*P)<4|kj&;_*m%(Q^ nزFSqk=ʦh 5ؠƒv3-k;a|yoaߡe?FMXm70'Bm w`3)t Ht7]]dgF^֓OaӬ%A[rB xJ*Nzw+{"ߢ75Oz:E&+Ke+J[1ǂP fɲ~n&UJ@q<`P[/% T63? 0 ~H .' LX[DL,4f=PX=tEfƬ~j؃]L_ݶ1fTKjkO/Z<wkZ>}a(^3vf8rSF>}hdHeHW 㱭5kڑ;o^hO 8YפQs{-)B<TB܂X'î2-7|$BkϾ'9(ivIųS ) δ>{.VID#& Q$Yh, !mS9N lcbO'{7l(5{zo*Uu8C99~f䛥AvZD NNU/!43ۢ7 w aNm^b)o2B"c" eQ2=v#rVw jt-`ʖ=raޱ<ٸ0}ge:hV\ Afh:&<k5C40xOOﰙjx)HY[uUD2] ^Y!"$lBCwDZ}&^RSnTUgEjQu(^,2}bGH T燛 920,'5^RS.g196@2xu`Dk5WW 7w^sߍouh^g+50q0Iř<>X-g*p#=BQr)71G~E<[saOggS@Y y? R?U',_4V帟*@^fޡG9.N)X@~-ԝ W:EWZ-wtwB%e*W,j0=4 v }P(22@&0A@PZ ޚe͜1.J5`9bύbw?_'/|tٟwYGlpVsfL@crts:ߨq#cFpTv鮱(\zrդ#Ӏ)0c@1`BcT{2@޺׌322vF+W7ӳ TMWHX^?@ s S"vak#ッn"&I>"ɒBr4{Z&̽^|u'繒=%bR8Svb X-5񻀣LZl؝P6>+ ~ ?^ {7MG  K `Nb`4[:eIMsq+.}Vl/*$<&!TWO dw#4;Y+5.a4SdE䄣>*Q:G4< .Gؖ,)wbv>KvE*mF90`G|?{&MĶQ@-paQ̴ 福8|Ϟ,i˯^a"zO.Z.y_jgvQIcbY^R 5950^里My?VI[I>Mm+` Ğ] gDZ |1' =M%}X:> PFg.k:ى 6ABr|ί?U6wjcdeSޚ7B tRG7t۸p^5 VQC3~Xs?u@L. B6]O{x|zeoDT#rRّ_e G0Z 2Kҿ V{2O2.'NBKТ^xȺi.LX@y=jYSΨ+2.` D3A" h&HTHf oVr;upbL=8ߥp `*@Rm vd[~zB=>5NVyY]_nI}WzŔKhT(2ͳPl@H^]%{zN)v{+Ӫ=֘ͼ%sLA5%vn]H@6MQ'(ϓ l^]5Fw |F @V/(a4y}~N:gq-I2uѥ.* c!]iGF֕[`<}ɅmH:ĭu X @x $<hyQ~3q+\6kzWpZ+p{9Hi`yCP{ì ]j0b ?m.N8Dno5[96}\Tu{&蒾#\եœ=֩i~?Bt6; P]z S)pQnFw_-{W>۷M|5CJZv n224 %m}\+ɂe ¯2zw>J2׆'W(脽#=: lf[{ ?B#&5@ULP"SbsqaOJr)iy 7Ώw^4R>_Ղ(ub;Tș((5zAE:$:e;nLCv;.*Ɲp;%VIVԦpfS 0V:0s ~ @8fvq˫ o.ɻ?z"AiެPӖ@?|2 _hwP&qc$JT/i=cҔ .nxI-0Spy1BWl ʓqU1 `O pW5 9L` TfV&oܤod=˩f~o{ gɤNn}ڠ<ĭ5~3HӬg@GUX>k& g.|O:ʒ:8e"?v8x@.YauUuOguS l4}fBhjn*LǍ^8hӗL};4DqTz'\; 1u 1%R&tD|& Y9 Da)[WWnM]/^ݘ>l[=@T[?9Hx&$=e=%n5,~`Xў fަ?W/7xb.vrX (t14nڰCR-رHយkQV^^KEb (yN``r$^No D]e= {4|%%K(n 37*p3 RK/~6:xs|"cJDV&<#G …frp$?;+쑝=`BDHe2H}8;T20j<'&h<̺xWoMnIJYT$ ^"*- ufͽSWlFWM@a;LBf^[?ZENDnA@XvV(ـT*f?fC4ƪ BT9aFQ:0Esij';p;42lI N \LY}qlMݭѱԞ0 *œ/]1V8XІ?I׿lhV8 c|rcFܩyM~ ?Ӥ2cOY#d(@c )0`/lW?$feUOt(.HH@|.9|Bv߷9einVi4+w՝gj/Mhn * 63'9t`5Ι9vȓa|HX?mu~u:7b+8,ܒ{d_=W8 } n\/b%Ӣގpj . /ީl21s^eLC9Rpx7ܱz6w_xOggS@ Ud^iڐ| 4 S"ί=؎>x=ӲyfvApծ-dzRGD0M wVQ6 T<.~(ė,Up 1it&6X*sXҬ>W&LKvہЕ+c5g}8HW?9{J῅KZ~IaD?xN>sP ZԬvcrSڞ?k5o) W6uV`:"}?#FJwZ~%!*0T&MxDhG)60UI/w0I,M $@N?SexH`:p? S`9LkӭJ5xqak͜.Sfo`?!WBԃ@dFo<)jko&6<( 5(Cuk^5OW<064H9K65nhliçc^ 3i8 {CsLCer4(R[|]`u-y}(Ѷ&x0ґ' :Qk2X`B 8m\^?O IƪxXP:>30eU-<Z,S4iMsXI\RNb<@l[1. 'bt`&SW@N-{bE LinPV۽NʺKнM 6?ӌ67l3@j`9HxNXQ طNtq$֔9G4+YoUE P5lJl({E_;<՛wUUK t5|ڄ#/KԂ!gRzDգ` x 9@l𷺢cL ;i<^֯G.! o\0&i⨲G3-۰8/l:\\rݠHΜ:bl@K|X6+ f?0㨞\o@Ẃ1'z~t>]%iSv0S,+> @$z>u.@ Xoο\a,_ ?SBJGG64`3d1~Q_XFR2?< <8ȝM^1%o68~zUT$htsaU/j;+c}sxpwgCU0rQ{ f^u2hH^JaFY5*<) o-hALd?Q"+tH06M py8}pkڟ8H}Ӯ[ZKe9 ="h.z du] B57~q8ԧk+zmޙB! `4$);>)R$~:63sjɔZn4v櫯)ްRv\{uNa (@:cux @:V~;~6O80ȥX :6֜մSWskʨ/ @ aß`e_Rzx 1פz?l~\ ]5bJ|ttJ^F{sGG`! 5.u`69@ @sFqn}rhwiaݔ)Mn$SF&2w0џs@U_֚ :~#Հ]vEh`$OC$V) B 4ԣw_zTPnʥOaJԃ01meD3'gLm8&` s)H`~t8u~'*rߛ@%"D/ B<1gw9C~fӜ$ >,;f+1*m^ 4!Й7<2U Ȏoe勡pHLP4Z"2CjL:O bhNtHY]Mc5}ٶ aA i" 3jlFLuS}2$a\/yD Ȩzѐ hQFq4e `US6 Z =1g.ltOggS@ (.JʲĶZm+s(LcՙY֣g"θY.\ZG?]p9k95JS(1u_=Y/n%kHE@pnp}+ @:b ש+j|~i-yܧt33^s+ӭޚ'gFb2Q :@Cc+@vu_^C- efVDIH*PSGޠCP/C+Î͑hKwc*rK׵>5qw9`WP^P1L)JLGRYa+;gxI0MѦ\&Z-tJjN !-8-49M_ٔV0 .Wim 4r(UD4K}Fh꽔*`"g"^;%aŐ8_/ a\`oml3*PJ!DeoZk:{| cڒYs ~XG2Y|pJ?Y:g7{R40hޖؽ9׋O$ff$0S.?oͯ’벺g]M_8 (KEBb `ѫF m^!&CE4e!6{5 XAD55V p?5`cfM_Ҭ>_l0=M{ @̾nDv/*>qMzΘ),60`g/nG1\m?j4Ph@|B.x$% 2'S .`s@wwj4y;IͶ}\¡ M@ vK!R-ˉ|tURl's7`_<<}sd? ;к&B^ZMbiQ8 V:+JO`<s@,,CغJea<+=is%l 9  *\4ʆSxf*VBr 0S@(=֭.)Lk:_K۵;xH R Gj w8zZ<F`Ii6mAב9^|6gJ5D fcoيg@ps013$};m>tc2uϩS0a^`p@؛=cD=>Hϖ֬Ly"Ixl9c:p;s8+C_w{?0!FD ԋטGRj^+6 zfFN(kSht)9a0w_{BmNJοJ>H rę{Εn8/5 Xv~.Q.Do)'nENDǙjDWA2ʵpuVB)֚0o*[շiY_l*Nfafggܽ|@rkdQHJ.*يP1X 7*V@VטG!Ȣc$l;׳{HFp>B,HעX2a0H?UB⪢ex ~e?#3ti34nӁ!CK pC;̽_-qX S ` MyqLԞݒYeY0sZ@t*A\?;Nu}S"sӁ@D+[+MRMtZ)Z4w{!A= t-d]9*uA-%@w40;BXS@/_Nen+lbz҇rSR5]+VۡrVP ( Ox(`eZL3 pkR̮Qwq;Wt*cV\3!^| ۱^Y` с7z [5KgN!\ Tؤ6M& P`ʖm~ԫnAðD #q^6߬{a[[E;TQѵQhAE?nA.̪y{WiSJ_0bdtd? sߜaO5I&ƒ=wӛdho?(>f󵟃Xyj WgǓ˧~I7lj>NU&^kP@y]]|p{wM33LEvyɯO+8( VScm08f\v3,,˫gpFO5U;ur:#^HC >G+*hk$Z3 JG}qqTf T9 ` dc|_%&f34y "TFTU"8BjX05We(pWc&~ &٣fh \D@V^2Ius8rL 7v"7*$KMQ@Y@\ "Xԁ9 1 H|8}է(]/!!j s2aTWL@8@3R "TɹCV+=`l%/9y!DV>Q7vsm@s=adQK[x&ĭfA2zs Wy/{_XW:Kۏ[v{6 1Pmm<7LV 40#]|\vj{bk+^nR Z5Ǧ<Kk+mv` @`iA) taץ _?w@TS@[' 3bcZo +[Fյzj&i&a@V"!*(a9p?5@$l(~o}>fGjy\wP8svvCrd:SۋnBru&#oՆVaV=n^ 60grV张dA{u4(f[.h`;J1qoS?W^ڳKɁ쒂۠O ԑL((8ɛlny(=ݟ..r<34LZ+%W- f@Ɣo`40Nk8t2/Mp'J?3qve pW80 }:`\92\͇[.=8jxvK) $kw.ڶDUu%{4E jSS36ʠ$vh:'<(R[hwck1}u –Z yQH*qYRӫ@xNr0Ikn͙}ǧ#Lk7'{Ξ74"}L6+QEKc(cVԽb6k > I@uMBBxp«0J/6gϬlۄӡ-?S8 rzO 8+}yJ|onؒ4/XC=,ir˲POr76 {;X=~[v|NgJXqEy&~Qq_~$8Ӫ X_b- {jΔK_p(B3i%=(/O 'aiA< ` w_~--Ȑ_mMo9KۭH^R8(tvxo$IKM{;I~On@ÒAzSr^Pފ5XT%?fƒ@c3spTShﶸ&Ȭڜ`5F^ 2vP\"Ϥg73v0~0|$f쉷ґ3X~ >Y B@IU, &Y6b: 3vжJ?I V9 P$ڪ ~J`*,+ /}myi{1f2mjSоQɢ@=W5\;D=S/Q7wvvzs)d)i[pC R~-*6 t)e))4#+ ;SM;%iz5NLmTs 9 ha5G<e;C?3fl6q@(t.Up4e2UJm +dT-Lל%lXvw [)B:;uESO 1,K7h':( sž2`Hw_x:p֣[Pi4)R*? "£?,6  9À`,33=}UkW_] 'Aϧ\xo% |Wn5" @ۜ@_%3ϧFDC򅎣!b[--2TԺxf8{ǯ1Uc%Х0q#-̩t$ lKh4%SP戟-NM{ M?#2 .R+MI`ҁE0  !` Km:1aތ]\-:߬T+TZ7IJ0o 8z!ĉ^Fu:"a;ٮaT^nP(˧K_Th|v\퐆n6hH(_O399  ) w}sktOVz{ @Xz)PQ5~^$:N-޻d:8اD7b4r^v g=~CM[K@7(/~|kAn%tn#Q&jN9ث|VZ@¤j9xp?5@)_?GϼSOTX@7Qڟ xrd%=87} Zbq-{>qH#(|T!ѽRn3/zkD>hrfbFx>3@Ɂ<<&ӈ1.P뭇Qn_M]cp xӇRz#Bjk;(GEm_}kDHZ{V8kq?;sݳ9qPkD5e?aX,gĨdo$J?S[ 4*A@ ڃ IKc2H3|w!{z~+52( 8EgkAIV=Jn´8rT .]Dfj Jp`%832tSm+pf89YŲW'@XUtf1TI6Ո>;(Nx)C M?fG>dC3X0j2 Dt V/d[8<$>1~o2ϤN(S P Ko>(y /d!9 h5-@Xg&N]d*/F"XFv2N&B*rh's;ZN$%j#q<Z;Ls5)DZtnN p3 Bi /Bq&Ik z1җ V,7 8Ui;ם/WVa #:Bf uVi'NrfV|h>KCfʜ|O:~-B1()7Tyk`F`3 Ъ! uvorӼisڞüԄ{L E x$8cWfl k iٮ5獂;w̅{DZ]mdF{5`1Yjv=9Ed T{`>[M迄IfP;s)<!@&R?ox8vŲJvi,RVʇ}`Ne 2H |ϠUf5p3[\8Q{?pjN!@T_}omȍsS,:4{UvUۆ<+ha[=c(n q4emi,tGLaN0\E گ=[JG~trbPX;(a`Nf>y K0<ѝI(8\7zMրb~]f @Ć:vN$=)ژ=窩ڡ8<ړJEN I'CiY`, @ fA_\ŨtG3Rw+%{蕩'|Z8% @9Q Bx N{uC= :.udԽei*5Oq9v%fp3{7<]1[6X!&)8^*eDq4)g6@U:*I`M48k+?$JKl93iz Q :,PN]/׎mO53k23O<޼!))N0|D.,RG5=~JyM4~%V5|#R9e0=+*59v,^JNH<=1C:Xᴠ@@'ɼ7\9+srN8nɄN;/D iHz"Ke ?>yLsF$"˟5#q`t ,:]%}S *` |[AXtdw +Y5 Ja8JЦ7blF3n:lxֵf>ia^1AJ컬 X~>~*TXEg(^?ͦ>{SK3 v@O]>@>w@f tfpOku tqn(CDqƑ54&kFx:3,JDlKF`_(X̹T_5 7lD̑vdH &U99U ``+9#CrA_luXh{,PG 8`1 ӥXl"^RC N<9BR_*TO 恈l8Tx&Y4GawaadÑK [_% 3ƄJ~Zu!sFR^i'~0<heu~χ ;aNQxL \x MKZ2NmYPzѶ@K8uyX|V-VM}1͌r3*v^ ,&ؐ~l0ͽឲ/yO蘨;uGHcNjbGD  k|s  Ve@'Z7c;SrqBߺ*/7ӳaq>߫5JkJfSn4]hWk3F&X8ʒ$?$nGw[GD jWΎ}7M æu9XVv=iUmp i @(XtԄl~ꟷ}llr]ֳU?v@gAfMN ГvSFws\RR4c.VJфwjK%7]ĮJPʳasaGײKc^Je[ä{qPf؄ (;:Lξ`߉ovikr' H43"$M?4e ((\ZaNT84h_=I7MJoⵖ*ɥnWz4wZDϠ2yPU3 .9I`3Sc{wO{RRggDI<. ]gJE![,)Y]WTL#!2V&O>B֙O ? QMrN+`R9IVNF1j?RI 3HjN$g>~~2/uNs]H%ޕsIB- m<$A+6i{Wk yFKV~T"K%tjơq CVip[8s\9læs,-k pYAUӣ94S@}r.R[Cِk' P _ZeUKJ(}3/0c0// @{4=U̒>ˌ#J(Ou/cRVDE4s]sO;[)Dʧh5Hx`T) 3ks翾pʶqm7?1ʣD m@Ҥ\"3)ʯ25{ϨІϣaxߘHo'-wm)VzFNսy@*wmĖl1xm۞/;Ƿ꫹#ٜ${`jc4Pdzͽ~|zEȃ(AMg#ħdF:SXrnN=VLA`[k+-kh%;w]H:0X:w&FЦ~@ Dd ,~˗dx~+ O2 ohF&,۩ )xSl~e\k #1E<+?e\/% R nޥ'szG!rZ>ML %5SLI op2i:<gϬUdQ1*i G ~1bQ& +9`\jyQ$[Nm?vMUeWWV%xAy T9|/v,%7"L 45vdqͲֲqNJ.'7*il8c6(61i:Ԝ0FQ{O/^xx4| u}XR?Nl 7g) }.WNA<J;wdLZYm1N.2P"Z_ c"C֓vNW@AWLcUcٵ.q*sLh':in:UDˊ@Y~*jTY x>Z{H.O9 CR~^~} ھ23o=&^(/ 4,OwFٓ hNe I+Ҏyu%;<08( ^!X9+: DrZ&R7OsQ5OlUwbm^J!@ADjų`ك h?Ua`F0+gwSr"{)B Ԟ<@k _ߜ1~Q=e[wNځac>{}˱ťlj`-L/aNRĐrox$|o -8?5h9T`ZQI9rC7U@s 9U@hh .>4y[SAɰ![*A}Ph3Sf0L^] :ZA>sMξ8Htv҉9f5@TLWխYW;;tf/zn{9 dOTug-L3S0:!xa6 ֣%c(p xP$F{" ^K/-AQ-hs![}cӞT,%zaٔ<yF!`HZ+ 69 Cd27?o2 uc`WiXw.Xd1觶B L{L=Wm0hS`+o#Tfn~EU]M{TJ97 PĹ| k͍ Rk U?jNb };l9ߴ/]nPIw TӼ胞)Pᶂնܬf2zhnwHJM_&ch$P*K~BU^2}~/B !ϞE(K?pQ_{- CpA%k ` 3B`,f ry?ܿ4'Ӵ1{2,lΥD2V]T2N϶;X T8oyIQ 3)fѮ75sY4 1HAj5ĶuL>i@];xZCY{FgMESh~jC_ 8p%A98ge8ɐ^/b27ZgF&c";KJ:< hV> e*ȯ6ewh 1\?6v! oSw? G6u{^Bw)~vc0n;:T{8J]>Rk\DBB]ϭ^Z%a0 xv`̄y@@ɧd_:͹u+tO@V=oj4dr @?g'=(/J\Q{t~t^~-phڻv5x/fw 8QAj%fg,Y6 iA;,rN @6[oK=||Z5n[z) X%B Pg @P{=Cq3~ҞsH#aB}e3ިxBݑPg>M75*Ԋ*rä*F@YDe E `gk`?'y<:,AԜa f$9^܌5RlHI}"m!ip'Zi "eI{mi" |z[8O|31܁ɟj=/~Ku)˾,ϱN+hIZk0VP4 = ?m{i2½k__)I,CO~-!m[_ ˅voƻVmK3\i1;QcFVj1JM>TV\it=, UŃ>*mteD@aK/^[uȝB\p 䔘Qiu85 E L92v}~K17.*OgO4m/xkth17d("Kt'n Xok% lejC;L,y8WkN)/WfVs?OggS@} 2LjøļJI -BW@u H3 `$u_q &g$^|oXtf(,2Urm V/Ů(1ZxݿwPH@8M_Cd;Fzabom_e}%IL ؚ&%HPZW9A>>֠1$ـ^S6h*(? bnpw+?].Nk^q{EM|_rAn#VDu'$ĐQ>m̙kJWsf_((zs.S_]ᐧ֡9Z9\"D/9) /ڀߺd2c 'fiؤp( !+dFY9eH=dւG3R?$ ̠75کA|EgNok i*F GMjD:!ݷs*WK+.dsnY ['m>ZEX)gV9FONNs@:OQ^y;S]ly{[ݩLڰOOm]yܓjE.4R_)aBߜMjFke#ncW}MKO^"߫,Д6T(CE[S*rlu)J]7!E?{(J9(g]pcZ9 !#%z` y0@h`/rZr//5 8]8ϻ{U9,m&ui- Z{Q7N2p.Ovq%=0N֩坯|2`(%dLHδvl y*XY%W!D5rja%r]BP-,xxddy'6s~PEwS}-cBnvl6m9}EʬUE;M Un-Q>NT5-VlOގpx`׊jA/0qA5**k% x{ض4 d2w2v>m}F׷/?"0&&}p a0†dtB/w'S/Q9y*:HM,0 _mg|RCRC4+W*Ъ6 w҄I򊖭^J5\9)P$m<@8OQ [[;x4SޞM)~<.-rlzù.E 0e͔J`MV5rFE臇uEe{%<1^zA~JEM\('sڮ4 50±??{rmr/v1в-8MEXt^[ze+TZ3}!B3z!ӡ0ālMv)GHhR?*2ⓔT9P-c,s&i>ڍJM&,5iFe Vs @4ZQ@ua+O /Keut5/N*+2k#u1r`φRmCG]HErxS3ZQR&<Í.л"Yqxӏ;AvlPZ[ P5Kk @Kdx\S5xE g:ykaz2py>N jLNtIeC \6B~;;v!/JG][4[F0 /~-JK>G~g Κ@IkbIi INwHb3mf\c@*Za a׮vhS4UձmN+^[D3Ôy{0I1`㔢9?rw?Dx./n,U+%bZjD&pl4&nF d(dQBO+J (ö_aM-4jhO{up=^\:֤0cIA I5@pIQ1R}nmwU}?f,ԍu:Iّgnm  H'4D[d癙l>*=Dc<4Ah5^MO_՝FivNů DեK h@dGqT,A,Zy,F"&a3Jb J3P[)&(8$~JaA^yU> ,L@՘uF|^t,oY c63XE1ǻ/<۷ )u؁YT0\b\ȃDBvfKim]/ZߝTݬ" U ݢ>_%jKczŇh 7"l⬪vyULo`+k& ́ |fIng6_\b/uWs%mj@)(*&1Jތi"]UC͸0*uXBY\zY*=P|8^0-_mu倹p `$A()ΜJH۶u^EϝYdhV,W>o`A'>0 !/&mh5 OTYЩKUh0SZ1Nb><O/+_ GdLdԏ]X~ڊ5Ck$kkڭ̭b1(]' ?_FQǧDdg q0ϙߏ@v;` ĭ}B[Uo"g1QCJD$ǦKzU&s 0۷r_Ӑ[y!?gt@1jde?4Z%*,kV4CYB1"K|/> _ `>y@ahW€Ci=݆?j3<Y3 :yޥWRBm"0F' >|ˡ:HmV̉J9"8I@l Nj1Ak]:ab(ڪ7[nѾeD#5Ї''X `&X OU@h:sVv Y.ZS7pJkzY_6{`Hfgie&"Kx'RmʚVݽB4d&t6*,ϭ 5|0#%QI:joSkCؐǓRrf5?jZ@B*h@ fL϶TѝSOp <S*!J3UTc#k=M%0GD3Tq3gqbJ _d6xO4KQ <âÛ2ٯ{i=6 [Cg!OggS@ 3żJ@b t4j:m_C3wˇ>Ҷ|aJ ܴ@x-v(',O9@V?R H1scv:fOb@6Awז; :O'j_OȂ}&'@IAT_ YYsXZ5ɚA S/t& 2W)۬`OrF4a};QgshbюN{ 3 To `j UG+׉oRi,жm=&DxW̍<zsՀxzz`&N Ax’0I͘&@sfĿS.&)X.}tC4 7?zA!pGeп䨥(=bnxvd=vE jh^qp9@y6A'Ҷ\HZ+CZPzEp x" \s޽1ް_O:0bm \`scM}f!-qkFH=@&Q;A7 /fox=.g Y/*ٿɮЦޏɗ-]E(-wGM#?΃x [쯅X9' 0NtyU= HOC%TW@9 3o6-fmL3EӷIrh?^jo࿮ʈ)S=ȝ^#~:9bpۏ$+Und=q:%FjR) H!9E_08Сf O&e1Jxkeb:EA{0Fd gѹ3 bέ߃s/Yr}Dhͪ5[RJ #GkO@ FON'3~ %eG3"5R*lz62qPB}Y'굜pNS^laCBٔcj<2xV64@U8KP<Dj,ll|Wcg=(XK"[봗tKDd559(5w%3_fG0񼇪_9s|IeX:4A!(eӚX-!QeM5#5S>j%S_ovKղ^J V]~jX՜apJSra^dl}]}=?ғ~`d:Ҥ9\Lu|# y1|oZQjZmxact94Ȗv@❨Z00 ` ;G٣_6S|",AMPT K_p;! ~Z̔(`<Z4:iet@-9s$Uџ//}ϟ>vb3mSAxTS.}~ މsA^ ⡏Z&`ypDerg{uo9$;;#F{ʖ&Q$jf q, IB:˼ԧ*zeZ~|0NA@SOY^}pbϧ~+BSR8<X~CCٞ#ď lCFi`Ad3 S`*Eoުb;2?6X0[@1T_}COmJi>}C]Gp?9I$~5JYanhmqA75U4 * P#)go 5so s ؑDc <&J"pgs t&Fjj:s8p^z6X͒ఽ }..zMfs:m~k| Dh>e&7\zn0VHt!g]o~,nwcf[o>Cmj5v%Z-J(>zO0sYҁ @saX0Ň2:?l}46eH6<8h\[mLlBn%Z@@.G޲uvb|ٷϧ $8W_{dEXpI/ٔ[ c=]Kb;bł@5ll &?=Vlmuy%u(]+ z0@jdAhf ,@s&ڟ]5Q|o#dZ]4yb+` 7.È.D؟-&(6ReXw4!!j.4OߧD@:t% ٨+a"K0+䷊sKwޚ5 <W")Vx(ϩ k+]fcysAKiO]OXhw6н, >y8Y=ْJ+ Ŝڑ-#2 8󔯪H~A6dflIoD "x$\co<^ S,Ʉ  xN3^`V?vžӇOczʤ'vCi}\Vz44V3H.+p&45q  4+fivOə<'PKwБfzӚ0R2U ƀyNfS3j|qŪWd>&*TȏP^9!N 䤖-rYql6/4DL"-]ߍ 5Dׂ+D p]ƙ/.ݾYt3nCW[W^KuBfȉ'6ps d|8;%}$g69y)3@n_@G8" VN6B̰ zLiv;^-Scpo,w/3ˎ%:6L28Ǵ)[a2TSOggS@1 b y²Ͼ .; /2?UY5 i pO)gJgN!>&5F耯u=2 䕸33F-t!0mS?N9KZR|%H׎D, t{=W-[fs5OtH!@rM-V0,vN$@F^blG?iZl$?s@RTK @1Pb C76jzECSujNkZvg`BR@8:7P-dA/kExM0Q!JC*160 0.h Mk`k0Sae͕?T >tFY=~hAȟ!PJ_5fc~pE^bs]ب)8`RT8PBI =B5_Ybʚs, S[T딆H2شcpm,'!\*Na"Қ HxN7Ʋ$0j﫻Г rKjs&RȚY8z ;~v8Z{Jc0 /%r2C2" YH3:Dd#"̠G[nU5/*Ud̤5]khJaV[BJ3L Y'OS>seS2#A^~e#"/Kus(88~pbD=u'pz[9IY讈2c흻yd(VLçϭZ8BZˆxžfE:L{_g Z`>Sa#aJ2j%u^PQV~@IZɘ40SR AsgϏ Y7"us Qs` pQD:L6߫kqBEX\'_oCyL-(;&+j@Pdܜ[\4To޸>ԧVgb("=xK@#F[XH6=*hxN׊82^6 QDHa I&aQk}PKKu!cB~^> 9x~jP~ݶgOӆw,#eg^lQrEsk! o 읓r WpяѻuMtd %?}HL6=}(l4'F]sd5s >ڜ~so.\H:?#2Rd0PYP@Mҁ`O5$?劣|}jD&<wPkڪxuPQ[:fjPn5'^c^59_( #HC3W?#Ft~['M_/gdĮ4R&/k FÔVQǎ0tަ~IU1AxSd@tħ6:`=u#3 @qf`6|g,p~O\LV=D ncUGcpc>.eg j5NGס6w)-@q*0s5ٺi RĬ\4LA@g)%5ആ™oAR sZ 8pzo/z~x>_n7wCY ݅,R*ay/ղA^aZIA~wR>ݼ{q8ܼ:Ԑ/N-e{W;{2#b:]5̵NJAk0͍9YƤC|J<RZS3r m_.qXOLF[Y\m);N5z L^:NhuJg5U99 1 XrUY['>V[^x5]:mELGn zzu?y6--CqUܞtA mj:=)uq&w͉UâNaU@p ϗ\`HոAː.X]oW'hXa{ram5smc^R&r|SuR.@,vCiNe#I;;7LPz5:A8WOs;CN i`DEe=N{ӗ^ *E(R#Dͨ 4ZM~{Yr$\_&e?JNr ,U`t2} 6ޞ<ټ2SŨm@^&٫)z2IwjWm~ >M?2osyFG6$VVRX LL`ަ%}ܰDpdZU,*m=cG ^*?8sY,-̢cV ( ؾC/^{b{@xDŽpgiQ&@ԋ{ᐠbs_J"$ 9~tXr& 0\8du[2\`wҡ7+EO+wRYTWFJcH1Zrst́: RI2Կo;vvLqJt@䂩@I+P <цRx_?efB0Hdws`l֯ vhn׸ W6x6& h|ut]!toȖtAgJ5Ǫc]Ub@],@" ,)H 0G'߼bwtbR9@zZ 5OvRdr;wMvsv]yRD X07s[}@øJ%=('`3i=TLt6FCؖnj4P( ~d -x`S9Mۻw޳㜞rཽ-. 7ZA;,p@ $Q{X֖$0lR$\ZόQC 7יِ澞CtFg`p\z|ź\'t%POggS@ ɿǻ?N#[  ̃h XVi6n% \4=8{wmrTWj%UlA")>뭧qDKcitWL汿켈()H9 ^q~'D+ ̩l&z!1169/Xsu BC: |#g!ӲJ_X @Zc h-֍w<{ȼI92Eik!%uDq8&^9B47~~c]ͅMe=AEfvs-+=!h]je3^8B[bdOcp;,%A_Kj߷h HHS8{yUaǀeNs&,LZ{v8!At@iQ4GHQG?E]2),4sFLKN7pbf/ؔzࡹ[Ͳ1V^NuuclAkm5Ћ2dz笢\%UH=iT7kՔJXZl@n7U N<]έЫU uGŲ@`&0zSl諈æ@@&jM^uTc+$9;s@# "dzG?ϸȈ-AV1żM&g-4ޡH)sfQzU_tꍦ/k!j"YXS"͙|a_)Z e 4l4h,Ua ~*PNS ;3?ͬz$1h')K5-Hg@ŭi'Wf'E)W&ע He"Gpo%+M}Bܻv&UW^G]s(vcnRQ<(qVz5CdT9>dM{ǹJg /\,@s0Tx)~ߖ7{qfÏozz:0sΘMm(@f@MFFԙl&CwZf=5}e#fBc|ާ; ʧyE.F;ZkɴrKsL =={tg쓁J:eNW^LT&@qѡFS >HC´N)` v_]_x~;ݜ m]XnIϳ[A [g (ם-vrZ?Ml|/9I+ g3CӱSv$@_ րH~L:>, ĽI3U|+6t!+|~:U4VzxN5fŞBǧM4 u=PwpV;1Mxz&Oi,*Hd w$)e *]^/uuas2Z1>AåLK+ϛL˭0S`JLdK0-s~`&:E(5AL7gFh d |̮?Aey ħ[噸8qz0|Bch;mV.MP&*|QwIŰ@-!yB] ]RsQ#h:Y>j-!ǁ i"MMYf&'ɀLLq ``. ɰ ?}hl+pb+d@z;ZֲþVym\;cGkY c-;S t!`.Pw,$蹆yYX+@rPS~4h041dKb+g: ,@b@a(`ɇɲr@r{cӋϧ܇ }uŽ`Jm58'e6Q֍KD \ӧ:)o#fT' :x *M L0dN{REnGkjk?Xe$Cp fGN *(=(W `$<Cs/ԾOZG΅aۓݥ~1$6]MiB|ΧEk?/й@#P[2åN 84w Lըmj-Wm~lz#PwIcdAѵB_!"eT&y4t( te-Q@́DidAjeW/'nǸ'aG(gj$yI|xQ/oJp2SEiܷ|&/Z n?r6SB{Y(r;!%N 26mjLۚ6GK] Hk(l2OO ,@4`4u0¯/$ӓ+/]?LgyV#@ΪTAx)P[,uc*VnӅ}S6'#ȸ݅l:NʧaN*,1H^V)]Rt%b;(K]QerQ;HmqoCƪRJv+E!Et~Lw@ɞi5n EA13p(ń, w_RuKm'ڛ":  G_  IG(2c 5AǙ^{qu8I_!^B.yMxWN t(c dh s 0X̴sg 㗶y!o~) idx8%\80.ྸ=3_VL/r/Ϩz\V@Gh6~V.X#6kl<KS7P0 J5҃RDE!MIxA^A ]CChj!9 XUFbdvQ]/~{3tăoРN1L(o@PY x<+ Nt׌:֚ j࢘\ϸQd,zd=JJC"bo+'43R ؤD&F}u{WjtD^n' h OggS@ 7>Lįp`gճ~> *=$L )_]vƭ^W$. ~ % o(yi+m^.T'"Nטo̵Ԉ;*fnyռtxݠ\pj Wقq"]f]^X㩶iO(Ng! >[ز4=$59N%`I޺dOWovމ=91w\L\JkzOFP`%\v'OZ qSZ]ys)hQd=(m8}[Ƀmgp}Q@%oh3ys֑ݥqlϩéd4W itJc3 9쓯LO}CoXg{[V*a `/{ #U>]&,(6g\i1p6#&j te22>Kd3|.Q.$7E# ;L/s<`TjɾR[kQCLߍ%" Z vjHng\ |+ _[eO4 EHp ܢjDv7ĸ-x"#m2'q΄r:Y+x.ɝK 4^gf 5x[( 2rܿ ZS4lG/jDqW-,@BڪX(&9HXm农PƩAG(ZFc)tod$$nXi 3 D)t'Qh6Fq 'GTg<#6z̕]{K*^+&WVLrHy5Q|?J,j*`,T3O8}mE;S:Cj;$GKtfuy4g1Hh> h %6ԯ\Ӊ mͳxz'f5'T]TZ*p ',uD84Iɼv8'-5G[@챖'.y舲^+TURKeaO|5p--\G# ;_zCXŗ-3VXyG!Fdi>V@W" a28Ws,'W_/%M&Q(^4Dյ48HiJ1ks'BZ$0:l=s"뭢zr+$L.n,Gb/_Y[b"a5Hr6>,;A)m0ki``,@i _O\囌Wnl}T@4n\Y8` Iz~fkㅾʉQ)9ҿ?]i::31TBF^)HG# &^55tbN̿M2w'}\lb\{^p;0ϖe\!+VAj%6l7ԺyGp`q.I7 ) di>}2VVXnY`@lwWAxsxjo _cOM,H.LB SjkBpGKkwo۵M)ju8 ya:SH-U y;4ndYYn`@OC,ۓ٣~y%tB<"  p,\v_*rq=d*I6ktؑNv?d0 &  c ~6Ů,eYU3BHgQX3UKq1#; 9YsR)]&*T|ݩhu,LQ l;tOp>ht *v;$@@'1pV?]6u\Ϝ%Oc&]CETe#my+:NKbqx48){o EafDo7؏$74˓wt'(2ηv%/JuütN_KVt+G^6 ԽwZWLTƞުF# ꏭw/xkqd.1AE.2@ZY q;J_%GSI]X,`J-ua1O6w`QT?c*a4wJj30i B^)2jͷnNO-@|>ˆo* +_N1D3~[-S4hOZC=[Cc 0@hd6;|A3Քbt)`D &.<6G2W^ӊEh[^};:~G@`YI"풣r =[5]hdWP"i:/PP@\i[nM;K#5u;oz9fۢ;T+FhC\| ,mkH8%Jb'ҭE3t +v 0->0;ª-9 &x8&g'X뮎Ǘ +(ņ-]ٜi7 ,Q1NWHȹ2^U>I'1OT,?4'<#` mN;0&͵B(8Ng6((@ c6 VVL0AӔUY:g)d{#:_'!FoY1N֝'$-%ڜoS/!;H`Ӈ ]%zU5͍*yW>yWܑVxFHGoatR,;O=Ë3?זM&u70yd)EW&8J#%z0UT~(9U3(qy p@eqT 0 Wd[d@"<+yY[IU׀Xga ?d(U `.#ү6 VOggS YBe ĺ^$"u}IJF! `Lth0gɑX(`Tߺ>dN/MY-@Eu(,j0*Dze l}D',Pk5*`@gQ /qANayg7߀n2[OvqxpC_Z=IDZYީ釞/-r>y+Ġ{}ZX*@ 0 UQb~vevګ{S[-=Yz_" Tr@*wrM _dh%G83d BtOpa'ٖ3{0AQ @sVW^|`v`MEn?l&R =ͦ3ߤ~X;Ɨ $ c Xk0%OO^8s X꛲vIG a&Դ*RIXќ_Ng&`SSDx@%]ab~u [! z@pU-SY}x`ʭI+ъ% ".YD`נÞI/: r̝ ֳ >I,4~ # ;$0ZkmKۚy9ʟWN2Ί=f8'#%DqlWh&]LZ:hi?ŅV,NNwj{kC岇dCۂkUKf^8V^nQy^{R9{&^I#DI;- @Z@5$0b;2M95ULIt"~hac¯˫($m}gVD' !"@gs/m`dSv;mߦaH]؝'єw\%ݿun]PZ|[X4̎-}v$af+aJAE~IoB914 s&$uMVwP^8Ĭ{l» _F@F^;xj1zbİ, : Dtp{#iɲx$)lw(EC's syb=1vҵprʥKkz,l%K聂kŖz!oQg'5Nb+챝H7}-7A^Y-(Y3: ͪ^t\a[ڣ_8ts0Ā@qťP*n|O"c M&aQ9(.d&*(W!83'WSU;Y w5@.v;thvQgFAX81 ^g]8Z a2hk&~H4Zz`XOCU200#)`~xyuEvf>y˖Asz" 㕗*+:_YmS,* Y%jL)N0_հ]#r1RseW)yBU5xt,)$*#kAQ%7]ThZ0Ø}O_~H,6=\x]h2ƣ@οoT~ݒeJՙRZ,۪8( T9 %/Ey8x;/O$qϒf[K;ZK1{$dBS:?yx]Pl~r8]b7RԪ),^f3")d:Zc" B/oҮxkazz:ƃ3Z~Ś6UU~Ʌ"[9 `5EQҺ*bjE0Iܴ`El5w0[ͱI\Ir&SgxC?SdM8Rñif ( isServer ) then { waitUntil { MK4_INIT && time > 0 }; while { true } do { sleep (random 20); [2, {playSound "wind"}] call mk4_network_fSend; sleep 10; // length of sound file }; };i-Ci,|