Trying to change zombie spawns from SPAWN to CALL

joikd

Well-Known Member
My changes to zombie spawns have made DayZ better IMHO, but have not achieved everything that I wanted. My changes so far include: increased number of zombies per spawn, increased spawn radius, elimination of multiple players increasing the number spawned, "safe zone" around a player once cleared, and zombies spawning while players are in vehicles.

With these changes one issue I am having is delayed spawning of zombies. I think this might be caused by the player_spawnCheck.sqf using timers and "spawn buildings_spawnZombies". I want to simplify the code by removing all of the timer, waitUntil's, and the change from SPAWN to CALL on the buildings_spawnZombies.

Instead I want a check on the "building" to see if the number of zombies within a certain radius is less than a certain amount, and, if so, call buildings_spawnZombies (assuming a player is within range).

It looks like I can just comment out most of the stuff relating to zombies in buildings_spawnZombies, add a line to check the number of zombies in whatever radius, and do an if/then based on that number. I would appreciate any input on this from a scripting standpoin.
 
if you do that, it will spawn infinite zeds when the actual are inside a building, that can be dangerous.
 
Found success with this below. Zombie spawn radius varies inversely with the amount of potential building spawns. Still tweaking, but it's a good start.

Code:
_inVehicle = vehicle player isKindOf "player";
_fastRun = _this select 0;
_position = getPosATL player;
if (count (_position nearObjects ["building",500]) < 11) then {
    _nearby = _position nearObjects ["building",500];
} else {
    if (count (_position nearObjects ["building",400]) < 11) then {
    _nearby = _position nearObjects ["building",400];
    } else {
        if (count (_position nearObjects ["building",300]) < 11) then {
            _nearby = _position nearObjects ["building",300];
        } else {           
            if (count (_position nearObjects ["building",200]) > 0) then {
                _nearby = _position nearObjects ["building",200];
                _tooManyZs = {alive _x} count (_position nearEntities ["zZombie_Base",200]) > dayz_maxLocalZombies;
            {
                _type = typeOf _x;
                _config =        configFile >> "CfgBuildingLoot" >> _type;
                _canLoot =        isClass (_config);       
                if (_canLoot) then {
                    if (!_tooManyZs) then {
                        _dis = _x distance player;                   
                        _bPos = getPosATL _x;
                        _zombiesNum = {alive _x} count (_bPos nearEntities ["zZombie_Base",(((sizeOf _type) * 2) + 10)]);
                        if (_zombiesNum == 0) then {
                            [_x,_fastRun] call building_spawnZombies;
                        };
                    };       
                };
            } forEach _nearby;
            };
        };
    };
};
 
I would like to add this to my server, did you add this as an addition sqf to be execed or replace/comment out the existing code in one of the sqf files.
 
Use this instead. It's the latest version of mine, which has been optimized by a much more capable person than myself.

Change the two numbers to your liking in [,] for each of the "call SpawnCheack"s. Just make sure that you go from highest to lowest for the range (second number) since it checks from long range and moves to short range, if necessary. You could even add additional range checks if you wanted. One thing I have found is that "building"s can include many non-spawning buildings, especially in industrial areas (cargo containers?). So, 51 was just a test--it is probably too high.

This version also has the _tooManyMen check, which will prevent additional players from causing zombies to spawn from the same buildings that the first player already initiated spawns. So, the number of zombies spawned has nothing to do with the number of players unlike vanilla DayZ (which I think is dumb).

Also, I have a "safe zone" of 100 around each player where zombies cannot spawn (the "safe zone" moves with the player). This allows a decent sized area to be cleared, and remain clear of all zombies (unless they wander over on their own, they see you, or a player makes a loud noise). If you are interested in that (or in a couple of other zombie tweaks I have made) let me know, and I will post it all.

This code replaced my entire player_spawnCheck.sqf, but you can keep the loot sections if you want. I am currently working on making loot spawn only once when the first player joins a server (loot code will probably go back into this file). That will stop farming, and force players to roam the map looking for crash sites, care packages, and even go to some of the smaller towns--really struggle to survive when combined with tweaked loot chances (lower).

Code:
SpawnCheck =
{
private ["_nearby","_ncount","_distance","_num","_tooManyZs","_tooManyMen"];
 
_num = _this select 0;
_distance = _this select 1;
_nearby = _position nearObjects ["building", _distance];
_ncount = count _nearby;
_tooManyZs = {alive _x} count (_position nearEntities ["zZombie_Base",200]) > dayz_maxLocalZombies;
_tooManyMen = {_x} count (_nearby nearEntities ["CAManBase",_distance]) > 1;
 
if ((_ncount > 0) and (_ncount < _num )) then {
if (!_tooManyZs) then {   
if (!_tooManyMen) then {
    _counter = 1;
    {
        _type = typeOf _x;
        _config = configFile >> "CfgBuildingLoot" >> _type;
        _canLoot = isClass (_config);       
        if (_canLoot) then {                                           
            _bPos = getPosATL _x;
            _zombiesNum = {alive _x} count (_bPos nearEntities ["zZombie_Base",(((sizeOf _type) * 2) + 30)]);
            if (_zombiesNum == 0) then {
                [_x,_fastRun] call building_spawnZombies;
            };               
        };
    } forEach _nearby;
};
};
};
};
 
private ["_nearby","_bPos","_zombiesNum","_type","_config","_canLoot","_inVehicle","_fastRun","_position","_counter"];
_inVehicle = vehicle player isKindOf "player";
_fastRun = _this select 0;
_position = getPosATL player;
_counter = 0;   
 
[51,500] call SpawnCheck;
 
if (_counter != 0) then {
    _counter = 0;
} else {
    [51,400] call SpawnCheck;
};
if (_counter != 0) then {
    _counter = 0;
} else {
    [51,300] call SpawnCheck;
};
if (_counter != 0) then {
    _counter = 0;
} else {
    [1000, 200] call SpawnCheck;
};
 
Thank you very much, I am definitely interested in that safe zone. I found that I could exec this inside the init like this and it would work properly.


fnc_usec_selfActions = compile preprocessFileLineNumbers "fixes\zombieSpawns.sqf";
 
I forgot to mention that I think a short "sleep" (.1 maybe?) might be needed in between call building_spawnZombies and forEach _nearby since it seems that call dominates completely until it completes as opposed to spawn (want to avoid any stutter in-game). If you do this, and find a good setting, please let me know. That goes for the rest of the settings as well. By the way, if you enable zombie spawning while speeding in a vehicle, the code above will spawn them just in time in most cases from what I have seen (sometimes even earlier--still tweaking).

Safe zone:
dayz_code\compile\zombie_generate.sqf
Code:
_isNoone =    {isPlayer _x} count (_position nearEntities ["AllVehicles",100]) == 0;

The 100 is the safe zone. Change to your whatever you want. You know where to alter the other zombie stuff, right (numbers, etc.)?


It appears you are much more knowledgeable than I am, thevisad. Maybe you can help me with something. I am trying to get this code to run just once upon server start (or when the first player joins, but only once per restart). This will spawn all building loot just the one time (well, if it works). Any ideas? I tried adding it to the dayz_server.pbo, but it didn't like that (couldn't even get past the "Loading" screen).

Code:
spawn_allBuildingLoot = {
    private["_center","_Chernarus","_allBldngs","_fastRun","_type","_config","_canLoot","_handle"];
   
    if (isDedicated) then {
        _center = getArray (configFile >> "CfgWorlds" >> _Chernarus >> "centerPosition";
        _allBldngs = _center nearObjects ["building",20000];
        _fastRun = _this select 0;
        {
            _type = typeOf _x;
            _config = configFile >> "CfgBuildingLoot" >> _type;
            _canLoot = isClass (_config);       
            if (_canLoot) then {               
                _handle = [_x,_fastRun] spawn building_spawnLoot;
                waitUntil{scriptDone _handle};
                _x setVariable ["permaLoot",true];
            };
        } forEach _allBldngs;
    };
};
 
I think I am going to add this after _tooManyMen in player_spawnCheck. I have noticed that buildings will keep spawning zombies as soon as the preceding group reaches a certain distance.

Code:
_nearbyZs = {_x} count (_nearby nearEntities ["zZombie_Base",30]) > 4;

Then, add under the: if (!_tooManyMen) then

Code:
if (!_nearbyZs) then {
 
Thank you sir, I will test these out and you give me more credit then I deserve. I am just beginning to mod Dayz; although, I have been developing video games for the past 4 years , so I have a little background in this stuff already.
 
This bit of code here looks to be redundant, the if (!_counter) are all the same. This would cause each to run, tripling the amount of zeds within the area. In addition, it looks like _counter will always equal 0, which means these will always execute. I am rewriting the existing player_spawnCheck.sqf file to handle the new code. This should also allow all of the items in the server to spawn once and be done.


Code:
_counter = 0; 
 
[51,500] call SpawnCheck;
 
if (_counter != 0) then {
    _counter = 0;
} else {
    [51,400] call SpawnCheck;
};
if (_counter != 0) then {
    _counter = 0;
} else {
    [51,300] call SpawnCheck;
};
if (_counter != 0) then {
    _counter = 0;
} else {
    [1000, 200] call SpawnCheck;
};
 
Not near a machine I can actually test this on, but here is a modified player_spawnCheck.sqf that should allow all items to spawn in game a single time per server start, in addition to causing zeds to spawn regardless of player being in vehicle.

Code:
_isAir = vehicle player iskindof "Air";
_inVehicle = vehicle player isKindOf "player";
_fastRun = _this select 0;
_dateNow = (DateToNumber date);
_age = -1;
_handle = [_x,_fastRun] call building_spawnLoot;
waitUntil{scriptDone _handle};
 
    _position = getPosATL player;
    _nearby = _position nearObjects ["building",400];
    _tooManyZs = {alive _x} count (_position nearEntities ["zZombie_Base",400]) > dayz_maxLocalZombies;
    {
        _type = typeOf _x;
        _config =        configFile >> "CfgBuildingLoot" >> _type;
        _canLoot =        isClass (_config);       
        if (_canLoot) then {           
               
            if ((time - dayz_spawnWait) > dayz_spawnDelay) then {
                if (dayz_spawnZombies < dayz_maxLocalZombies) then {
                    if (!_tooManyZs) then {
                        private["_zombied"];
                        _zombied = (_x getVariable ["zombieSpawn",-0.1]);
                        _dateNow = (DateToNumber date);
                        _age = (_dateNow - _zombied) * 525948;
                        if (_age > 5) then {
                            _bPos = getPosATL _x;
                            _zombiesNum = {alive _x} count (_bPos nearEntities ["zZombie_Base",(((sizeOf _type) * 2) + 10)]);
                            if (_zombiesNum == 0) then {
                                _x setVariable ["zombieSpawn",_dateNow,true];
                                _handle = [_x,_fastRun] call building_spawnZombies;
                                waitUntil{scriptDone _handle};
                            };
                        };
                    };
                } else {
                    dayz_spawnWait = time;
                    dayz_spawnZombies = 0;
                };
            };
        };
        if (!_fastRun) then {
            sleep 0.1;
        };
    } forEach _nearby;
 
You were right about that version of my zombie spawn--_counter was kooky.

My latest version works perfectly at the different ranges. The only issue is that I can't figure out how to count how many zombies are in each _nearby's radius. Without this, zombies keep spewing out until _tooManyZs is reached. This is a showstopper.

The code I am having trouble with is the two lines below--zero zombies spawn ever. Any help would be appreciated.

Code:
_nearbyZs = {alive _x} count ((getPosATL _nearby) nearEntities ["zZombie_Base",30]);
                if (_nearbyZs < 10) then {


Here is the entire thing:

Code:
private ["_nearby","_nearby5","_nearby4","_nearby3","_type","_config","_canLoot","_inVehicle","_position"];
_inVehicle = vehicle player isKindOf "player";
_position = getPosATL player;
_tooManyZs = {alive _x} count (_position nearEntities ["zZombie_Base",200]) > dayz_maxLocalZombies;   
 
if (!_tooManyZs) then {
    _nearby5 = count (_position nearObjects ["building",500]);
    if ((_nearby5 > 0) and (_nearby5 < 41)) then {
        _nearby = _position nearObjects ["building",500];
        _nearbyZs = {alive _x} count ((getPosATL _nearby) nearEntities ["zZombie_Base",30]);
        if (_nearbyZs < 10) then {
            {
                _type = typeOf _x;
                _config = configFile >> "CfgBuildingLoot" >> _type;
                _canLoot = isClass (_config);       
                if (_canLoot) then {           
                    [_x] call building_spawnZombies;
                };
            } forEach _nearby;
        } else {
            _nearby4 = count (_position nearObjects ["building",400]);
            if ((_nearby4 > 0) and (_nearby4 < 41)) then {
                _nearby = _position nearObjects ["building",400];
                _nearbyZs = {alive _x} count ((getPosATL _nearby) nearEntities ["zZombie_Base",30]);
                if (_nearbyZs < 10) then {
                    {
                        _type = typeOf _x;
                        _config = configFile >> "CfgBuildingLoot" >> _type;
                        _canLoot = isClass (_config);       
                        if (_canLoot) then {           
                            [_x] call building_spawnZombies;
                        };
                    } forEach _nearby;           
                } else {
                    _nearby3 = count (_position nearObjects ["building",300]);
                    if ((_nearby3 > 0) and (_nearby3 < 41)) then {
                        _nearby = _position nearObjects ["building",300];
                        _nearbyZs = {alive _x} count ((getPosATL _nearby) nearEntities ["zZombie_Base",30]);
                        if (_nearbyZs < 10) then {
                            {
                                _type = typeOf _x;
                                _config = configFile >> "CfgBuildingLoot" >> _type;
                                _canLoot = isClass (_config);       
                                if (_canLoot) then {                               
                                    [_x] call building_spawnZombies;
                                };
                            } forEach _nearby;           
                        } else {           
                            _nearby = _position nearObjects ["building",200];
                            _nearbyZs = {alive _x} count ((getPosATL _nearby) nearEntities ["zZombie_Base",30]);
                            if (_nearbyZs < 10) then {
                                {
                                    _type = typeOf _x;
                                    _config = configFile >> "CfgBuildingLoot" >> _type;
                                    _canLoot = isClass (_config);       
                                    if (_canLoot) then {                                   
                                        [_x] call building_spawnZombies;   
                                    };
                                } forEach _nearby;                       
                            };
                        };
                    };
                };
            };
        };
    };
};
 
I didn't think that one would work. It was one of many variations. Thanks for the explanation, Killzone. I did steal that line from another file, so now I am confused about your #1.

I've tried changing two different lines in building_spawnZombies.sqf, but with no success.

Any ideas on how to count the zombies around a building before it spawns more?
 
Edit: wrong file (corrected)

One thing that I think I never mentioned was that if you increase the zombie spawn range, you must also increase the 200 to your max range in dayz_code\system\_zombieAgent.fsm. Otherwise, the zombies will spawn, then disappear in a few seconds. Line 376 & 540

Code:
"_list = (getposATL _agent) nearEntities [[""CAManBase"",""AllVehicles""],500];" \n

Code:
"_list = (getposATL _agent) nearEntities [[""CAManBase"",""AllVehicles""],500];" \n

One of these lines has something to do with loiter behavior. They were both the same, so I figured that they should remain the same upon changing the other one.
 
I have a new version of my zombie spawn with a few big changes (for the better).

1. It uses nearestObjects rather than nearObjects, which does two important things.

It arranges by distance from close to far, which gives a better chance of spawning zombies while moving fast in a vehicle.

It also only gets "building"s that can spawn zombies, which does two good things itself--no need to filter out the non-spawning "building"s (waste of resources), and more importantly, does not skew zombie spawning distance when the player is near a bunch of non-spawning "building"s. Using nearObjects in an industrial area would cause the zombie spawn range to drop to the lowest range because it was counting those non-spawning "building"s.

2. It also uses nearestObjects just once, then whittles down that array from one range to the next, so there is no need to process a bunch of unnecessary "building"s over and over at each range. The first 100 it subtracts is my "safe zone"--no need to keep processing those over and over since they can't spawn.

3. It uses a three-pronged approach for controlling zombie spawn numbers. The first is the vanilla dayz_maxLocalZombies (set to 150), which I have set to check within my highest range (450). The second is that it counts the number of zombies within 450 of each building itself right before each building spawns, and determines whether it passes. This keeps multiple players from causes a glut of zombies to spawn from the same building.

With just these two you are guaranteed to never have more than the number of zombies that you specified with 450 of the player and building. That works great if there are many buildings. But, what if there is just one building? Using just those two will cause that one building to keep spawning zombies until the max threshold is reached. In my case, it will keep spewing them until it hits 150 zombies. Well, that's no good! And, that's where the third check comes in.

It takes the number of buildings in the _nearby array, and multiplies it by a number to reach an acceptable zombie max spawn number. In my case, it will multiply 7.5 by the number of buildings. So, if there is only one building in range, then there is only one building in _nearby. 7.5 x 1 = 7.5. So, once there are 8 or more zombies within 450, that building will not spawn anymore. This scales just fine no matter how many buildings are in range.

I hacked down _building_spawnZombies to remove unnecessary checks. I also changed the zombie min/max spawn amount to a simple random 20. I prefer this as it makes for very unpredictable spawning numbers. Some buildings might spawn a lot, some a little, and some even none. The zero spawn is an effective counter to players knowing if another player is around since, without this, the "safe zone" would give the other player away (no zombies spawning around some buildings).

I also discarded zombie spawns inside buildings to encourage a larger dispersal, and give a better chance of vehicles at fast speeds coming into contact with zombies.

Hopefully, this will be of use to someone.

player_spawnCheck

Code:
private["_isAir","_inVehicle","_position","_within100","_beyond300","_beyond200","_within450","_tooManyZs","_mydistance","_legit450","_nearby","_legit300","_bPos","_bWithin","_zombiesNum"];
_isAir = vehicle player iskindof "Air";
_inVehicle = vehicle player isKindOf "player";
_position = getPosATL player;
_within100 = [];
_beyond300 = [];
_beyond200 = [];
_within450 = nearestObjects [_position, ["Office","Church","Land_HouseV_1I4","Land_kulna","Land_Ind_Workshop01_01","Land_Ind_Garage01","Land_Ind_Workshop01_02","Land_Ind_Workshop01_04","Land_Ind_Workshop01_L","Land_Hangar_2","Land_hut06","Land_stodola_old_open","Land_A_FuelStation_Build","Land_A_GeneralStore_01a","Land_A_GeneralStore_01","Land_Farm_Cowshed_a","Land_stodola_open","Land_Barn_W_01","Land_Hlidac_budka","Land_HouseV2_02_Interier","Land_a_stationhouse","Land_Mil_ControlTower","Land_SS_hangar","Land_A_Pub_01","Land_HouseB_Tenement","Land_A_Hospital","Land_Panelak","Land_Panelak2","Land_Shed_Ind02","Land_Shed_wooden","Land_Misc_PowerStation","Land_HouseBlock_A1_1","Land_Shed_W01","Land_HouseV_1I1","Land_Tovarna2","Land_rail_station_big","Land_Ind_Vysypka","Land_A_MunicipalOffice","Land_A_Office01","Land_A_Office02","Land_A_BuildingWIP","Land_Church_01","Land_Church_03","Land_Church_02","Land_Church_02a","Land_Church_05R","Land_Mil_Barracks_i","Land_A_TVTower_Base","Land_Mil_House","Land_Misc_Cargo1Ao","Land_Misc_Cargo1Bo","Land_Nav_Boathouse","Land_ruin_01","Land_wagon_box","Land_HouseV2_04_interier","Land_HouseV2_01A","Land_psi_bouda","Land_KBud","Land_A_Castle_Bergfrit","Land_A_Castle_Stairs_A","Land_A_Castle_Gate","Land_Mil_Barracks","Land_Mil_Barracks_L","Land_Barn_W_02","Land_sara_domek_zluty","Land_HouseV_3I4","Land_Shed_W4","Land_HouseV_3I1","Land_HouseV_1L2","Land_HouseV_1T","Land_telek1","Land_Rail_House_01","Land_HouseV_2I","Land_Misc_deerstand","Camp","CampEast","CampEast_EP1","MASH","MASH_EP1","UH1Wreck_DZ","USMC_WarfareBFieldhHospital","Land_Ind_Shed_02_main","Land_Shed_W03","Land_HouseV_1I3","Land_HouseV_1L1","Land_HouseV_1I2","Land_HouseV_2L","Land_HouseV_2T1","Land_houseV_2T2","Land_HouseV_3I2","Land_HouseV_3I3","Land_HouseBlock_A1","Land_HouseBlock_A1_2","Land_HouseBlock_A2","Land_HouseBlock_A2_1","Land_HouseBlock_A3","Land_HouseBlock_B1","Land_HouseBlock_B2","Land_HouseBlock_B3","Land_HouseBlock_B4","Land_HouseBlock_B5","Land_HouseBlock_B6","Land_HouseBlock_C1","Land_HouseBlock_C2","Land_HouseBlock_C3","Land_HouseBlock_C4","Land_HouseBlock_C5","Land_HouseV2_01B","Land_Misc_Cargo1D","Land_HouseV2_03","Land_Ind_Shed_01_end","Land_A_statue01","Land_Shed_W02"], 450];
_tooManyZs = {alive _x} count (_position nearEntities ["zZombie_Base",450]) > dayz_maxLocalZombies;
{
    _mydistance = player distance _x;
    if (_mydistance <= 100) then {
        _within100 set [_x];
    };
} foreach _within450;
_legit450 = _within450 - _within100;
if ((count _legit450 > 0) and (count _legit450 < 11)) then {
    _nearby = _legit450;
} else {
    {
        if (_mydistance > 300) then {
            _beyond300 set [_x];
        };
    } foreach _legit450;
    _legit300 = _legit450 - _beyond300;
    if ((count _legit300 > 0) and (count _legit300 < 11)) then {
        _nearby = _legit300;
    } else {
        {
            if (_mydistance > 200) then {
                _beyond200 set [_x];
            };
        } foreach _legit300;
        _nearby = _legit300 - _beyond200; 
    };
};
{
    if (!_tooManyZs) then {
        _bPos = getPosATL _x;
        _bWithin = count _nearby;
        _zombiesNum = {alive _x} count (_bPos nearEntities ["zZombie_Base",450]);
        if ((_zombiesNum < 150) and (_zombiesNum < (7.5 * _bWithin))) then {
            [_x] call building_spawnZombies;
        };
    }; 
} forEach _nearby


building_spawnZombies

Code:
private["_obj","_type","_config","_originalPos","_unitTypes","_num"];
_obj =            _this select 0;
_type =        typeOf _obj;
_config =        configFile >> "CfgBuildingLoot" >> _type;
_originalPos =    getPosATL _obj;
 
//Get zombie class
_unitTypes =    getArray (_config >> "zombieClass");
 
//Walking Zombies
_num = round(random 20);
for "_i" from 1 to _num do
{
    [_originalPos,true,_unitTypes] call zombie_generate;
    sleep .1;
};
dayz_buildingMonitor set [count dayz_buildingMonitor,_obj];
 
IMPORTANT UPDATE!

After much testing and experimentation I have discovered that the cause of zombie spawn stuttering is directly tied to the number of zombies spawning simultaneously. It sounds obvious, but everything I tried yielded, at least, some very noticeable stuttering. Most times it was just for a split second, but that is still annoying.

The fix for this is to spawn no more than 2 or 3 zombies per spawn point at a time, and begin the spawning far out (which is something that we want anyway!). An analogy would be turning on a faucet at a very low level for an extended period of time instead of a high level for a very short time. I was finally able to run all the way through Cherno with no stutter and with lots of zombies from beginning to end.

Now we need to find out what is the limit of the number of concurrent zombies. I probably won't be able to get enough players to test this on my server, so please test this if you can.

I will post all of the code for the three zombie spawn sqf's. Of course, you might have to tweak the numbers slightly depending on the number of players. My dayz_maxLocalZombies in variables.sqf is 300. Anything in zombie_agent.fsm that had the default 300 with CAManBase was changed to 600 (I think maybe 4 or 5 of them).

If you have any questions, input, ideas, please post.


player_spawnCheck.sqf
Code:
private["_isAir","_inVehicle","_position","_nearby","_tooManyZs","_bPos","_bWithin","_zombiesNum"];
_isAir = vehicle player iskindof "Air";
_inVehicle = vehicle player isKindOf "player";
_position = getPosATL player;
_nearby = nearestObjects [_position, ["Office","Church","Land_HouseV_1I4","Land_kulna","Land_Ind_Workshop01_01","Land_Ind_Garage01","Land_Ind_Workshop01_02","Land_Ind_Workshop01_04","Land_Ind_Workshop01_L","Land_Hangar_2","Land_hut06","Land_stodola_old_open","Land_A_FuelStation_Build","Land_A_GeneralStore_01a","Land_A_GeneralStore_01","Land_Farm_Cowshed_a","Land_stodola_open","Land_Barn_W_01","Land_Hlidac_budka","Land_HouseV2_02_Interier","Land_a_stationhouse","Land_Mil_ControlTower","Land_SS_hangar","Land_A_Pub_01","Land_HouseB_Tenement","Land_A_Hospital","Land_Panelak","Land_Panelak2","Land_Shed_Ind02","Land_Shed_wooden","Land_Misc_PowerStation","Land_HouseBlock_A1_1","Land_Shed_W01","Land_HouseV_1I1","Land_Tovarna2","Land_rail_station_big","Land_Ind_Vysypka","Land_A_MunicipalOffice","Land_A_Office01","Land_A_Office02","Land_A_BuildingWIP","Land_Church_01","Land_Church_03","Land_Church_02","Land_Church_02a","Land_Church_05R","Land_Mil_Barracks_i","Land_A_TVTower_Base","Land_Mil_House","Land_Misc_Cargo1Ao","Land_Misc_Cargo1Bo","Land_Nav_Boathouse","Land_ruin_01","Land_wagon_box","Land_HouseV2_04_interier","Land_HouseV2_01A","Land_psi_bouda","Land_KBud","Land_A_Castle_Bergfrit","Land_A_Castle_Stairs_A","Land_A_Castle_Gate","Land_Mil_Barracks","Land_Mil_Barracks_L","Land_Barn_W_02","Land_sara_domek_zluty","Land_HouseV_3I4","Land_Shed_W4","Land_HouseV_3I1","Land_HouseV_1L2","Land_HouseV_1T","Land_telek1","Land_Rail_House_01","Land_HouseV_2I","Land_Misc_deerstand","Camp","CampEast","CampEast_EP1","MASH","MASH_EP1","UH1Wreck_DZ","USMC_WarfareBFieldhHospital","Land_Ind_Shed_02_main","Land_Shed_W03","Land_HouseV_1I3","Land_HouseV_1L1","Land_HouseV_1I2","Land_HouseV_2L","Land_HouseV_2T1","Land_houseV_2T2","Land_HouseV_3I2","Land_HouseV_3I3","Land_HouseBlock_A1","Land_HouseBlock_A1_2","Land_HouseBlock_A2","Land_HouseBlock_A2_1","Land_HouseBlock_A3","Land_HouseBlock_B1","Land_HouseBlock_B2","Land_HouseBlock_B3","Land_HouseBlock_B4","Land_HouseBlock_B5","Land_HouseBlock_B6","Land_HouseBlock_C1","Land_HouseBlock_C2","Land_HouseBlock_C3","Land_HouseBlock_C4","Land_HouseBlock_C5","Land_HouseV2_01B","Land_Misc_Cargo1D","Land_HouseV2_03","Land_Ind_Shed_01_end","Land_A_statue01","Land_Shed_W02"], 500];
_tooManyZs = {alive _x} count (_position nearEntities ["zZombie_Base",500]) > dayz_maxLocalZombies;
 
{
    if (!_tooManyZs) then {
        _bPos = getPosATL _x;
        _bWithin = count _nearby;
        _zombiesNum = {alive _x} count (_bPos nearEntities ["zZombie_Base",500]);
        if ((_zombiesNum < 300) and (_zombiesNum < (20 * _bWithin))) then {
            [_x] call building_spawnZombies;
        };
    };   
} forEach _nearby


building_spawnZombies.sqf
Code:
private["_obj","_type","_config","_originalPos","_unitTypes","_num"];
_obj =            _this select 0;
_type =        typeOf _obj;
_config =        configFile >> "CfgBuildingLoot" >> _type;
_originalPos =    getPosATL _obj;
 
//Get zombie class
_unitTypes =    getArray (_config >> "zombieClass");
 
//Walking Zombies
_num = 2;
for "_i" from 1 to _num do
{
    [_originalPos,_unitTypes] call zombie_generate;
};
dayz_buildingMonitor set [count dayz_buildingMonitor,_obj];


zombie_generate.sqf
Code:
private["_position","_unitTypes","_isNoone","_loot","_array","_agent","_type","_radius","_method","_myDest","_newDest","_rnd","_lootType","_id"];
_position =    _this select 0;
_unitTypes =    _this select 1;
_isNoone =    {isPlayer _x} count (_position nearEntities ["AllVehicles",450]) == 0;
_loot =    "";
_array =    [];
_agent =    objNull;
 
//Exit if a player is nearby
if (!_isNoone) exitWith {};
if (count _unitTypes == 0) then {
    _unitTypes =    []+ getArray (configFile >> "CfgBuildingLoot" >> "Default" >> "zombieClass");
};
_type = _unitTypes call BIS_fnc_selectRandom;
 
//Create the Group and populate it
_radius = 0;
_method = "CAN_COLLIDE";
_radius = 40;
_method = "NONE";
_agent = createAgent [_type, _position, [], _radius, _method];
_agent setPosATL _position;
_position = getPosATL _agent;
if (random 1 > 0.7) then {
    _agent setUnitPos "Middle";
};       
_agent setPos _position;   
_myDest = getPosATL _agent;
_newDest = getPosATL _agent;
_agent setVariable ["myDest",_myDest];
_agent setVariable ["newDest",_newDest];
 
//Add some loot
_rnd = random 1;
if (_rnd > 0.3) then {
    _lootType = configFile >> "CfgVehicles" >> _type >> "zombieLoot";
    if (isText _lootType) then {
        _array = []+ getArray (configFile >> "cfgLoot" >> getText(_lootType));
        if (count _array > 0) then {
            _loot = _array call BIS_fnc_selectRandomWeighted;
            if(!isNil "_array") then {
                _agent addMagazine _loot;
            };
        };
    };
};
 
//Start behavior
_id = [_position,_agent] execFSM "\z\AddOns\dayz_code\system\zombie_agent.fsm";
 
No, I didn't realize that zombies are local. Thanks for the info. That's probably better since the workload can be spread over many computers (i.e. we can have more zombies).

So, the question is how many zombies can a given level of player computer handle? I have a decent one (2500k @ 4.7). Using the settings above (with despawn set at 600) it is hitting around 72% for me.

Since there are so many private servers to choose from, maybe I will make the first server for decent computers only! Nah, I'm just kidding. I have given no thought the max zombie number. Using 300 was just to see if the principle was sound. And, it sure looks like that it is easier (smoother) for any given system to spawn 1 zombie from 40 spawn points rather than 40 zombies from 1 spawn point.

Also, I didn't mention that the code above gives a "safe zone" of 450 where no zombies will spawn. So, Cherno can now be cleared of zombies leaving the player free to roam zombie-free. But, now I need to figure out a way to spawn players at least 500 from any zombie spawn point. Otherwise, cheesy players will run to the middle of a city, then log off/log on and face zero zombies, but have free reign of the entire city!
 
Back
Top