Clean up code and optimize building_spawnZombies

Checking for near zombies and players in the forEach loop is inappropriate and inefficient. Because it was checking for near zombies, the internal zombies were not spawning at all. It appeared that they were because the walking zombies were using the building position plus the radius option on createAgent. fn_selectRandomLocation using the size of the object as the minimum distance prevents the zombies from potentially spawning into objects and dying. The max distance for the crash site zombies is increased a bit so they can spawn farther away from the object since they are in an open field. The position on the internal zombies should not have the z coordinate automatically set to zero. This prevents the zombies from spawning at positions on upper floors of buildings.
This commit is contained in:
worldwidesorrow
2020-01-09 16:20:03 -06:00
committed by GitHub
parent 6bcfb68baa
commit 22a04e7955

View File

@@ -2,58 +2,43 @@
Created exclusively for ArmA2:OA - DayZMod. Created exclusively for ArmA2:OA - DayZMod.
Please request permission to use/alter/distribute from project leader (R4Z0R49) Please request permission to use/alter/distribute from project leader (R4Z0R49)
*/ */
private ["_wreck","_iPos","_nearByZed","_nearByPlayer","_rnd","_positions","_zombieChance","_unitTypes","_min","_max","_num","_clean","_obj","_type","_config","_canLoot","_originalPos","_fastRun","_enabled","_i","_Pos"]; private ["_type","_position","_minDist","_maxDist","_isWreck","_nearByPlayer","_iPos","_positions","_zombieChance","_unitTypes","_min","_max","_num","_clean","_obj","_config","_i","_objPos"];
_obj = _this select 0; _obj = _this select 0;
_type = _this select 1; _objPos = _this select 1;
_config = _this select 2; _config = _this select 2;
_wreck = false; _isWreck = _this select 3;
if (count _this > 3) then { _type = typeOf _obj;
_wreck = _this select 3;
};
_originalPos = getPosATL _obj;
if (!([_originalPos] call DZE_SafeZonePosCheck)) then { if (!([_objPos] call DZE_SafeZonePosCheck)) then {
//Get zombie class
_unitTypes = getArray (_config >> "zombieClass"); _unitTypes = getArray (_config >> "zombieClass");
_min = getNumber (_config >> "minRoaming"); _min = getNumber (_config >> "minRoaming");
_max = getNumber (_config >> "maxRoaming"); _max = getNumber (_config >> "maxRoaming");
_zombieChance = getNumber (_config >> "zombieChance"); _zombieChance = getNumber (_config >> "zombieChance");
_num = round(random(_max - _min) + _min);
//Walking Zombies _minDist = (sizeOf _type);
_num = (round(random _max)) max _min; // + round(_max / 3); _maxDist = if (_isWreck) then {(_minDist + 20)} else {(_minDist + 10)}; // zeds at crash sites can spawn further away.
//diag_log ("Class: " + _type + " / Zombies: " + str(_unitTypes) + " / Walking: " + str(_num));
for "_i" from 0 to _num do // Walking Zombies
{ for "_i" from 0 to _num do {
//_iPos = _obj modelToWorld _originalPos;
if ((dayz_spawnZombies < dayz_maxControlledZombies) && {dayz_CurrentNearByZombies < dayz_maxNearByZombies} && {dayz_currentGlobalZombies < dayz_maxGlobalZeds}) then { if ((dayz_spawnZombies < dayz_maxControlledZombies) && {dayz_CurrentNearByZombies < dayz_maxNearByZombies} && {dayz_currentGlobalZombies < dayz_maxGlobalZeds}) then {
[_originalPos,true,_unitTypes,_wreck] call zombie_generate; _position = [_objPos,_minDist,_maxDist,1] call fn_selectRandomLocation;
[_position,true,_unitTypes,_isWreck,false] call zombie_generate;
}; };
}; };
//Add Internal Zombies // Internal Zombies
if ((random 1) < _zombieChance) then { _nearByPlayer = ({isPlayer _x} count (_objPos nearEntities ["CAManBase",30])) > 0;
_clean = {alive _x} count ((getPosATL _obj) nearEntities ["zZombie_Base",(sizeOf _type)]) == 0; if (!_nearByPlayer) then {
if (_clean) then { _positions = getArray (_config >> "zedPos");
_positions = getArray (_config >> "zedPos"); {
//diag_log format["Building: %1 / Positions: %2 / Chance: %3",_type,_positions,_zombieChance]; if (random 1 < _zombieChance) then {
{ _iPos = _obj modelToWorld _x;
_Pos = [_x select 0, _x select 1, 0]; _iPos set [2, 0 max (_iPos select 2)];
_rnd = random 1; if ((dayz_spawnZombies < dayz_maxControlledZombies) && {dayz_CurrentNearByZombies < dayz_maxNearByZombies} && {dayz_currentGlobalZombies < dayz_maxGlobalZeds}) then {
if (_rnd < _zombieChance) then { [_iPos,false,_unitTypes,false,true] call zombie_generate;
_iPos = _obj modelToWorld _Pos;
_nearByZed = {alive _x} count (_iPos nearEntities ["zZombie_Base",(((sizeOf _type) * 2) + 10)]) > 0;
_nearByPlayer = ({isPlayer _x} count (_iPos nearEntities ["CAManBase",30])) > 0;
//diag_log ("BUILDING: " + _type + " / " + str(_nearByZed) + " / " + str(_nearByPlayer));
if ((dayz_spawnZombies < dayz_maxControlledZombies) && {dayz_CurrentNearByZombies < dayz_maxNearByZombies} && {dayz_currentGlobalZombies < dayz_maxGlobalZeds}) then {
if (!_nearByPlayer and {!_nearByZed}) then {
[_iPos,false,_unitTypes,false] call zombie_generate;
};
};
}; };
} forEach _positions; };
}; } forEach _positions;
}; };
}; };
//diag_log ("2 end");