From 58acf95dc735bf4fab9ac03e9f8966b079765528 Mon Sep 17 00:00:00 2001 From: icomrade Date: Mon, 29 Feb 2016 00:29:23 -0500 Subject: [PATCH] Server Done I Think --- SQF/dayz_server/NOTE.txt | 39 + SQF/dayz_server/compile/fa_antiwallhack.sqf | 96 ++ .../compile/fa_fuelConsumption.sqf | 18 + .../compile/fa_hiveMaintenance.hpp | 58 ++ .../compile/fa_hiveMaintenance.sqf | 584 ++++++++++++ .../compile/server_onPlayerDisconnect.sqf | 56 +- .../compile/server_plantSpawner.sqf | 23 + SQF/dayz_server/compile/server_playerDied.sqf | 18 +- .../compile/server_playerLogin.sqf | 72 +- .../compile/server_playerSetup.sqf | 146 +-- SQF/dayz_server/compile/server_playerSync.sqf | 47 +- .../compile/server_spawnCarePackages.sqf | 85 ++ .../compile/server_spawnCrashSites.sqf | 139 +++ .../compile/server_spawnInfectedCamps.sqf | 91 ++ .../compile/server_toggle_debug.hpp | 19 + .../compile/server_updateNearbyObjects.sqf | 9 + .../compile/server_updateObject.sqf | 306 ++++-- .../compile/zombie_Wildgenerate.sqf | 51 + SQF/dayz_server/compile/zombie_findOwner.sqf | 8 + SQF/dayz_server/config.cpp | 76 +- .../server_sendToClient.sqf | 57 +- SQF/dayz_server/init/Epoch_Init.sqf | 853 +++++++++++++++++ SQF/dayz_server/init/server_functions.sqf | 893 ++---------------- SQF/dayz_server/system/lit_fireplaces.sqf | 28 + SQF/dayz_server/system/s_fps.sqf | 4 + .../system/scheduler/sched_corpses.sqf | 158 ++++ .../system/scheduler/sched_init.sqf | 35 + .../system/scheduler/sched_lootpiles.sqf | 113 +++ .../scheduler/sched_playersHivesync.sqf | 44 + .../system/scheduler/sched_safetyVehicle.sqf | 12 + .../system/scheduler/sched_sync.sqf | 25 + .../system/scheduler/sched_traps.sqf | 33 + .../scheduler/sched_vehiclesHivesync.sqf | 37 + SQF/dayz_server/system/server_cleanup.fsm | 465 ++++----- SQF/dayz_server/system/server_cleanup.sqf | 81 ++ SQF/dayz_server/system/server_monitor.sqf | 137 ++- SQF/dayz_server/system/zombie_wildagent.fsm | 203 ++++ 37 files changed, 3919 insertions(+), 1200 deletions(-) create mode 100644 SQF/dayz_server/NOTE.txt create mode 100644 SQF/dayz_server/compile/fa_antiwallhack.sqf create mode 100644 SQF/dayz_server/compile/fa_fuelConsumption.sqf create mode 100644 SQF/dayz_server/compile/fa_hiveMaintenance.hpp create mode 100644 SQF/dayz_server/compile/fa_hiveMaintenance.sqf create mode 100644 SQF/dayz_server/compile/server_plantSpawner.sqf create mode 100644 SQF/dayz_server/compile/server_spawnCarePackages.sqf create mode 100644 SQF/dayz_server/compile/server_spawnCrashSites.sqf create mode 100644 SQF/dayz_server/compile/server_spawnInfectedCamps.sqf create mode 100644 SQF/dayz_server/compile/server_toggle_debug.hpp create mode 100644 SQF/dayz_server/compile/server_updateNearbyObjects.sqf create mode 100644 SQF/dayz_server/compile/zombie_Wildgenerate.sqf create mode 100644 SQF/dayz_server/compile/zombie_findOwner.sqf rename SQF/dayz_server/{compile => eventHandlers}/server_sendToClient.sqf (65%) create mode 100644 SQF/dayz_server/init/Epoch_Init.sqf create mode 100644 SQF/dayz_server/system/lit_fireplaces.sqf create mode 100644 SQF/dayz_server/system/s_fps.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_corpses.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_init.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_lootpiles.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_playersHivesync.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_safetyVehicle.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_sync.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_traps.sqf create mode 100644 SQF/dayz_server/system/scheduler/sched_vehiclesHivesync.sqf create mode 100644 SQF/dayz_server/system/server_cleanup.sqf create mode 100644 SQF/dayz_server/system/zombie_wildagent.fsm diff --git a/SQF/dayz_server/NOTE.txt b/SQF/dayz_server/NOTE.txt new file mode 100644 index 000000000..3724913ab --- /dev/null +++ b/SQF/dayz_server/NOTE.txt @@ -0,0 +1,39 @@ + + +NEW VARS IN SENDTOCLIENT: + +OpenTarget +PVCDZ_OpenTarget_Reset + +GutBody +PVCDZ_obj_GutBody + +SetEngineState +PVCDZ_veh_engineSwitch + +Legs (BREAKS LEGS???) +PVCDZ_plr_Legs + +Antibiotics +PVCDZ_hlt_AntiB + +dayzSetDate +dayzSetDate + +Transfuse_completed +PVCDZ_hlt_Transfuse_completed + +CHANGE NEW VAR/PV NAMES --> OLD + +PVCDZ_veh_SH --> PVCDZE_vehSH +SetFuel --> SFuel +PVCDZ_veh_SetFuel --> PVDZE_veh_SFuel +PVCDZ_obj_HideBody --> PVDZE_plr_HideBody +PVCDZ_plr_Humanity --> PVDZE_plr_HumanityChange +PVCDZ_hlt_Transfuse --> usecTransfuse +PVCDZ_hlt_PainK--> usecPainK +PVCDZ_hlt_Morphine --> usecMorphine +PVCDZ_hlt_Epi --> usecEpi +PVCDZ_hlt_Bandage --> usecBandage +dayzPlayerLogin --> PVCDZ_plr_PlayerAccepted +PVCDZ_plr_PlayerAccepted --> PVCDZE_plr_PlayerAccepted \ No newline at end of file diff --git a/SQF/dayz_server/compile/fa_antiwallhack.sqf b/SQF/dayz_server/compile/fa_antiwallhack.sqf new file mode 100644 index 000000000..a2c346e36 --- /dev/null +++ b/SQF/dayz_server/compile/fa_antiwallhack.sqf @@ -0,0 +1,96 @@ +/* + Created exclusively for ArmA2:OA - DayZMod. + Please request permission to use/alter/distribute from project leader (R4Z0R49) AND the author (facoptere@gmail.com) +*/ + +private ["_antiwallhack","_houseType","_houseList","_tmp","_patchList","_house","_o","_nbhouses","_nbpatchs","_pos"]; + +_antiwallhack=[ + [ + "Land_A_Hospital", // building type + [ + [6414.05,2760.21,0], [6817.3,2702.03,0], [10517.9,2287.55,0], [11956.7,9120.21,0] // optional precomputed building positions + ], + [ + [17.6182,-1.8418,3.23178,"Land_CncBlock_D",0],[15.7192,-1.84277,3.22177,"Land_CncBlock_D",0],[-17.4,-0.38,-4.25,"Land_CncBlock_D",90],[-17.4,2.25,-4.25,"Land_CncBlock_D",90],[-17.4,4.22,-4.25,"Land_CncBlock_D",90],[-17.42,-3.55,-7.63,"Land_CncBlock_D",90],[-13.27,2.83,-4.25,"Fort_RazorWire",180],[-13.23,4.28,-4.25,"Fort_RazorWire",180],[-16.81,1.38,-4.25,"Hedgehog",85],[-16.82,-0.6,-4.25,"Hedgehog",90],[-7.45,4.26,-4.25,"Fort_RazorWire",180] // what to add on building (coordinates/type/angle) + ] + ], + [ + "Land_HouseB_Tenement", + [ + [6855.66,2496.78,0] + ], + [ + [-9.66602,7.66602,18.3236,"Fort_RazorWire",0], [-1.30273,7.66602,18.3236,"Fort_RazorWire",0], [-9.66602,0.814453,18.3236,"Fort_RazorWire",0], [-1.30273,0.814453,18.3236,"Fort_RazorWire",0], [-15.0029,4.18359,18.3236,"Fort_RazorWire",90], [3.62109,3.95117,18.3236,"Fort_RazorWire",270], [-7.42,8.15,-20.57,"Fort_RazorWire",180], [-4.67,9.92,-21.55,"Fort_RazorWire",180] + ] + ], + [ + "Land_A_Office02", + [[6552.96,2807.47,0], [7036.05,2526.13,0], [10028.6,1832.52,0]], + [ + [2.17627, 1.98828, 5.31387, "Land_CncBlock_D" , 0], [2.85547, 3.02246, 5.38394, "Land_CncBlock_D" , 0], [-15.7412, 3.98145, 5.38394, "Land_CncBlock_D" , 270], [-20.2915, 4.01563, 5.35391, "Land_CncBlock_D" , 90], [-20.291, 1.22559, 5.36392, "Land_CncBlock_D" , 90], [-19.0527, -0.318359, 5.38394, "Land_CncBlock_D" , 0], [-16.6426, -0.321289, 5.38394, "Land_CncBlock_D" , 0], [-15.4575, 1.01563, 5.35391, "Land_CncBlock_D" , 270], [-16.7344, 5.30762, 5.38394, "Land_CncBlock_D" , 180], [-19.0361, 5.30859, 5.38394, "Land_CncBlock_D" , 180] + ] + ], + [ + "Land_A_Office01", + [[3804.1,8924.83,-0.15], [10481.5,2358.45,0], [12742.4,9593.23,0]], + [ + [0.837891, -1.13086, 5.93463, "Land_CncBlock_D", 90], [2.30957, -2.65918, 6.02472, "Land_CncBlock_D", 0], [3.68457, -1.2168, 6.06476, "Land_CncBlock_D", 270], [2.36914, -1.09863, 6.01471, "Land_CncBlock_D", 225], [2.4043, 0.155273, 6.14484, "Land_CncBlock_D", 180], [2.18359, -1.36035, 6.01471, "Land_CncBlock_D", 135] + ] + ], + [ + "Land_A_statue01", + [[3796.36,8838.01,0], [6531.07,2804.09,0], [6811.04,2455.16,0]], + [ + [1.50049,2.14844,-3.6926,"Land_CncBlock_D",180], [2.86523,0.0966797,-3.69263,"Land_CncBlock_D",270], [1.38232,-2.17578,-3.69305,"Land_CncBlock_D",0] + ] + ], + [ + "Land_Barn_Metal", + [[2860.45,9746.05,0.682495],[4565.07,4528.81,0.199997], [6339.55,7693.31,0.0499878],[11329.8,6646.15,0.331261]], + [ + [7.02,17.13,-5.74,"Misc_TyreHeap",36], [-5.4,7.85,-5.44,"SKODAWreck",181], [-7.5,8.87,-5.44,"SKODAWreck",181], [-0.99,-9.31,-5.44,"UralWreck",320], + [8.33,8.43,-5.44,"datsun01Wreck",176], [4.13,10.16,-5.44,"SKODAWreck",176], [-7.21,-15.37,-5.44,"SKODAWreck",8], [3.3,15.19,-5.44,"UralWreck",210], + [-5.76,12.87,-5.44,"SKODAWreck",150], [6.76,-6.86,-5.54,"LADAWreck",85], [-0.42,-21.9,-5.75,"Misc_TyreHeap",95] + ] + ] +]; + +_nbhouses = 0; +_nbpatchs = 0; +{ + _houseType = _x select 0; + _houseList = _x select 1; + if (count _houseList == 0) then { + _houseList = (getMarkerpos "center") nearObjects [_houseType, 20000]; + } + else { + _tmp = []; + { + _tmp set [count _tmp, _x nearestObject _houseType]; + } forEach _houseList; + _houseList = _tmp; + }; + _patchList = _x select 2; + { + _nbhouses = _nbhouses +1; + _house = _x; + { + _pos = +(_x); + _pos resize 3; + _pos = _house modelToWorld _pos; + _o = createVehicle [(_x select 3), _pos, [], 0, "CAN_COLLIDE"]; + _o setDir ((getDir _house)+(_x select 4)); + _o setPosATL _pos; + diag_log [ typeOf _o, getPosATL _o, getDir _o, 0, nil]; + _nbpatchs = _nbpatchs +1; + } forEach _patchList; + //diag_log format["Found building %1 at %2", _houseType, getPosATL _house ]; + } forEach _houseList; +} forEach _antiwallhack; + +diag_log(format["%1: %2 buildings patched with %3 objects", __FILE__, _nbhouses, _nbpatchs]); + + + + diff --git a/SQF/dayz_server/compile/fa_fuelConsumption.sqf b/SQF/dayz_server/compile/fa_fuelConsumption.sqf new file mode 100644 index 000000000..036d071ca --- /dev/null +++ b/SQF/dayz_server/compile/fa_fuelConsumption.sqf @@ -0,0 +1,18 @@ +/* + Not Used Test System +*/ + + +//_vehicle = _this select 0; +//_engineState = _this select 1; + +_rate = getNumber (configFile >> "CfgVehicles" >> (typeOf (_this select 0)) >> "fuelconsumptionrate"); + +if (_this select 1) then { + //[_vehicle, _rate] spawn { + while {isEngineOn (_this select 0)} do { + (_this select 0) setFuel ( Fuel (_this select 0) - (_this select 1)); + sleep 1; + }; + //}; +}; \ No newline at end of file diff --git a/SQF/dayz_server/compile/fa_hiveMaintenance.hpp b/SQF/dayz_server/compile/fa_hiveMaintenance.hpp new file mode 100644 index 000000000..3f631f6e4 --- /dev/null +++ b/SQF/dayz_server/compile/fa_hiveMaintenance.hpp @@ -0,0 +1,58 @@ +/* + Created exclusively for ArmA2:OA - DayZMod. + Please request permission to use/alter/distribute from project leader (R4Z0R49) AND the author (facoptere@gmail.com) +*/ + +//// TENTS CHECK //// + +// Proceed to empty tents check: extra empty tents will be ignored (tents won't be created on map) +// comment this out if you don't want any check +//#define EMPTY_TENTS_CHECK + +// Max number of empty tents +#define EMPTY_TENTS_GLOBAL_LIMIT 100 + +// Keep a least this number of empty tents per user +#define EMPTY_TENTS_USER_LIMIT 3 + + + +//// OUT-OF-MAP CHECK //// + +// Move out-of-map tents and other crafted/installed objects next to map boundary. +//#define OBJECTS_FIX_OUTOFMAP + +// Move out-of-map vehicle next to map boundary. +//#define VEH_MAINTENANCE_FIX_OUTOFMAP + +// Move out-of-map player next to map boundary during playerSetup +//#define PLAYERS_FIX_OUTOFMAP + + + +//// VEHICLE MAINTENANCE ///// + +// Ignore (don't create on map) vehicles not decribed in Cfg file, or outnumbered ones +//#define VEH_MAINTENANCE_IGNORE_UNKNOWN + +// Add missing vehicles, as described in Cfg file. Respawn damaged vehicles. +//#define VEH_MAINTENANCE_ADD_MISSING + +// Don't look for a suitable place anywhere on map if current place is not safe +#define VEH_MAINTENANCE_DONT_BE_SMART + +// Damage the vehicle for 1 startup over 5 +// don't define if you don't want any damage +//#define VEH_MAINTENANCE_ROTTEN_AT_STARTUP 5 + +// How the damage is computed. Here, a 0% damaged vehicle would be respawned after 100 restarts +#define VEH_MAINTENANCE_ROTTEN_LOGIC (_damage * 1.04 + 0.03) + +// How initial fuel level is set when a vehicle is created/spawned +#define VEH_MAINTENANCE_SPAWN_FUEL_LOGIC (0.1 + floor(random 3) / 10) + + + + +// where the config is described +#define CONFIGBASE_VEHMAINTENANCE configFile >> "CfgPatches" >> "vehMaint" diff --git a/SQF/dayz_server/compile/fa_hiveMaintenance.sqf b/SQF/dayz_server/compile/fa_hiveMaintenance.sqf new file mode 100644 index 000000000..28e83de06 --- /dev/null +++ b/SQF/dayz_server/compile/fa_hiveMaintenance.sqf @@ -0,0 +1,584 @@ +/* + Created exclusively for ArmA2:OA - DayZMod. + Please request permission to use/alter/distribute from project leader (R4Z0R49) AND the author (facoptere@gmail.com) +*/ + +#include "fa_hiveMaintenance.hpp" + +// coor2str: convert position to a GPS coordinates +fa_coor2str = { + private["_pos","_res","_nearestCity","_town"]; + + _pos = +(_this); + if (count _pos < 1) then { _pos = [0,0]; } + else { if (count _pos < 2) then { _pos = [_pos select 0,0]; }; + }; + _nearestCity = nearestLocations [_pos, ["NameCityCapital","NameCity","NameVillage","NameLocal"],1000]; + _town = "Wilderness"; + if (count _nearestCity > 0) then {_town = text (_nearestCity select 0)}; + _res = format["%1 [%2:%3]", _town, round((_pos select 0)/100), round((15360-(_pos select 1))/100)]; + + _res +}; + +// print vehicle OID and name. if OID is unknown, it should be an hacked vehicle so print hacker PID. +fa_veh2str = { + private["_res","_oid", "_type"]; + + _res = "anything"; + if (!isNil "_this") then { + _oid = _this getVariable ["ObjectID", nil]; + if (isNil "_oid" OR {(_oid == "")}) then { + _oid = "Hacked vehicle owned by PID#" + str(owner _this); + } + else { + _oid = "OID#" + _oid; + }; + _type = getText(configFile >> "CfgVehicles" >> (typeOf _this) >> "displayName"); + if (_type == "") then { _type = typeOf _this; }; + _res = format["%1(%2)", _oid, _type ]; + }; + + _res +}; + +// print player player PID and name. If name unknown then print UID. +fa_plr2str = { + private["_x","_res","_name"]; + _x = _this; + _res = "nobody"; + if (!isNil "_x") then { + _name = _x getVariable ["bodyName", nil]; + if ((isNil "_name" OR {(_name == "")}) AND ({alive _x})) then { _name = name _x; }; + if (isNil "_name" OR {(_name == "")}) then { _name = "UID#"+(getPlayerUID _x); }; + _res = format["PID#%1(%2)", owner _x, _name ]; + }; + _res +}; + + +// isoutofmap: return true if position is out of map +fa_isoutofmap = { + private ["_SWcorner","_NEcorner"]; + _SWcorner = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "SWcorner"); + _NEcorner = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "NEcorner"); + (!((((_this select 0 >= _SWcorner select 0) AND {(_this select 0 <= _NEcorner select 0)}) + AND {(_this select 1 >= _SWcorner select 1)}) AND {(_this select 1 <= _NEcorner select 1)})) +}; + +// spawninventory: draw preexisting loot in the vehicle. helicrash loot type is taken here + parts taken as arg +fa_spawninventory = { + private["_partType","_partChance","_lootWeight","_config","_itemType","_itemChance","_weights", + "_index","_y","_partWeight","_spawnType","_spawnChance","_inventory","_weaponType","_weaponQty" ]; + + _partType = _this select 0; + _partChance = _this select 1; + _config = configFile >> "CfgLoot" >> "Buildings" >> "HeliCrash"; + // append parts to loot item + _itemType = (getArray (_config >> "itemType")); + { _itemType set [count _itemType, [_x,"object"]] } forEach _partType; + _itemChance = getArray (_config >> "itemChance"); + //diag_log (format["FACO _itemType:%1 _itemChance:%2", _itemType, _itemChance]); + // _partWeight : sum of weights of parts list + _partWeight = 0; { _partWeight = _partWeight + _x; } forEach _partChance; + // _lootWeight : sum of weights of loot list + _lootWeight = 0; { _lootWeight = _lootWeight + _x; } forEach _itemChance; + // multiply parts weight so that parts have same chance to be chosen as regular loot + // and append parts chance to loot item weight array + { _itemChance set [count _itemChance, _x * _lootWeight / _partWeight]; } forEach _partChance; + // _partWeight : now, number of item to be chosen + _partWeight = ceil(random(_partWeight)); + // lets choose the inventory + _spawnType = []; + _spawnQty = []; + _weaponType = []; + _weaponQty = []; + _weights = [_itemType,_itemChance] call fnc_buildWeightedArray; + for "_x" from 0 to _partWeight do { + _index = _weights call BIS_fnc_selectRandom; + if (_index < count _itemType) then { + _y=(_itemType select _index) select 0; + if (_y != "") then { + if (_y isKindOf "Pistol" OR _y isKindOf "RifleCore" OR _y isKindOf "Binocular") then { + _weaponType set [count _weaponType, _y ]; + _weaponType set [count _weaponType, 1]; + } + else { + _spawnType set [count _spawnType, _y ]; + _spawnQty set [count _spawnQty, 1]; + }; + }; + }; + }; + _inventory = [[_weaponType,_weaponQty],[_spawnType,_spawnQty],[[],[]]]; + _inventory +}; + +// populateCargo: add item and quantity to the 3 cargos (magazines,weapons,backpack) of an unit +fa_populateCargo = { + private["_entity","_config","_magItemTypes","_magItemQtys","_i","_inventory"]; + _entity = _this select 0; + _inventory = _this select 1; + + clearWeaponCargoGlobal _entity; + clearMagazineCargoGlobal _entity; + clearBackpackCargoGlobal _entity; + _config = ["CfgWeapons", "CfgMagazines", "CfgVehicles" ]; + { + _magItemTypes = _x select 0; + _magItemQtys = _x select 1; + _i = _forEachIndex; + { + if (_x == "Crossbow") then { _x = "Crossbow_DZ" }; // Convert Crossbow to Crossbow_DZ + if (_x == "BoltSteel") then { _x = "WoodenArrow" }; // Convert BoltSteel to WoodenArrow + if (_x == "ItemBloodbag") then { _x = "bloodBagONEG" }; // Convert ItemBloodbag into universal blood type/rh bag + // Convert to DayZ Weapons + if (_x == "DMR") then { _x = "DMR_DZ" }; + //if (_x == "M14_EP1") then { _x = "M14_DZ" }; + if (_x == "SVD") then { _x = "SVD_DZ" }; + if (_x == "SVD_CAMO") then { _x = "SVD_CAMO_DZ" }; + if (isClass(configFile >> (_config select _i) >> _x) && + getNumber(configFile >> (_config select _i) >> _x >> "stopThis") != 1) then { + if (_forEachIndex < count _magItemQtys) then { + switch (_i) do { + case 0: { _entity addWeaponCargoGlobal [_x,(_magItemQtys select _forEachIndex)]; }; + case 1: { _entity addMagazineCargoGlobal [_x,(_magItemQtys select _forEachIndex)]; }; + case 2: { _entity addBackpackCargoGlobal [_x,(_magItemQtys select _forEachIndex)]; }; + }; + }; + }; + } forEach _magItemTypes; + } forEach _inventory; +}; + + +// all damageable parts names defined in Legacy/dayz_vehicles/config.cpp, some of them commented. +// other damageables parts, defined in other CfgVehicles, are ignored. +dayZ_damageableParts = [ "motor", "sklo predni P", "sklo predni L", "karoserie", "palivo", "wheel_1_1_steering", "wheel_2_1_steering", "wheel_1_2_steering", "wheel_2_2_steering", "glass1", "glass2", "glass3", "glass4" +//, "glass5", "glass6", "door_fl", "door_rl", "door_fr", "door_rr" +]; + +// setDamagedParts: declare some damageable parts of a vehicle. Randomly set damage to 80% (very damaged) to some parts +// compute global damage of the vehicle +// return: global damage, "_this" is modified and should be _hitpoints array from server_monitor +fa_setDamagedParts = { + private ["_part_damage", "_part_name", "_damage", "_hitpoints"]; + _damage = 0; + _hitpoints = _this; + { + _part_damage = 0.05; // don't put 0, otherwise server_updateObject will think it's repaired + if (random(3)<1) then { _part_damage = 0.80; }; + _part_name = getText (configFile >> "CfgVehicles" >> (typeOf _entity) >> "HitPoints" >> _x >> "name"); + if (_part_name IN dayZ_damageableParts) then { + _damage = _damage + _part_damage; + _hitpoints set [count _hitpoints, [ _part_name, _part_damage ]]; + }; + } forEach (_entity call vehicle_getHitpoints); + _damage = _damage / (1 + (count _hitpoints)); // avoid DIV0 + + _damage +}; + +fa_tentEmpty = { + ( (count _this == 0) || { + (count ((_this select 0) select 0) == 0) && + (count ((_this select 1) select 0) == 0) && + (count ((_this select 2) select 0) == 0) + }) +}; + +// ignore empty tents from array of objects fetched from hive +fa_removeExtraTents = { + private ["_emptytenttotal", "_idx", "_intentory", "_k", "_maxEmptyTents", "_allowedEmptyTents", "_ownerID", "_stall", "_tentcur", "_tentidx", "_tentowner", "_y", "_z", "_myArray"]; + + _myArray = _this select 0; + _maxEmptyTents = _this select 1; + _allowedEmptyTents = _this select 2; + + _tentowner=[]; + _tentidx=[]; + _tentcur=[]; + _emptytenttotal=0; + + { + if ((_x select 2) == "TentStorage") then { + _idx=_forEachIndex; + _ownerID = _x select 3; + if (!(_ownerID IN _tentowner)) then { + _tentidx set [count _tentidx, []]; + _tentcur set [count _tentcur, 0]; + _tentowner set [count _tentowner, _ownerID]; + }; + _intentory = (_x select 5); + if (_intentory call fa_tentEmpty) then { + { + if (_x == _ownerID) then { + (_tentidx select _forEachIndex) set [count (_tentidx select _forEachIndex), _idx]; + _emptytenttotal = _emptytenttotal + 1; + }; + } forEach _tentowner; + }; + }; + } forEach _myArray; + diag_log (format [ "fa_removeExtraTents: Empty tents: %1, would like less than %2.", + _emptytenttotal, + _maxEmptyTents + ]); + if (_emptytenttotal > _maxEmptyTents) then { + for [{_k = _emptytenttotal / 2}, {_k >= 2}, {_k = _k / 2}] do { + _stall = 0; + while {_emptytenttotal > _maxEmptyTents && _stall == 0} do { + _stall = 1; + for [{_x = (count _tentidx) - 1}, {_x >= 0 && _emptytenttotal >= _maxEmptyTents}, {_x = _x - 1}] do { + _y = _tentidx select _x; + _z = _tentcur select _x; + if (_z < (count _y) -_allowedEmptyTents + 2 - _k) then { + _idx = _myArray select (_y select _z); + /*diag_log (format ["fa_removeExtraTents: will remove Tent ID=%1, owner=%2", + _idx select 1, + _idx select 3 + ]);*/ + _idx set [ 8, 1 ]; // Set damage to 100% + _emptytenttotal = _emptytenttotal - 1; + _tentcur set [_x, _z + 1]; + _stall=0; + }; + }; + _z =_z + 1; + }; + }; + }; +}; + +// check that vehicles list from the Hive has the right count of each vehicle +// if some vehicles are missing, add them to the array +// if a vehicle is illegal or outnumbered, delete it +fa_checkVehicles = { + private ["_vehcat", "_myArray", "_y", "_j","_type", "_count", "_idKey" ]; + _myArray = _this select 0; + + // populate catalogue by browsing configFile + _vehcat = []; + _list = configFile >> "CfgPatches" >> "vehMaint"; + for "_x" from 0 to (count _list - 1) do { + _class = configname (_list select _x); + _qty = getNumber(CONFIGBASE_VEHMAINTENANCE >> _class >> "quantity"); + if (_qty > 0) then { + _vehcat set [count _vehcat, [_class, _qty]]; +// diag_log(format["class:%1 val:%2", _class, _qty]); + }; + }; + + // check the amount of vehicles of each kind + { + _type = _x select 2; + for "_j" from 0 to (count _vehcat-1) do { + if (_type == ((_vehcat select _j) select 0)) then { + _count = ((_vehcat select _j) select 1); + if (_count > 0) then { + (_vehcat select _j) set [1, (_count-1)]; + if ((_x select 8) >= 1) then { +#ifdef VEH_MAINTENANCE_ADD_MISSING + (_myArray select _forEachIndex) set [8, 0.9] ; // damage = 0.9 so this veh will me respawned + diag_log (format["fa_checkVehicles: recycling vehicle class=%1, oid=%2", _x select 2, _x select 1]); +#endif + }; + } +#ifdef VEH_MAINTENANCE_IGNORE_UNKNOWN + else { + (_myArray select _forEachIndex) set [8,2]; // damage=2, so this veh will be deleted + diag_log (format["fa_checkVehicles: skipping vehicle class=%1, oid=%2", + _x select 2, _x select 1]); + } +#endif + ;_j = 999999; // break; + }; + }; + } foreach _myArray; + +#ifdef VEH_MAINTENANCE_ADD_MISSING + // create missing vehicles of each kind. + { + for "_y" from 1 to (_x select 1) do { + // create a new one at the end of _myArray list + _type = (_x select 0); + _idKey = format["%1%2",48,60000+floor(random 10000)]; + // "1" as Character ID since if I put "0" the vehicle is not stored in hive (since january 2013) + _myArray set [count _myArray, ["CREATED",_idKey,_type,"1",[0,[0,0,0]],[[[],[]],[[],[]],[[],[]]],[],0,0.9]]; + diag_log (format["fa_checkVehicles: inserting in HIVE: vehicle class=%1, chosen oid=%2", _type, _idKey]); + }; + } foreach _vehcat; +#endif +}; + +// move object to map boundary if it's out of map +fa_staywithus = { + + private["_a","_dir","_px","_py","_b","_cx","_cy","_k", "_SWcorner", "_NEcorner"]; + + _dir = +(_this select 0); // current position of player / vehicle + _a = +(_this select 1); // current position of player / vehicle + + _SWcorner = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "SWcorner"); + _NEcorner = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "NEcorner"); + + _a = ASLtoATL [_a select 0, _a select 1, 0]; + if ((((_a select 2) > 9) AND {(surfaceisWater _a)}) // entity in water and sea depth above 9 meters? + OR {(_a call fa_isoutofmap)}) then { // or entity is out of map? + // first : put object close to the map boundary, following an axis to the center of the map. + _px = _a select 0; + _py = _a select 1; + _b = getMarkerpos "center"; + + _cx = (_b select 0) - _px; if (_cx == 0) then { _cx = 0.00001; }; + _cy = (_b select 1) - _py; if (_cy == 0) then { _cy = 0.00001; }; + if (_px <= (_SWcorner select 0)) then { _py = _py + (1 + (_SWcorner select 0) - _px) / _cx * _cy; _px = 1 + (_SWcorner select 0); }; + if (_py <= (_SWcorner select 1)) then { _px = _px + (1 + (_SWcorner select 1) - _py) / _cy * _cx; _py = 1 + (_SWcorner select 1); }; + if (_px >= (_NEcorner select 0)) then { _py = _py + ((_NEcorner select 0) - 1 - _px) / _cx * _cy; _px = (_NEcorner select 0) - 1; }; + if (_py >= (_NEcorner select 1)) then { _px = _px + ((_NEcorner select 1) - 1 - _py) / _cy * _cx; _py = (_NEcorner select 1) - 1; }; + // 2nd: compute the object direction, so that it heads toward the center of the map. + _dir = atan(_cx / _cy); + if (_cy < 0) then { _dir = _dir + 180; }; + + // 3rd: if the object is on shalow sea, make it virtually swim so that sea depth is below 9 meters. + _a = [_px,_py,0]; + for "_k" from 0 to 1 step 0.005 do { + _a = [_px + _cx * _k, _py + _cy * _k, 0]; +// if ((_k*200) mod 5 == 4) then { diag_log (format["fa_staywithus: a:%1 water:%2 zx:%3", _a, surfaceisWater _a, (getPosATL _o) select 2]); }; + if (surfaceisWater _a) then { + _a = ASLtoATL [_a select 0, _a select 1, 0]; + if (((_a select 2) < 9) AND{(!(_a call fa_isoutofmap))}) then { _k = 2; } + else { if ((_a select 2) < 30) then { _k = _k - 0.0045; };}; // slow down on the axis + } + else { + if (!(_a call fa_isoutofmap)) then { _k = 2; }; + }; + }; + /*diag_log (format["FACO out-of-map new pos:%1 direction:%2 in water:%3 out-of-map:%4 ", + (getPosATL _o) call fa_coor2str, + round(_dir), + surfaceisWater _a, + (if ([_a] call fa_isoutofmap == 1) then { true } else { false }) + ]);*/ + }; + + // cancel the change if it is too near original pos + if (([(_this select 1),_a] call BIS_fnc_distance2Dsqr) <= 30) then { + [_this select 0, +(_this select 1)] + } + else { + [ _dir, [_a select 0, _a select 1, 0]] + } +}; + +// used only by fa_server_locationCheck +stream_locationFill = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\stream_locationFill.sqf"; +dayz_locationsActive = []; +// used only by fa_smartlocation. Same as stream_locationCheck, but without any deletion. +fa_server_locationCheck = { + private ["_point","_rad","_config","_i","_location","_distCfg","_distAct"]; + + _point = _this select 0; + _rad = _this select 1; + _config = configFile >> "CfgTownGeneratorChernarus"; + + if (count _point >= 2) then { + for "_i" from (count _config -1) to 0 step -1 do { + _x = _config select _i; + _location = getArray (_x >> "position"); + _distCfg = getNumber (_x >> "size"); + _distAct = [_point select 0, _point select 1, 0] distance [_location select 0, _location select 1, 0]; + + if (!(_i in dayz_locationsActive)) then { + if (_distAct < _distCfg + _rad) then { + dayz_locationsActive set [count dayz_locationsActive,_i]; + diag_log format ["%1::fa_server_locationCheck : creating %2 objects at '%3'", __FILE__, count _x, _location]; + [_x, false] call stream_locationFill; // create wrecks & rubbish as local objects + }; + }; + }; + }; +}; + +// used only by fa_smartlocation +fa_smartlocation_commonTests = { // [_type, _pos, _minAltitude, _maxAltitude, _found] + private ["_found", "_point", "_worldspace"]; + + _found = false; + _point = _this select 1; + + //diag_log(format["fa_smartlocation %1 %2", __LINE__, _this]); + + _point set [2, 0]; + _point = ATLtoASL _point; + if (((_point select 2) < _this select 3) AND {((_point select 2) > _this select 2)}) then { + if (count (_point nearEntities [["Air", "LandVehicle", "Ship"], _this select 4]) <= 0) then { + if (_this select 3 < 0) then { // boats + _found = surfaceisWater _point; + } + else { // not boats + _point set [2, 0]; + _worldspace = [_this select 0, _point] call fn_niceSpot; + if (count _worldspace == 2) then { + _point = _worldspace select 1; + (_this select 1) set [0, _point select 0]; + (_this select 1) set [1, _point select 1]; + (_this select 1) set [2, 0]; + _found = true; + }; + }; + }; + }; +// diag_log(format["fa_smartlocation %1 %2", __LINE__, _this]); + + _found +}; + +// move vehicle to a safe position, respawn vehicle. +fa_smartlocation = { +private ["_type","_class","_dir","_oldpos","_action","_distance","_minAltitude","_maxAltitude","_tmpobject","_width","_found","_wp","_worldCenter","_worldRadius","_locations","_radius","_nearObjectTypes","_types","_pickedLocation","_o","_objects","_counter","_locpos","_loc","_y","_r","_deg","_veh","_size","_old", "_point"]; + + _type = _this select 0; // vehicle "typeOf" + _class = _type; + if (_type isKindOf "Air") then { _class = "Land_Ind_TankBig"; }; // for helis we take a big circular tank as a footprint + _dir = _this select 1; + _oldpos = +(_this select 2); // current vehicle position (from hive) + _action = _this select 3; // "OBJ"=> read from hive, keep position the best we can. Otherwise: choose a random position. + _distance = 500; // distance from other vehicles. decrease as soon as we can't find a spot + + _minAltitude = getNumber(CONFIGBASE_VEHMAINTENANCE >> _type >> "minAltitude"); + _maxAltitude = getNumber(CONFIGBASE_VEHMAINTENANCE >> _type >> "maxAltitude"); + + // workaround for sizeof bug -- do not remove + _tmpobject = _class createVehicleLocal (getMarkerPos "respawn_west"); + sleep 0.01; // wait object loading + _width = (((boundingBox _tmpobject) select 1) select 0); + //diag_log(format["fa_smartlocation _this:%1 %2", _this, (sizeOf _class)]); + + _point = []; + _found = false; + // try to place the object in a safe position near current position + if ((!(_action IN [ "CREATED", "SPAWNED"])) and {(count _oldpos>=2)}) then { +#ifdef VEH_MAINTENANCE_FIX_OUTOFMAP + // move object back on the map + _wp = [0, _oldpos] call fa_staywithus; // use ATL format + _point = +(_wp select 1); + if (count _point < 2) then { _point = _oldpos; }; +#else + _point = +(_oldpos); +#endif + // find a safe position around current position for air vehicles + if (_type isKindOf "Air") then { + [_point, 20] call fa_server_locationCheck; // towngenerator around spawn point, to limit collisions + deleteVehicle _tmpobject; + _tmpobject = _class createVehicleLocal _point; + _point = getPosATL _tmpobject; + }; + // check altitude +#ifdef VEH_MAINTENANCE_FIX_OUTOFMAP + if (count _point >= 2) then { + _point set [2, 0]; + _point = ATLtoASL _point; + _found = (((_point select 2) < _maxAltitude) AND {((_point select 2) > _minAltitude)}); + }; +#else + _found = true; +#endif + /*diag_log(format["fa_smartlocation: Looking for a safe place near original position... _action:%1 _type:%2 suitable:%3 distance:%4", + _action, + _type, + _found, + if (_found) then { [_oldpos, _point] call BIS_fnc_distance2D } else { "" } + ]);*/ + } + else { + [_point, 20] call fa_server_locationCheck; // towngenerator around spawn point, to limit collisions + }; + deleteVehicle _tmpobject; + sleep 0.01; // wait object destroy. nearEntities may return false info if not done. +#ifndef VEH_MAINTENANCE_DONT_BE_SMART + if (!_found) then { // we failed to find a suitable position around current one, so respawn vehicle + _worldCenter = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "center"); + _worldRadius = getNumber(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "spawnRadius"); + + // if vehicle is not described in configFile, then locations is empty. + _locations = nearestLocations [ + _worldCenter, + getArray(CONFIGBASE_VEHMAINTENANCE >> _type >> "localityTypes"), + _worldRadius + ]; + _radius = getNumber(CONFIGBASE_VEHMAINTENANCE >> _type >> "localityRadius"); + _nearObjectTypes = getArray(CONFIGBASE_VEHMAINTENANCE >> _type >> "nearObjects"); +// diag_log(format["fa_smartlocation: Getting choice logic: Altitude min:%1 max:%2 _radius:%3 _types=%4 countlocations:%5", _minAltitude, _maxAltitude, _radius, _nearObjectTypes, (count _locations) ]); + _pickedLocation = nil; + _o = nil; + _objects = nil; + _counter = 0; + _point = []; + while ({count _locations > 0 AND !_found}) do { + _pickedLocation = _locations call BIS_fnc_selectRandom; + _locpos = position _pickedLocation; + _locpos set [2,0]; + _locpos = ATLtoASL _locpos; + // if location is in the sea, or on the ground and at the right altitude + if ((_maxAltitude<0) OR {(((_locpos select 2) < _maxAltitude+0.05*_radius) AND {((_locpos select 2) > _minAltitude-0.05*_radius)})}) then { + [_locpos, _radius] call fa_server_locationCheck; + if (count _nearObjectTypes > 0 ) then { // spawn close to an object + _objects = nearestObjects [_locpos, _nearObjectTypes, _radius]; + //diag_log(format["fa_smartlocation: In locality loop _loc:%1 near objects count:%2 ", _pickedLocation, count _objects ]); + while ({count _objects > 0 AND !_found}) do { + _counter=_counter+0.0001; + _o = _objects call BIS_fnc_selectRandom; + // move spot in front of object, according to object length (its Y axis) and vehicle width (its X axis) + // vehicle should be located slightly in front object, twisted by a 90* angle + _point = _o modelToWorld [0,-(_width+(((boundingBox _o) select 1) select 1))/2,0]; + _point set [2, 0]; + _dir = (getDir _o)+90; + _found = [_class, _point, _minAltitude, _maxAltitude, _distance] call fa_smartlocation_commonTests; + //if (_found) then { diag_log(format["fa_smartlocation %1 %3 +--> %2", __LINE__, _point, _oldpos]); }; + _objects = _objects - [_o]; + _distance = _distance * 0.995; + }; + } + else { // spawn anywhere on the location + for [{_y = _radius * _radius / 20000}, {(_y > 0 ) AND !_found}, {_y = _y - 1}] do { + _counter=_counter+0.0001; + _r = random(_radius*_radius)^0.5; + _deg = random 360; + _point = [(_locpos select 0) + sin(_deg) * _r, (_locpos select 1) + cos(_deg) * _r, 0]; + _dir = _deg; + _found = [_class, _point, _minAltitude, _maxAltitude,_distance] call fa_smartlocation_commonTests; + //if (_found) then { diag_log(format["fa_smartlocation %1 %3 +--> %2", __LINE__, _point, _oldpos]); }; + _distance = _distance * 0.995; + }; + }; + }; // was suitable altitude + _counter = _counter + 1; + _locations = _locations - [_pickedLocation]; + }; // while suitable location + diag_log(format["fa_smartlocation: %2 _veh:%1 _size:%6 _old:%8 |--> _point:%3 _pickedLocation:%4 _counter=%5 badly near:%7", + _type, + if (_found) then {"ok"} else {"** FAILED **"}, + _point, + if (!isNil "_pickedLocation") then {text(_pickedLocation)} else {""}, + _counter, (sizeOf _class), + if (count _point >0) then { (_point nearEntities [["Air", "LandVehicle", "Ship"],_distance])-[_tmpobject] } else { "" }, + _oldpos + ]); + }; +#endif + + if (_found) then { [_dir, [_point select 0, _point select 1, 0]] } else { [] } +}; + + +FNC_kindOf = { + _inherit = inheritsFrom _this; + _list = [configName _this]; + while { (configName _inherit) != "" } do { + _list set[count _list,configName _inherit]; + _inherit = inheritsFrom( _inherit ); + }; + _list +}; + diff --git a/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf b/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf index 0f72ad72d..a9f2a103b 100644 --- a/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf +++ b/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf @@ -3,10 +3,11 @@ _playerUID = _this select 0; _playerName = _this select 1; _playerObj = nil; _playerPos = []; + { _PUID = [_x] call FNC_GetPlayerUID; - if (_PUID == _playerUID) exitWith {_playerObj = _x;}; -} count playableUnits; + if (_PUID == _playerUID) exitWith { _playerObj = _x; _playerPos = getPosATL _playerObj;}; +} count playableUnits; if (isNil "_playerObj") then { diag_log format["nil player object attempting PV, :%1", _this]; @@ -21,12 +22,23 @@ if (isNil "_playerObj") exitWith { _PUID = [_playerObj] call FNC_GetPlayerUID; diag_log format["get: %1 (%2), sent: %3 (%4)",typeName _PUID, _PUID, typeName _playerUID, _playerUID]; -if (!isNull _playerObj) then { +_characterID = _playerObj getVariable["characterID", "?"]; +_lastDamage = _playerObj getVariable["noatlf4",0]; +_Sepsis = _playerObj getVariable["USEC_Sepsis",false]; +if (_characterID != "?") exitwith { _playerPos = getPosATL _playerObj; - _characterID = _playerObj getVariable ["CharacterID","0"]; + //_characterID = _playerObj getVariable ["CharacterID","0"]; _timeout = _playerObj getVariable["combattimeout",0]; + //If the player has sepsis before logging off lets give them infected status. + if (_Sepsis) then { + _playerObj setVariable["USEC_infected",true,true]; + }; + + //Record Player Login/LogOut + [_playerUID,_characterID,2] call dayz_recordLogin; + _invehicle = false; if (vehicle _playerObj != _playerObj) then { @@ -53,20 +65,42 @@ if (!isNull _playerObj) then { _id = [_playerUID,_characterID,2] spawn dayz_recordLogin; if (alive _playerObj) then { - + + //[_playerObj,nil,true] call server_playerSync; + _isplayernearby = (DZE_BackpackGuard && !_invehicle && ({(isPlayer _x) && (alive _x)} count (_playerPos nearEntities ["AllVehicles", 5]) > 1)); // prevent saving more than 20 magazine items _magazines = [(magazines _playerObj),20] call array_reduceSize; [_playerObj,_magazines,true,true,_isplayernearby] call server_playerSync; - + + if (dayz_enableGhosting) then { + //diag_log format["GhostPlayers: %1, ActivePlayers: %2",dayz_ghostPlayers,dayz_activePlayers]; + if (!(_playerUID in dayz_ghostPlayers)) then { + dayz_ghostPlayers set [count dayz_ghostPlayers, _playerUID]; + dayz_activePlayers set [count dayz_activePlayers, [_playerUID,diag_ticktime]]; + + //diag_log format["playerID %1 added to ghost list",_playerUID]; + }; + }; + // remove player _playerObj call dayz_removePlayerOnDisconnect; - } else { - //Update Vehicle - { - [_x,"gear"] call server_updateObject; - } count (nearestObjects [_playerPos, dayz_updateObjects, 10]); }; + //Update Vehicle + { + [_x,"gear"] call server_updateObject; + } count (nearestObjects [_playerPos, DayZ_GearedObjects, 10]); }; + +if (isNull _playerObj) then { diag_log("Player Object does not esist"); }; + + +//Lets remove the object. +if (!isNull _playerObj) then { + _myGroup = group _playerObj; + deleteVehicle _playerObj; + deleteGroup _myGroup; +}; + diff --git a/SQF/dayz_server/compile/server_plantSpawner.sqf b/SQF/dayz_server/compile/server_plantSpawner.sqf new file mode 100644 index 000000000..7fb0e9fdf --- /dev/null +++ b/SQF/dayz_server/compile/server_plantSpawner.sqf @@ -0,0 +1,23 @@ +private ["_SWcorner","_NEcorner","_amount","_a","_b","_c"]; + +#define CONFIGBASE_VEHMAINTENANCE configFile >> "CfgPatches" >> "vehMaint" + +_SWcorner = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "SWcorner"); +_NEcorner = getArray(CONFIGBASE_VEHMAINTENANCE >> (worldName) >> "NEcorner"); + +_a = [(_SWcorner select 0), (_SWcorner select 1), (_NEcorner select 0) - (_SWcorner select 0), (_NEcorner select 1) - (_SWcorner select 1) ] call psrnd_init; +_b = [ -15, -15, 30, 30 ] call psrnd_init; +_c = [ 0, 0, 3, 360 ] call psrnd_init; + +PVCDZ_plr_plantSpawner = [ _a, _b, _c, [] ]; +//diag_log [ __FILE__, _a, _b, _c ]; + +"PVDZ_objgather_Delete" addPublicVariableEventHandler { + private [ "_pos", "_blacklist"]; + _pos = (_this select 1); + + _blacklist = PVCDZ_plr_plantSpawner select 3; + _blacklist set [ count _blacklist, _pos ]; + //diag_log [ __FILE__, _this, _blacklist ]; +}; + diff --git a/SQF/dayz_server/compile/server_playerDied.sqf b/SQF/dayz_server/compile/server_playerDied.sqf index 8c17c7d4c..0eb39c6fe 100644 --- a/SQF/dayz_server/compile/server_playerDied.sqf +++ b/SQF/dayz_server/compile/server_playerDied.sqf @@ -1,3 +1,4 @@ +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" private ["_characterID","_minutes","_newObject","_playerID","_infected","_victim","_victimName","_killer","_killerName","_weapon","_distance","_message","_loc_message","_key","_death_record"]; //[unit, weapon, muzzle, mode, ammo, magazine, projectile] _characterID = _this select 0; @@ -75,9 +76,14 @@ if (isnil "dayz_disco") then { dayz_disco = []; }; */ +dayz_died set [count dayz_died, _playerID]; // dayz_disco = dayz_disco - [_playerID]; _newObject setVariable["processedDeath",diag_tickTime]; +_newObject setVariable ["bodyName", _victimName, true]; +_pos = getPosATL _newObject; +if (_pos select 2 < 0.1) then { _pos set [2,0]; }; +_newObject setVariable [ "deathPos", _pos]; if (typeName _minutes == "STRING") then { @@ -97,4 +103,14 @@ if (_characterID != "0") then else { deleteVehicle _newObject; -}; \ No newline at end of file +}; +#ifdef PLAYER_DEBUG +diag_log format ["Player UID#%3 CID#%4 %1 as %5 died at %2", + _newObject call fa_plr2str, (getPosATL _newObject) call fa_coor2str, + getPlayerUID _newObject,_characterID, + typeOf _newObject +]; +#endif +_newObject setDamage 1; +_newObject setOwner 0; +//dead_bodyCleanup set [count dead_bodyCleanup,_newObject]; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_playerLogin.sqf b/SQF/dayz_server/compile/server_playerLogin.sqf index 6295a2230..feb5e191d 100644 --- a/SQF/dayz_server/compile/server_playerLogin.sqf +++ b/SQF/dayz_server/compile/server_playerLogin.sqf @@ -1,5 +1,5 @@ private ["_isInfected","_doLoop","_hiveVer","_isHiveOk","_playerID","_playerObj","_primary","_key","_charID","_playerName","_backpack","_isNew","_inventory","_survival","_model","_mags","_wpns","_bcpk","_config","_newPlayer"]; - +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" #ifdef DZE_SERVER_DEBUG diag_log ("STARTING LOGIN: " + str(_this)); #endif @@ -7,7 +7,7 @@ diag_log ("STARTING LOGIN: " + str(_this)); _playerID = _this select 0; _playerObj = _this select 1; _playerName = name _playerObj; - +_worldspace = []; if (_playerName == '__SERVER__' || _playerID == '' || local player) exitWith {}; if (isNil "sm_done") exitWith { @@ -15,6 +15,10 @@ if (isNil "sm_done") exitWith { diag_log ("Login cancelled, server is not ready. " + str(_playerObj)); #endif }; +// Cancel any login until server_monitor terminates. +// This is mandatory since all vehicles must be spawned before the first players spawn on the map. +// Otherwise, all vehicle event handlers won't be created on players' client side. +if (isNil "sm_done") exitWith { diag_log ("Login cancelled, server is not ready. " + str(_playerObj)); }; if (count _this > 2) then { dayz_players = dayz_players - [_this select 2]; @@ -23,10 +27,17 @@ if (count _this > 2) then { //Variables _inventory = []; _backpack = []; +_items = []; +_magazines = []; +_weapons = []; +_medicalStats = []; _survival = [0,0,0]; _isInfected = 0; +_tent = []; +_state = []; +_direction = 0; _model = ""; - +_newUnit = objNull; if (_playerID == "") then { _playerID = [_playerObj] call FNC_GetPlayerUID; }; @@ -41,6 +52,35 @@ if ((_playerID == "") || (isNil "_playerID")) exitWith { diag_log ("LOGIN ATTEMPT: " + str(_playerID) + " " + _playerName); #endif +_endMission = false; +_timeleft = 0; +{ + //if ((_playerID select _i) in activePlayers) exitWith { diag_log ("Login cancelled, player has logged out within the past 2 mins. " + str(_playerObj)); }; + _0 = _x select 0; + _1 = _x select 1; + _timeleft = diag_ticktime - _1; + + if (_playerID == _0) then { + //If players last logoff is about the ghost timer remove player from ghost que. + if ((_timeleft > dayz_ghostTimer) or (_timeleft < 0)) then { + dayz_ghostPlayers = dayz_ghostPlayers - [_0]; + dayz_activePlayers set[_forEachIndex, _0]; + dayz_activePlayers = dayz_activePlayers - [_0]; + } else { + //if player is in died allow them passage. + if (_playerID in dayz_died) then { + dayz_died = dayz_died - [_playerID]; + dayz_ghostPlayers = dayz_ghostPlayers - [_0]; + dayz_activePlayers set[_forEachIndex, _0]; + dayz_activePlayers = dayz_activePlayers - [_0]; + } else { + // Logoff time is not beyond ghost time and player didn't die + _endMission = true; + }; + }; + }; +}forEach dayz_activePlayers; + //Do Connection Attempt _doLoop = 0; while {_doLoop < 5} do { @@ -70,7 +110,7 @@ if ((_primary select 0) == "ERROR") exitWith { _newPlayer = _primary select 1; _isNew = count _primary < 7; //_result select 1; _charID = _primary select 2; - +_randomSpot = false; #ifdef DZE_SERVER_DEBUG diag_log ("LOGIN RESULT: " + str(_primary)); #endif @@ -114,7 +154,7 @@ if (!_isNew) then { _mags = getArray (_config >> "magazines"); _wpns = getArray (_config >> "weapons"); _bcpk = getText (_config >> "backpack"); - + _randomSpot = true; if(!isNil "DefaultMagazines") then { _mags = DefaultMagazines; }; @@ -146,5 +186,23 @@ if (worldName == "chernarus") then { ([4654,9595,0] nearestObject 145260) setDamage 1; }; -dayzPlayerLogin = [_charID,_inventory,_backpack,_survival,_isNew,dayz_versionNo,_model,_isHiveOk,_newPlayer,_isInfected]; -(owner _playerObj) publicVariableClient "dayzPlayerLogin"; +//dayzPlayerLogin = [_charID,_inventory,_backpack,_survival,_isNew,dayz_versionNo,_model,_isHiveOk,_newPlayer,_isInfected]; +PVCDZ_plr_Login = [_charID,_inventory,_backpack,_survival,_isNew,dayz_versionNo,_model,_isHiveOk,_newPlayer,_isInfected]; +#ifdef DZE_SERVER_DEBUG +diag_log format["%1, %2, %3, %4, %5, %6, %7, %8, %9, %10",_charID,_inventory,_backpack,_survival,_isNew,dayz_versionNo,_model,_isHiveOk,_newPlayer,_isInfected]; +#endif + +(owner _playerObj) publicVariableClient "PVCDZ_plr_Login"; + +//Make player wait till ghost timer is up. +if (_endMission) exitwith { + _remaining = dayz_ghostTimer - _timeleft; + diag_log format["LOGIN CANCELLED: player: %1 is in ghost mode. Time remianing: %2 before login!!",_playerObj,_remaining]; + PVCDZ_plr_Ghost = [_remaining]; + (owner _playerObj) publicVariableClient "PVCDZ_plr_Ghost"; +}; + +[_playerID,_charID,1] call dayz_recordLogin; + +PVCDZ_plr_PlayerAccepted = [_playerName,diag_ticktime]; +(owner _playerObj) publicVariableClient "PVCDZ_plr_PlayerAccepted"; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_playerSetup.sqf b/SQF/dayz_server/compile/server_playerSetup.sqf index d582e6484..dd629d571 100644 --- a/SQF/dayz_server/compile/server_playerSetup.sqf +++ b/SQF/dayz_server/compile/server_playerSetup.sqf @@ -4,15 +4,17 @@ private ["_characterID","_playerObj","_playerID","_dummy","_worldspace","_state" _characterID = _this select 0; _playerObj = _this select 1; +_spawnSelection = _this select 3; _playerID = [_playerObj] call FNC_GetPlayerUID; +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" if (isNull _playerObj) exitWith { diag_log ("SETUP INIT FAILED: Exiting, player object null: " + str(_playerObj)); }; //Add MPHit event handler // diag_log("Adding MPHit EH for " + str(_playerObj)); -_playerObj addMPEventHandler ["MPHit", {_this spawn fnc_plyrHit;}]; +//_playerObj addMPEventHandler ["MPHit", {_this spawn fnc_plyrHit;}]; if (_playerID == "") then { _playerID = [_playerObj] call FNC_GetPlayerUID; @@ -57,13 +59,34 @@ if (isNull _playerObj || !isPlayer _playerObj) exitWith { _medical = _primary select 1; _stats = _primary select 2; _state = _primary select 3; +_statearray = if (count _primary >= 4) then { _primary select 3 } else {[""]}; _worldspace = _primary select 4; _humanity = _primary select 5; _lastinstance = _primary select 6; +if (count _statearray == 0) then { _statearray = [""]; }; +//diag_log ("StateNew: "+str(_statearray)); + +if (typeName ((_statearray) select 0) == "STRING") then { + _statearray = [_statearray,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]; +}; + +_state = ((_statearray) select 0); +//diag_log ("State: "+str(_state)); +_Achievements = ((_statearray) select 1); + +if (count _Achievements == 0) then { + _Achievements = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; +}; +//diag_log ("Achievements: "+str(_Achievements)); + +_worldspace = _primary select 4; +_humanity = _primary select 5; + //Set position _randomSpot = false; +//diag_log ("WORLDSPACE: " + str(_worldspace)); if (count _worldspace > 0) then { _position = _worldspace select 1; @@ -81,11 +104,6 @@ if (count _worldspace > 0) then { if (_distance < 500) then { _randomSpot = true; }; - - // Came from another server force random spawn - if (_lastinstance != dayZ_instance) then { - _randomSpot = true; - }; //_playerObj setPosATL _position; } else { @@ -108,10 +126,10 @@ if (count _medical > 0) then { //Add Wounds { - _playerObj setVariable[_x,true,true]; + _playerObj setVariable["hit_"+_x,true, true]; //["usecBleed",[_playerObj,_x,_hit]] call broadcastRpcCallAll; - usecBleed = [_playerObj,_x,_hit]; - publicVariable "usecBleed"; + //usecBleed = [_playerObj,_x,_hit]; + //publicVariable "usecBleed"; } count (_medical select 8); //Add fractures @@ -119,21 +137,34 @@ if (count _medical > 0) then { _playerObj setVariable ["hit_legs",(_fractures select 0),true]; _playerObj setVariable ["hit_hands",(_fractures select 1),true]; - if (count _medical > 11) then { - //Additional medical stats - _playerObj setVariable ["messing",(_medical select 11),true]; + _playerObj setVariable["messing",if (count _medical >= 14) then {(_medical select 13)} else {[0,0,0]},true]; + + _playerObj setVariable["blood_testdone",if (count _medical >= 15) then {(_medical select 14)} else {false},true]; + if (count _medical >= 12) then { + _playerObj setVariable["blood_type",(_medical select 11),true]; + _playerObj setVariable["rh_factor",(_medical select 12),true]; + diag_log [ "Character data: blood_type,rh_factor,testdone=", + _playerObj getVariable ["blood_type", "?"],_playerObj getVariable ["rh_factor", "?"], _playerObj getVariable["blood_testdone", false] + ]; + } else { + _playerObj call player_bloodCalc; + diag_log [ "Character upgrade to 1.8.3: blood_type,rh_factor=",_playerObj getVariable ["blood_type", "?"],_playerObj getVariable ["rh_factor", "?"]]; }; - } else { + //Reset bleeding wounds + call fnc_usec_resetWoundPoints; //Reset Fractures _playerObj setVariable ["hit_legs",0,true]; _playerObj setVariable ["hit_hands",0,true]; _playerObj setVariable ["USEC_injured",false,true]; _playerObj setVariable ["USEC_inPain",false,true]; - _playerObj setVariable ["messing",[0,0],true]; + _playerObj call player_bloodCalc; // will set blood_type and rh_factor according to real population statitics + diag_log [ "New character setup: blood_type,rh_factor=",_playerObj getVariable ["blood_type", "?"],_playerObj getVariable ["rh_factor", "?"]]; + _playerObj setVariable ["messing",[0,0,0],true]; + _playerObj setVariable ["blood_testdone",false,true]; }; -if (count _stats > 0) then { +if (count _stats > 0) then { //register stats _playerObj setVariable["zombieKills",(_stats select 0),true]; _playerObj setVariable["headShots",(_stats select 1),true]; @@ -188,38 +219,46 @@ if (_randomSpot) then { // _spawnMC = actualSpawnMarkerCount; + + if (worldName in ["dzhg", "panthera2", "Sara", "Utes", "Dingor", "namalsk", "isladuala", "Tavi", "dayznogova","tasmania2010"]) then { _IslandMap = true; } else { _IslandMap = false; }; //spawn into random _findSpot = true; - _mkr = ""; - while {_findSpot} do { - _counter = 0; - while {_counter < 20 && _findSpot} do { - // switched to floor - _mkr = "spawn" + str(floor(random _spawnMC)); - _position = ([(getMarkerPos _mkr),0,spawnArea,10,0,2000,spawnShoremode] call BIS_fnc_findSafePos); - _isNear = count (_position nearEntities ["Man",100]) == 0; - _isZero = ((_position select 0) == 0) && ((_position select 1) == 0); - //Island Check //TeeChange - _pos = _position; - _isIsland = false; //Can be set to true during the Check - for [{_w=0},{_w<=150},{_w=_w+2}] do { - _pos = [(_pos select 0),((_pos select 1) + _w),(_pos select 2)]; - if(surfaceisWater _pos) exitWith { - _isIsland = true; - }; - }; - - if ((_isNear && !_isZero) || _isIsland) then {_findSpot = false}; - _counter = _counter + 1; + _mkr = []; + _position = [0,0,0]; + for [{_j=0},{_j<=100 AND _findSpot},{_j=_j+1}] do { + if (_spawnSelection == 9) then { + // random spawn location selected, lets get the marker and spawn in somewhere + if (dayz_spawnselection == 1) then { _mkr = getMarkerPos ("spawn" + str(floor(random 6))); } else { _mkr = getMarkerPos ("spawn" + str(floor(random 5))); }; + } else { + // spawn is not random, lets spawn in our location that was selected + _mkr = getMarkerPos ("spawn" + str(_spawnSelection)); }; + _position = ([_mkr,0,spawnArea,10,0,2,spawnShoremode] call BIS_fnc_findSafePos); + if ((count _position >= 2) // !bad returned position + AND {(_position distance _mkr < 1400)}) then { // !ouside the disk + _position set [2, 0]; + if (((ATLtoASL _position) select 2 > 2.5) //! player's feet too wet + AND {({alive _x} count (_position nearEntities ["Man",150]) == 0)}) then { // !too close from other players/zombies + _pos = +(_position); + _isIsland = false; //Can be set to true during the Check + // we check over a 809-meter cross line, with an effective interlaced step of 5 meters + for [{_w = 0}, {_w != 809}, {_w = ((_w + 17) % 811)}] do { + //if (_w < 17) then { diag_log format[ "%1 loop starts with _w=%2", __FILE__, _w]; }; + _pos = [((_pos select 0) - _w),((_pos select 1) + _w),(_pos select 2)]; + if((surfaceisWater _pos) and (!_IslandMap)) exitWith { + _isIsland = true; + }; + }; + if (!_isIsland) then {_findSpot = false}; + }; + }; + //diag_log format["%1: pos:%2 _findSpot:%3", __FILE__, _position, _findSpot]; }; - _isZero = ((_position select 0) == 0) && ((_position select 1) == 0); - _position = [_position select 0,_position select 1,0]; - if (!_isZero) then { - //_playerObj setPosATL _position; - _worldspace = [0,_position]; + if ((_findSpot) and (!_IslandMap)) exitWith { + diag_log format["%1: Error, failed to find a suitable spawn spot for player. area:%2",__FILE__, _mkr]; }; + _worldspace = [0,_position]; }; //Record player for management @@ -233,23 +272,22 @@ _playerObj setVariable["humanity_CHK",_humanity]; //_playerObj setVariable["state",_state,true]; _playerObj setVariable["lastPos",getPosATL _playerObj]; -dayzPlayerLogin2 = [_worldspace,_state]; - -// PVDZE_obj_Debris = DZE_LocalRoadBlocks; -_clientID = owner _playerObj; -if (!isNull _playerObj) then { - _clientID publicVariableClient "dayzPlayerLogin2"; - - if (isNil "PVDZE_plr_SetDate") then { - call server_timeSync; - }; - _clientID publicVariableClient "PVDZE_plr_SetDate"; +if (!isNil "faco_hook_playerSetup") then { + [_worldspace,_state,_playerObj, _characterID] call faco_hook_playerSetup; + _playerObj call faco_sendSecret; }; + + +PVCDZ_plr_Login2 = [_worldspace,_state,_Achievements]; +_clientID = owner _playerObj; + +_clientID publicVariableClient "PVCDZ_plr_Login2"; +_clientID publicVariableClient "PVCDZ_plr_plantSpawner"; //record time started _playerObj setVariable ["lastTime",time]; //_playerObj setVariable ["model_CHK",typeOf _playerObj]; //diag_log ("LOGIN PUBLISHING: " + str(_playerObj) + " Type: " + (typeOf _playerObj)); -PVDZE_plr_Login = nil; -PVDZE_plr_Login2 = nil; \ No newline at end of file +PVDZ_plr_Login1 = null; +PVDZ_plr_Login2 = null; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_playerSync.sqf b/SQF/dayz_server/compile/server_playerSync.sqf index 567e54254..edacc4bc5 100644 --- a/SQF/dayz_server/compile/server_playerSync.sqf +++ b/SQF/dayz_server/compile/server_playerSync.sqf @@ -1,7 +1,10 @@ private ["_empty","_name","_playerwasNearby","_character","_magazines","_force","_characterID","_charPos","_isInVehicle","_timeSince","_humanity","_debug","_distance","_isNewMed","_isNewPos","_isNewGear","_playerPos","_playerGear","_playerBackp","_medical","_distanceFoot","_lastPos","_backpack","_kills","_killsB","_killsH","_headShots","_lastTime","_timeGross","_timeLeft","_currentWpn","_currentAnim","_config","_onLadder","_isTerminal","_currentModel","_modelChk","_muzzles","_temp","_currentState","_array","_key","_pos","_forceGear","_friendlies"]; + _character = _this select 0; _magazines = _this select 1; +_Achievements = _character getVariable "Achievements"; + //_force = _this select 2; _forceGear = _this select 3; @@ -36,17 +39,33 @@ if (_characterID == "0") exitWith { diag_log ("ERROR: Cannot Sync Character " + (_name) + " as no characterID"); }; +if (isNil {_Achievements}) exitWith { + diag_log ("ERROR: Cannot Sync Achievements " + (name _character) + " has no default Achievements"); + _Achievements = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; +}; + +/* private["_debug","_distance"]; _debug = getMarkerpos "respawn_west"; _distance = _debug distance _charPos; if (_distance < 2000) exitWith { diag_log format["ERROR: server_playerSync: Cannot Sync Player %1 [%2]. Position in debug! %3",_name,_characterID,_charPos]; -}; +}; */ + + + + + + + + + + //Check for server initiated updates _isNewMed = _character getVariable["medForceUpdate",false]; //Med Update is forced when a player receives some kind of med incident _isNewPos = _character getVariable["posForceUpdate",false]; //Med Update is forced when a player receives some kind of med incident -_isNewGear = (count _magazines) > 0; +_isNewGear = if (!isNil "_magazines") then { true } else { false }; //Check for player initiated updates if (_characterID != "0") then { @@ -80,7 +99,10 @@ if (_characterID != "0") then { }; _character setVariable ["posForceUpdate",false,true]; }; + if (_isNewGear || _forceGear) then { + + //diag_log ("gear..."); uiSleep 0.05; _playerGear = [weapons _character,_magazines]; //diag_log ("playerGear: " +str(_playerGear)); @@ -92,6 +114,7 @@ if (_characterID != "0") then { _playerBackp = [typeOf _backpack,getWeaponCargo _backpack,getMagazineCargo _backpack]; }; }; + if (_isNewMed || _force) then { //diag_log ("medical..."); uiSleep 0.05; if (!(_character getVariable["USEC_isDead",false])) then { @@ -121,8 +144,8 @@ if (_characterID != "0") then { /* Assess how much time has passed, for recording total time on server */ - _lastTime = _character getVariable["lastTime",time]; - _timeGross = (time - _lastTime); + _lastTime = _character getVariable["lastTime",diag_ticktime]; + _timeGross = (diag_ticktime - _lastTime); _timeSince = floor(_timeGross / 60); _timeLeft = (_timeGross - (_timeSince * 60)); /* @@ -139,7 +162,7 @@ if (_characterID != "0") then { if (_currentModel == _modelChk) then { _currentModel = ""; } else { - _currentModel = _currentModel; + _currentModel = str(_currentModel); _character setVariable ["model_CHK",typeOf _character]; }; @@ -165,7 +188,9 @@ if (_characterID != "0") then { }; }; _temp = round(_character getVariable ["temperature",100]); - _currentState = [_currentWpn,_currentAnim,_temp]; + + _currentState = [[_currentWpn,_currentAnim,_temp],_Achievements]; + if(DZE_FriendlySaving) then { // save only last/most recent 5 entrys as we only have 200 chars in db field && weapon + animation names are sometimes really long 60-70 chars. _friendlies = [(_character getVariable ["friendlies",[]]),5] call array_reduceSizeReverse; @@ -183,16 +208,21 @@ if (_characterID != "0") then { } count (_playerPos select 1); _playerPos set [1,_array]; }; + if (!isNull _character) then { if (alive _character) then { //Wait for HIVE to be free //Send request _key = format["CHILD:201:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:",_characterID,_playerPos,_playerGear,_playerBackp,_medical,false,false,_kills,_headShots,_distanceFoot,_timeSince,_currentState,_killsH,_killsB,_currentModel,_humanity]; //diag_log ("HIVE: WRITE: "+ str(_key) + " / " + _characterID); + + + _key call server_hiveWrite; }; }; + // If player is in a vehicle, keep its position updated if (vehicle _character != _character) then { //[vehicle _character, "position"] call server_updateObject; @@ -203,14 +233,15 @@ if (_characterID != "0") then { }; // Force gear updates for nearby vehicles/tents + { [_x, "gear"] call server_updateObject; - } count (nearestObjects [_charPos, dayz_updateObjects, 10]); + } count (nearestObjects [_charPos, DayZ_GearedObjects, 10]); //[_charPos] call server_updateNearbyObjects; //Reset timer if (_timeSince > 0) then { - _character setVariable ["lastTime",(time - _timeLeft)]; + _character setVariable ["lastTime",(diag_ticktime - _timeLeft)]; }; }; }; diff --git a/SQF/dayz_server/compile/server_spawnCarePackages.sqf b/SQF/dayz_server/compile/server_spawnCarePackages.sqf new file mode 100644 index 000000000..d7bfe407d --- /dev/null +++ b/SQF/dayz_server/compile/server_spawnCarePackages.sqf @@ -0,0 +1,85 @@ +/* +Spawns care packages. + +Single parameter: + integer Number of care packages to spawn. + +Author: + Foxy +*/ + +#include "\z\addons\dayz_code\util\Math.hpp" +#include "\z\addons\dayz_code\util\Vector.hpp" +#include "\z\addons\dayz_code\loot\Loot.hpp" + +//Number of care packages to spawn +#define SPAWN_NUM 6 + +#define SEARCH_CENTER [7542,7134] +#define SEARCH_RADIUS 6150 +#define SEARCH_DIST_MIN 30 +#define SEARCH_SLOPE_MAX 1000 +#define SEARCH_BLACKLIST [[[12923,3643],[14275,2601]]] + +private +[ + "_typeGroup", + "_position", + "_type", + "_class", + "_vehicle", + "_loot", + "_lootGroup", + "_lootNum", + "_lootPos", + "_lootVeh", + "_size" +]; + +_lootGroup = Loot_GetGroup("CarePackage"); +_typeGroup = Loot_GetGroup("CarePackageType"); + +for "_i" from 1 to (SPAWN_NUM) do +{ + _type = Loot_SelectSingle(_typeGroup); + _class = _type select 1; + _lootNum = round Math_RandomRange(_type select 2, _type select 3); + _position = [SEARCH_CENTER, 0, SEARCH_RADIUS, SEARCH_DIST_MIN, 0, SEARCH_SLOPE_MAX, 0, SEARCH_BLACKLIST] call BIS_fnc_findSafePos; + _position set [2, 0]; + + diag_log format ["DEBUG: Spawning a care package (%1) at %2 with %3 items.", _class, _position, _lootNum]; + + _vehicle = createVehicle [_class, _position, [], 0, "CAN_COLLIDE"]; + dayz_serverObjectMonitor set [count dayz_serverObjectMonitor, _vehicle]; + _vehicle setVariable ["ObjectID", 1, true]; + + _size = sizeOf _class; + + { + //Calculate random loot position + _lootPos = Vector_Add(_position, Vector_Multiply(Vector_FromDir(random 360), _size * 0.6 + random _size)); + _lootPos set [2, 0]; + + _lootVeh = Loot_Spawn(_x, _lootPos); + _lootVeh setVariable ["permaLoot", true]; + + switch (dayz_spawncarepkgs_clutterCutter) do + { + case 1: //Lift loot up by 5cm + { + _lootPos set [2, 0.05]; + _lootVeh setPosATL _lootpos; + }; + + case 2: //Clutter cutter + { + createVehicle ["ClutterCutter_small_2_EP1", _lootPos, [], 0, "CAN_COLLIDE"]; + }; + + case 3: //Debug sphere + { + createVehicle ["Sign_sphere100cm_EP1", _lootPos, [], 0, "CAN_COLLIDE"]; + }; + }; + } foreach Loot_Select(_lootGroup, _lootNum); +}; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_spawnCrashSites.sqf b/SQF/dayz_server/compile/server_spawnCrashSites.sqf new file mode 100644 index 000000000..37f906f3f --- /dev/null +++ b/SQF/dayz_server/compile/server_spawnCrashSites.sqf @@ -0,0 +1,139 @@ +/* +Spawns crash sites at the beginning of mission and periodically during it. + +Author: + Foxy +*/ + +#include "\z\addons\dayz_code\util\Math.hpp" +#include "\z\addons\dayz_code\util\Vector.hpp" +#include "\z\addons\dayz_code\loot\Loot.hpp" + +//Spawn frequency ± variance in minutes +#define SPAWN_FREQUENCY 40 +#define SPAWN_VARIANCE 15 + +//The higher the number, the more accurate the timer is. +//Must be positive and non-zero. +#define TIMER_RESOLUTION 10 + +//Chance to spawn a crash site +#define SPAWN_CHANCE 0.75 + +//Parameters for finding a suitable position to spawn the crash site +#define SEARCH_CENTER [7049,9241] +#define SEARCH_RADIUS 4880 +#define SEARCH_DIST_MIN 20 +#define SEARCH_SLOPE_MAX 2 +#define SEARCH_BLACKLIST [[[2092,14167],[10558,12505]]] + +//Number of crash sites to spawn at the beginning of the mission +#define INITIAL_NUM 3 + +//Number of loot items to spawn per site +#define LOOT_MIN 5 +#define LOOT_MAX 8 + +private +[ + "_debugZone", + "_spawnCrashSite", + "_type", + "_class", + "_lootGroup", + "_position", + "_vehicle", +// "_size", +// "_loot", + "_lootParams", + "_dir", + "_mag", + "_lootNum", + "_lootPos", + "_lootVeh", + "_lootpos", + "_time" +]; + +diag_log format ["CRASHSPAWNER: Starting crash site spawner. Frequency: %1±%2 min. Spawn chance: %3", SPAWN_FREQUENCY, SPAWN_VARIANCE, SPAWN_CHANCE]; + +_spawnCrashSite = +{ + _type = Loot_SelectSingle(Loot_GetGroup("CrashSiteType")); + _class = _type select 1; + _lootGroup = Loot_GetGroup(_type select 2); + + _position = [SEARCH_CENTER, 0, SEARCH_RADIUS, SEARCH_DIST_MIN, 0, SEARCH_SLOPE_MAX, 0, SEARCH_BLACKLIST] call BIS_fnc_findSafePos; + _position set [2, 0]; + + _lootNum = round Math_RandomRange(LOOT_MIN, LOOT_MAX); + + diag_log format ["CRASHSPAWNER: Spawning crash site (%1) at %2 with %3 items.", _class, _position, _lootNum]; + + _vehicle = createVehicle ["ClutterCutter_small_2_EP1", _position, [], 0, "CAN_COLLIDE"]; + _vehicle = createVehicle [_class, _position, [], 0, "CAN_COLLIDE"]; + dayz_serverObjectMonitor set [count dayz_serverObjectMonitor, _vehicle]; + _vehicle setVariable ["ObjectID", 1, true]; + _vehicle setDir random 360; + _vehicle setPos _position; + + _lootParams = getArray (configFile >> "CfgVehicles" >> _class >> "lootParams"); + + { + _dir = random 360; + _mag = random (_lootParams select 4); + _lootPos = [((_lootParams select 2) + _mag) * sin _dir, ((_lootParams select 3) + _mag) * cos _dir, 0]; + _lootPos = Vector_Add(_lootPos, _lootParams select 0); + _lootPos = Vector_Rotate2D(_lootPos, _lootParams select 1); + _lootPos = _vehicle modelToWorld _lootPos; + _lootPos set [2, 0]; + + _lootVeh = Loot_Spawn(_x, _lootPos); + _lootVeh setVariable ["permaLoot", true]; + + switch (dayz_spawnCrashSite_clutterCutter) do + { + case 1: //Lift loot up by 5cm + { + _lootPos set [2, 0.05]; + _lootVeh setPosATL _lootpos; + }; + + case 2: //Clutter cutter + { + createVehicle ["ClutterCutter_small_2_EP1", _lootPos, [], 0, "CAN_COLLIDE"]; + }; + + case 3: //Debug sphere + { + createVehicle ["Sign_sphere100cm_EP1", _lootPos, [], 0, "CAN_COLLIDE"]; + }; + }; + } + foreach Loot_Select(_lootGroup, _lootNum); +}; + +//Spawn initial crash sites +for "_i" from 1 to (INITIAL_NUM) do +{ + call _spawnCrashSite; +}; + +while {true} do +{ + //Pick a time to attempt spawning + //currentTime + frequency + ±1 * variance + _time = time + 60 * ((SPAWN_FREQUENCY) + ((round random 1) * 2 - 1) * random (SPAWN_VARIANCE)); + + //Wait until the previously decided time + while {time < _time} do + { + sleep (60 * (SPAWN_FREQUENCY) / (TIMER_RESOLUTION)); + }; + + //try to spawn + if ((SPAWN_CHANCE) > random 1) then + { + call _spawnCrashSite; + }; +}; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_spawnInfectedCamps.sqf b/SQF/dayz_server/compile/server_spawnInfectedCamps.sqf new file mode 100644 index 000000000..c72d865eb --- /dev/null +++ b/SQF/dayz_server/compile/server_spawnInfectedCamps.sqf @@ -0,0 +1,91 @@ +/* +Spawns infected camps + +Author: + Foxy +*/ + +#include "\z\addons\dayz_code\util\Math.hpp" +#include "\z\addons\dayz_code\loot\Loot.hpp" + +//Number of infected camps to spawn +#define CAMP_NUM 3 + +//Minimum distance between camps +#define CAMP_MIN_DIST 300 + +//Base class of objects to add loot to +#define CAMP_CONTAINER_BASE "IC_Tent" + +//Loot per tent +#define LOOT_MIN 10 +#define LOOT_MAX 20 + +//Random objects per camp +#define OBJECT_MIN 4 +#define OBJECT_MAX 12 + +//Radius around the camp in which random objects are spawned +#define OBJECT_RADIUS_MIN 8 +#define OBJECT_RADIUS_MAX 13 + +#define SEARCH_CENTER getMarkerPos "center" +#define SEARCH_RADIUS 7500 +#define SEARCH_EXPRESSION "(5 * forest) + (4 * trees) + (3 * meadow) - (20 * houses) - (30 * sea)" //+ (3 * meadow) - (20 * houses) - (30 * sea) +#define SEARCH_PRECISION 30 +#define SEARCH_ATTEMPTS 10 + +private +[ + "_typeGroup", + "_lootGroup", + "_objectGroup", + "_type", + "_position", + "_composition", + "_compositionObjects", + "_objectPos" +]; + +_typeGroup = Loot_GetGroup("InfectedCampType"); +_lootGroup = Loot_GetGroup("InfectedCamp"); +_objectGroup = Loot_GetGroup("InfectedCampObject"); + +for "_i" from 1 to (CAMP_NUM) do +{ + //Select type of camp + _type = Loot_SelectSingle(_typeGroup); + _composition = _type select 1; + + //Find a position + + for "_j" from 1 to (SEARCH_ATTEMPTS) do + { + _position = ((selectBestPlaces [SEARCH_CENTER, SEARCH_RADIUS, SEARCH_EXPRESSION, SEARCH_PRECISION, 1]) select 0) select 0; + _position set [2, 0]; + + //Check if a camp already exists within the minimum distance + if (count (nearestObjects [_position, [CAMP_CONTAINER_BASE], CAMP_MIN_DIST]) < 1) exitWith {}; + }; + + diag_log format ["Spawning an infected camp (%1) at %2", _composition, _position]; + + //Spawn composition + _compositionObjects = [_position, random 360,_composition] call spawnComposition; + + //Add loot to containers + { + if (_x isKindOf (CAMP_CONTAINER_BASE)) then + { + Loot_InsertCargo(_x, _lootGroup, round Math_RandomRange(LOOT_MIN, LOOT_MAX)); + }; + } foreach _compositionObjects; + + //Spawn objects around the camp + { + _objectPos = [_position, OBJECT_RADIUS_MIN, OBJECT_RADIUS_MAX, 5] call fn_selectRandomLocation; + + Loot_Spawn(_x, _objectPos); + + } foreach Loot_Select(_objectGroup, round Math_RandomRange(OBJECT_MIN, OBJECT_MAX)); +}; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_toggle_debug.hpp b/SQF/dayz_server/compile/server_toggle_debug.hpp new file mode 100644 index 000000000..46f1fbffd --- /dev/null +++ b/SQF/dayz_server/compile/server_toggle_debug.hpp @@ -0,0 +1,19 @@ +/* +Created exclusively for ArmA2:OA - DayZMod. +Please request permission to use/alter/distribute from project leader (R4Z0R49) +*/ + +//// TOGGLE DEBUGS //// + +// comment this out if you don't want any LOGIN related debug +#define LOGIN_DEBUG + +// comment this out if you don't want any VEHICLE/TENT/OBJECT related debug +#define OBJECT_DEBUG + +// comment this out if you don't want any PLAYER (WORLDSPACE/INVENTORY/ETC) related debug +#define PLAYER_DEBUG + +// comment this out if you don't want any misc SERVER (ZOMBIE, LOOT, CLEANUP) related debug +#define SERVER_DEBUG + diff --git a/SQF/dayz_server/compile/server_updateNearbyObjects.sqf b/SQF/dayz_server/compile/server_updateNearbyObjects.sqf new file mode 100644 index 000000000..083b556a3 --- /dev/null +++ b/SQF/dayz_server/compile/server_updateNearbyObjects.sqf @@ -0,0 +1,9 @@ +private["_pos"]; +_pos = _this select 0; +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" + + +{ + [_x, "gear"] call server_updateObject; +} forEach nearestObjects [_pos, DayZ_GearedObjects, 10]; + diff --git a/SQF/dayz_server/compile/server_updateObject.sqf b/SQF/dayz_server/compile/server_updateObject.sqf index 67a23aa4d..ea1701f09 100644 --- a/SQF/dayz_server/compile/server_updateObject.sqf +++ b/SQF/dayz_server/compile/server_updateObject.sqf @@ -2,6 +2,8 @@ USAGE: [_object, _type] spawn server_updateObject; */ +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" +if (isNil "sm_done") exitwith {}; private ["_object","_type","_objectID","_uid","_lastUpdate","_needUpdate","_object_position","_object_inventory","_object_damage","_isNotOk","_parachuteWest","_firstTime","_object_killed","_object_repair","_isbuildable"]; @@ -11,25 +13,51 @@ if (isNull _object) exitWith { diag_log format ["Skipping Null Object: %1", _object]; }; -_type = _this select 1; +_type = _this select 1; +_forced = false; +_recorddmg = false; _parachuteWest = (typeOf _object) in ["ParachuteWest","ParachuteC"]; _isbuildable = (typeOf _object) in dayz_allowedObjects; _isNotOk = false; _firstTime = false; -_objectID = _object getVariable ["ObjectID","0"]; -_uid = _object getVariable ["ObjectUID","0"]; +_objectID = "0"; +_objectUID = "0"; -if (typeName _objectID != "STRING" || typeName _uid != "STRING") then { - diag_log format ["Non-string Object: ID %1 UID %2", _objectID, _uid]; - _objectID = "0"; - _uid = "0"; +if (!((isNil "_object") OR {(isNull _object)})) then { + _objectID = _object getVariable ["ObjectID","0"]; + _objectUID = _object getVariable ["ObjectUID","0"]; +}; + +if ((typeName _objectID == "SCALAR") || (typeName _objectUID == "SCALAR")) then { + + #ifdef OBJECT_DEBUG + diag_log(format["Non-string Object: ID %1 UID %2", _objectID, _objectUID]); + #endif + + //force fail + _objectID = nil; + _objectUID = nil; }; if (!_parachuteWest && !locked _object) then { - if (_objectID == "0" && _uid == "0") then { + if (!(_objectID in dayz_serverIDMonitor) AND isNil {_objectUID}) then { + //force fail + _objectID = nil; + _objectUID = nil; + }; + + if ((isNil {_objectID}) AND (isNil {_objectUID})) then + { _object_position = getPosATL _object; - _isNotOk = true; + #ifdef OBJECT_DEBUG + diag_log(format["Object %1 with invalid ID at pos [%2,%3,%4]", + typeOf _object, + _object_position select 0, + _object_position select 1, + _object_position select 2]); + #endif + _isNotOk = true; }; }; @@ -39,75 +67,143 @@ if (_isNotOk) exitWith { diag_log format ["Deleting object %1 with invalid ID at pos [%2,%3,%4]", typeOf _object, _object_position select 0, _object_position select 1, _object_position select 2]; }; -_lastUpdate = _object getVariable ["lastUpdate", time]; +_lastUpdate = _object getVariable ["lastUpdate",diag_tickTime]; _needUpdate = _object in needUpdate_objects; - _object_position = { - private ["_position","_worldspace","_fuel","_key"]; + private["_position","_worldspace","_fuel","_key"]; _position = getPosATL _object; _worldspace = [ - round (getDir _object), + round(direction _object), _position ]; - _fuel = if (_object isKindOf "AllVehicles") then { fuel _object } else { 0 }; - _key = format ["CHILD:305:%1:%2:%3:", _objectID, _worldspace, _fuel]; - _key call server_hiveWrite; + _fuel = 0; + if (_object isKindOf "AllVehicles") then { + _fuel = fuel _object; + }; + + _key = format["CHILD:305:%1:%2:%3:",_objectID,_worldspace,_fuel]; + _key call server_hiveWrite; + + #ifdef OBJECT_DEBUG + diag_log ("HIVE: WRITE: "+ str(_key)); + #endif }; _object_inventory = { private["_inventory","_previous","_key"]; - _inventory = [ - getWeaponCargo _object, - getMagazineCargo _object, - getBackpackCargo _object - ]; - _previous = str (_object getVariable ["lastInventory", []]); - if (str _inventory != _previous) then { - _object setVariable ["lastInventory", _inventory]; - _key = if (_objectID == "0") then { format ["CHILD:309:%1:", _uid] + str _inventory + ":" } else { format ["CHILD:303:%1:", _objectID] + str _inventory + ":" }; + if (_object isKindOf "TrapItems") then { + _inventory = [["armed",_object getVariable ["armed", false]]]; + } else { + _inventory = [ + getWeaponCargo _object, + getMagazineCargo _object, + getBackpackCargo _object + ]; + }; + + _previous = str(_object getVariable["lastInventory",[]]); + if (str(_inventory) != _previous) then { + _object setVariable["lastInventory",_inventory]; + if (_objectID == "0") then { + _key = format["CHILD:309:%1:%2:",_objectUID,_inventory]; + } else { + _key = format["CHILD:303:%1:%2:",_objectID,_inventory]; + }; + + #ifdef OBJECT_DEBUG + diag_log ("HIVE: WRITE: "+ str(_key)); + #endif + _key call server_hiveWrite; }; }; _object_damage = { - private ["_hitpoints","_array","_hit","_selection","_key","_damage"]; + //Allow dmg process + private["_hitpoints","_array","_hit","_selection","_key","_damage", "_allFixed"]; _hitpoints = _object call vehicle_getHitpoints; _damage = damage _object; _array = []; + _allFixed = true; { - _hit = [_object, _x] call object_getHit; - _selection = getText (configFile >> "CfgVehicles" >> typeOf _object >> "HitPoints" >> _x >> "name"); - if (_hit > 0) then { - _array set [count _array, [_selection,_hit]]; - }; - _object setHit [_selection, _hit]; - } count _hitpoints; + _hit = [_object,_x] call object_getHit; + _selection = getText (configFile >> "CfgVehicles" >> (typeOf _object) >> "HitPoints" >> _x >> "name"); + if (_hit > 0) then { + _allFixed = false; + _array set [count _array,[_selection,_hit]]; + //diag_log format ["Section Part: %1, Dmg: %2",_selection,_hit]; + } else { + _array set [count _array,[_selection,0]]; + }; + + } forEach _hitpoints; + + if (_allFixed) then { + _object setDamage 0; + }; - _key = "CHILD:306:" + _objectID + ":" + str _array + ":" + str _damage + ":"; - _key call server_hiveWrite; - _object setVariable ["needUpdate", false, true]; + if (_forced) then { + if (_object in needUpdate_objects) then { + needUpdate_objects = needUpdate_objects - [_object]; + }; + _recorddmg = true; + } else { + //Prevent damage events for the first 10 seconds of the servers live. + if (diag_ticktime - _lastUpdate > 10) then { + if (!(_object in needUpdate_objects)) then { + //diag_log format["DEBUG: Monitoring: %1",_object]; + needUpdate_objects set [count needUpdate_objects, _object]; + _recorddmg = true; + }; + }; + }; + + if (_recorddmg) then { + if (_objectID == "0") then { + _key = format["CHILD:306:%1:%2:%3:",_objectUID,_array,_damage]; + } else { + _key = format["CHILD:306:%1:%2:%3:",_objectID,_array,_damage]; + }; + diag_log ("HIVE: WRITE: "+ str(_key)); + _key call server_hiveWrite; + }; +}; + +//Walls +_objWallDamage = { + private["_key"]; + _damage = _this select 2; + + _object setDamage _damage; + + if (_objectID == "0") then { + _key = format["CHILD:306:%1:%2:%3:",_objectUID,[],_damage]; + } else { + _key = format["CHILD:306:%1:%2:%3:",_objectID,[],_damage]; + }; + + _key call server_hiveWrite; }; _object_killed = { - private ["_hitpoints","_array","_hit","_PUID","_selection","_key","_damage"]; - _hitpoints = _object call vehicle_getHitpoints; - _damage = 1; - - _array = []; - { - _hit = [_object, _x] call object_getHit; - _selection = getText (configFile >> "CfgVehicles" >> typeOf _object >> "HitPoints" >> _x >> "name"); - if (_hit > 0) then { - _array set [count _array, [_selection, _hit]]; - }; - _object setHit [_selection, 1]; - } count _hitpoints; - - _key = "CHILD:306:" + _objectID + ":" + str _array + ":" + str _damage + ":"; - _key call server_hiveWrite; - - _object setVariable ["needUpdate", false, true]; + private["_key"]; + _object setDamage 1; + + if (_objectID == "0") then { + //Need to update hive to make a new call too allow UID to be updated for a killed event + //_key = format["CHILD:306:%1:%2:%3:",_objectUID,[],1]; + _key = format["CHILD:310:%1:",_objectUID]; + } else { + _key = format["CHILD:306:%1:%2:%3:",_objectID,[],1]; + }; + + diag_log ("HIVE: WRITE: "+ str(_key)); + _key call server_hiveWrite; + + if ((typeOf _object) in DayZ_removableObjects) then { + [_objectID,_objectUID] call server_deleteObj; + }; if (count _this > 2) then { _killer = _this select 2; @@ -145,38 +241,80 @@ _object_repair = { _object setVariable ["needUpdate", false, true]; }; -_object setVariable ["lastUpdate", time, true]; +_object_maintenance = { + private["_ownerArray","_key"]; -if (_type == "all") exitWith { - call _object_position; - call _object_inventory; - call _object_damage; -}; + _ownerArray = _object getVariable ["ownerArray",[]]; + _accessArray = _object getVariable ["dayz_padlockCombination",[]]; + + _variables set [ count _variables, ["ownerArray", _ownerArray]]; + _variables set [ count _variables, ["padlockCombination", _accessArray]]; -if (_type == "position") exitWith { - if !(_object in needUpdate_objects) then { - needUpdate_objects set [count needUpdate_objects, _object]; - }; -}; - -if (_type == "gear") exitWith { - call _object_inventory; -}; - -if (_type == "damage") exitWith { - if (time - _lastUpdate > 5) then { - call _object_damage; + if (_objectID == "0") then { + _key = format["CHILD:309:%1:%2:",_objectUID,_ownerArray]; + //Wont work just now. + _key = format["CHILD:306:%1:%2:%3:",_objectUID,[],0]; } else { - if !(_object in needUpdate_objects) then { - needUpdate_objects set [count needUpdate_objects, _object]; - }; + _key = format["CHILD:303:%1:%2:",_objectID,_ownerArray]; + _key = format["CHILD:306:%1:%2:%3:",_objectID,[],0]; + }; + +// #ifdef OBJECT_DEBUG + diag_log ("HIVE: WRITE: Maintenance, "+ str(_key)); +// #endif + + _key call server_hiveWrite; +}; + +_object_variables = { + private["_ownerArray","_key","_accessArray","_variables"]; + + _ownerArray = _object getVariable ["ownerArray",[]]; + _accessArray = _object getVariable ["dayz_padlockCombination",[]]; + _lockedArray = _object getVariable ["BuildLock",false]; + + //diag_log format ["[%1,%2]",_ownerArray,_accessArray]; + _variables = []; + + _variables set [ count _variables, ["ownerArray", _ownerArray]]; + _variables set [ count _variables, ["padlockCombination", _accessArray]]; + _variables set [ count _variables, ["BuildLock", _lockedArray]]; + + if (_objectID == "0") then { + _key = format["CHILD:309:%1:%2:",_objectUID,_variables]; + } else { + _key = format["CHILD:303:%1:%2:",_objectID,_variables]; + }; + + _key call server_hiveWrite; +}; + +_object setVariable ["lastUpdate",diag_ticktime,true]; +switch (_type) do { + case "all": { + call _object_position; + call _object_inventory; + call _object_damage; + }; + case "position": { + call _object_position; + }; + case "gear": { + call _object_inventory; + }; + case "maintenance": { + call _object_maintenance; + }; + case "damage"; case "repair" : { + call _object_damage; + }; + case "killed": { + call _object_killed; + }; + case "accessCode"; case "buildLock" : { + call _object_variables; + }; + case "objWallDamage": { + call _objWallDamage; }; }; - -if (_type == "killed") exitWith { - call _object_killed; -}; - -if (_type == "repair") exitWith { - call _object_damage; -}; diff --git a/SQF/dayz_server/compile/zombie_Wildgenerate.sqf b/SQF/dayz_server/compile/zombie_Wildgenerate.sqf new file mode 100644 index 000000000..67fb92581 --- /dev/null +++ b/SQF/dayz_server/compile/zombie_Wildgenerate.sqf @@ -0,0 +1,51 @@ +private ["_position","_doLoiter","_unitTypes","_array","_agent","_type","_radius","_method","_rndx","_rndy","_counter","_amount","_wildsdone"]; +_unitTypes = _this select 0; +_amount = _this select 1; +//_doLoiter = true; +_wildsdone = true; +_counter = 0; + +while {_counter < _amount} do { + //_loot = ""; + //_array = []; + _agent = objNull; + _type = _unitTypes call BIS_fnc_selectRandom; + + //Create the Group and populate it + //diag_log ("Spawned: " + _type); + //_radius = 0; + _method = "CAN_COLLIDE"; + + //_createSafePos = getMarkerPos "center"; + _position = [getMarkerPos "center",1,6500,1] call fn_selectRandomLocation; + + //Create Zed + _agent = createAgent [_type, _position, [], 1, _method]; + //Set Random Direction + _agent setDir floor(random 360); + //Loiter State + _agent setVariable ["doLoiter",true]; //Might not be used. + //Zed stance + if (random 1 > 0.7) then { + _agent setUnitPos "Middle"; + }; + //Set home location to loiter around + _position = getPosATL _agent; + _agent setVariable ["homePos",_position,true]; + //Store _agentobject + _agent setVariable["agentObject",_agent,true]; + + //add to counter + _counter = _counter + 1; + + //Start behavior + //_id = [_position,_agent] execFSM "\z\AddOns\dayz_code\system\zombie_wildagent.fsm"; + //_agent setVariable [ "fsmid", _id ]; + + //Disable all zed systems + _agent enableSimulation false; + + //diag_log format ["CREATE WILD: Active: %1, Waiting: %2",_counter,(_amount - _counter)] +}; + +_wildsdone \ No newline at end of file diff --git a/SQF/dayz_server/compile/zombie_findOwner.sqf b/SQF/dayz_server/compile/zombie_findOwner.sqf new file mode 100644 index 000000000..186f23f7c --- /dev/null +++ b/SQF/dayz_server/compile/zombie_findOwner.sqf @@ -0,0 +1,8 @@ +private["_unit"]; +_unit = _this select 0; +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" + +#ifdef SERVER_DEBUG +diag_log ("CLEANUP: DELETE UNCONTROLLED ZOMBIE: " + (typeOf _unit) + " OF: " + str(_unit) ); +#endif +deleteVehicle _unit; diff --git a/SQF/dayz_server/config.cpp b/SQF/dayz_server/config.cpp index 47897fa2a..b620ee90c 100644 --- a/SQF/dayz_server/config.cpp +++ b/SQF/dayz_server/config.cpp @@ -5,4 +5,78 @@ class CfgPatches { requiredVersion = 0.1; requiredAddons[] = {"dayz_code"}; }; -}; \ No newline at end of file + + class vehMaint { + class CAWorld {}; + class Chernarus:CAWorld { + center[] = {7839,8414}; // x y + SWcorner[] = {0,1360}; + NEcorner[] = {14400,13560}; + spawnRadius = 6000; + }; + + class AllVehicles { + // location types where vehicles will be spawned + localityTypes[] = { "Airport", "CityCenter", "FlatArea", "FlatAreaCity", "FlatAreaCitySmall", "Hill", "NameCity", "NameCityCapital", "NameLocal", "NameMarine", "NameVillage" }; + // disk radius around location + localityRadius = 1500; + // enabled altitudes (or sea depth) + minAltitude = 3; + maxAltitude = 400; + // look for objects class/type in location. Leave it empty for a random spot inside the disk + nearObjects[] = { "Land_Wall_Gate_Ind1_L", "Land_Wall_Gate_Ind2A_L", "Land_Wall_Gate_Ind2B_L", "Land_Wall_Gate_Ind2Rail_L", "Land_Wall_Gate_Kolchoz", "Land_CncBlock_Stripes", "Land_repair_center", "Land_A_FuelStation_Build" }; + }; + class Air:AllVehicles { + nearObjects[] = { "Body","Body1","Body2","NT72Wreck","Fort_Razor_Wire", "HeliHRescue", "Land_A_Castle_Bastion", "Land_CamoNetB_NATO_EP1", "Land_SS_hangar", "HeliH","HeliHCivil", "HeliHRescue", "Land_Tent_East" }; // "UralWreck","HMMWVWreck", + }; + class Ship:AllVehicles { + localityTypes[] = { "NameMarine" }; + localityRadius = 900; + minAltitude = -9; // sea depth + maxAltitude = -1.2; // sea depth + nearObjects[] = {}; + }; + class PBX : Ship { quantity = 1; }; + class Smallboat_1 : Ship { quantity = 2; }; + class Smallboat_2 : Ship { quantity = 1; }; + class MH6J_DZ : Air { quantity = 3; }; + class UH1H_DZ : Air { quantity = 1; }; + class AH6X_DZ : Air { quantity = 1; }; + class Mi17_DZ : Air { quantity = 2; }; + class AN2_DZ : Air { quantity = 1; }; + class Motorcycle : AllVehicles {}; + + class TT650_Civ : Motorcycle { quantity = 1; }; + class TT650_Ins : Motorcycle { quantity = 1; }; + class M1030 : Motorcycle { quantity = 2; }; + + class Bicycle : Motorcycle { + nearObjects[] = { "Land_Misc_Cargo1B", "Land_loco_742_blue", "Land_Misc_Cargo1Bo", "Land_Misc_Cargo1D", "Land_Rail_Zavora","Land_HouseV_3I1","Land_rail_station_big", "Land_Rail_House_01", "Land_HouseV_1L2","Land_NAV_Lighthouse", "Land_NAV_Lighthouse2", "Land_A_FuelStation_Build", "Land_Hlidac_budka", "Land_Shed_W01" }; + maxAltitude = 60; + }; + class Old_bike_TK_INS_EP1 : Bicycle { quantity = 4; }; + class Old_bike_TK_CIV_EP1 : Bicycle { quantity = 6; }; + class Car:AllVehicles {}; + class Truck:Car {}; + class Ural_TK_CIV_EP1:Truck { quantity = 1; }; + class Ikarus : Car { quantity = 2; }; // Bus? + + class V3S_Civ:Truck { quantity = 1; }; + class tractor:Car { + localityTypes[] = { "Hill", "NameLocal", "NameVillage" }; + nearObjects[] = { "Land_seno_balik" }; // haystack + quantity = 4; + }; + class ATV_US_EP1 : Car { quantity = 5; }; + class ATV_CZ_EP1 : Car { quantity = 4; }; + class car_hatchback : Car { quantity = 1; }; + class Volha_2_TK_CIV_EP1 : Car { quantity = 1; }; + class Lada2 : Car { quantity = 1; }; + class hilux1_civil_3_open : Car { quantity = 2; }; + class UAZ_CDF : Car { quantity = 1; }; + class BAF_Offroad_W : Car { quantity = 1; }; + class S1203_TK_CIV_EP1 : Car { quantity = 1; }; + class HMMWV_DZ : Car { quantity = 2; }; + class SUV_DZ : Car { quantity = 1; }; + }; +}; diff --git a/SQF/dayz_server/compile/server_sendToClient.sqf b/SQF/dayz_server/eventHandlers/server_sendToClient.sqf similarity index 65% rename from SQF/dayz_server/compile/server_sendToClient.sqf rename to SQF/dayz_server/eventHandlers/server_sendToClient.sqf index 57ad96677..e98c4a097 100644 --- a/SQF/dayz_server/compile/server_sendToClient.sqf +++ b/SQF/dayz_server/eventHandlers/server_sendToClient.sqf @@ -2,7 +2,7 @@ private ["_unit","_variable","_arraytosend","_owner","_vehicle","_qty"]; //Inbound [_unit,"PVCDZ_hlt_Transfuse",[_unit,player,1000]] _unit = _this select 0; -if(isNull _unit) exitWith {diag_log format ["ERROR: sendToClient is Null: %1", _unit]}; +//if(isNull _unit) exitWith {diag_log format ["ERROR: sendToClient is Null: %1", _unit]}; _variable = _this select 1; _arraytosend = _this select 2; @@ -32,7 +32,26 @@ switch (_variable) do { _owner publicVariableClient "PVDZE_veh_SFuel"; }; }; + + case "SetEngineState": { + _vehicle = _arraytosend select 0; + _state = _arraytosend select 1; + + if (local _vehicle) then { + //_vehicle engineOn _state; + _vehicle setOwner _owner; + } else { + PVCDZ_veh_engineSwitch = _arraytosend; + _owner publicVariableClient "PVCDZ_veh_engineSwitch"; + }; + }; + + case "GutBody": { + PVCDZ_obj_GutBody = _arraytosend; + _owner publicVariableClient "PVCDZ_obj_GutBody"; + }; + case "HideBody": { PVDZE_plr_HideBody = _arraytosend select 0; _owner publicVariableClient "PVDZE_plr_HideBody"; @@ -52,7 +71,14 @@ switch (_variable) do { usecBleed = _arraytosend; _owner publicVariableClient "usecBleed"; }; - + + case "dayzSetDate": { + dayzSetDate = dayz_storeTimeDate; + _owner publicVariableClient "dayzSetDate"; + + //diag_log ("Time and date: " +str (dayz_storeTimeDate)); + }; + case "HideObj": { PVDZE_obj_Hide = _arraytosend select 0; _owner publicVariableClient "PVDZE_obj_Hide"; @@ -69,6 +95,12 @@ switch (_variable) do { _unit setVariable["medForceUpdate",true]; }; + case "Transfuse_completed": { + PVCDZ_hlt_Transfuse_completed = true; + _owner publicVariableClient "PVCDZ_hlt_Transfuse_completed"; + _unit setVariable["medForceUpdate",true]; + }; + case "Painkiller": { usecPainK = _arraytosend; _owner publicVariableClient "usecPainK"; @@ -94,8 +126,27 @@ switch (_variable) do { _owner publicVariableClient "usecBandage"; _unit setVariable["medForceUpdate",true]; }; + + case "Antibiotics": { + PVCDZ_hlt_AntiB = _arraytosend; + _owner publicVariableClient "PVCDZ_hlt_AntiB"; + _unit setVariable["medForceUpdate",true]; + }; + case "tagFriendly": { PVDZE_plr_FriendRQ = _arraytosend; _owner publicVariableClient "PVDZE_plr_FriendRQ"; }; -}; + case "Legs": { + PVCDZ_plr_Legs = _arraytosend; + _owner publicVariableClient "PVCDZ_plr_Legs"; + }; + + case "OpenTarget": + { + _unit setVariable["OpenTarget",true,true]; + + PVCDZ_OpenTarget_Reset = true; + _owner publicVariableClient "PVCDZ_OpenTarget_Reset"; + }; +}; \ No newline at end of file diff --git a/SQF/dayz_server/init/Epoch_Init.sqf b/SQF/dayz_server/init/Epoch_Init.sqf new file mode 100644 index 000000000..1d23d7ca4 --- /dev/null +++ b/SQF/dayz_server/init/Epoch_Init.sqf @@ -0,0 +1,853 @@ + +/* +server_updateNearbyObjects = { + private["_pos"]; + _pos = _this select 0; + { + [_x, "gear"] call server_updateObject; + } count nearestObjects [_pos, dayz_updateObjects, 10]; +}; */ + +server_handleZedSpawn = { + private["_zed"]; + _zed = _this select 0; + _zed enableSimulation false; +}; +/* +zombie_findOwner = { + private["_unit"]; + _unit = _this select 0; + #ifdef DZE_SERVER_DEBUG + diag_log ("CLEANUP: DELETE UNCONTROLLED ZOMBIE: " + (typeOf _unit) + " OF: " + str(_unit) ); + #endif + deleteVehicle _unit; +}; */ + +vehicle_handleInteract = { + private["_object"]; + _object = _this select 0; + needUpdate_objects = needUpdate_objects - [_object]; + [_object, "all"] call server_updateObject; +}; + +array_reduceSizeReverse = { + private["_array","_count","_num","_newarray","_startnum","_index"]; + _array = _this select 0; + _newarray = []; + _count = _this select 1; + _num = count _array; + if (_num > _count) then { + _startnum = _num - 1; + _index = _count - 1; + for "_i" from 0 to _index do { + _newarray set [(_index-_i),_array select (_startnum - _i)]; + }; + _array = _newarray; + }; + _array +}; + +array_reduceSize = { + private ["_array1","_array","_count","_num"]; + _array1 = _this select 0; + _array = _array1 - ["Hatchet_Swing","Machete_Swing","Fishing_Swing","sledge_swing","crowbar_swing","CSGAS"]; + _count = _this select 1; + _num = count _array; + if (_num > _count) then { + _array resize _count; + }; + _array +}; + +object_handleServerKilled = { + private["_unit","_objectID","_objectUID","_killer"]; + _unit = _this select 0; + _killer = _this select 1; + + _objectID = _unit getVariable ["ObjectID","0"]; + _objectUID = _unit getVariable ["ObjectUID","0"]; + + [_objectID,_objectUID,_killer] call server_deleteObj; + + _unit removeAllMPEventHandlers "MPKilled"; + _unit removeAllEventHandlers "Killed"; + _unit removeAllEventHandlers "HandleDamage"; + _unit removeAllEventHandlers "GetIn"; + _unit removeAllEventHandlers "GetOut"; +}; + +server_hiveReadWriteLarge = { + private["_key","_resultArray","_data"]; + _key = _this; + _data = "HiveExt" callExtension _key; + _resultArray = call compile _data; + _resultArray +}; + +server_checkIfTowed = { + private ["_vehicle","_player","_attached"]; + if (DZE_HeliLift) then { + _vehicle = _this select 0; + _player = _this select 2; + _attached = _vehicle getVariable["attached",false]; + if (typeName _attached == "OBJECT") then { + _player action ["eject", _vehicle]; + detach _vehicle; + _vehicle setVariable["attached",false,true]; + _attached setVariable["hasAttached",false,true]; + }; + }; +}; + +server_characterSync = { + private ["_characterID","_playerPos","_playerGear","_playerBackp","_medical","_currentState","_currentModel","_key"]; + _characterID = _this select 0; + _playerPos = _this select 1; + _playerGear = _this select 2; + _playerBackp = _this select 3; + _medical = _this select 4; + _currentState = _this select 5; + _currentModel = _this select 6; + + _key = format["CHILD:201:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:",_characterID,_playerPos,_playerGear,_playerBackp,_medical,false,false,0,0,0,0,_currentState,0,0,_currentModel,0]; + _key call server_hiveWrite; +}; + +if(isnil "dayz_MapArea") then { + dayz_MapArea = 10000; +}; +if(isnil "DynamicVehicleArea") then { + DynamicVehicleArea = dayz_MapArea / 2; +}; + +// Get all buildings && roads only once TODO: set variables to nil after done if nessicary +MarkerPosition = getMarkerPos "center"; +RoadList = MarkerPosition nearRoads DynamicVehicleArea; + +// Very taxing !!! but only on first startup +BuildingList = []; +{ + if (DZE_MissionLootTable) then { + if (isClass (missionConfigFile >> "CfgBuildingLoot" >> (typeOf _x))) then + { + BuildingList set [count BuildingList,_x]; + }; + } else { + if (isClass (configFile >> "CfgBuildingLoot" >> (typeOf _x))) then + { + BuildingList set [count BuildingList,_x]; + }; + }; + + +} count (MarkerPosition nearObjects ["building",DynamicVehicleArea]); + +spawn_vehicles = { + private ["_random","_lastIndex","_weights","_index","_vehicle","_velimit","_qty","_isAir","_isShip","_position","_dir","_istoomany","_veh","_objPosition","_marker","_iClass","_itemTypes","_cntWeights","_itemType","_num","_allCfgLoots"]; + + if (!isDedicated) exitWith { }; //Be sure the run this + + while {count AllowedVehiclesList > 0} do { + // BIS_fnc_selectRandom replaced because the index may be needed to remove the element + _index = floor random count AllowedVehiclesList; + _random = AllowedVehiclesList select _index; + + _vehicle = _random select 0; + _velimit = _random select 1; + + _qty = {_x == _vehicle} count serverVehicleCounter; + + // If under limit allow to proceed + if (_qty <= _velimit) exitWith {}; + + // vehicle limit reached, remove vehicle from list + // since elements cannot be removed from an array, overwrite it with the last element && cut the last element of (as long as order is not important) + _lastIndex = (count AllowedVehiclesList) - 1; + if (_lastIndex != _index) then { + AllowedVehiclesList set [_index, AllowedVehiclesList select _lastIndex]; + }; + AllowedVehiclesList resize _lastIndex; + }; + + if (count AllowedVehiclesList == 0) then { + diag_log("DEBUG: unable to find suitable vehicle to spawn"); + } else { + + // add vehicle to counter for next pass + serverVehicleCounter set [count serverVehicleCounter,_vehicle]; + + // Find Vehicle Type to better control spawns + _isAir = _vehicle isKindOf "Air"; + _isShip = _vehicle isKindOf "Ship"; + + if(_isShip || _isAir) then { + if(_isShip) then { + // Spawn anywhere on coast on water + waitUntil{!isNil "BIS_fnc_findSafePos"}; + _position = [MarkerPosition,0,DynamicVehicleArea,10,1,2000,1] call BIS_fnc_findSafePos; + //diag_log("DEBUG: spawning boat near coast " + str(_position)); + } else { + // Spawn air anywhere that is flat + waitUntil{!isNil "BIS_fnc_findSafePos"}; + _position = [MarkerPosition,0,DynamicVehicleArea,10,0,2000,0] call BIS_fnc_findSafePos; + //diag_log("DEBUG: spawning air anywhere flat " + str(_position)); + }; + + + } else { + // Spawn around buildings && 50% near roads + if((random 1) > 0.5) then { + + waitUntil{!isNil "BIS_fnc_selectRandom"}; + _position = RoadList call BIS_fnc_selectRandom; + + _position = _position modelToWorld [0,0,0]; + + waitUntil{!isNil "BIS_fnc_findSafePos"}; + _position = [_position,0,10,10,0,2000,0] call BIS_fnc_findSafePos; + + //diag_log("DEBUG: spawning near road " + str(_position)); + + } else { + + waitUntil{!isNil "BIS_fnc_selectRandom"}; + _position = BuildingList call BIS_fnc_selectRandom; + + _position = _position modelToWorld [0,0,0]; + + waitUntil{!isNil "BIS_fnc_findSafePos"}; + _position = [_position,0,40,5,0,2000,0] call BIS_fnc_findSafePos; + + //diag_log("DEBUG: spawning around buildings " + str(_position)); + + }; + }; + // only proceed if two params otherwise BIS_fnc_findSafePos failed && may spawn in air + if ((count _position) == 2) then { + + _dir = round(random 180); + + _istoomany = _position nearObjects ["AllVehicles",50]; + if((count _istoomany) > 0) exitWith { diag_log("DEBUG: Too many vehicles at " + str(_position)); }; + + //place vehicle + _veh = createVehicle [_vehicle, _position, [], 0, "CAN_COLLIDE"]; + _veh setdir _dir; + _veh setpos _position; + + if(DZEdebug) then { + _marker = createMarker [str(_position) , _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "DOT"; + _marker setMarkerText _vehicle; + }; + + // Get position with ground + _objPosition = getPosATL _veh; + + clearWeaponCargoGlobal _veh; + clearMagazineCargoGlobal _veh; + // _veh setVehicleAmmo DZE_vehicleAmmo; + + // Add 0-3 loots to vehicle using random cfgloots + _num = floor(random 4); + _allCfgLoots = ["trash","civilian","food","generic","medical","military","policeman","hunter","worker","clothes","militaryclothes","specialclothes","trash"]; + + for "_x" from 1 to _num do { + _iClass = _allCfgLoots call BIS_fnc_selectRandom; + + _itemTypes = []; + if (DZE_MissionLootTable) then{ + { + _itemTypes set[count _itemTypes, _x select 0] + } count getArray(missionConfigFile >> "cfgLoot" >> _iClass); + } + else { + { + _itemTypes set[count _itemTypes, _x select 0] + } count getArray(configFile >> "cfgLoot" >> _iClass); + }; + + _index = dayz_CLBase find _iClass; + _weights = dayz_CLChances select _index; + _cntWeights = count _weights; + + _index = floor(random _cntWeights); + _index = _weights select _index; + _itemType = _itemTypes select _index; + _veh addMagazineCargoGlobal [_itemType,1]; + //diag_log("DEBUG: spawed loot inside vehicle " + str(_itemType)); + }; + + [_veh,[_dir,_objPosition],_vehicle,true,"0"] call server_publishVeh; + }; + }; +}; + +spawn_ammosupply = { + private ["_position","_veh","_istoomany","_marker","_spawnveh","_WreckList"]; + if (isDedicated) then { + _WreckList = ["Supply_Crate_DZE"]; + waitUntil{!isNil "BIS_fnc_selectRandom"}; + _position = RoadList call BIS_fnc_selectRandom; + _position = _position modelToWorld [0,0,0]; + waitUntil{!isNil "BIS_fnc_findSafePos"}; + _position = [_position,5,20,5,0,2000,0] call BIS_fnc_findSafePos; + if ((count _position) == 2) then { + + _istoomany = _position nearObjects ["All",5]; + + if((count _istoomany) > 0) exitWith { diag_log("DEBUG VEIN: Too many at " + str(_position)); }; + + _spawnveh = _WreckList call BIS_fnc_selectRandom; + + if(DZEdebug) then { + _marker = createMarker [str(_position) , _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "DOT"; + _marker setMarkerText str(_spawnveh); + }; + + _veh = createVehicle [_spawnveh,_position, [], 0, "CAN_COLLIDE"]; + _veh enableSimulation false; + _veh setDir round(random 360); + _veh setpos _position; + _veh setVariable ["ObjectID","1",true]; + }; + }; +}; + +DZE_LocalRoadBlocks = []; + +spawn_roadblocks = { + private ["_position","_veh","_istoomany","_marker","_spawnveh","_WreckList"]; + _WreckList = ["SKODAWreck","HMMWVWreck","UralWreck","datsun01Wreck","hiluxWreck","datsun02Wreck","UAZWreck","Land_Misc_Garb_Heap_EP1","Fort_Barricade_EP1","Rubbish2"]; + + waitUntil{!isNil "BIS_fnc_selectRandom"}; + if (isDedicated) then { + + _position = RoadList call BIS_fnc_selectRandom; + + _position = _position modelToWorld [0,0,0]; + + waitUntil{!isNil "BIS_fnc_findSafePos"}; + _position = [_position,0,10,5,0,2000,0] call BIS_fnc_findSafePos; + + if ((count _position) == 2) then { + // Get position with ground + + _istoomany = _position nearObjects ["All",5]; + + if((count _istoomany) > 0) exitWith { diag_log("DEBUG: Too many at " + str(_position)); }; + + waitUntil{!isNil "BIS_fnc_selectRandom"}; + _spawnveh = _WreckList call BIS_fnc_selectRandom; + + if(DZEdebug) then { + _marker = createMarker [str(_position) , _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "DOT"; + _marker setMarkerText str(_spawnveh); + }; + + _veh = createVehicle [_spawnveh,_position, [], 0, "CAN_COLLIDE"]; + _veh enableSimulation false; + + _veh setDir round(random 360); // Randomize placement a bit + _veh setpos _position; + + _veh setVariable ["ObjectID","1",true]; + }; + + }; + +}; + +spawn_mineveins = { + private ["_position","_veh","_istoomany","_marker","_spawnveh","_positions"]; + + if (isDedicated) then { + + _position = [getMarkerPos "center",0,(HeliCrashArea*0.75),10,0,2000,0] call BIS_fnc_findSafePos; + + if ((count _position) == 2) then { + + _positions = selectBestPlaces [_position, 500, "(1 + forest) * (1 + hills) * (1 - houses) * (1 - sea)", 10, 5]; + + _position = (_positions call BIS_fnc_selectRandom) select 0; + + // Get position with ground + _istoomany = _position nearObjects ["All",10]; + + if((count _istoomany) > 0) exitWith { diag_log("DEBUG VEIN: Too many objects at " + str(_position)); }; + + if(isOnRoad _position) exitWith { diag_log("DEBUG VEIN: on road " + str(_position)); }; + + _spawnveh = ["Iron_Vein_DZE","Iron_Vein_DZE","Iron_Vein_DZE","Iron_Vein_DZE","Iron_Vein_DZE","Silver_Vein_DZE","Silver_Vein_DZE","Silver_Vein_DZE","Gold_Vein_DZE","Gold_Vein_DZE"] call BIS_fnc_selectRandom; + + if(DZEdebug) then { + _marker = createMarker [str(_position) , _position]; + _marker setMarkerShape "ICON"; + _marker setMarkerType "DOT"; + _marker setMarkerText str(_spawnveh); + }; + + //diag_log("DEBUG: Spawning a crashed " + _spawnveh + " with " + _spawnloot + " at " + str(_position)); + _veh = createVehicle [_spawnveh,_position, [], 0, "CAN_COLLIDE"]; + _veh enableSimulation false; + + // Randomize placement a bit + _veh setDir round(random 360); + _veh setpos _position; + + _veh setVariable ["ObjectID","1",true]; + + + }; + }; +}; + +if(isnil "DynamicVehicleDamageLow") then { + DynamicVehicleDamageLow = 0; +}; +if(isnil "DynamicVehicleDamageHigh") then { + DynamicVehicleDamageHigh = 100; +}; + +if(isnil "DynamicVehicleFuelLow") then { + DynamicVehicleFuelLow = 0; +}; +if(isnil "DynamicVehicleFuelHigh") then { + DynamicVehicleFuelHigh = 100; +}; + +if(isnil "DZE_DiagFpsSlow") then { + DZE_DiagFpsSlow = false; +}; +if(isnil "DZE_DiagFpsFast") then { + DZE_DiagFpsFast = false; +}; +if(isnil "DZE_DiagVerbose") then { + DZE_DiagVerbose = false; +}; + +dze_diag_fps = { + if(DZE_DiagVerbose) then { + diag_log format["DEBUG FPS : %1 OBJECTS: %2 : PLAYERS: %3", diag_fps,(count (allMissionObjects "")),(playersNumber west)]; + } else { + diag_log format["DEBUG FPS : %1", diag_fps]; + }; +}; + +// Damage generator function +generate_new_damage = { + private ["_damage"]; + _damage = ((random(DynamicVehicleDamageHigh-DynamicVehicleDamageLow))+DynamicVehicleDamageLow) / 100; + _damage; +}; + +// Damage generator fuction +generate_exp_damage = { + private ["_damage"]; + _damage = ((random(DynamicVehicleDamageHigh-DynamicVehicleDamageLow))+DynamicVehicleDamageLow) / 100; + + // limit this to 85% since vehicle would blow up otherwise. + //if(_damage >= 0.85) then { + // _damage = 0.85; + //}; + _damage; +}; + +server_getDiff = { + private["_variable","_object","_vNew","_vOld","_result"]; + _variable = _this select 0; + _object = _this select 1; + _vNew = _object getVariable[_variable,0]; + _vOld = _object getVariable[(_variable + "_CHK"),_vNew]; + _result = 0; + if (_vNew < _vOld) then { + //JIP issues + _vNew = _vNew + _vOld; + _object getVariable[(_variable + "_CHK"),_vNew]; + } else { + _result = _vNew - _vOld; + _object setVariable[(_variable + "_CHK"),_vNew]; + }; + _result +}; + +server_getDiff2 = { + private["_variable","_object","_vNew","_vOld","_result"]; + _variable = _this select 0; + _object = _this select 1; + _vNew = _object getVariable[_variable,0]; + _vOld = _object getVariable[(_variable + "_CHK"),_vNew]; + _result = _vNew - _vOld; + _object setVariable[(_variable + "_CHK"),_vNew]; + _result +}; + +currentObjectUIDs = []; +keyStartNumber = 100000000000; + +dayz_objectUID = { + private["_position","_dir","_key","_object"]; + _object = _this; + _position = getPosATL _object; + _dir = direction _object; + _key = [_dir,_position] call dayz_objectUID2; + _key +}; + +dayz_objectUID2 = { + private["_position","_dir","_key"]; + _dir = _this select 0; + _key = ""; + _position = _this select 1; + { + _x = _x * 10; + if ( _x < 0 ) then { _x = _x * -10 }; + _key = _key + str(round(_x)); + } count _position; + _key = _key + str(round(_dir)); + // Make sure the generated key is not a duplicate + while {true} do { + if !(_key in currentObjectUIDs) exitWith {currentObjectUIDs set [count currentObjectUIDs,_key];}; + keyStartNumber = keyStartNumber + 1; + _key = str keyStartNumber; + }; + _key +}; + +dayz_objectUID3 = { + private["_position","_dir","_key"]; + _dir = _this select 0; + _key = ""; + _position = _this select 1; + { + _x = _x * 10; + if ( _x < 0 ) then { _x = _x * -10 }; + _key = _key + str(round(_x)); + } count _position; + _key = _key + str(round(_dir + time)); + // Make sure the generated key is not a duplicate + while {true} do { + if !(_key in currentObjectUIDs) exitWith {currentObjectUIDs set [count currentObjectUIDs,_key];}; + keyStartNumber = keyStartNumber + 1; + _key = str keyStartNumber; + }; + _key +}; + +dayz_recordLogin = { + private["_key"]; + _key = format["CHILD:103:%1:%2:%3:",_this select 0,_this select 1,_this select 2]; + _key call server_hiveWrite; +}; + +dayz_perform_purge = { + if(!isNull(_this)) then { + _group = group _this; + _this removeAllMPEventHandlers "mpkilled"; + _this removeAllMPEventHandlers "mphit"; + _this removeAllMPEventHandlers "mprespawn"; + _this removeAllEventHandlers "FiredNear"; + _this removeAllEventHandlers "HandleDamage"; + _this removeAllEventHandlers "Killed"; + _this removeAllEventHandlers "Fired"; + _this removeAllEventHandlers "GetOut"; + _this removeAllEventHandlers "GetIn"; + _this removeAllEventHandlers "Local"; + clearVehicleInit _this; + deleteVehicle _this; + if ((count (units _group) == 0) && (_group != grpNull)) then { + deleteGroup _group; + }; + }; +}; + +dayz_perform_purge_player = { + + private ["_countr","_backpack","_backpackType","_backpackWpn","_backpackMag","_objWpnTypes","_objWpnQty","_location","_dir","_holder","_weapons","_magazines"]; + diag_log ("Purging player: " + str(_this)); + + if(!isNull(_this)) then { + + _location = getPosATL _this; + _dir = getDir _this; + + _holder = createVehicle ["GraveDZE", _location, [], 0, "CAN_COLLIDE"]; + _holder setDir _dir; + _holder setPosATL _location; + + _holder enableSimulation false; + + _weapons = weapons _this; + _magazines = magazines _this; + + // find backpack + if(!(isNull unitBackpack _this)) then { + _backpack = unitBackpack _this; + _backpackType = typeOf _backpack; + _backpackWpn = getWeaponCargo _backpack; + _backpackMag = getMagazineCargo _backpack; + + _holder addBackpackCargoGlobal [_backpackType,1]; + + // add items from backpack + _objWpnTypes = _backpackWpn select 0; + _objWpnQty = _backpackWpn select 1; + _countr = 0; + { + _holder addWeaponCargoGlobal [_x,(_objWpnQty select _countr)]; + _countr = _countr + 1; + } count _objWpnTypes; + + // add backpack magazine items + _objWpnTypes = _backpackMag select 0; + _objWpnQty = _backpackMag select 1; + _countr = 0; + { + _holder addMagazineCargoGlobal [_x,(_objWpnQty select _countr)]; + _countr = _countr + 1; + } count _objWpnTypes; + }; + }; + + // add weapons + { + _holder addWeaponCargoGlobal [_x, 1]; + } count _weapons; + + // add mags + { + _holder addMagazineCargoGlobal [_x, 1]; + } count _magazines; + _group = group _this; + _this removeAllMPEventHandlers "mpkilled"; + _this removeAllMPEventHandlers "mphit"; + _this removeAllMPEventHandlers "mprespawn"; + _this removeAllEventHandlers "FiredNear"; + _this removeAllEventHandlers "HandleDamage"; + _this removeAllEventHandlers "Killed"; + _this removeAllEventHandlers "Fired"; + _this removeAllEventHandlers "GetOut"; + _this removeAllEventHandlers "GetIn"; + _this removeAllEventHandlers "Local"; + clearVehicleInit _this; + deleteVehicle _this; + if ((count (units _group) == 0) && (_group != grpNull)) then { + deleteGroup _group; + }; + // _this = nil; +}; + + +dayz_removePlayerOnDisconnect = { + if(!isNull(_this)) then { + _group = group _this; + _this removeAllMPEventHandlers "mphit"; + deleteVehicle _this; + deleteGroup (group _this); + }; +}; + +server_timeSync = { + //Send request + private ["_hour","_minute","_date","_key","_result","_outcome"]; + _key = "CHILD:307:"; + _result = _key call server_hiveReadWrite; + _outcome = _result select 0; + if(_outcome == "PASS") then { + _date = _result select 1; + //date setup + _year = _date select 0; + _month = _date select 1; + _day = _date select 2; + _hour = _date select 3; + _minute = _date select 4; + + if(dayz_ForcefullmoonNights) then { + _date = [2012,8,2,_hour,_minute]; + }; + setDate _date; + PVDZE_plr_SetDate = _date; + publicVariable "PVDZE_plr_SetDate"; + diag_log ("TIME SYNC: Local Time set to " + str(_date)); + }; +}; + +// must spawn these +server_spawncleanDead = { + private ["_deathTime","_delQtyZ","_delQtyP","_qty","_allDead"]; + _allDead = allDead; + _delQtyZ = 0; + _delQtyP = 0; + { + if (local _x) then { + if (_x isKindOf "zZombie_Base") then + { + _x call dayz_perform_purge; + uiSleep 0.05; + _delQtyZ = _delQtyZ + 1; + } else { + if (_x isKindOf "CAManBase") then { + _deathTime = _x getVariable ["processedDeath", diag_tickTime]; + if (diag_tickTime - _deathTime > 1800) then { + _x call dayz_perform_purge_player; + uiSleep 0.025; + _delQtyP = _delQtyP + 1; + }; + }; + }; + }; + uiSleep 0.025; + } count _allDead; + if (_delQtyZ > 0 || _delQtyP > 0) then { + _qty = count _allDead; + diag_log (format["CLEANUP: Deleted %1 players && %2 zombies out of %3 dead",_delQtyP,_delQtyZ,_qty]); + }; +}; +server_cleanupGroups = { + if (DZE_DYN_AntiStuck3rd > 3) then { DZE_DYN_GroupCleanup = nil; DZE_DYN_AntiStuck3rd = 0; }; + if(!isNil "DZE_DYN_GroupCleanup") exitWith { DZE_DYN_AntiStuck3rd = DZE_DYN_AntiStuck3rd + 1;}; + DZE_DYN_GroupCleanup = true; + { + if ((count (units _x) == 0) && (_x != grpNull)) then { + deleteGroup _x; + }; + uiSleep 0.001; + } count allGroups; + DZE_DYN_GroupCleanup = nil; +}; + +server_checkHackers = { + if (DZE_DYN_AntiStuck2nd > 3) then { DZE_DYN_HackerCheck = nil; DZE_DYN_AntiStuck2nd = 0; }; + if(!isNil "DZE_DYN_HackerCheck") exitWith { DZE_DYN_AntiStuck2nd = DZE_DYN_AntiStuck2nd + 1;}; + DZE_DYN_HackerCheck = true; + { + if (!((isNil "_x") || {(isNull _x)})) then { + if(vehicle _x != _x && !(vehicle _x in PVDZE_serverObjectMonitor) && (isPlayer _x) && !((typeOf vehicle _x) in DZE_safeVehicle)) then { + diag_log ("CLEANUP: KILLING A HACKER " + (name _x) + " " + str(_x) + " IN " + (typeOf vehicle _x)); + (vehicle _x) setDamage 1; + _x setDamage 1; + uiSleep 0.25; + }; + }; + uiSleep 0.001; + } count allUnits; + DZE_DYN_HackerCheck = nil; +}; + +server_spawnCleanFire = { + private ["_delQtyFP","_qty","_missionFires"]; + _missionFires = allMissionObjects "Land_Fire_DZ"; + _delQtyFP = 0; + { + if (local _x) then { + deleteVehicle _x; + uiSleep 0.025; + _delQtyFP = _delQtyFP + 1; + }; + uiSleep 0.001; + } count _missionFires; + if (_delQtyFP > 0) then { + _qty = count _missionFires; + diag_log (format["CLEANUP: Deleted %1 fireplaces out of %2",_delQtyFP,_qty]); + }; +}; +server_spawnCleanLoot = { + private ["_created","_delQty","_nearby","_age","_keep","_qty","_missionObjs","_dateNow"]; + if (DZE_DYN_AntiStuck > 3) then { DZE_DYN_cleanLoot = nil; DZE_DYN_AntiStuck = 0; }; + if(!isNil "DZE_DYN_cleanLoot") exitWith { DZE_DYN_AntiStuck = DZE_DYN_AntiStuck + 1;}; + DZE_DYN_cleanLoot = true; + + _missionObjs = allMissionObjects "ReammoBox"; + _delQty = 0; + _dateNow = (DateToNumber date); + { + if (!isNull _x) then { + _keep = _x getVariable["permaLoot", false]; + if (!_keep) then { + _created = _x getVariable["created", -0.1]; + if (_created == -0.1) then{ + _x setVariable["created", _dateNow, false]; + _created = _dateNow; + } + else { + _age = (_dateNow - _created) * 525948; + if (_age > 20) then{ + _nearby = { (isPlayer _x) && (alive _x) } count(_x nearEntities[["CAManBase", "AllVehicles"], 130]); + if (_nearby == 0) then{ + deleteVehicle _x; + uiSleep 0.025; + _delQty = _delQty + 1; + }; + }; + }; + }; + }; + uiSleep 0.001; + } forEach _missionObjs; + if (_delQty > 0) then { + _qty = count _missionObjs; + diag_log (format["CLEANUP: Deleted %1 Loot Piles out of %2",_delQty,_qty]); + }; + DZE_DYN_cleanLoot = nil; +}; + +server_spawnCleanAnimals = { + private ["_pos","_delQtyAnimal","_qty","_missonAnimals","_nearby"]; + _missonAnimals = entities "CAAnimalBase"; + _delQtyAnimal = 0; + { + if (local _x) then { + _x call dayz_perform_purge; + uiSleep 0.05; + _delQtyAnimal = _delQtyAnimal + 1; + } else { + if (!alive _x) then { + _pos = getPosATL _x; + if (count _pos > 0) then { + _nearby = {(isPlayer _x) && (alive _x)} count (_pos nearEntities [["CAManBase","AllVehicles"], 130]); + if (_nearby==0) then { + _x call dayz_perform_purge; + uiSleep 0.05; + _delQtyAnimal = _delQtyAnimal + 1; + }; + }; + }; + }; + uiSleep 0.001; + } forEach _missonAnimals; + if (_delQtyAnimal > 0) then { + _qty = count _missonAnimals; + diag_log (format["CLEANUP: Deleted %1 Animals out of %2",_delQtyAnimal,_qty]); + }; +}; + +server_logUnlockLockEvent = { + private["_player", "_obj", "_objectID", "_objectUID", "_statusText", "_PUID", "_status", "_clientID", "_type"]; + _player = _this select 0; + _obj = _this select 1; + _status = _this select 2; + _type = typeOf _obj; + if (isNull _player) then {diag_log "ERROR: server_logUnlockLockEvent called with Null player object";}; + _clientID = owner _player; + _PUID = [_player] call FNC_GetPlayerUID; + _statusText = if (_status) then {"LOCKED"} else {"UNLOCKED"}; + + if (!isNull _obj) then { + _objectID = _obj getVariable["ObjectID", "0"]; + _objectUID = _obj getVariable["ObjectUID", "0"]; + + if (_status) then {[_obj, "gear"] call server_updateObject;}; + diag_log format["%6 %5: ID:%1 UID:%2 BY %3(%4)",_objectID,_objectUID,name _player,_PUID,_statusText,_type]; + dze_waiting = "success"; + _clientID publicVariableClient "dze_waiting"; + } else { + diag_log format["ERROR: %4 BY %1(%2) IS NULL AND COULD NOT BE %3 (THIS SHOULD NOT HAPPEN)",name _player,_PUID,_statusText,_type]; + dze_waiting = "fail"; + _clientID publicVariableClient "dze_waiting"; + }; +}; diff --git a/SQF/dayz_server/init/server_functions.sqf b/SQF/dayz_server/init/server_functions.sqf index a2e6e0195..79c82ba2f 100644 --- a/SQF/dayz_server/init/server_functions.sqf +++ b/SQF/dayz_server/init/server_functions.sqf @@ -1,3 +1,5 @@ +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" + waituntil {!isnil "bis_fnc_init"}; BIS_MPF_remoteExecutionServer = { @@ -7,6 +9,7 @@ BIS_MPF_remoteExecutionServer = { }; BIS_Effects_Burn = {}; +dayz_disconnectPlayers = []; server_playerLogin = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_playerLogin.sqf"; server_playerSetup = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_playerSetup.sqf"; server_onPlayerDisconnect = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_onPlayerDisconnect.sqf"; @@ -21,87 +24,62 @@ server_publishVeh3 = compile preprocessFileLineNumbers "\z\addons\dayz_server server_tradeObj = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_tradeObject.sqf"; server_traders = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_traders.sqf"; server_playerSync = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_playerSync.sqf"; -server_spawnCrashSite = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_spawnCrashSite.sqf"; +//server_spawnCrashSite = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_spawnCrashSite.sqf"; server_spawnEvents = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_spawnEvent.sqf"; //server_weather = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_weather.sqf"; fnc_plyrHit = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\fnc_plyrHit.sqf"; server_deaths = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_playerDeaths.sqf"; server_maintainArea = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_maintainArea.sqf"; +zombie_findOwner = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\zombie_findOwner.sqf"; +server_updateNearbyObjects = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_updateNearbyObjects.sqf"; +server_Wildgenerate = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\zombie_Wildgenerate.sqf"; +server_plantSpawner = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_plantSpawner.sqf"; +base_fireMonitor = compile preprocessFileLineNumbers "\z\addons\dayz_code\system\fire_monitor.sqf"; +server_systemCleanup = compile preprocessFileLineNumbers "\z\addons\dayz_server\system\server_cleanup.sqf"; + +spawnComposition = compile preprocessFileLineNumbers "ca\modules\dyno\data\scripts\objectMapper.sqf"; //"\z\addons\dayz_code\compile\object_mapper.sqf"; /* PVS/PVC - Skaronator */ -server_sendToClient = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_sendToClient.sqf"; - -//onPlayerConnected {[_uid,_name] call server_onPlayerConnect;}; -onPlayerDisconnected {[_uid,_name] call server_onPlayerDisconnect;}; - -server_updateNearbyObjects = { - private["_pos"]; - _pos = _this select 0; - { - [_x, "gear"] call server_updateObject; - } count nearestObjects [_pos, dayz_updateObjects, 10]; +server_sendToClient = compile preprocessFileLineNumbers "\z\addons\dayz_server\eventHandlers\server_sendToClient.sqf"; +server_medicalSync = { + _player = _this select 0; + _array = _this select 1; + + _player setVariable["USEC_isDead",(_array select 0)]; //0 + _player setVariable["NORRN_unconscious", (_array select 1)]; //1 + _player setVariable["USEC_infected",(_array select 2)]; //2 + _player setVariable["USEC_injured",(_array select 3)]; //3 + _player setVariable["USEC_inPain",(_array select 4)]; //4 + _player setVariable["USEC_isCardiac",(_array select 5)]; //5 + _player setVariable["USEC_lowBlood",(_array select 6)]; //6 + _player setVariable["USEC_BloodQty",(_array select 7)]; //7 +// _wounds; //8 +// [_legs,_arms]; //9 + _player setVariable["unconsciousTime",(_array select 10)]; //10 + _player setVariable["blood_type",(_array select 11)]; //11 + _player setVariable["rh_factor",(_array select 12)]; //12 + _player setVariable["messing",(_array select 13)]; //13 + _player setVariable["blood_testdone",(_array select 14)]; //14 }; -server_handleZedSpawn = { - private["_zed"]; - _zed = _this select 0; - _zed enableSimulation false; +dayz_Achievements = { + _achievementID = (_this select 0) select 0; + _player = (_this select 0) select 1; + _playerOwnerID = owner _player; + + _achievements = _player getVariable "Achievements"; + + _achievements set [_achievementID,1]; + + _player setVariable ["Achievements",_achievements]; }; -zombie_findOwner = { - private["_unit"]; - _unit = _this select 0; - #ifdef DZE_SERVER_DEBUG - diag_log ("CLEANUP: DELETE UNCONTROLLED ZOMBIE: " + (typeOf _unit) + " OF: " + str(_unit) ); - #endif - deleteVehicle _unit; -}; - -vehicle_handleInteract = { - private["_object"]; - _object = _this select 0; - needUpdate_objects = needUpdate_objects - [_object]; - [_object, "all"] call server_updateObject; -}; - -array_reduceSizeReverse = { - private["_array","_count","_num","_newarray","_startnum","_index"]; - _array = _this select 0; - _newarray = []; - _count = _this select 1; - _num = count _array; - if (_num > _count) then { - _startnum = _num - 1; - _index = _count - 1; - for "_i" from 0 to _index do { - _newarray set [(_index-_i),_array select (_startnum - _i)]; - }; - _array = _newarray; - }; - _array -}; - -array_reduceSize = { - private ["_array1","_array","_count","_num"]; - _array1 = _this select 0; - _array = _array1 - ["Hatchet_Swing","Machete_Swing","Fishing_Swing","sledge_swing","crowbar_swing","CSGAS"]; - _count = _this select 1; - _num = count _array; - if (_num > _count) then { - _array resize _count; - }; - _array -}; - -object_handleServerKilled = { - private["_unit","_objectID","_objectUID","_killer"]; +vehicle_handleServerKilled = { + private["_unit","_killer"]; _unit = _this select 0; _killer = _this select 1; - - _objectID = _unit getVariable ["ObjectID","0"]; - _objectUID = _unit getVariable ["ObjectUID","0"]; - [_objectID,_objectUID,_killer] call server_deleteObj; + [_unit, "killed"] call server_updateObject; _unit removeAllMPEventHandlers "MPKilled"; _unit removeAllEventHandlers "Killed"; @@ -111,17 +89,32 @@ object_handleServerKilled = { }; check_publishobject = { - private["_allowed","_object","_playername"]; + private ["_saveObject","_allowed","_allowedObjects","_object","_playername"]; _object = _this select 0; _playername = _this select 1; _allowed = false; - if ((typeOf _object) in dayz_allowedObjects) then { - //diag_log format ["DEBUG: Object: %1 published by %2 is Safe",_object, _playername]; - _allowed = true; +#ifdef OBJECT_DEBUG + diag_log format ["DEBUG: Checking if Object: %1 is allowed, published by %2", _object, _playername]; +#endif + + if ((typeOf _object) in DayZ_SafeObjects) then { + _saveObject = "DayZ_SafeObjects"; + _allowed = true; }; - _allowed + + //Buildings + if (_object iskindof "DZ_buildables") then { + _saveObject = "DZ_buildables"; + _allowed = true; + }; + + #ifdef OBJECT_DEBUG + diag_log format ["DEBUG: Object: %1 published by %2 is allowed by %3",_object, _playername, _saveObject]; + #endif + + _allowed }; //event Handlers @@ -168,387 +161,7 @@ server_hiveReadWrite = { _resultArray }; -server_hiveReadWriteLarge = { - private["_key","_resultArray","_data"]; - _key = _this; - _data = "HiveExt" callExtension _key; - _resultArray = call compile _data; - _resultArray -}; - -server_checkIfTowed = { - private ["_vehicle","_player","_attached"]; - if (DZE_HeliLift) then { - _vehicle = _this select 0; - _player = _this select 2; - _attached = _vehicle getVariable["attached",false]; - if (typeName _attached == "OBJECT") then { - _player action ["eject", _vehicle]; - detach _vehicle; - _vehicle setVariable["attached",false,true]; - _attached setVariable["hasAttached",false,true]; - }; - }; -}; - -server_characterSync = { - private ["_characterID","_playerPos","_playerGear","_playerBackp","_medical","_currentState","_currentModel","_key"]; - _characterID = _this select 0; - _playerPos = _this select 1; - _playerGear = _this select 2; - _playerBackp = _this select 3; - _medical = _this select 4; - _currentState = _this select 5; - _currentModel = _this select 6; - - _key = format["CHILD:201:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:",_characterID,_playerPos,_playerGear,_playerBackp,_medical,false,false,0,0,0,0,_currentState,0,0,_currentModel,0]; - _key call server_hiveWrite; -}; - -if(isnil "dayz_MapArea") then { - dayz_MapArea = 10000; -}; -if(isnil "DynamicVehicleArea") then { - DynamicVehicleArea = dayz_MapArea / 2; -}; - -// Get all buildings && roads only once TODO: set variables to nil after done if nessicary -MarkerPosition = getMarkerPos "center"; -RoadList = MarkerPosition nearRoads DynamicVehicleArea; - -// Very taxing !!! but only on first startup -BuildingList = []; -{ - if (DZE_MissionLootTable) then { - if (isClass (missionConfigFile >> "CfgBuildingLoot" >> (typeOf _x))) then - { - BuildingList set [count BuildingList,_x]; - }; - } else { - if (isClass (configFile >> "CfgBuildingLoot" >> (typeOf _x))) then - { - BuildingList set [count BuildingList,_x]; - }; - }; - - -} count (MarkerPosition nearObjects ["building",DynamicVehicleArea]); - -spawn_vehicles = { - private ["_random","_lastIndex","_weights","_index","_vehicle","_velimit","_qty","_isAir","_isShip","_position","_dir","_istoomany","_veh","_objPosition","_marker","_iClass","_itemTypes","_cntWeights","_itemType","_num","_allCfgLoots"]; - - if (!isDedicated) exitWith { }; //Be sure the run this - - while {count AllowedVehiclesList > 0} do { - // BIS_fnc_selectRandom replaced because the index may be needed to remove the element - _index = floor random count AllowedVehiclesList; - _random = AllowedVehiclesList select _index; - - _vehicle = _random select 0; - _velimit = _random select 1; - - _qty = {_x == _vehicle} count serverVehicleCounter; - - // If under limit allow to proceed - if (_qty <= _velimit) exitWith {}; - - // vehicle limit reached, remove vehicle from list - // since elements cannot be removed from an array, overwrite it with the last element && cut the last element of (as long as order is not important) - _lastIndex = (count AllowedVehiclesList) - 1; - if (_lastIndex != _index) then { - AllowedVehiclesList set [_index, AllowedVehiclesList select _lastIndex]; - }; - AllowedVehiclesList resize _lastIndex; - }; - - if (count AllowedVehiclesList == 0) then { - diag_log("DEBUG: unable to find suitable vehicle to spawn"); - } else { - - // add vehicle to counter for next pass - serverVehicleCounter set [count serverVehicleCounter,_vehicle]; - - // Find Vehicle Type to better control spawns - _isAir = _vehicle isKindOf "Air"; - _isShip = _vehicle isKindOf "Ship"; - - if(_isShip || _isAir) then { - if(_isShip) then { - // Spawn anywhere on coast on water - waitUntil{!isNil "BIS_fnc_findSafePos"}; - _position = [MarkerPosition,0,DynamicVehicleArea,10,1,2000,1] call BIS_fnc_findSafePos; - //diag_log("DEBUG: spawning boat near coast " + str(_position)); - } else { - // Spawn air anywhere that is flat - waitUntil{!isNil "BIS_fnc_findSafePos"}; - _position = [MarkerPosition,0,DynamicVehicleArea,10,0,2000,0] call BIS_fnc_findSafePos; - //diag_log("DEBUG: spawning air anywhere flat " + str(_position)); - }; - - - } else { - // Spawn around buildings && 50% near roads - if((random 1) > 0.5) then { - - waitUntil{!isNil "BIS_fnc_selectRandom"}; - _position = RoadList call BIS_fnc_selectRandom; - - _position = _position modelToWorld [0,0,0]; - - waitUntil{!isNil "BIS_fnc_findSafePos"}; - _position = [_position,0,10,10,0,2000,0] call BIS_fnc_findSafePos; - - //diag_log("DEBUG: spawning near road " + str(_position)); - - } else { - - waitUntil{!isNil "BIS_fnc_selectRandom"}; - _position = BuildingList call BIS_fnc_selectRandom; - - _position = _position modelToWorld [0,0,0]; - - waitUntil{!isNil "BIS_fnc_findSafePos"}; - _position = [_position,0,40,5,0,2000,0] call BIS_fnc_findSafePos; - - //diag_log("DEBUG: spawning around buildings " + str(_position)); - - }; - }; - // only proceed if two params otherwise BIS_fnc_findSafePos failed && may spawn in air - if ((count _position) == 2) then { - - _dir = round(random 180); - - _istoomany = _position nearObjects ["AllVehicles",50]; - if((count _istoomany) > 0) exitWith { diag_log("DEBUG: Too many vehicles at " + str(_position)); }; - - //place vehicle - _veh = createVehicle [_vehicle, _position, [], 0, "CAN_COLLIDE"]; - _veh setdir _dir; - _veh setpos _position; - - if(DZEdebug) then { - _marker = createMarker [str(_position) , _position]; - _marker setMarkerShape "ICON"; - _marker setMarkerType "DOT"; - _marker setMarkerText _vehicle; - }; - - // Get position with ground - _objPosition = getPosATL _veh; - - clearWeaponCargoGlobal _veh; - clearMagazineCargoGlobal _veh; - // _veh setVehicleAmmo DZE_vehicleAmmo; - - // Add 0-3 loots to vehicle using random cfgloots - _num = floor(random 4); - _allCfgLoots = ["trash","civilian","food","generic","medical","military","policeman","hunter","worker","clothes","militaryclothes","specialclothes","trash"]; - - for "_x" from 1 to _num do { - _iClass = _allCfgLoots call BIS_fnc_selectRandom; - - _itemTypes = []; - if (DZE_MissionLootTable) then{ - { - _itemTypes set[count _itemTypes, _x select 0] - } count getArray(missionConfigFile >> "cfgLoot" >> _iClass); - } - else { - { - _itemTypes set[count _itemTypes, _x select 0] - } count getArray(configFile >> "cfgLoot" >> _iClass); - }; - - _index = dayz_CLBase find _iClass; - _weights = dayz_CLChances select _index; - _cntWeights = count _weights; - - _index = floor(random _cntWeights); - _index = _weights select _index; - _itemType = _itemTypes select _index; - _veh addMagazineCargoGlobal [_itemType,1]; - //diag_log("DEBUG: spawed loot inside vehicle " + str(_itemType)); - }; - - [_veh,[_dir,_objPosition],_vehicle,true,"0"] call server_publishVeh; - }; - }; -}; - -spawn_ammosupply = { - private ["_position","_veh","_istoomany","_marker","_spawnveh","_WreckList"]; - if (isDedicated) then { - _WreckList = ["Supply_Crate_DZE"]; - waitUntil{!isNil "BIS_fnc_selectRandom"}; - _position = RoadList call BIS_fnc_selectRandom; - _position = _position modelToWorld [0,0,0]; - waitUntil{!isNil "BIS_fnc_findSafePos"}; - _position = [_position,5,20,5,0,2000,0] call BIS_fnc_findSafePos; - if ((count _position) == 2) then { - - _istoomany = _position nearObjects ["All",5]; - - if((count _istoomany) > 0) exitWith { diag_log("DEBUG VEIN: Too many at " + str(_position)); }; - - _spawnveh = _WreckList call BIS_fnc_selectRandom; - - if(DZEdebug) then { - _marker = createMarker [str(_position) , _position]; - _marker setMarkerShape "ICON"; - _marker setMarkerType "DOT"; - _marker setMarkerText str(_spawnveh); - }; - - _veh = createVehicle [_spawnveh,_position, [], 0, "CAN_COLLIDE"]; - _veh enableSimulation false; - _veh setDir round(random 360); - _veh setpos _position; - _veh setVariable ["ObjectID","1",true]; - }; - }; -}; - -DZE_LocalRoadBlocks = []; - -spawn_roadblocks = { - private ["_position","_veh","_istoomany","_marker","_spawnveh","_WreckList"]; - _WreckList = ["SKODAWreck","HMMWVWreck","UralWreck","datsun01Wreck","hiluxWreck","datsun02Wreck","UAZWreck","Land_Misc_Garb_Heap_EP1","Fort_Barricade_EP1","Rubbish2"]; - - waitUntil{!isNil "BIS_fnc_selectRandom"}; - if (isDedicated) then { - - _position = RoadList call BIS_fnc_selectRandom; - - _position = _position modelToWorld [0,0,0]; - - waitUntil{!isNil "BIS_fnc_findSafePos"}; - _position = [_position,0,10,5,0,2000,0] call BIS_fnc_findSafePos; - - if ((count _position) == 2) then { - // Get position with ground - - _istoomany = _position nearObjects ["All",5]; - - if((count _istoomany) > 0) exitWith { diag_log("DEBUG: Too many at " + str(_position)); }; - - waitUntil{!isNil "BIS_fnc_selectRandom"}; - _spawnveh = _WreckList call BIS_fnc_selectRandom; - - if(DZEdebug) then { - _marker = createMarker [str(_position) , _position]; - _marker setMarkerShape "ICON"; - _marker setMarkerType "DOT"; - _marker setMarkerText str(_spawnveh); - }; - - _veh = createVehicle [_spawnveh,_position, [], 0, "CAN_COLLIDE"]; - _veh enableSimulation false; - - _veh setDir round(random 360); // Randomize placement a bit - _veh setpos _position; - - _veh setVariable ["ObjectID","1",true]; - }; - - }; - -}; - -spawn_mineveins = { - private ["_position","_veh","_istoomany","_marker","_spawnveh","_positions"]; - - if (isDedicated) then { - - _position = [getMarkerPos "center",0,(HeliCrashArea*0.75),10,0,2000,0] call BIS_fnc_findSafePos; - - if ((count _position) == 2) then { - - _positions = selectBestPlaces [_position, 500, "(1 + forest) * (1 + hills) * (1 - houses) * (1 - sea)", 10, 5]; - - _position = (_positions call BIS_fnc_selectRandom) select 0; - - // Get position with ground - _istoomany = _position nearObjects ["All",10]; - - if((count _istoomany) > 0) exitWith { diag_log("DEBUG VEIN: Too many objects at " + str(_position)); }; - - if(isOnRoad _position) exitWith { diag_log("DEBUG VEIN: on road " + str(_position)); }; - - _spawnveh = ["Iron_Vein_DZE","Iron_Vein_DZE","Iron_Vein_DZE","Iron_Vein_DZE","Iron_Vein_DZE","Silver_Vein_DZE","Silver_Vein_DZE","Silver_Vein_DZE","Gold_Vein_DZE","Gold_Vein_DZE"] call BIS_fnc_selectRandom; - - if(DZEdebug) then { - _marker = createMarker [str(_position) , _position]; - _marker setMarkerShape "ICON"; - _marker setMarkerType "DOT"; - _marker setMarkerText str(_spawnveh); - }; - - //diag_log("DEBUG: Spawning a crashed " + _spawnveh + " with " + _spawnloot + " at " + str(_position)); - _veh = createVehicle [_spawnveh,_position, [], 0, "CAN_COLLIDE"]; - _veh enableSimulation false; - - // Randomize placement a bit - _veh setDir round(random 360); - _veh setpos _position; - - _veh setVariable ["ObjectID","1",true]; - - - }; - }; -}; - -if(isnil "DynamicVehicleDamageLow") then { - DynamicVehicleDamageLow = 0; -}; -if(isnil "DynamicVehicleDamageHigh") then { - DynamicVehicleDamageHigh = 100; -}; - -if(isnil "DynamicVehicleFuelLow") then { - DynamicVehicleFuelLow = 0; -}; -if(isnil "DynamicVehicleFuelHigh") then { - DynamicVehicleFuelHigh = 100; -}; - -if(isnil "DZE_DiagFpsSlow") then { - DZE_DiagFpsSlow = false; -}; -if(isnil "DZE_DiagFpsFast") then { - DZE_DiagFpsFast = false; -}; -if(isnil "DZE_DiagVerbose") then { - DZE_DiagVerbose = false; -}; - -dze_diag_fps = { - if(DZE_DiagVerbose) then { - diag_log format["DEBUG FPS : %1 OBJECTS: %2 : PLAYERS: %3", diag_fps,(count (allMissionObjects "")),(playersNumber west)]; - } else { - diag_log format["DEBUG FPS : %1", diag_fps]; - }; -}; - -// Damage generator function -generate_new_damage = { - private ["_damage"]; - _damage = ((random(DynamicVehicleDamageHigh-DynamicVehicleDamageLow))+DynamicVehicleDamageLow) / 100; - _damage; -}; - -// Damage generator fuction -generate_exp_damage = { - private ["_damage"]; - _damage = ((random(DynamicVehicleDamageHigh-DynamicVehicleDamageLow))+DynamicVehicleDamageLow) / 100; - - // limit this to 85% since vehicle would blow up otherwise. - //if(_damage >= 0.85) then { - // _damage = 0.85; - //}; - _damage; -}; +onPlayerDisconnected {[_uid,_name] call server_onPlayerDisconnect;}; server_getDiff = { private["_variable","_object","_vNew","_vOld","_result"]; @@ -579,55 +192,16 @@ server_getDiff2 = { _result }; -currentObjectUIDs = []; -keyStartNumber = 100000000000; - -dayz_objectUID = { - private["_position","_dir","_key","_object"]; - _object = _this; - _position = getPosATL _object; - _dir = direction _object; - _key = [_dir,_position] call dayz_objectUID2; - _key -}; - dayz_objectUID2 = { - private["_position","_dir","_key"]; - _dir = _this select 0; - _key = ""; - _position = _this select 1; - { - _x = _x * 10; - if ( _x < 0 ) then { _x = _x * -10 }; - _key = _key + str(round(_x)); - } count _position; - _key = _key + str(round(_dir)); - // Make sure the generated key is not a duplicate - while {true} do { - if !(_key in currentObjectUIDs) exitWith {currentObjectUIDs set [count currentObjectUIDs,_key];}; - keyStartNumber = keyStartNumber + 1; - _key = str keyStartNumber; - }; - _key -}; - -dayz_objectUID3 = { - private["_position","_dir","_key"]; - _dir = _this select 0; - _key = ""; - _position = _this select 1; - { - _x = _x * 10; - if ( _x < 0 ) then { _x = _x * -10 }; - _key = _key + str(round(_x)); - } count _position; - _key = _key + str(round(_dir + time)); - // Make sure the generated key is not a duplicate - while {true} do { - if !(_key in currentObjectUIDs) exitWith {currentObjectUIDs set [count currentObjectUIDs,_key];}; - keyStartNumber = keyStartNumber + 1; - _key = str keyStartNumber; - }; + private["_p","_d","_key"]; + _d = _this select 0; + _p = _this select 1; + _key = format [ "%1%2%3%4", + abs round(10 * (_p select 0)), + abs round(10 * (_p select 1)), + abs round(100 * (_p select 2)), + abs round((_d * diag_tickTime) % 1000) + ]; _key }; @@ -637,307 +211,20 @@ dayz_recordLogin = { _key call server_hiveWrite; }; -dayz_perform_purge = { - if(!isNull(_this)) then { - _group = group _this; - _this removeAllMPEventHandlers "mpkilled"; - _this removeAllMPEventHandlers "mphit"; - _this removeAllMPEventHandlers "mprespawn"; - _this removeAllEventHandlers "FiredNear"; - _this removeAllEventHandlers "HandleDamage"; - _this removeAllEventHandlers "Killed"; - _this removeAllEventHandlers "Fired"; - _this removeAllEventHandlers "GetOut"; - _this removeAllEventHandlers "GetIn"; - _this removeAllEventHandlers "Local"; - clearVehicleInit _this; - deleteVehicle _this; - if ((count (units _group) == 0) && (_group != grpNull)) then { - deleteGroup _group; - }; - }; -}; - -dayz_perform_purge_player = { - - private ["_countr","_backpack","_backpackType","_backpackWpn","_backpackMag","_objWpnTypes","_objWpnQty","_location","_dir","_holder","_weapons","_magazines"]; - diag_log ("Purging player: " + str(_this)); - - if(!isNull(_this)) then { - - _location = getPosATL _this; - _dir = getDir _this; - - _holder = createVehicle ["GraveDZE", _location, [], 0, "CAN_COLLIDE"]; - _holder setDir _dir; - _holder setPosATL _location; - - _holder enableSimulation false; - - _weapons = weapons _this; - _magazines = magazines _this; - - // find backpack - if(!(isNull unitBackpack _this)) then { - _backpack = unitBackpack _this; - _backpackType = typeOf _backpack; - _backpackWpn = getWeaponCargo _backpack; - _backpackMag = getMagazineCargo _backpack; - - _holder addBackpackCargoGlobal [_backpackType,1]; - - // add items from backpack - _objWpnTypes = _backpackWpn select 0; - _objWpnQty = _backpackWpn select 1; - _countr = 0; - { - _holder addWeaponCargoGlobal [_x,(_objWpnQty select _countr)]; - _countr = _countr + 1; - } count _objWpnTypes; - - // add backpack magazine items - _objWpnTypes = _backpackMag select 0; - _objWpnQty = _backpackMag select 1; - _countr = 0; - { - _holder addMagazineCargoGlobal [_x,(_objWpnQty select _countr)]; - _countr = _countr + 1; - } count _objWpnTypes; - }; - }; - - // add weapons - { - _holder addWeaponCargoGlobal [_x, 1]; - } count _weapons; - - // add mags - { - _holder addMagazineCargoGlobal [_x, 1]; - } count _magazines; - _group = group _this; - _this removeAllMPEventHandlers "mpkilled"; - _this removeAllMPEventHandlers "mphit"; - _this removeAllMPEventHandlers "mprespawn"; - _this removeAllEventHandlers "FiredNear"; - _this removeAllEventHandlers "HandleDamage"; - _this removeAllEventHandlers "Killed"; - _this removeAllEventHandlers "Fired"; - _this removeAllEventHandlers "GetOut"; - _this removeAllEventHandlers "GetIn"; - _this removeAllEventHandlers "Local"; - clearVehicleInit _this; - deleteVehicle _this; - if ((count (units _group) == 0) && (_group != grpNull)) then { - deleteGroup _group; - }; - // _this = nil; -}; - - -dayz_removePlayerOnDisconnect = { - if(!isNull(_this)) then { - _group = group _this; - _this removeAllMPEventHandlers "mphit"; - deleteVehicle _this; - deleteGroup (group _this); - }; -}; - -server_timeSync = { - //Send request - private ["_hour","_minute","_date","_key","_result","_outcome"]; - _key = "CHILD:307:"; - _result = _key call server_hiveReadWrite; - _outcome = _result select 0; - if(_outcome == "PASS") then { - _date = _result select 1; - - if(dayz_fullMoonNights) then { - _hour = _date select 3; - _minute = _date select 4; - //Force full moon nights - _date = [2013,8,3,_hour,_minute]; - }; - - setDate _date; - PVDZE_plr_SetDate = _date; - publicVariable "PVDZE_plr_SetDate"; - diag_log ("TIME SYNC: Local Time set to " + str(_date)); - }; -}; - -// must spawn these -server_spawncleanDead = { - private ["_deathTime","_delQtyZ","_delQtyP","_qty","_allDead"]; - _allDead = allDead; - _delQtyZ = 0; - _delQtyP = 0; - { - if (local _x) then { - if (_x isKindOf "zZombie_Base") then - { - _x call dayz_perform_purge; - uiSleep 0.05; - _delQtyZ = _delQtyZ + 1; - } else { - if (_x isKindOf "CAManBase") then { - _deathTime = _x getVariable ["processedDeath", diag_tickTime]; - if (diag_tickTime - _deathTime > 1800) then { - _x call dayz_perform_purge_player; - uiSleep 0.025; - _delQtyP = _delQtyP + 1; - }; - }; - }; - }; - uiSleep 0.025; - } count _allDead; - if (_delQtyZ > 0 || _delQtyP > 0) then { - _qty = count _allDead; - diag_log (format["CLEANUP: Deleted %1 players && %2 zombies out of %3 dead",_delQtyP,_delQtyZ,_qty]); - }; -}; -server_cleanupGroups = { - if (DZE_DYN_AntiStuck3rd > 3) then { DZE_DYN_GroupCleanup = nil; DZE_DYN_AntiStuck3rd = 0; }; - if(!isNil "DZE_DYN_GroupCleanup") exitWith { DZE_DYN_AntiStuck3rd = DZE_DYN_AntiStuck3rd + 1;}; - DZE_DYN_GroupCleanup = true; - { - if ((count (units _x) == 0) && (_x != grpNull)) then { - deleteGroup _x; - }; - uiSleep 0.001; - } count allGroups; - DZE_DYN_GroupCleanup = nil; -}; - -server_checkHackers = { - if (DZE_DYN_AntiStuck2nd > 3) then { DZE_DYN_HackerCheck = nil; DZE_DYN_AntiStuck2nd = 0; }; - if(!isNil "DZE_DYN_HackerCheck") exitWith { DZE_DYN_AntiStuck2nd = DZE_DYN_AntiStuck2nd + 1;}; - DZE_DYN_HackerCheck = true; - { - if (!((isNil "_x") || {(isNull _x)})) then { - if(vehicle _x != _x && !(vehicle _x in PVDZE_serverObjectMonitor) && (isPlayer _x) && !((typeOf vehicle _x) in DZE_safeVehicle)) then { - diag_log ("CLEANUP: KILLING A HACKER " + (name _x) + " " + str(_x) + " IN " + (typeOf vehicle _x)); - (vehicle _x) setDamage 1; - _x setDamage 1; - uiSleep 0.25; - }; - }; - uiSleep 0.001; - } count allUnits; - DZE_DYN_HackerCheck = nil; -}; - -server_spawnCleanFire = { - private ["_delQtyFP","_qty","_missionFires"]; - _missionFires = allMissionObjects "Land_Fire_DZ"; - _delQtyFP = 0; - { - if (local _x) then { - deleteVehicle _x; - uiSleep 0.025; - _delQtyFP = _delQtyFP + 1; - }; - uiSleep 0.001; - } count _missionFires; - if (_delQtyFP > 0) then { - _qty = count _missionFires; - diag_log (format["CLEANUP: Deleted %1 fireplaces out of %2",_delQtyFP,_qty]); - }; -}; -server_spawnCleanLoot = { - private ["_created","_delQty","_nearby","_age","_keep","_qty","_missionObjs","_dateNow"]; - if (DZE_DYN_AntiStuck > 3) then { DZE_DYN_cleanLoot = nil; DZE_DYN_AntiStuck = 0; }; - if(!isNil "DZE_DYN_cleanLoot") exitWith { DZE_DYN_AntiStuck = DZE_DYN_AntiStuck + 1;}; - DZE_DYN_cleanLoot = true; - - _missionObjs = allMissionObjects "ReammoBox"; - _delQty = 0; - _dateNow = (DateToNumber date); - { - if (!isNull _x) then { - _keep = _x getVariable["permaLoot", false]; - if (!_keep) then { - _created = _x getVariable["created", -0.1]; - if (_created == -0.1) then{ - _x setVariable["created", _dateNow, false]; - _created = _dateNow; - } - else { - _age = (_dateNow - _created) * 525948; - if (_age > 20) then{ - _nearby = { (isPlayer _x) && (alive _x) } count(_x nearEntities[["CAManBase", "AllVehicles"], 130]); - if (_nearby == 0) then{ - deleteVehicle _x; - uiSleep 0.025; - _delQty = _delQty + 1; - }; - }; - }; - }; - }; - uiSleep 0.001; - } forEach _missionObjs; - if (_delQty > 0) then { - _qty = count _missionObjs; - diag_log (format["CLEANUP: Deleted %1 Loot Piles out of %2",_delQty,_qty]); - }; - DZE_DYN_cleanLoot = nil; -}; - -server_spawnCleanAnimals = { - private ["_pos","_delQtyAnimal","_qty","_missonAnimals","_nearby"]; - _missonAnimals = entities "CAAnimalBase"; - _delQtyAnimal = 0; - { - if (local _x) then { - _x call dayz_perform_purge; - uiSleep 0.05; - _delQtyAnimal = _delQtyAnimal + 1; - } else { - if (!alive _x) then { - _pos = getPosATL _x; - if (count _pos > 0) then { - _nearby = {(isPlayer _x) && (alive _x)} count (_pos nearEntities [["CAManBase","AllVehicles"], 130]); - if (_nearby==0) then { - _x call dayz_perform_purge; - uiSleep 0.05; - _delQtyAnimal = _delQtyAnimal + 1; - }; - }; - }; - }; - uiSleep 0.001; - } forEach _missonAnimals; - if (_delQtyAnimal > 0) then { - _qty = count _missonAnimals; - diag_log (format["CLEANUP: Deleted %1 Animals out of %2",_delQtyAnimal,_qty]); - }; -}; - -server_logUnlockLockEvent = { - private["_player", "_obj", "_objectID", "_objectUID", "_statusText", "_PUID", "_status", "_clientID", "_type"]; - _player = _this select 0; - _obj = _this select 1; - _status = _this select 2; - _type = typeOf _obj; - if (isNull _player) then {diag_log "ERROR: server_logUnlockLockEvent called with Null player object";}; - _clientID = owner _player; - _PUID = [_player] call FNC_GetPlayerUID; - _statusText = if (_status) then {"LOCKED"} else {"UNLOCKED"}; +dayz_reseed = { + private ["_Loc","_i","_radius","_Ref"]; + _Loc = _this select 0; + _Ref = _this select 1; - if (!isNull _obj) then { - _objectID = _obj getVariable["ObjectID", "0"]; - _objectUID = _obj getVariable["ObjectUID", "0"]; - - if (_status) then {[_obj, "gear"] call server_updateObject;}; - diag_log format["%6 %5: ID:%1 UID:%2 BY %3(%4)",_objectID,_objectUID,name _player,_PUID,_statusText,_type]; - dze_waiting = "success"; - _clientID publicVariableClient "dze_waiting"; - } else { - diag_log format["ERROR: %4 BY %1(%2) IS NULL AND COULD NOT BE %3 (THIS SHOULD NOT HAPPEN)",name _player,_PUID,_statusText,_type]; - dze_waiting = "fail"; - _clientID publicVariableClient "dze_waiting"; - }; + diag_log(str(_Loc)); + + //_lootspawner =[[10416.695, 4198.4634],[7982.2563, 1419.8256],[10795.93, 1419.8263],[7966.083, 4088.7463],[9259.7266, 2746.1985],[5200.5234, 3915.3274],[6494.1665, 2572.7798],[5216.6968, 1246.407],[2564.7244, 3915.3296],[3858.3674, 2572.782],[2580.8977, 1246.4092],[13398.995, 4400.5874],[12242.025, 2948.3196],[13551.842, 1832.2257],[14870.512, 3009.5117],[-178.19415, 1062.4478],[1099.2754, 2388.8206],[-194.36755, 3731.3679],[10394.215, 8322.1719],[7959.7759, 5543.5342],[10773.449, 5543.5342],[7943.6025, 8212.4551],[9237.2461, 6869.9063],[5178.043, 8039.0361],[6471.686, 6696.4883],[5194.2163, 5370.1152],[2542.2439, 8039.0381],[3835.887, 6696.4902],[2558.4172, 5370.1172],[13376.514, 8524.2969],[12219.544, 7072.0273],[13529.361, 5955.9336],[14848.032, 7133.2197],[-200.67474, 5186.1563],[1076.7949, 6512.5283],[-216.84814, 7855.0771],[10293.751, 12197.736],[7859.312, 9419.0996],[10672.988, 9419.0996],[7843.1387, 12088.021],[9136.7822, 10745.474],[5077.5791, 11914.601],[6371.2222, 10572.052],[5093.7524, 9245.6816],[2441.78, 11914.604],[3735.4231, 10572.055],[2457.9534, 9245.6816],[13276.053, 12399.861],[12119.08, 10947.596],[13428.897, 9831.501],[14747.566, 11008.786],[-301.13867, 9061.7207],[976.33112, 10388.096],[-317.31201, 11730.642],[10271.271, 16321.429],[7836.8315, 13542.813],[10650.506, 13542.813],[7820.6582, 16211.718],[9114.3018, 14869.175],[5055.0986, 16038.3],[6348.7417, 14695.758],[5071.272, 13369.392],[2419.2996, 16038.305],[3712.9426, 14695.76],[2435.4729, 13369.392],[13253.568, 16523.553],[12096.6, 15071.295],[13406.416, 13955.209],[14725.089, 15132.486],[-323.61914, 13185.43],[953.85059, 14511.8],[-339.79248, 15854.346]]; + //{ + _radius = 1500; + dayz_lootspawner = [_Loc,_radius,_Ref] spawn server_lootSpawner; + waitUntil {scriptDone dayz_lootspawner}; + //} foreach dayz_grid; }; + +call compile preprocessFileLineNumbers "\z\addons\dayz_server\init\Epoch_Init.sqf"; +call compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\fa_hiveMaintenance.sqf"; \ No newline at end of file diff --git a/SQF/dayz_server/system/lit_fireplaces.sqf b/SQF/dayz_server/system/lit_fireplaces.sqf new file mode 100644 index 000000000..04491eaf4 --- /dev/null +++ b/SQF/dayz_server/system/lit_fireplaces.sqf @@ -0,0 +1,28 @@ +// (c) facoptere@gmail.com, licensed to DayZMod for the community + +{ + if (random 1 < 0.33) then { + _flame = createVehicle [ "flamable_DZ", _x, [], 0, "CAN_COLLIDE"]; + _flame inflame true; + _flame setVariable ["permaLoot",true]; // = won't be removed by the cleaner, cf. sched_lootpiles.sqf + }; + sleep 0.001; +} count [ + [11580.2,3391.72,-1.20629], [11604.4,3389.41,0.0161071], [11664.6,3415.82,-0.524297], [11678.4,3421.32,-0.526046], [11681.4,3409.25,0.028707], + [11700.9,3416.6,-0.433657], [11707.7,3431.61,0.597957], [11817.8,12693.7,-0.131821], [11844.7,12749.8,-0.109467], [11845.2,12747.7,-0.119843], + [11846.3,12751.1,-0.234741], [11862.3,12748.1,-0.31282], [11863,12748.5,-0.302368], [11863.9,12749.1,-0.279175], [11911.8,9101.2,0.597935], + [11983,9162.89,0.597931], [12013.1,9159.38,0.597931], [12197.2,9499.66,0.603302], [12210.8,9728.83,0.597929], [12218.7,9752.14,0.597929], + [12247,9746.97,0.597929], [12271.7,9719.5,0.597929], [12407.3,9549.83,0.599188], [12698.9,9523.05,0.039454], [12700.7,9515.4,7.22985], + [12701.1,9516.98,7.29042], [12704,9511.34,0.0394101], [12706.2,9510.56,0.0394883], [12706,9513.22,0.0393739], [12707.3,9520.42,0.03929], + [12707.4,9537.02,0.0394235], [12710.4,9548.67,9.79484], [12712.2,9544.37,9.98028], [12714.3,9535.06,-0.634063], [12715.2,9539.4,0.039432], + [12715.5,9536.36,0.0393863], [12718.4,9550.81,-0.633002], [12718.6,9550.53,0.0454731], [12721.6,9502.26,0.0394025], [1689.3,11754.5,-0.640869], + [1693.15,11750.4,0.0564575], [1698.03,11751.3,0.0558929], [1700.78,11733,0.0564728], [1704.94,11761.2,0.0585327], [1705.92,11728.9,0.0565643], + [1709.39,11727.4,0.0566864], [1713.98,11724.6,0.0566711], [1724.37,11729.1,0.054306], [1725.6,11729.7,0.0551147], [1727.1,11727.7,0.0535278], + [1727.33,11724.1,-0.64357], [1728.14,11729.9,-0.644043], [1729.12,11729.2,0.0558777], [1730.91,11729.7,-0.644058], [1731.99,11728.5,0.0557709], + [1746.26,11721.7,0.0542297], [1782.34,11754.6,0.598038], [4889.27,2234.81,0.272388], [4892.66,2235.29,0.272345], [6043.67,7781.65,0.597931], + [6177.52,2125.36,0.598278], [6291.18,7808.69,0.597961], [6317.3,7835.18,0.597961], [6428.26,2244.95,0.59796], [6513.29,2298.32,0.597929], + [6536.12,2639.35,0.597929], [6545.71,2630.16,0.597929], [6663.22,2286.33,0.597929], [6706.46,3012.04,0.59866], [6725.35,2576.59,0.597929], + [6754.5,2780.37,0.597929], [6760.03,2727.7,0.597929], [6789.35,2692.69,0.597929], [6796.09,2726.09,0.597929], [6810.51,2499.86,0.597929], + [6822.79,2482.01,0.597929], [6832.25,2500.24,0.597929], [6833.6,3176.97,0.59797], [6835.19,2694.23,0.597929], [6847.45,2360.25,0.597929], + [6856.71,2522.75,0.597929], [6864.41,2464.66,0.597929], [7065.12,2622.94,0.597929], [7095.99,2740.68,0.597929] +]; diff --git a/SQF/dayz_server/system/s_fps.sqf b/SQF/dayz_server/system/s_fps.sqf new file mode 100644 index 000000000..e03f89d7f --- /dev/null +++ b/SQF/dayz_server/system/s_fps.sqf @@ -0,0 +1,4 @@ +while {isServer} do { + diag_log ("DEBUG FPS : " + str(diag_fps) ); + sleep 360; +}; \ No newline at end of file diff --git a/SQF/dayz_server/system/scheduler/sched_corpses.sqf b/SQF/dayz_server/system/scheduler/sched_corpses.sqf new file mode 100644 index 000000000..cd303915f --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_corpses.sqf @@ -0,0 +1,158 @@ +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" + +sched_co_deleteVehicle = { + private "_group"; + _this removeAllMPEventHandlers "mpkilled"; + _this removeAllMPEventHandlers "mphit"; + _this removeAllMPEventHandlers "mprespawn"; + _this removeAllEventHandlers "FiredNear"; + _this removeAllEventHandlers "HandleDamage"; + _this removeAllEventHandlers "Killed"; + _this removeAllEventHandlers "Fired"; + _this removeAllEventHandlers "GetIn"; + _this removeAllEventHandlers "GetOut"; + _this removeAllEventHandlers "Local"; + _this removeAllEventHandlers "Respawn"; + + clearVehicleInit _this; + _group = group _this; + deleteVehicle _this; + if (count units _group == 0) then { + deleteGroup _group; + }; + _this = nil; +}; + + +sched_corpses = { + private ["_delQtyZ","_delQtyP","_addFlies","_x","_deathTime","_onoff","_delQtyAnimal", "_sound", "_deathPos", "_cpos"]; + // EVERY 2 MINUTE + // DELETE UNCONTROLLED ZOMBIES --- PUT FLIES ON FRESH PLAYER CORPSES --- REMOVE OLD FLIES & CORPSES + _delQtyZ = 0; + _delQtyP = 0; + _addFlies = 0; +// diag_log "bodies ..."; + { + if (local _x) then { + if (_x isKindOf "zZombie_Base") then { + _x call sched_co_deleteVehicle; + _delQtyZ = _delQtyZ + 1; + } else { + if (_x isKindOf "CAManBase") then { + _deathTime = _x getVariable ["sched_co_deathTime", -1]; + if (_deathTime == -1) then { + + _deathPos = _x getVariable [ "deathPos", getMarkerPos "respawn_west" ]; + _cpos = getPosATL _x; + // forbid a move further than 50 meters, or burried body (antihack) + if (_deathPos distance _cpos > 50 or _deathPos select 2 < -0.2) then { + diag_log [ __FILE__, "Corpse has been moved! CID#",(_x getVariable["characterID", "?"]),"from:", _cpos, "to:", _deathPos ]; + _x setPosATL _deathPos; + }; + _deathTime = diag_tickTime; + _x setVariable ["sched_co_deathTime", _deathTime]; + _x setVariable ["sched_co_fliesAdded", true]; + _addFlies = _addFlies + 1; + + }; + // 40 minutes = how long a player corpse stays on the map + if (diag_tickTime - _deathTime > 40*60) then { + if (_x getVariable ["sched_co_fliesDeleted", false]) then { + // flies have been switched off, we can delete body + _sound = _x getVariable ["sched_co_fliesSource", nil]; + + if !(isNil "_sound") then { + detach _sound; + deleteVehicle _sound; + }; + + _x call sched_co_deleteVehicle; + _delQtyP = _delQtyP + 1; + } else { + PVCDZ_flies = [ 0, _x ]; + publicVariable "PVCDZ_flies"; + _x setVariable ["sched_co_fliesDeleted", true]; + // body will be deleted at next round + }; + } else { + _onoff = 1; + // remove flies on heavy rain. + if (rain > 0.25) then { _onoff = 0; }; + // switch flies sound on/off. + // sound must be deleted/respawned periodically because new players won't ear it otherwise, + // and other players would ear it several times (very loud noise) + _sound = _x getVariable ["sched_co_fliesSource", nil]; + if !(isNil "_sound") then { + detach _sound; + deleteVehicle _sound; + _x setVariable ["sched_co_fliesSource", nil]; + //diag_log "delete sound"; + }; + if (_onoff == 1) then { + _sound = createSoundSource["Sound_Flies",getPosATL _x,[],0]; + _sound attachTo [_x]; + _x setVariable ["sched_co_fliesSource", _sound]; + //diag_log "create sound"; + }; + // broadcast flies status for everyone periodically, to update visible swarm + PVCDZ_flies = [ _onoff, _x ]; + publicVariable "PVCDZ_flies"; + }; + }; + }; + }; + } forEach allDead; + + _delQtyAnimal = 0; + { + if (local _x) then { + _x call sched_co_deleteVehicle; + _delQtyAnimal = _delQtyAnimal + 1; + }; + } forEach entities "CAAnimalBase"; + + _delQtyGrp=0; + { + if (count units _x==0) then { + deleteGroup _x; + _delQtyGrp = _delQtyGrp + 1; + }; + } forEach allGroups; + +#ifdef SERVER_DEBUG + if (_delQtyZ+_delQtyP+_addFlies+_delQtyGrp > 0) then { + diag_log format ["%1: Deleted %2 uncontrolled zombies, %3 uncontrolled animals, %4 dead character bodies and %5 empty groups. Added %6 flies.", __FILE__, + _delQtyZ, _delQtyAnimal, _delQtyP,_delQtyGrp, _addFlies ]; + }; +#endif + + objNull +}; + +/* +sched_disconnectedPlayers = { + private ["_x","_disconnectTime"]; + { + diag_log (_x); + if (local _x) then { + _disconnectTime = _x getVariable ["sched_co_disconnectTime", -1]; + if (_disconnectTime == -1) then { + _disconnectTime = diag_tickTime; + _x setVariable ["sched_co_disconnectTime", _disconnectTime]; + }; + if (diag_tickTime - _disconnectTime > dayz_ghostTimer) then { + if (alive _x) then { + [_x,nil] call server_playerSync; + }; + + dayz_disconnectPlayers = dayz_disconnectPlayers - [_x]; + + _x call sched_co_deleteVehicle; + }; + diag_log format["%1 - %2",_x,_disconnectTime]; + }; + } forEach dayz_disconnectPlayers; + + objNull +}; +*/ \ No newline at end of file diff --git a/SQF/dayz_server/system/scheduler/sched_init.sqf b/SQF/dayz_server/system/scheduler/sched_init.sqf new file mode 100644 index 000000000..b217c5980 --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_init.sqf @@ -0,0 +1,35 @@ + +_base="z\addons\dayz_server\system\scheduler\"; + +call compile preprocessFileLineNumbers (_base+"sched_corpses.sqf"); +call compile preprocessFileLineNumbers (_base+"sched_lootpiles.sqf"); +//call compile preprocessFileLineNumbers (_base+"sched_playersHivesync.sqf"); +//call compile preprocessFileLineNumbers (_base+"sched_vehiclesHivesync.sqf"); +call compile preprocessFileLineNumbers (_base+"sched_sync.sqf"); +//call compile preprocessFileLineNumbers (_base+"sched_traps.sqf"); +call compile preprocessFileLineNumbers (_base+"sched_safetyVehicle.sqf"); + +[ + // period offset code <-> ctx init code ->ctx + //[ 60, 121, sched_playersHivesync, sched_playersHivesync_init ], + //[ 60, 133, sched_vehiclesHivesync, sched_vehiclesHivesync_init ], + [ 60, 224, sched_corpses ], + [ 300, 336, sched_lootpiles_5m, sched_lootpiles_5m_init ], + [ 6, 340, sched_lootpiles ], + [ 900, 0, sched_sync ], + [ 120, 48, sched_safetyVehicle ] + //[ 0.1, 1, sched_traps ] +] execFSM ("z\addons\dayz_code\system\scheduler\scheduler.fsm"); + +//diag_log [ __FILE__, "Scheduler started"]; + + + + +/* +// (see ViralZeds.hpp -> zombie_agent.fsm -> zombie_findOwner.sqf), called when a zombie becomes "local" to the server after the player disconnected +zombie_findOwner = { + (_this select 0) call fa_deleteVehicle; +}; +*/ + diff --git a/SQF/dayz_server/system/scheduler/sched_lootpiles.sqf b/SQF/dayz_server/system/scheduler/sched_lootpiles.sqf new file mode 100644 index 000000000..2deaefd1b --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_lootpiles.sqf @@ -0,0 +1,113 @@ +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" + +sched_lootpiles_5m_init = { + sched_lp_state = 0; + sched_lp_var1 = 0; + sched_lp_lootTotal = 0; + sched_lp_delqty = 0; + sched_lp_players = []; + sched_lp_list = []; + + objNull +}; + +sched_lootpiles_5m = { + private ["_created","_kind","_x"]; + if (sched_lp_state == 0) then { + sched_lp_list = []; + sched_lp_lootTotal = 0; + { + _kind = _x; + { + _created = _x getVariable ["created",-1]; + if (_created == -1) then { + _created = diag_tickTime; + _x setVariable ["created",_created]; + }; + if (!(_x getVariable ["permaLoot",false]) AND {(diag_tickTime - _created > 1500)}) then { + sched_lp_list set [ count sched_lp_list, _x ]; + }; + sched_lp_lootTotal = sched_lp_lootTotal + 1; + } forEach allMissionObjects _kind; + } forEach [ "Blood_Trail_DZ", "ReammoBox", "Land_Fire_DZ", "flamable_DZ" ]; +#ifdef SERVER_DEBUG + diag_log ["sched_lootpiles_5mn: reset lootpiles check, total visited:", sched_lp_lootTotal, "listed:", count sched_lp_list]; +#endif + if (count sched_lp_list > 0) then { + sched_lp_state = 1; + sched_lp_var1 = 0; + sched_lp_players = +(playableUnits); + }; + }; + objNull +}; + +sched_lootpiles = { + private ["_plrBatch","_chunkSize","_imax","_plr","_i","_x", "_changed"]; + // EVERY 5 MINUTES, ONE OF THESE TASKS SPACED BY 5 SECONDS: + // LOOK FOR OLD LOOTPILES -OR- IGNORE LOOTPILES NEAR _plrBatch PLAYERS -OR- REMOVE REMAINING _chunkSize LOOTPILES + _chunkSize = 50; + _plrBatch = 10; + switch true do { + case (sched_lp_state == 1): { // forEach players -> ignore nearby loot + _imax = (count sched_lp_players) min (sched_lp_var1 + _plrBatch); + //diag_log format ["%1: lootpiles foreach players from:%2 to:%3 players:%4 old:%5 total:%6", __FILE__, sched_lp_var1, _imax, count sched_lp_players, count sched_lp_list, sched_lp_lootTotal ]; + for "_i" from sched_lp_var1 to _imax-1 do { + _plr = (sched_lp_players select _i); + if (!(isNull _plr) AND {(isPlayer _plr)}) then { + _plr = vehicle _plr; + { + if (_x IN sched_lp_list) then { + sched_lp_list = sched_lp_list - [_x]; + }; + } forEach ((getPosATL _plr) nearObjects ["ReammoBox",250]); + }/* + else { + diag_log format [ "%1 player left? %2", __FILE__, _x ]; + }*/; + }; + sched_lp_var1 = _imax; + _changed = false; + if (_imax == count sched_lp_players) then { // catch the few players who entered meanwhile + { + if !(_x in sched_lp_players) then { + sched_lp_players set [ count sched_lp_players, _x ]; + _changed = true; + }; + } forEach playableUnits; + }; + if (!_changed) then { + sched_lp_state = 2; + sched_lp_var1 = 0; + sched_lp_delqty = count sched_lp_list; +#ifdef SERVER_DEBUG + diag_log [ "sched_lootpiles:Will delete",sched_lp_delqty,"lootpiles"]; +#endif + } + else { +#ifdef SERVER_DEBUG + diag_log [ "sched_lootpiles:Extended loop for new players", _imax, count sched_lp_players]; +#endif + }; + }; + case (sched_lp_state == 2): { // forEAch remaining lootpiles -> delete + _imax = (sched_lp_delqty) min (sched_lp_var1 + _chunkSize); + //diag_log format ["%1: lootpiles foreach loot to del from:%2 to:%3 old:%4 total:%5", __FILE__, sched_lp_var1, _imax, sched_lp_delqty, sched_lp_lootTotal ]; + for "_i" from sched_lp_var1 to _imax-1 do { + _x = sched_lp_list select _i; + deleteVehicle _x; + }; + sched_lp_var1 = _imax; + if (_imax == sched_lp_delqty) then { + sched_lp_state = 0; + sched_lp_list = []; +#ifdef SERVER_DEBUG + diag_log format ["%1: deleted %2 lootpiles from %3 total", __FILE__, sched_lp_delqty, sched_lp_lootTotal ]; +#endif + }; + }; + }; // switch + + objNull +}; + diff --git a/SQF/dayz_server/system/scheduler/sched_playersHivesync.sqf b/SQF/dayz_server/system/scheduler/sched_playersHivesync.sqf new file mode 100644 index 000000000..e55e4357a --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_playersHivesync.sqf @@ -0,0 +1,44 @@ + + +sched_playershivewrite = { + private ["_n","_x","_damage","_pos","_otime","_opos","_odamage"]; + // EVERY 1 MINUTE + // FORCE HIVE WRITE FOR PLAYERS WHO NEED IT (HUMANITY OR POSITION OR TIMEOUT CHANGE) + _n = 0; + { + if ((isPlayer _x) AND {(alive _x)}) then { + _damage = _x getVariable [ "USEC_BloodQty", -1 ]; + _pos = visiblePosition _x; // genuine position, deals with player in vehicle or not + if (_damage >= 0) then { // not a character? + _otime = _x getVariable [ "sched_ph_sync_time", -1]; + _opos = _x getVariable [ "sched_ph_sync_pos", _pos]; + _odamage = _x getVariable [ "sched_ph_sync_dmg", _damage]; + if (_otime == -1) then { + _otime = diag_tickTime; + _x setVariable [ "sched_ph_sync_time", _otime]; + _x setVariable [ "sched_ph_sync_pos", _opos]; + _x setVariable [ "sched_ph_sync_dmg", _odamage]; + }; + if ((diag_tickTime - _otime > 600) OR {((_pos distance _opos > 50) OR {(_odamage != _damage)})}) then { + [_x, nil, true] call server_playerSync; + _x setVariable [ "sched_ph_sync_time", diag_tickTime]; + _x setVariable [ "sched_ph_sync_pos", _pos]; + _x setVariable [ "sched_ph_sync_dmg", _damage]; + _n = _n + 1; + }; + }; + if ([ -11000+500, 15360-21000+500, 0 ] distance _pos < 2000) then { + diag_log format [ "HACK, player %1 at anti-ESP zone, killing him but no HIVE save for him.", _x call fa_plr2str ]; + _x setVariable ["CharacterID", nil, true ]; + unassignVehicle _x; + _pos set [2, 2000]; // will be killed by gravity OR kick by anti TP + _x setPosATL _pos; + }; + }; + } forEach playableUnits; + if (_n > 0) then { + diag_log format ["%1: sync'ed %2 players to HIVE", __FILE__, _n]; + }; + + objNull +}; diff --git a/SQF/dayz_server/system/scheduler/sched_safetyVehicle.sqf b/SQF/dayz_server/system/scheduler/sched_safetyVehicle.sqf new file mode 100644 index 000000000..3f0ddc768 --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_safetyVehicle.sqf @@ -0,0 +1,12 @@ + +sched_safetyVehicle = { + { + if (vehicle _x != _x && !(vehicle _x in dayz_serverObjectMonitor) && (typeOf vehicle _x) != "ParachuteWest") then { + diag_log [ __FILE__, "KILLING A HACKER", name _x, " IN ", typeOf vehicle _x ]; + (vehicle _x) setDamage 1; + _x setDamage 1; + }; + } forEach allUnits; + + objNull +}; diff --git a/SQF/dayz_server/system/scheduler/sched_sync.sqf b/SQF/dayz_server/system/scheduler/sched_sync.sqf new file mode 100644 index 000000000..d939187e4 --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_sync.sqf @@ -0,0 +1,25 @@ +sched_sync = { + private ["_result","_outcome","_date","_hour","_minute"]; + // EVERY 15 MINUTES + // RESYNC TIME WITH HIVE DLL SYSTEM CALL + + _result = "CHILD:307:" call server_hiveReadWrite; + _outcome = _result select 0; + if(_outcome == "PASS") then { + _date = _result select 1; + + _hour = _date select 3; + _minute = _date select 4; + + if(dayz_ForcefullmoonNights) then { + _date = [2012,8,2,_hour,_minute]; + }; + + setDate _date; + dayzSetDate = _date; + publicVariable "dayzSetDate"; + diag_log [ __FILE__, "TIME SYNC: Local Time set to:", _date, "Fullmoon:",dayz_ForcefullmoonNights, "Date given by HiveExt.dll:", _result select 1]; + }; + + objNull +}; diff --git a/SQF/dayz_server/system/scheduler/sched_traps.sqf b/SQF/dayz_server/system/scheduler/sched_traps.sqf new file mode 100644 index 000000000..47b9ede4c --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_traps.sqf @@ -0,0 +1,33 @@ +sched_traps = { + private ["_n","_x"]; + // EVERY 5 SECONDS + // CHECK TRAPS STATE + if (!isNil "dayz_traps") then { + _n = 0; + { + if ((isNil "_x") OR {(isNull _x)}) then { + dayz_traps = dayz_traps - [_x]; + } + else { + if (_x getVariable ["armed", false]) then { + if !(_x in dayz_traps_active) then { + ["arm", _x] call compile getText (configFile >> "CfgVehicles" >> typeOf _x >> "script"); + if !(_x in dayz_traps_active) then { dayz_traps_active set [ count dayz_traps_active, _x ]; }; + _n = _n + 1; + }; + } else { + if (_x in dayz_traps_active) then { + ["disarm", _x] call compile getText (configFile >> "CfgVehicles" >> typeOf _x >> "script"); + if (_x in dayz_traps_active) then { dayz_traps_active = dayz_traps_active - [_x]; }; + _n = _n + 1; + }; + }; + }; + } forEach dayz_traps; + if (_n > 0) then { + diag_log format ["%1: traps polling, changed %2 states", __FILE__, _n]; + }; + }; + + objNull +}; \ No newline at end of file diff --git a/SQF/dayz_server/system/scheduler/sched_vehiclesHivesync.sqf b/SQF/dayz_server/system/scheduler/sched_vehiclesHivesync.sqf new file mode 100644 index 000000000..46d37c192 --- /dev/null +++ b/SQF/dayz_server/system/scheduler/sched_vehiclesHivesync.sqf @@ -0,0 +1,37 @@ + +sched_vehicleshivewrite = { +private ["_n","_x","_damage","_pos","_otime","_opos","_odamage"]; + // EVERY 1 MINUTE + // FORCE HIVE WRITE FOR VEHICLES WHO NEED IT (DAMAGE OR POSITION OR TIMEOUT CHANGE) + _n = 0; + { + if (_x isKindOf "AllVehicles") then { + _damage = damage _x; + _pos = getPosASL _x; + _otime = _x getVariable [ "sched_vh_sync_time", -1]; + _opos = _x getVariable [ "sched_vh_sync_pos", _pos]; + _odamage = _x getVariable [ "sched_vh_sync_dmg", _damage]; + if (_otime == -1) then { + _otime = diag_tickTime - random 480; + _x setVariable [ "sched_vh_sync_time", _otime]; + _x setVariable [ "sched_vh_sync_pos", _opos]; + _x setVariable [ "sched_vh_sync_dmg", _odamage]; + }; + if ((diag_tickTime - _otime > 600) OR {((_pos distance _opos > 50) OR {(_odamage != _damage)})}) then { + _x setVariable [ "sched_vh_sync_time", diag_tickTime]; + _x setVariable [ "sched_vh_sync_pos", _pos]; + _x setVariable [ "sched_vh_sync_dmg", _damage]; + [_x, "all", true] call server_updateObject; + _n = _n + 1; + }/* + else { + diag_log format ["%1: veh %2 %3 %4 %5", __FILE__, _x, _otime, _opos, _odamage]; + }*/; + }; + } forEach vehicles; + if (_n > 0) then { + diag_log format ["%1: sync'ed %2 vehicles to HIVE", __FILE__, _n]; + }; + + objNull +}; diff --git a/SQF/dayz_server/system/server_cleanup.fsm b/SQF/dayz_server/system/server_cleanup.fsm index d8fa7aca2..cca32c1fa 100644 --- a/SQF/dayz_server/system/server_cleanup.fsm +++ b/SQF/dayz_server/system/server_cleanup.fsm @@ -1,60 +1,73 @@ -/*%FSM*/ +/*%FSM*/ /*%FSM*/ /* -item0[] = {"init",0,250,-25.000000,-350.000000,75.000000,-300.000000,0.000000,"init"}; -item1[] = {"prepare",2,250,375.000000,-350.000000,475.000000,-300.000000,0.000000,"prepare"}; -item2[] = {"initialized",4,218,175.000000,-350.000000,275.000000,-300.000000,0.000000,"initialized"}; -item3[] = {"true",8,218,375.000000,-275.000000,475.000000,-225.000000,0.000000,"true"}; -item4[] = {"waiting",2,250,375.000000,-200.000000,475.000000,-150.000000,0.000000,"waiting"}; -item5[] = {"true",8,218,375.000000,75.000000,475.000000,125.000000,0.000000,"true"}; -item6[] = {"general_cleanup",2,250,375.000000,150.000000,475.000000,200.000000,0.000000,"general" \n "cleanup" \n "loop"}; -item7[] = {"",7,210,21.000000,170.999985,29.000000,179.000000,0.000000,""}; -item8[] = {"",7,210,21.000004,-254.000000,28.999998,-246.000000,0.000000,""}; -item9[] = {"",7,210,821.000000,-179.000000,829.000000,-171.000000,0.000000,""}; -item10[] = {"",7,210,821.000000,96.000000,829.000000,104.000000,0.000000,""}; -item11[] = {"___second_loop",4,218,50.000000,-75.000000,150.000000,-25.000000,1.000000,"3 second" \n "loop"}; -item12[] = {"__0s_update__obj",4,218,175.000000,-100.000000,275.000000,-50.000000,2.000000,"50s" \n "update " \n "objects"}; -item13[] = {"___min__loop",4,218,300.000000,-125.000000,400.000000,-75.000000,3.000000,"1 min" \n " loop"}; -item14[] = {"___min_loop",4,218,450.000000,-125.000000,550.000000,-75.000000,4.000000,"5 min" \n "loop"}; -item15[] = {"__0_min__loop",4,218,575.000000,-100.000000,675.000000,-50.000000,5.000000,"10 min" \n " loop"}; -item16[] = {"__5_min__loop",4,218,700.000000,-75.000000,800.000000,-25.000000,6.000000,"15 min" \n " loop"}; -item17[] = {"cleanup_animals",2,250,700.000000,25.000000,800.000000,75.000000,0.000000,"cleanup" \n "animals && fire"}; -item18[] = {"cleanup_dead",2,250,575.000000,0.000000,675.000000,50.000000,0.000000,"cleanup" \n "dead"}; -item19[] = {"sync_time",2,250,450.000000,-25.000000,550.000000,25.000000,0.000000,"sync time"}; -item20[] = {"cleanup_loot",2,250,300.000000,-25.000000,400.000000,25.000000,0.000000,"cleanup" \n "loot"}; -item21[] = {"group_cleanup",2,250,50.000000,25.000000,150.000000,75.000000,0.000000,"group" \n "cleanup"}; -item22[] = {"update_objects",2,250,175.000000,0.000000,275.000000,50.000000,0.000000,"update objects"}; -link0[] = {0,2}; -link1[] = {1,3}; -link2[] = {2,1}; -link3[] = {3,4}; -link4[] = {4,9}; -link5[] = {4,11}; -link6[] = {4,12}; -link7[] = {4,13}; -link8[] = {4,14}; -link9[] = {4,15}; -link10[] = {4,16}; -link11[] = {5,6}; -link12[] = {6,7}; -link13[] = {7,8}; -link14[] = {8,3}; -link15[] = {9,10}; -link16[] = {10,5}; -link17[] = {11,21}; -link18[] = {12,22}; -link19[] = {13,20}; -link20[] = {14,19}; -link21[] = {15,18}; -link22[] = {16,17}; -link23[] = {17,5}; -link24[] = {18,5}; -link25[] = {19,5}; -link26[] = {20,5}; -link27[] = {21,5}; -link28[] = {22,5}; -globals[] = {25.000000,1,0,0,0,640,480,1,136,6316128,1,-53.328339,954.791992,443.544983,-436.145996,1044,911,1}; -window[] = {2,-1,-1,-1,-1,912,100,1392,100,3,1062}; +item0[] = {"init",0,250,-75.000000,-425.000000,25.000000,-375.000000,0.000000,"init"}; +item1[] = {"true",8,218,-75.000000,-200.000000,25.000000,-150.000000,0.000000,"true"}; +item2[] = {"waiting",2,250,-75.000000,-125.000000,25.000000,-75.000000,0.000000,"waiting"}; +item3[] = {"too_many_dead",4,218,-125.000000,0.000000,-25.000000,50.000000,2.000000,"too many" \n "dead"}; +item4[] = {"cleanup_dead",2,250,-125.000000,75.000000,-25.000000,125.000000,0.000000,"cleanup" \n "dead"}; +item5[] = {"too_many_objects",4,218,175.000000,0.000000,275.000000,50.000000,2.000000,"too many" \n "objects"}; +item6[] = {"cleanup_objects",2,4346,175.000000,75.000000,275.000000,125.000000,0.000000,"cleanup" \n "objects"}; +item7[] = {"time_sync",4,218,-225.000000,0.000000,-125.000000,50.000000,1.000000,"time" \n "sync"}; +item8[] = {"sync_the_time",2,250,-225.000000,175.000000,-125.000000,225.000000,0.000000,"sync" \n "the time"}; +item9[] = {"true",8,218,-75.000000,250.000000,25.000000,300.000000,0.000000,"true"}; +item10[] = {"general_cleanup",2,250,-75.000000,350.000000,25.000000,400.000000,0.000000,"general" \n "cleanup"}; +item11[] = {"",7,210,-254.000015,371.000000,-246.000000,379.000031,0.000000,""}; +item12[] = {"",7,210,-254.000015,-179.000000,-246.000000,-171.000000,0.000000,""}; +item13[] = {"initialized",4,218,-75.000000,-350.000000,25.000000,-300.000000,0.000000,"initialized"}; +item14[] = {"prepare",2,250,-75.000000,-275.000000,25.000000,-225.000000,0.000000,"prepare"}; +item15[] = {"update_objects",2,250,-25.000000,75.000000,75.000000,125.000000,0.000000,"update objects"}; +item16[] = {"Objects_need_upd",4,218,-25.000000,0.000000,75.000000,50.000000,1.000000,"Objects" \n "need update"}; +item17[] = {"",7,210,-29.000000,-41.500000,-21.000000,-33.499996,0.000000,""}; +item18[] = {"",7,210,20.999998,-41.500000,29.000000,-33.500000,0.000000,""}; +item19[] = {"",7,210,121.000000,-41.500000,129.000000,-33.500000,0.000000,""}; +item20[] = {"",7,210,-79.000000,-41.500000,-71.000000,-33.500000,0.000000,""}; +item21[] = {"",7,210,-179.000000,-41.499996,-171.000000,-33.500000,0.000000,""}; +item22[] = {"",7,210,-79.000000,146.000000,-71.000000,154.000000,0.000000,""}; +item23[] = {"",7,210,21.000000,146.000000,28.999998,154.000000,0.000000,""}; +item24[] = {"",7,210,-29.000000,146.000000,-20.999998,154.000000,0.000000,""}; +item25[] = {"",7,210,308.500000,-104.000000,316.500000,-96.000000,0.000000,""}; +item26[] = {"",7,210,308.500031,271.000000,316.499969,279.000000,0.000000,""}; +item27[] = {"",7,210,-179.000000,271.000000,-171.000000,279.000000,0.000000,""}; +item28[] = {"",7,210,221.000000,-41.500000,229.000000,-33.500000,0.000000,""}; +item29[] = {"New_Cleanup_Obje",2,250,375.000000,75.000000,475.000000,125.000000,0.000000,"New Cleanup" \n "Objects"}; +item30[] = {"",7,210,221.000031,271.000000,228.999969,279.000000,0.000000,""}; +link0[] = {0,13}; +link1[] = {1,2}; +link2[] = {2,17}; +link3[] = {2,25}; +link4[] = {3,4}; +link5[] = {4,22}; +link6[] = {5,6}; +link7[] = {6,30}; +link8[] = {7,8}; +link9[] = {8,27}; +link10[] = {9,10}; +link11[] = {10,11}; +link12[] = {11,12}; +link13[] = {12,1}; +link14[] = {13,14}; +link15[] = {14,1}; +link16[] = {15,23}; +link17[] = {16,15}; +link18[] = {17,18}; +link19[] = {17,20}; +link20[] = {18,16}; +link21[] = {18,19}; +link22[] = {19,28}; +link23[] = {20,3}; +link24[] = {20,21}; +link25[] = {21,7}; +link26[] = {22,24}; +link27[] = {23,24}; +link28[] = {24,9}; +link29[] = {25,26}; +link30[] = {26,30}; +link31[] = {27,9}; +link32[] = {28,5}; +link33[] = {30,9}; +globals[] = {25.000000,1,0,0,0,640,480,1,13,6316128,1,-520.235962,640.978394,444.212921,-448.684845,779,599,1}; +window[] = {2,-1,-1,-32000,-32000,878,150,1479,150,3,797}; *//*%FSM*/ class FSM { @@ -65,7 +78,7 @@ class FSM class init { name = "init"; - init = /*%FSM*/"//Major Performance Speedup by Skaronator ;)"/*%FSM*/; + init = /*%FSM*/""/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links { @@ -82,150 +95,58 @@ class FSM }; }; /*%FSM*/ - /*%FSM*/ - class prepare - { - name = "prepare"; - init = /*%FSM*/"diag_log (""CLEANUP: INITIALIZING CLEANUP SCRIPT"");" \n - "" \n - "_lastUpdate = diag_tickTime;" \n - "_lastNeedUpdate = diag_tickTime;" \n - "_lastCleanupVehicles = diag_tickTime;" \n - "_lastCleanupGroups = diag_tickTime;" \n - "_lastCleanupNull = diag_tickTime;" \n - "" \n - "_lastCleanup900 = diag_tickTime;" \n - "" \n - ""/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - priority = 0.000000; - to="waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ /*%FSM*/ class waiting { name = "waiting"; init = /*%FSM*/"//diag_log ""CLEANUP: Waiting for next task"";" \n + "" \n + "_numDead = {local _x} count allDead;" \n ""/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links { - /*%FSM*/ - class __5_min__loop + /*%FSM*/ + class too_many_dead { - priority = 6.000000; - to="cleanup_animals"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _lastCleanup900) > 900)"/*%FSM*/; - action=/*%FSM*/"_lastCleanup900 = diag_tickTime;"/*%FSM*/; - }; - /*%FSM*/ - /*%FSM*/ - class __0_min__loop - { - priority = 5.000000; + priority = 2.000000; to="cleanup_dead"; precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _lastCleanupNull) > 600)"/*%FSM*/; - action=/*%FSM*/"_lastCleanupNull = diag_tickTime;"/*%FSM*/; + condition=/*%FSM*/"(_numDead > 100)"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; }; /*%FSM*/ - /*%FSM*/ - class ___min_loop + /*%FSM*/ + class too_many_objects { - priority = 4.000000; - to="sync_time"; + priority = 2.000000; + to="cleanup_objects"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _timeNem) > 150)" \n + "//(((count dayz_deseedloot) > 0) && (!isNil ""sm_done""))"/*%FSM*/; + action=/*%FSM*/"_timeNem = diag_tickTime;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class time_sync + { + priority = 1.000000; + to="sync_the_time"; precondition = /*%FSM*/""/*%FSM*/; condition=/*%FSM*/"((diag_tickTime - _lastUpdate) > 300)"/*%FSM*/; action=/*%FSM*/"_lastUpdate = diag_tickTime;"/*%FSM*/; }; /*%FSM*/ - /*%FSM*/ - class ___min__loop + /*%FSM*/ + class Objects_need_upd { - priority = 3.000000; - to="cleanup_loot"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _lastCleanupVehicles) > 60)"/*%FSM*/; - action=/*%FSM*/"_lastCleanupVehicles = diag_tickTime;"/*%FSM*/; - }; - /*%FSM*/ - /*%FSM*/ - class __0s_update__obj - { - priority = 2.000000; + priority = 1.000000; to="update_objects"; precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"(( (count needUpdate_objects) > 0) && (diag_tickTime -_lastNeedUpdate> 50))"/*%FSM*/; + condition=/*%FSM*/"(( (count needUpdate_objects) > 0) && (diag_tickTime -_lastNeedUpdate> 5) && (!isNil ""sm_done""))"/*%FSM*/; action=/*%FSM*/"_lastNeedUpdate = diag_tickTime;"/*%FSM*/; }; /*%FSM*/ - /*%FSM*/ - class ___second_loop - { - priority = 1.000000; - to="group_cleanup"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _lastCleanupGroups) > 3)"/*%FSM*/; - action=/*%FSM*/"_lastCleanupGroups = diag_tickTime;"/*%FSM*/; - }; - /*%FSM*/ - /*%FSM*/ - class true - { - priority = 0.000000; - to="general_cleanup"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class general_cleanup - { - name = "general_cleanup"; - init = /*%FSM*/"//diag_log ""CLEANUP: Starting loop for next task"";" \n - ""/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - priority = 0.000000; - to="waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class cleanup_animals - { - name = "cleanup_animals"; - init = /*%FSM*/"[] spawn server_spawnCleanFire;" \n - "[] spawn server_spawnCleanAnimals;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { /*%FSM*/ class true { @@ -243,7 +164,7 @@ class FSM class cleanup_dead { name = "cleanup_dead"; - init = /*%FSM*/"[] spawn server_spawncleanDead;"/*%FSM*/; + init = /*%FSM*/""/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links { @@ -260,14 +181,11 @@ class FSM }; }; /*%FSM*/ - /*%FSM*/ - class sync_time + /*%FSM*/ + class cleanup_objects { - name = "sync_time"; - init = /*%FSM*/"if (DZE_DiagFpsSlow) then {" \n - " call dze_diag_fps;" \n - "};" \n - "call server_timeSync;"/*%FSM*/; + name = "cleanup_objects"; + init = /*%FSM*/""/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links { @@ -284,19 +202,70 @@ class FSM }; }; /*%FSM*/ - /*%FSM*/ - class cleanup_loot + /*%FSM*/ + class sync_the_time { - name = "cleanup_loot"; - init = /*%FSM*/"if (DZE_DiagFpsFast) then {" \n - " call dze_diag_fps;" \n - "};" \n + name = "sync_the_time"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="general_cleanup"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class general_cleanup + { + name = "general_cleanup"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="waiting"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class prepare + { + name = "prepare"; + init = /*%FSM*/"diag_log (""CLEANUP: INITIALIZING CLEANUP SCRIPT"");" \n "" \n - "[] spawn server_spawnCleanLoot;" \n + "_safety = dayz_serverObjectMonitor;" \n + "_dateNow = (DateToNumber date);" \n "" \n - "// set player save time based on server performance" \n - "PVDZE_plr_SetSaveTime = round(60 - diag_fps);" \n - "publicVariable ""PVDZE_plr_SetSaveTime"";"/*%FSM*/; + "_lastUpdate = diag_tickTime;" \n + "_timeNem =diag_tickTime;" \n + "_deadBodies = [];" \n + "_lastNeedUpdate = diag_tickTime;" \n + "_timeout = diag_tickTime;" \n + "_maxBodies = 15;" \n + "" \n + "_lootspawnerfdbykr = diag_tickTime; " \n + "_reseedloot = false;" \n + "" \n + "_amount = 0;" \n + "_hour = 0;" \n + "_minute = 0;"/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links { @@ -304,29 +273,7 @@ class FSM class true { priority = 0.000000; - to="general_cleanup"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class group_cleanup - { - name = "group_cleanup"; - init = /*%FSM*/"[] spawn server_checkHackers;" \n - "[] spawn server_cleanupGroups;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - priority = 0.000000; - to="general_cleanup"; + to="waiting"; precondition = /*%FSM*/""/*%FSM*/; condition=/*%FSM*/"true"/*%FSM*/; action=/*%FSM*/""/*%FSM*/; @@ -339,10 +286,14 @@ class FSM class update_objects { name = "update_objects"; - init = /*%FSM*/"{" \n + init = /*%FSM*/"diag_log format[""DEBUG: needUpdate_objects=%1"",needUpdate_objects];" \n + "" \n + "{" \n + "// _x setVariable [""needUpdate"",false,true];" \n " needUpdate_objects = needUpdate_objects - [_x];" \n " [_x,""damage"",true] call server_updateObject;" \n - "} count needUpdate_objects;"/*%FSM*/; + "} forEach needUpdate_objects;" \n + ""/*%FSM*/; precondition = /*%FSM*/""/*%FSM*/; class Links { @@ -359,6 +310,86 @@ class FSM }; }; /*%FSM*/ + /*%FSM*/ + class New_Cleanup_Obje + { + name = "New_Cleanup_Obje"; + init = /*%FSM*/"diag_log ""DEBUG: New_Cleanup_Obje ""; " \n + "_lootingrids = [];" \n + "" \n + "{" \n + " _loc = _x select 0;" \n + " _ref = _x select 1;" \n + "" \n + " _nearBy = nearestObjects [_loc, [""ReammoBox""], 1500];" \n + " {" \n + " _lootingrids set [count _lootingrids,[_x,_ref]];" \n + " } foreach _nearBy;" \n + "" \n + " dayz_deseedloot set [0,-1];" \n + " dayz_deseedloot = dayz_deseedloot - [-1];" \n + "" \n + "}foreach dayz_deseedloot;" \n + "" \n + "_qty = count _lootingrids;" \n + "diag_log (""CLEANUP:TOTAL "" + str(_qty) + "" LOOT BAGS"");" \n + "" \n + "_delQty = 0;" \n + "_delQtyDroped = 0;" \n + "_delQtySpawned = 0;" \n + "_delQtyPerma = 0;" \n + "" \n + "{" \n + " " \n + " _obj = _x select 0;" \n + " _ref = _x select 1;" \n + "" \n + " diag_log format [""%1,%2"", _obj, _ref];" \n + "" \n + " _Dropped = (_obj getVariable [""Dropped"",false]);" \n + " _Spawned = (_obj getVariable [""spawnedLoot"",false]);" \n + " _Perma = (_obj getVariable [""permaLoot"",false]);" \n + "" \n + " if (!_Spawned and !_Perma) then {" \n + " _obj setVariable [""Dropped"",true];" \n + " };" \n + "" \n + " //Dropped loot" \n + " if (_Dropped) then {" \n + " " \n + " [""Dropped_Loot"",_obj,_ref] call server_systemCleanup;" \n + " _delQtyDroped = _delQtyDroped + 1;" \n + "" \n + " };" \n + "" \n + " //Spawned Loot" \n + " if (_Spawned) then {" \n + "" \n + " [""Spawned_Loot"",_obj,_ref] call server_systemCleanup;" \n + " _delQtySpawned = _delQtySpawned + 1; " \n + " " \n + " };" \n + "" \n + " //Permaloot" \n + " if (_Perma) then {" \n + "" \n + " _delQtyPerma = _delQtyPerma + 1;" \n + "" \n + " };" \n + "" \n + "} foreach _lootingrids;" \n + "" \n + "if ((_delQtySpawned > 0) or (_delQtyDroped > 0) or (_delQtyPerma > 0)) then {" \n + " //diag_log (""CLEANUP: DELETED "" + str(_delQty) + "" LOOT BAGS"");" \n + " diag_log format [""CLEANUP: (DELETED, DroppedLoot: %1, SpawnedLoot: %2), (KEPT, PermaLoot: %3)"", _delQtyDroped, _delQtySpawned, _delQtyPerma];" \n + "};" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + }; + }; + /*%FSM*/ }; initState="init"; finalStates[] = diff --git a/SQF/dayz_server/system/server_cleanup.sqf b/SQF/dayz_server/system/server_cleanup.sqf new file mode 100644 index 000000000..71a95b1cb --- /dev/null +++ b/SQF/dayz_server/system/server_cleanup.sqf @@ -0,0 +1,81 @@ + +_lootype = _this select 0; +_lootobj = _this select 1; +_lootref = _this select 2; + +_dateNow = diag_ticktime; + +switch (_lootype) do +{ + case "Dropped_Loot": + { + /* + diag_log("Dropped Loot"); + _created = (_lootobj getVariable ["created",-0.1]); + if (_created == -0.1) then { + _lootobj setVariable ["created",diag_ticktime,false]; + _created = diag_ticktime; + }; + + _age = (_dateNow - _created); + _nearby = {(isPlayer _lootobj) and (alive _lootobj)} count (_lootobj nearEntities [["CAManBase","AllVehicles"], 130]); + if ((_nearby==0) then { + if (_age > 20) then { + _remove = true; + } else { + dayz_droppedlootarray set [count dayz_droppedlootarray,_lootobj]; + }; + }; + */ + //diag_log("Dropped Loot"); + deleteVehicle _lootobj; + }; + + case "Spawned_Loot": + { + //diag_log("Spawned Loot"); + deleteVehicle _lootobj; + }; + + case "Perma_Loot": + { + //diag_log("Perma Loot"); + }; +}; + +/* +{ + + _Dropped = (_x getVariable ["Dropped",false]); + _Spawned = (_x getVariable ["spawnedLoot",false]); + _Perma = (_x getVariable ["permaLoot",false]); + + if (!_Spawned and !_Perma) then { + _x setVariable ["Dropped",true]; + }; + + //Dropped loot + if (_Dropped) then { + _x setVariable ["created",diag_ticktime,false]; + _created = diag_ticktime; + + diag_log("Dropped Loot"); + }; + + //Spawned Loot + if (_Spawned) then { + diag_log("Spawned Loot"); + }; + + //Permaloot + if (_Perma) then { + //Ignore perma loot + diag_log("Perma Loot"); + }; +} foreach _lootingrids; + + +if (_delQty > 0) then { + diag_log ("CLEANUP: DELETED " + str(_delQty) + " LOOT BAGS"); +}; +*/ \ No newline at end of file diff --git a/SQF/dayz_server/system/server_monitor.sqf b/SQF/dayz_server/system/server_monitor.sqf index ee9f0f809..09b9af75a 100644 --- a/SQF/dayz_server/system/server_monitor.sqf +++ b/SQF/dayz_server/system/server_monitor.sqf @@ -1,15 +1,43 @@ -private ["_nul","_result","_pos","_wsDone","_dir","_isOK","_countr","_objWpnTypes","_objWpnQty","_dam","_selection","_totalvehicles","_object","_idKey","_type","_ownerID","_worldspace","_inventory","_hitPoints","_fuel","_damage","_key","_vehLimit","_hiveResponse","_objectCount","_codeCount","_data","_status","_val","_traderid","_retrader","_traderData","_id","_lockable","_debugMarkerPosition","_vehicle_0","_bQty","_vQty","_BuildingQueue","_objectQueue","_superkey","_shutdown","_res","_hiveLoaded"]; +private ["_date","_year","_month","_day","_hour","_minute","_date1","_hiveResponse","_key","_objectCount","_dir","_point","_i","_action","_dam","_selection","_wantExplosiveParts","_entity","_worldspace","_damage","_booleans","_rawData","_ObjectID","_class","_CharacterID","_inventory","_hitpoints","_fuel","_id","_objectArray","_script","_result","_outcome"]; +[]execVM "\z\addons\dayz_server\system\s_fps.sqf"; //server monitor FPS (writes each ~181s diag_fps+181s diag_fpsmin*) +#include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" + +waitUntil{!isNil "BIS_MPF_InitDone"}; +waitUntil{initialized}; //means all the functions are now defined +if (!isNil "sm_done") exitWith {}; // prevent server_monitor be called twice (bug during login of the first player) +sm_done = false; + +dayz_serverIDMonitor = []; dayz_versionNo = getText(configFile >> "CfgMods" >> "DayZ" >> "version"); dayz_hiveVersionNo = getNumber(configFile >> "CfgMods" >> "DayZ" >> "hiveVersion"); _hiveLoaded = false; -waitUntil{initialized}; //means all the functions are now defined - diag_log "HIVE: Starting"; -waituntil{isNil "sm_done"}; // prevent server_monitor be called twice (bug during login of the first player) +//Set the Time +_key = "CHILD:307:"; +_result = _key call server_hiveReadWrite; +_outcome = _result select 0; +if(_outcome == "PASS") then { + _date = _result select 1; + + //date setup + _year = _date select 0; + _month = _date select 1; + _day = _date select 2; + _hour = _date select 3; + _minute = _date select 4; + + if(dayz_ForcefullmoonNights) then { + _date = [2012,8,2,_hour,_minute]; + }; + diag_log [ "TIME SYNC: Local Time set to:", _date, "Fullmoon:",dayz_ForcefullmoonNights, "Date given by HiveExt.dll:", _result select 1]; + setDate _date; + dayzSetDate = _date; + publicVariable "dayzSetDate"; +}; // Custom Configs if(isnil "MaxVehicleLimit") then { @@ -262,6 +290,100 @@ if (isServer && isNil "sm_done") then { } forEach (_BuildingQueue + _objectQueue); // # END SPAWN OBJECTS # + // Draw the pseudo random seeds + call server_plantSpawner; + + // launch the legacy task scheduler + [] execFSM "\z\addons\dayz_server\system\server_cleanup.fsm"; + + // launch the new task scheduler + [] execVM "\z\addons\dayz_server\system\scheduler\sched_init.sqf"; + + createCenter civilian; + if (isDedicated) then { + endLoadingScreen; + }; + allowConnection = true; + sm_done = true; + publicVariable "sm_done"; + + // Trap loop + [] spawn { + private ["_array","_array2","_array3","_script","_armed"]; + _array = str dayz_traps; + _array2 = str dayz_traps_active; + _array3 = str dayz_traps_trigger; + + while {1 == 1} do { + if ((str dayz_traps != _array) || (str dayz_traps_active != _array2) || (str dayz_traps_trigger != _array3)) then { + _array = str dayz_traps; + _array2 = str dayz_traps_active; + _array3 = str dayz_traps_trigger; + + //diag_log "DEBUG: traps"; + //diag_log format["dayz_traps (%2) -> %1", dayz_traps, count dayz_traps]; + //diag_log format["dayz_traps_active (%2) -> %1", dayz_traps_active, count dayz_traps_active]; + //diag_log format["dayz_traps_trigger (%2) -> %1", dayz_traps_trigger, count dayz_traps_trigger]; + //diag_log "DEBUG: end traps"; + }; + + { + if (isNull _x) then { + dayz_traps = dayz_traps - [_x]; + }; + + _script = call compile getText (configFile >> "CfgVehicles" >> typeOf _x >> "script"); + _armed = _x getVariable ["armed", false]; + + if (_armed) then { + if !(_x in dayz_traps_active) then { + ["arm", _x] call _script; + }; + } else { + if (_x in dayz_traps_active) then { + ["disarm", _x] call _script; + }; + }; + + sleep 0.01; + } forEach dayz_traps; + sleep 1; + }; + }; + + //Points of interest + [] execVM "\z\addons\dayz_server\compile\server_spawnInfectedCamps.sqf"; + [] execVM "\z\addons\dayz_server\compile\server_spawnCarePackages.sqf"; + [] execVM "\z\addons\dayz_server\compile\server_spawnCrashSites.sqf"; + + + [] execVM "\z\addons\dayz_server\system\lit_fireplaces.sqf"; + + + "PVDZ_sec_atp" addPublicVariableEventHandler { + _x = _this select 1; + switch (1==1) do { + case (typeName _x == "STRING") : { // just some logs from the client + diag_log _x; + }; + case (count _x == 2) : { // wrong side + diag_log Format [ "P1ayer %1 reports possible 'side' hack... Server may be comprised!", (_x select 1) call fa_plr2Str ]; + }; + default { // player hit + _unit = _x select 0; + _source = _x select 1; + if (((!(isNil {_source})) AND {(!(isNull _source))}) AND {((_source isKindOf "CAManBase") AND {(owner _unit != owner _source)})}) then { + diag_log format ["P1ayer %1 hit by %2 %3 from %4 meters", + _unit call fa_plr2Str, _source call fa_plr2Str, _x select 2, _x select 3]; + if (_unit getVariable["processedDeath", 0] == 0) then { + _unit setVariable [ "attacker", name _source ]; + _unit setVariable [ "noatlf4", diag_ticktime ]; // server-side "not in combat" test, if player is not already dead + }; + }; + }; + }; + }; + // preload server traders menu data into cache if !(DZE_ConfigTrader) then { { @@ -347,13 +469,6 @@ if (isServer && isNil "sm_done") then { if (isDedicated) then { // Epoch Events _id = [] spawn server_spawnEvents; - // server cleanup - [] spawn { - private ["_id"]; - uiSleep 200; //Sleep Lootcleanup, don't need directly cleanup on startup + fix some performance issues on serverstart - waitUntil {!isNil "server_spawnCleanAnimals"}; - _id = [] execFSM "\z\addons\dayz_server\system\server_cleanup.fsm"; - }; // spawn debug box _debugMarkerPosition = getMarkerPos "respawn_west"; diff --git a/SQF/dayz_server/system/zombie_wildagent.fsm b/SQF/dayz_server/system/zombie_wildagent.fsm new file mode 100644 index 000000000..1c4182d4e --- /dev/null +++ b/SQF/dayz_server/system/zombie_wildagent.fsm @@ -0,0 +1,203 @@ +/*%FSM*/ +/*%FSM*/ +/* +item0[] = {"init",0,250,-75.000000,-400.000000,25.000000,-350.000000,0.000000,"init"}; +item1[] = {"No_More_Needed",4,218,-250.000000,-250.000000,-150.000000,-200.000000,0.000000,"No More" \n "Needed"}; +item2[] = {"Delay_",2,250,-75.000000,50.000000,25.000000,100.000000,0.000000,"Delay" \n ""}; +item3[] = {"Need_more",4,218,-75.000000,-175.000000,25.000000,-125.000000,3.000000,"Need more"}; +item4[] = {"Spawn",2,250,-75.000000,-100.000000,25.000000,-50.000000,0.000000,"Spawn"}; +item5[] = {"Timeout",4,218,50.000000,-250.000000,150.000000,-200.000000,0.000000,"Timeout"}; +item6[] = {"Return",8,218,-75.000000,-25.000000,25.000000,25.000000,0.000000,"Return"}; +item7[] = {"initialized",4,218,-75.000000,-325.000000,25.000000,-275.000000,0.000000,"initialized"}; +item8[] = {"prepare",2,250,-75.000000,-250.000000,25.000000,-200.000000,0.000000,"prepare"}; +item9[] = {"Check",2,250,-250.000000,-25.000000,-150.000000,25.000000,0.000000,"Check"}; +item10[] = {"",7,210,-204.000000,-154.000000,-196.000000,-146.000000,0.000000,""}; +item11[] = {"Released_Delay_",4,4314,-250.000000,50.000000,-150.000000,100.000000,0.000000,"Released" \n "Delay" \n ""}; +link0[] = {0,7}; +link1[] = {1,8}; +link2[] = {2,11}; +link3[] = {3,4}; +link4[] = {4,6}; +link5[] = {5,8}; +link6[] = {6,2}; +link7[] = {7,8}; +link8[] = {8,3}; +link9[] = {8,5}; +link10[] = {9,10}; +link11[] = {10,1}; +link12[] = {10,3}; +link13[] = {11,9}; +globals[] = {25.000000,1,0,0,0,640,480,1,47,6316128,1,-497.761261,579.685730,295.259521,-641.446960,689,599,1}; +window[] = {2,-1,-1,-32000,-32000,930,150,1479,150,3,707}; +*//*%FSM*/ +class FSM +{ + fsmName = "DayZ Wild Zeds Control"; + class States + { + /*%FSM*/ + class init + { + name = "init"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class initialized + { + priority = 0.000000; + to="prepare"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"!isnil ""bis_fnc_init"""/*%FSM*/; + action=/*%FSM*/"diag_log (""WILD SPAWN: INITIALIZING WILD SPAWN SCRIPT"");" \n + ""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Delay_ + { + name = "Delay_"; + init = /*%FSM*/"_timeD = diag_tickTime;"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class Released_Delay_ + { + priority = 0.000000; + to="Check"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"(diag_tickTime - _timeD) > 5"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Spawn + { + name = "Spawn"; + init = /*%FSM*/"_timeN = diag_tickTime;" \n + "" \n + "" \n + "_tmp = [_unitTypes, _amount2Spawn];" \n + "_waiting = _tmp call server_Wildgenerate;" \n + "" \n + "" \n + "" \n + "" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class Return + { + priority = 0.000000; + to="Delay_"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_waiting"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class prepare + { + name = "prepare"; + init = /*%FSM*/"_timeN = diag_tickTime;" \n + "_spawnmore = false;" \n + "_amount2Spawn = 100;" \n + "_totalamount=1000;" \n + "_unitTypes = [""Wild_Civ_newBase""];" \n + "" \n + "" \n + "_debugarea = getMarkerPos ""respawn_west"";" \n + "_pos = getMarkerPos ""center"";" \n + "" \n + "_wildZombies = {local _x} count (_pos nearEntities [""WildZombie_Base"",7500]);" \n + "_count = _totalamount - _wildZombies;" \n + "" \n + "if (_count > _amount2Spawn) then {" \n + " _spawnmore = true;" \n + "};" \n + "" \n + "diag_log format [""WILD SPAWN: Active: %1, Waiting: %2"",_wildZombies,_count]" \n + ""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class Need_more + { + priority = 3.000000; + to="Spawn"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_spawnmore"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class Timeout + { + priority = 0.000000; + to="prepare"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"(diag_tickTime - _timeN) > 600"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Check + { + name = "Check"; + init = /*%FSM*/"_spawnmore = false;" \n + "_wildZombies = {local _x} count (_pos nearEntities [""WildZombie_Base"",7500]);" \n + "_count = 200 - _wildZombies;" \n + "" \n + "if (_count > _amount2Spawn) then {" \n + " _spawnmore = true;" \n + "};"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class Need_more + { + priority = 3.000000; + to="Spawn"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"_spawnmore"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class No_More_Needed + { + priority = 0.000000; + to="prepare"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"!_spawnmore"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + }; + initState="init"; + finalStates[] = + { + }; +}; +/*%FSM*/ \ No newline at end of file