SERVER: Greater parity for Zombie spawning

This commit is contained in:
cypress 2023-12-20 14:45:51 -05:00
parent 0874299caf
commit 7453903a0b
4 changed files with 78 additions and 43 deletions

View file

@ -1104,6 +1104,7 @@ void() removeZombie =
self.outside = TRUE; self.outside = TRUE;
self.hop_step = 0; self.hop_step = 0;
self.onfire = false;
self.calc_time = 0; self.calc_time = 0;
self.tries = 0; self.tries = 0;
self.takedamage = DAMAGE_NO; self.takedamage = DAMAGE_NO;
@ -1465,6 +1466,8 @@ void() spawn_zombie =
if (cvar("developer")) if (cvar("developer"))
setmodel(self, "models/ai/zfull.mdl"); setmodel(self, "models/ai/zfull.mdl");
self.classname = "spawn_zombie"; self.classname = "spawn_zombie";
self.spawn_id = zombie_spawn_points;
zombie_spawn_points++;
} }
//self.think = zombie_spawn_think; //self.think = zombie_spawn_think;
@ -1493,6 +1496,39 @@ void() set_z_health =
} }
}; };
//
// Zombie_ReassignSpawnIDs()
// To be called whenever we mess with a spawn point,
// this makes sure that spawn_a_zombieA() can never
// try to spawn a zombie at a point which index is
// inactive.
//
void() Zombie_ReassignSpawnIDs =
{
float num_spawns = zombie_spawn_points;
// First, clear the list.
zombie_spawn_points = 0;
while(num_spawns > -1) {
entity zombie_spawn = findfloat(world, spawn_id, num_spawns);
if (zombie_spawn) {
zombie_spawn.spawn_id = 0;
}
num_spawns--;
zombie_spawn = findfloat(world, spawn_id, num_spawns);
}
// Now do the re-assignment
entity zombie_spawns = find(world, classname, "spawn_zombie");
while(zombie_spawns) {
zombie_spawns.spawn_id = zombie_spawn_points;
zombie_spawn_points++;
zombie_spawns = find(zombie_spawns, classname, "spawn_zombie");
}
}
inline entity() getFreeZombieEnt = inline entity() getFreeZombieEnt =
{ {
entity who; entity who;
@ -1503,51 +1539,41 @@ inline entity() getFreeZombieEnt =
float() spawn_a_zombieA = float() spawn_a_zombieA =
{ {
//dprint("Spawn_a_zombieA \n"); // cypress (20 dec 2023) -- rewrote this routine to be a little less
local float pcount; // needlessly bloaty/bogged down and be in greater parity.
local entity thing, szombie;
local float FAIL;
//warn // don't bother doing anything if it's not even time yet (avoids needless
pcount = 0; // iteration over ent chain)
if (zombie_spawn_timer > time)
return false;
FAIL = false; // look for a free entity
szombie = getFreeZombieEnt(); entity zombie_ent = getFreeZombieEnt();
if(szombie == world || zombie_spawn_timer > time)
{ // no free entity found, maximum are in play.
//bprint(PRINT_HIGH, "STOPPED AT A\n"); if (!zombie_ent)
//dprint("No avaible zombie entity\n"); return false;
return 0;
} // look for a random spawn point. note -- before there was a routine that
szombie.onfire = false; // prevented spawns from repeating one after the other before. i liked the
lastspawn = find(lastspawn, classname, "spawn_zombie"); // evened out use of the playspace at the beginning of the game but this
while (random() < 0.4) // isn't standard CoD functionality and it has negative consequences with
{ // larger areas.
lastspawn = find(lastspawn, classname, "spawn_zombie"); entity zombie_spawn;
float zombie_spawn_id = rint((random() * (zombie_spawn_points - 1))); // starts at 0!
zombie_spawn = find(world, classname, "spawn_zombie");
while(zombie_spawn != world) {
if (zombie_spawn.spawn_id == zombie_spawn_id)
break;
zombie_spawn = find(zombie_spawn, classname, "spawn_zombie");
} }
while(lastspawn) // prompt stage 2: the actual spawning of the zombie.
{ spawn_a_zombieB(zombie_spawn);
thing = findradius(lastspawn.origin, 60); spawn_delay = time + delay_at_round;
while (thing) return true;
{
pcount = 0;
if (thing.classname == "ai_zombie")
{
pcount = 1;
break;
}
thing = thing.chain;
}
if (!pcount && random() < 0.6)
{
spawn_a_zombieB(lastspawn);
spawn_delay = time + delay_at_round;
return true;
}
lastspawn = find(lastspawn, classname, "spawn_zombie");
}
return 0; //no free locations fround
}; };
void(float i) spawnSingleZombEnt = void(float i) spawnSingleZombEnt =

View file

@ -302,6 +302,7 @@ void(vector pos) tesla_spark;
.float onfire; .float onfire;
.entity firer; .entity firer;
float crawler_num; float crawler_num;
float zombie_spawn_points;
//==== Reference Vars ==== //==== Reference Vars ====
#define WWINDOW 1 #define WWINDOW 1
#define WBOX1 2 #define WBOX1 2
@ -344,6 +345,7 @@ entity lastspawn; // last spawn point used by spawning code
.entity goaldummy; // Used to store the origin of the zombies target .entity goaldummy; // Used to store the origin of the zombies target
.float goalway; // Used to store the origin of the zombies target .float goalway; // Used to store the origin of the zombies target
.float walktype; // decides animations and moving speeds for zombies .float walktype; // decides animations and moving speeds for zombies
.float spawn_id; // assigned to spawn point ents, for grabbing one at random.
.void() th_walk; .void() th_walk;
//.void() th_run; //.void() th_run;
.void() th_die; .void() th_die;

View file

@ -171,6 +171,8 @@ void() SUB_UseTargets =
if (t.classname == "spawn_zombie_in") if (t.classname == "spawn_zombie_in")
{ {
t.classname = "spawn_zombie"; t.classname = "spawn_zombie";
t.spawn_id = zombie_spawn_points;
zombie_spawn_points++;
} }
if (t.classname == "waypoint_s") if (t.classname == "waypoint_s")
{ {

View file

@ -28,6 +28,8 @@
#define SPAWNFLAG_NOMESSAGE 1 #define SPAWNFLAG_NOMESSAGE 1
#define SPAWNFLAG_NOTOUCH 1 #define SPAWNFLAG_NOTOUCH 1
void() Zombie_ReassignSpawnIDs;
// the wait time has passed, so set back up for another activation // the wait time has passed, so set back up for another activation
void() multi_wait = void() multi_wait =
{ {
@ -218,6 +220,8 @@ void() trigger_activator_touch =
if (t.classname == "spawn_zombie_away") if (t.classname == "spawn_zombie_away")
{ {
t.classname = "spawn_zombie"; t.classname = "spawn_zombie";
t.spawn_id = zombie_spawn_points;
zombie_spawn_points++;
/*if (cvar("developer")) /*if (cvar("developer"))
setmodel(t, "progs/ai/zfull.mdl");*/ setmodel(t, "progs/ai/zfull.mdl");*/
} }
@ -225,6 +229,7 @@ void() trigger_activator_touch =
} }
} }
} }
Zombie_ReassignSpawnIDs();
} }
void() trigger_activator = void() trigger_activator =