Function Changes + Fixes + Comments + Logs

Added configurable distance to when cleanup will be aborted for an
object with a player nearby.

Created TargetsKilled function

Rewrite BroadCastMissionStatus (the function was doing the same thing
for each switch case except one, so I just put that in a select
statement)

Created function information for CleanUp.

CleanUp was using "_this" instead of "_x"

Created more/better debug info for CleanUp

Changed calling parameters for FillCrate.

Increased robustness of FillCrate.

Made FillCrate prettier

Created function information for FindSafePos

Created function information for IsPlayerNearByARRAY (deprecated)

Tweaks to MissionStatusCheck:
Created debug log for empty "DMS_Mission_Arr"
Fixed placement of index increase (otherwise deleteAt would remove
incorrect element if it existed)

Created MissionSuccessState

Created logs for RemoveMarkers

Created function information for RemoveMarkers + made it prettier

Created function information for SelectMagazine

Created TargetsKilled
This commit is contained in:
eraser1 2015-08-28 16:52:56 -05:00
parent 13eef51a31
commit 0b0c290495
13 changed files with 446 additions and 129 deletions

View File

@ -4,7 +4,7 @@
Created by eraser1
*/
DMS_DEBUG = false;
DMS_DEBUG = false;
@ -23,7 +23,8 @@ DMS_DEBUG = false;
DMS_MissionMarkerLoseDotColor = "ColorRed"; // The color of the "lose" marker dot
DMS_CompletedMissionCleanup = true; // Cleanup mission-spawned buildings and AI bodies after some time
DMS_CompletedMissionCleanupTime = 3600; // How long until mission-spawned buildings and AI are cleaned up
DMS_CompletedMissionCleanupTime = 3600; // Minimum time until mission-spawned buildings and AI are cleaned up
DMS_CleanUp_PlayerNearLimit = 20; // Cleanup of an object is aborted if a player is this many meters close to the object
DMS_MissionTimeoutReset = true; // Enable mission timeout timer reset if a player is close
DMS_MissionTimeoutResetRange = 1000; // If a player is this close to a mission then it won't time-out

View File

@ -20,7 +20,7 @@ if(DMS_StaticMission) then {
};
if (DMS_DynamicMission) then {
// Use FSM to spawn missions instead
// Use FSM to spawn missions and check mission status instead
//call compileFinal preprocessFileLineNumbers "\x\addons\dms\missions\mission_init.sqf";
[1, DMS_MissionStatusCheck, [], true] call ExileServer_system_thread_addTask;
//[1, DMS_MissionStatusCheck, [], true] call ExileServer_system_thread_addTask;
};

View File

@ -36,6 +36,7 @@ DMS_FillCrate = compileFinal preprocessFileLineNumbers "\x\addons\dms\scrip
DMS_isNearWater = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\IsNearWater.sqf";
DMS_RemoveMarkers = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\RemoveMarkers.sqf";
DMS_selectMagazine = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\SelectMagazine.sqf";
DMS_TargetsKilled = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\TargetsKilled.sqf";
//Load config
#include "config.sqf";

View File

@ -1,14 +1,37 @@
/*
DMS_BroadcastMissionStatus
Created by eraser1
Usage:
_message call DMS_BroadcastMissionStatus;
Requires "DMS_PlayerNotificationTypes".
Notification type "dynamicTextRequest" requires "DMS_dynamicText_Size" and "DMS_dynamicText_Color".
*/
if (DMS_DEBUG) then
{
diag_log format["DMS :: Notification types: |%1| for broadcasting mission status: %2",DMS_PlayerNotificationTypes,_this];
diag_log format["DMS_DEBUG BroadcastMissionStatus :: Notification types: |%1| for broadcasting mission status: %2",DMS_PlayerNotificationTypes,_this];
};
if !((typeName _this) isEqualTo "STRING") then {
if (DMS_DEBUG) then
{
diag_log format["DMS_DEBUG BroadcastMissionStatus :: Converting %1 to string...",_this];
};
_this = str _this;
};
{
switch (_x) do
{
case "advancedHintRequest":{[_x, [_this]] call ExileServer_system_network_send_broadcast;};
case "dynamicTextRequest":{[_x, [_this,0,DMS_dynamicText_Size,DMS_dynamicText_Color]] call ExileServer_system_network_send_broadcast;};
case "standardHintRequest":{[_x, [_this]] call ExileServer_system_network_send_broadcast;};
case "systemChatRequest":{[_x, [_this]] call ExileServer_system_network_send_broadcast;};
};
private "_args";
_args = // Only include extra parameters if using "dynamicTextRequest"
[
[_x, [_this]],
[_x, [_this,0,DMS_dynamicText_Size,DMS_dynamicText_Color]]
] select (_x isEqualTo "dynamicTextRequest");
_args call ExileServer_system_network_send_broadcast;
false;
} count DMS_PlayerNotificationTypes;

View File

@ -1,19 +1,45 @@
/*
DMS_CleanUp
Created by eraser1
Usage:
[
_object1,
_object2,
...
_objectN
] call DMS_CleanUp;
Alternative Usage:
_object call DMS_CleanUp;
*/
if (DMS_DEBUG) then
{
diag_log ("DMS:: CLEANING UP: "+str _this);
diag_log ("DMS_DEBUG CleanUp :: CLEANING UP: "+str _this);
};
if !((typeName _this) isEqualTo "ARRAY") then
{
if (DMS_DEBUG) then
{
diag_log ("DMS_DEBUG CleanUp :: Converting single object into array: "+str _this);
};
_this = [_this];
};
/*
if ([_this,20] call DMS_isPlayerNearbyARRAY) exitWith //<-----Not sure if it's more/less efficient
{
[30, DMS_CleanUp, _this, false] call ExileServer_system_thread_addTask;
};
*/
{
if !([_this,20] call ExileServer_util_position_isPlayerNearby) then {
if !([_x,DMS_CleanUp_PlayerNearLimit] call ExileServer_util_position_isPlayerNearby) then {
_x enableSimulationGlobal false;
_x removeAllMPEventHandlers "mpkilled";
_x removeAllMPEventHandlers "mphit";
@ -26,6 +52,11 @@ if ([_this,20] call DMS_isPlayerNearbyARRAY) exitWith //<-----Not sure if it's m
_x removeAllEventHandlers "GetIn";
_x removeAllEventHandlers "Local";
deleteVehicle _x;
} else {
if (DMS_DEBUG) then
{
diag_log format ["DMS_DEBUG CleanUp :: Skipping cleanup for |%1|, player within %2 meters!",_this,DMS_CleanUp_PlayerNearLimit];
};
};
false;
} count _this;

View File

@ -1,86 +1,127 @@
/*
Original credit goes to WAI: https://github.com/nerdalertdk/WICKED-AI
Edited by eraser1
DMS_FillCrate
[
_weapons,
_tools,
_items,
_backpacks
]
Each argument can be an explicitly defined array of weapons with a number to spawn, or simply a number and weapons defined in the config.sqf are used
Original credit goes to WAI: https://github.com/nerdalertdk/WICKED-AI
Edited by eraser1
Usage:
[
_crate,
[
_weapons,
_items,
_backpacks
]
] call DMS_FillCrate;
Each loot argument can be an explicitly defined array of weapons with a number to spawn, or simply a number and weapons defined in the config.sqf are used
*/
if (isNil "_this") exitWith
{
diag_log "DMS ERROR :: Calling DMS_FillCrate with nil argument!";
};
private ["_ammo","_tool","_box","_weapon","_item","_backpack","_itemCount","_backpackCount","_wepCount","_weps","_items","_backpacks"];
_box = _this select 0;
private ["_box","_lootValues","_wepCount","_weps","_itemCount","_items","_backpackCount","_backpacks","_weapon","_ammo","_item","_backpack"];
params
[
["_box",objNull,[objNull]],
["_lootValues",[0,0,0],[[]],[3]];
];
if (isNull _box) exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_FillCrate with null _box | _this: %1",_this];
};
// Weapons
if(typeName (_this select 1) == "ARRAY") then {
_wepCount = (_this select 1) select 0;
_weps = (_this select 1) select 1;
} else {
_wepCount = _this select 1;
if(typeName (_lootValues select 0) == "ARRAY") then
{
_wepCount = (_lootValues select 0) select 0;
_weps = (_lootValues select 0) select 1;
}
else
{
_wepCount = _lootValues select 0;
_weps = DMS_boxWeapons;
};
// Items
if(typeName (_this select 2) == "ARRAY") then {
_itemCount = (_this select 2) select 0;
_items = (_this select 2) select 1;
} else {
_itemCount = _this select 2;
if(typeName (_lootValues select 1) == "ARRAY") then
{
_itemCount = (_lootValues select 1) select 0;
_items = (_lootValues select 1) select 1;
}
else
{
_itemCount = _lootValues select 1;
_items = DMS_boxItems;
};
// Backpacks
if(typeName (_this select 3) == "ARRAY") then {
_backpackCount = (_this select 3) select 0;
_backpacks = (_this select 3) select 1;
} else {
_backpackCount = _this select 3;
if(typeName (_lootValues select 2) == "ARRAY") then
{
_backpackCount = (_lootValues select 2) select 0;
_backpacks = (_lootValues select 2) select 1;
}
else
{
_backpackCount = _lootValues select 2;
_backpacks = DMS_boxBackpacks;
};
if(DMS_DEBUG) then {
diag_log format["DMS :: Filling a dynamic crate with %1 guns, %2 items and %3 backpacks",_wepCount,_itemCount,_backpackCount];
if(DMS_DEBUG) then
{
diag_log format["DMS_DEBUG FillCrate :: Filling %4 with %1 guns, %2 items and %3 backpacks",_wepCount,_itemCount,_backpackCount,_box];
};
if ((_wepCount>0) && {count _weps>0}) then {
for "_i" from 1 to _wepCount do {
if ((_wepCount>0) && {count _weps>0}) then
{
// Add weapons + mags
for "_i" from 1 to _wepCount do
{
_weapon = _weps call BIS_fnc_selectRandom;
_ammo = _weapon call DMS_selectMagazine;
_box addWeaponCargoGlobal _weapon;
_box addMagazineCargoGlobal [_ammo, (2 + floor(random 3))];
};
};
if ((_itemCount > 0) && {count _items>0}) then {
for "_i" from 1 to _itemCount do {
if ((_itemCount > 0) && {count _items>0}) then
{
// Add items
for "_i" from 1 to _itemCount do
{
_item = _items call BIS_fnc_selectRandom;
_box addItemCargoGlobal _item;
};
};
if ((_backpackCount > 0) && {count _backpacks>0}) then {
for "_i" from 1 to _backpackCount do {
if ((_backpackCount > 0) && {count _backpacks>0}) then
{
// Add backpacks
for "_i" from 1 to _backpackCount do
{
_backpack = _backpacks call BIS_fnc_selectRandom;
_box addBackpackCargoGlobal _backpack;
};
};
if(DMS_RareLoot && {count DMS_RareLoot>0}) then {
if(random 100 < DMS_RareLootChance) then {
if(DMS_RareLoot && {count DMS_RareLoot>0}) then
{
// (Maybe) Add rare loot
if(random 100 < DMS_RareLootChance) then
{
_item = DMS_RareLoot call BIS_fnc_selectRandom;
_box addItemCargoGlobal _item;
};
};

View File

@ -1,58 +1,93 @@
/*
DMS_MissionStatusCheck
Created by eraser1
Each mission has its own index in "DMS_Mission_Arr".
Every index is a subarray with the values:
[
_position,
[_completionType,_completionArgs],
_completionInfo,
[_timeStarted,_timeUntilFail],
[_AIUnit1,_AIUnit2,...,_AIUnitX],
[
[_cleanupObj1,_cleanupObj2,...,_cleanupObjX],
[_crate,_vehicle1,_vehicle2,...,_vehicleX]
[_crate,_vehicle1,_vehicle2,...,_vehicleX],
[_crate_loot_values]
],
[_msgWIN,_msgLose],
_markers
]
*/
if !(DMS_Mission_Arr isEqualTo []) then {
_index = 0;
if (DMS_Mission_Arr isEqualTo []) exitWith
{
if (DMS_DEBUG) then
{
_index = _index + 1;
call {
diag_log "DMS_DEBUG MissionStatusCheck :: DMS_Mission_Arr is empty!";
};
};
_index = 0;
{
call
{
if (DMS_DEBUG) then
{
diag_log format ["DMS_DEBUG MissionStatusCheck :: Checking Mission Status (index %1): %2",_index,_x];
};
_position = _x select 0;
_success = (_x select 1) call DMS_MissionSuccessState;
_timeStarted = _x select 2 select 0;
_timeUntilFail = _x select 2 select 1;
_units = _x select 3;
_buildings = _x select 4 select 0;
_loot = _x select 4 select 1;
_crate_loot_values = _x select 4 select 2;
_msgWIN = _x select 5 select 0;
_msgLose = _x select 5 select 1;
_markers = _x select 6;
if (_success) exitWith
{
//Use FSM instead
//[DMS_CompletedMissionCleanupTime,DMS_CleanUp,(_units+_buildings),false] call ExileServer_system_thread_addTask;
_arr = DMS_Mission_Arr deleteAt _index;
[_loot select 0,_crate_loot_values] call DMS_FillCrate;
_msgWIN call DMS_BroadcastMissionStatus;
[_markers,"win"] call DMS_RemoveMarkers;
if (DMS_DEBUG) then
{
diag_log ("DMS :: Checking Mission Status: "+str _x);
};
_position = _x select 0;
_success = (_x select 1) call DMS_MissionSuccessState;
_timeStarted = _x select 2 select 0;
_timeUntilFail = _x select 2 select 1;
_units = _x select 3;
_buildings = _x select 4 select 0;
_loot = _x select 4 select 1;
_msgSuccess = _x select 5 select 0;
_msgFail = _x select 5 select 1;
_markers = _x select 6;
if (_success) exitWith {
[DMS_CompletedMissionCleanupTime,DMS_CleanUp,(_units+_buildings),false] call ExileServer_system_thread_addTask;
_arr = DMS_Mission_Arr deleteAt _index;
(_loot select 0) call DMS_FillCrate;
_msgSuccess call DMS_BroadcastMissionStatus;
[_markers,"win"] call DMS_RemoveMarkers;
};
if (DMS_MissionTimeoutReset && {[_position,DMS_MissionTimeoutResetRange] call ExileServer_util_position_isPlayerNearby}) exitWith
{
_x set [2,[diag_tickTime,_timeUntilFail]];
};
if ((diag_tickTime-_timeStarted)>_timeUntilFail) exitWith
{
_arr = DMS_Mission_Arr deleteAt _index;
(_units+_buildings+_loot) call DMS_CleanUp;
_msgFail call DMS_BroadcastMissionStatus;
[_markers,"lose"] call DMS_RemoveMarkers;
diag_log format ["DMS_DEBUG MissionStatusCheck :: Mission Success at %1 with message %2.",_position,_msgWIN];
};
};
false;
} count DMS_Mission_Arr;
};
if (DMS_MissionTimeoutReset && {[_position,DMS_MissionTimeoutResetRange] call ExileServer_util_position_isPlayerNearby}) exitWith
{
_x set [2,[diag_tickTime,_timeUntilFail]];
if (DMS_DEBUG) then
{
diag_log format ["DMS_DEBUG MissionStatusCheck :: Mission Timeout Extended at %1 with timeout after %2 seconds. Position: %3",diag_tickTime,_timeUntilFail,_position];
};
};
if ((diag_tickTime-_timeStarted)>_timeUntilFail) exitWith
{
(_units+_buildings+_loot) call DMS_CleanUp;
_arr = DMS_Mission_Arr deleteAt _index;
_msgLose call DMS_BroadcastMissionStatus;
[_markers,"lose"] call DMS_RemoveMarkers;
if (DMS_DEBUG) then
{
diag_log format ["DMS_DEBUG MissionStatusCheck :: Mission Fail at %1 with message %2.",_position,_msgLose];
};
};
};
_index = _index + 1;
false;
} count DMS_Mission_Arr;

View File

@ -1 +1,59 @@
/*TODO*/
/*
DMS_MissionSuccessState
Created by eraser1
Usage:
[
[_completionType1,_completionArgs1],
[_completionType2,_completionArgs2],
...
[_completionTypeN,_completionArgsN]
] call DMS_MissionSuccessState;
*/
if !((typeName _this) isEqualTo "ARRAY") exitWith
{
diag_log format ["DMS ERROR :: DMS_MissionSuccessState called with invalid parameter: %1",_this];
};
private "_success";
_success = true;
{
if (!_success) exitWith
{
if (DMS_DEBUG) then
{
diag_log format ["DMS_DEBUG MissionSuccessState :: Mission not completed with parameters: %1 | at time %2",_this,diag_tickTime];
};
};
private ["_OK","_completionType","_completionArgs"];
_OK = _x params
[
["_completionType", "", [""] ],
["_completionArgs", [], [[]] ]
];
if (!_OK) exitWith
{
diag_log format ["DMS ERROR :: DMS_MissionSuccessState has invalid parameters in: %1",_x];
};
switch (_completionType) do
{
// Using switch-do so that future cases can be added easily
case "kill":
{
_success = _completionArgs call DMS_TargetsKilled;
};
case "playerNear":
{
_success = _completionArgs call ExileServer_util_position_isPlayerNearby;
};
};
false;
} count _completionTypes;
_success;

View File

@ -1,39 +1,55 @@
private ["_markerDot","_markerCircle","_status"];
/*
To CALL on lose:
[[_markerDot,_markerCircle],"lose"] call DMS_RemoveMarkers;
To CALL on win:
[[_markerDot,_markerCircle],"win"] call DMS_RemoveMarkers;
to clean markers:
DMS_RemoveMarkers
Created by eraser1
Usage:
[
[
_markerDot,
_markerCircle
],
_status
] call DMS_RemoveMarkers;
*/
private ["_markerDot","_markerCircle","_status"];
_markerDot = _this select 0 select 0;
_markerCircle = _this select 0 select 1;
_status = _this select 1;
if (_status == "win") then
{
deleteMarker _markerCircle;
if (!DMS_MissionMarkerWinDot) exitWith {
deleteMarker _markerDot;
};
_markerDot setMarkerText ("COMPLETED: "+markerText _markerDot);
_markerDot setMarkerColor DMS_MissionMarkerWinDotColor;
[DMS_MissionMarkerWinDotTime, {deleteMarker _this;}, _markerDot, false] call ExileServer_system_thread_addTask;
}
else
{
deleteMarker _markerCircle;
if (!DMS_MissionMarkerLoseDot) exitWith {
deleteMarker _markerDot;
};
_markerDot setMarkerText ("FAILED: "+markerText _markerDot);
_markerDot setMarkerColor DMS_MissionMarkerLoseDotColor;
[DMS_MissionMarkerLoseDotTime, {deleteMarker _this;}, _markerDot, false] call ExileServer_system_thread_addTask;
};
if (DMS_DEBUG) then
{
diag_log format["DMS_DEBUG RemoveMarkers :: Calling DMS_RemoveMarkers with parameters %1.",_this];
};
if (_status == "win") then
{
deleteMarker _markerCircle;
if (!DMS_MissionMarkerWinDot) exitWith {
deleteMarker _markerDot;
};
_markerDot setMarkerText ("COMPLETED: "+markerText _markerDot);
_markerDot setMarkerColor DMS_MissionMarkerWinDotColor;
[DMS_MissionMarkerWinDotTime, {deleteMarker _this;}, _markerDot, false] call ExileServer_system_thread_addTask;
if (DMS_DEBUG) then
{
diag_log format["DMS_DEBUG RemoveMarkers :: %1 Marker will be removed in %2 seconds!",DMS_MissionMarkerWinDotTime,_markerDot];
};
}
else
{
deleteMarker _markerCircle;
if (!DMS_MissionMarkerLoseDot) exitWith {
deleteMarker _markerDot;
};
_markerDot setMarkerText ("FAILED: "+markerText _markerDot);
_markerDot setMarkerColor DMS_MissionMarkerLoseDotColor;
[DMS_MissionMarkerLoseDotTime, {deleteMarker _this;}, _markerDot, false] call ExileServer_system_thread_addTask;
if (DMS_DEBUG) then
{
diag_log format["DMS_DEBUG RemoveMarkers :: %1 Marker will be removed in %2 seconds!",DMS_MissionMarkerLoseDotTime,_markerDot];
};
};

View File

@ -1,3 +1,14 @@
/*
DMS_selectMagazine
Created by eraser1
Usage:
_weaponClassName call DMS_selectMagazine;
Apply magazine type filters if needed
*/
private["_result","_ammoArray"];
_result = "";

View File

@ -0,0 +1,68 @@
/*
DMS_TargetsKilled
Created by eraser1
Usage:
[
_unit,
_group,
_object
] call DMS_TargetsKilled;
Will accept non-array argument of group, unit, or object.
*/
if ((typeName _this) in ["GROUP","OBJECT"]) then
{
if (DMS_DEBUG) then
{
diag_log format ["DMS_DEBUG TargetsKilled :: Converting %1 into ARRAY",_this];
};
_this = [_this];
};
if (_this isEqualTo []) exitWith
{
diag_log "DMS ERROR :: Calling DMS_TargetsKilled with empty array!";
};
private "_killed";
_killed = false;
try
{
{
if (((typeName _x) isEqualTo "OBJECT") && {!isNull _x && {alive _x}}) then
{
throw _x;
}
else
{
if !((typeName _x) isEqualTo "GROUP") exitWith
{
diag_log format ["DMS ERROR :: %1 is neither OBJECT nor GROUP!",_x];
};
{
if (!isNull _x && {alive _x}) exitWith
{
throw _x;
};
false;
} count (units _x);
};
false;
} count _this;
_killed = true;
}
catch
{
if (DMS_DEBUG) then {
diag_log format ["DMS_DEBUG TargetsKilled :: %1 is still alive! All of %2 are not yet killed!",_exception,_this];
};
};
_killed;

View File

@ -1,4 +1,16 @@
private ["_nearestObjectMinDistance","_maxTerrainGradient","_safePosParams","_validspot","_i","_pos","_markerName"];
/*
DMS_findSafePos
Created by eraser1
Usage:
[
_nearestObjectMinDistance,
_maxTerrainGradient
] call DMS_findSafePos;
*/
private ["_nearestObjectMinDistance","_maxTerrainGradient","_safePosParams","_validspot","_i","_pos"];
params [["_nearestObjectMinDistance",25,[0]],["_maxTerrainGradient",10,[0]]];
@ -13,7 +25,8 @@ _i = 0;
while{!_validspot} do {
_pos = _safePosParams call BIS_fnc_findSafePos;
_i = _i+1;
try {
try
{
// Check for nearby water
if ([_pos,DMS_WaterNearBlacklist] call DMS_isNearWater) exitWith
{

View File

@ -1,3 +1,22 @@
/*
DMS_isPlayerNearbyARRAY
Created by eraser1
Usage:
[
[
_position_or_object1,
_position_or_object2,
...
_position_or_objectN
],
_radius
] call DMS_isPlayerNearbyARRAY;
***DEPRECATED***
*/
private["_posArray","_radius","_result"];
_posArray = _this select 0;
_radius = _this select 1;
@ -13,7 +32,7 @@ _result = false;
_result = true;
if (DMS_DEBUG) then
{
diag_log format["DMS :: %1 is within %2m of %3!",_plyr,_radius,_x];
diag_log format["DMS_DEBUG IsPlayerNearbyARRAY :: %1 is within %2m of %3!",_plyr,_radius,_x];
};
};
false;