// =====================
set g_spawn_near_teammate 0 "if set, players prefer spawns near a team mate"
set g_spawn_near_teammate_distance 640 "max distance to consider a spawn to be near a team mate"
+set g_spawn_near_teammate_ignore_spawnpoint 0 "ignore spawnpoints and spawn right at team mates"
+set g_spawn_near_teammate_ignore_spawnpoint_delay 2.5 "how long to wait before its OK to spawn at a player after someone just spawned at this player"
+set g_spawn_near_teammate_ignore_spawnpoint_delay_death 0 "how long to wait before its OK to spawn at a player after death"
+set g_spawn_near_teammate_ignore_spawnpoint_check_health 1 "only allow spawn at this player if their health is full"
+set g_spawn_near_teammate_ignore_spawnpoint_closetodeath 1 "spawn as close to death location as possible"
// ========================
set g_campcheck_damage 100
set g_campcheck_distance 1800
-
-// ==============
-// spawn system
-// ==============
-set g_spawnsystem 0 "spawn at teammates in teamplay modes"
-set g_spawnsystem_delay 2.5 "how long to wait before its OK to spawn at a player after someone just spawned at this player"
-set g_spawnsystem_delay_death 0 "how long to wait before its OK to spawn at a player after death"
-set g_spawnsystem_check_health 1 "only allow spawn at this player if their health is full"
-set g_spawnsystem_closetodeath 1 "spawn as close to death location as possible"
float autocvar_g_campcheck_distance;
float autocvar_g_campcheck_interval;
float autocvar_g_jump_grunt;
-float autocvar_g_spawnsystem;
-float autocvar_g_spawnsystem_delay;
-float autocvar_g_spawnsystem_delay_death;
-float autocvar_g_spawnsystem_check_health;
-float autocvar_g_spawnsystem_closetodeath;
+float autocvar_g_spawn_near_teammate_distance;
+float autocvar_g_spawn_near_teammate_ignore_spawnpoint;
+float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
+float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
+float autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
+float autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
{ if(cvar(mut_cvar) && dependence) { MUTATOR_ADD(mut_name); } }
CHECK_MUTATOR_ADD("g_dodging", mutator_dodging, 1);
- CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, 1);
+ CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, teamplay);
CHECK_MUTATOR_ADD("g_physical_items", mutator_physical_items, 1);
CHECK_MUTATOR_ADD("g_touchexplode", mutator_touchexplode, 1);
CHECK_MUTATOR_ADD("g_minstagib", mutator_minstagib, 1);
CHECK_MUTATOR_ADD("g_nades", mutator_nades, 1);
CHECK_MUTATOR_ADD("g_sandbox", sandbox, 1);
CHECK_MUTATOR_ADD("g_campcheck", mutator_campcheck, 1);
- CHECK_MUTATOR_ADD("g_spawnsystem", mutator_spawnsystem, teamplay);
#undef CHECK_MUTATOR_ADD
-float autocvar_g_spawn_near_teammate_distance;
.entity msnt_lookat;
+.float msnt_timer;
+.vector msnt_deathloc;
+
MUTATOR_HOOKFUNCTION(msnt_Spawn_Score)
{
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint)
+ return 0;
+
entity p;
spawn_spot.msnt_lookat = world;
MUTATOR_HOOKFUNCTION(msnt_PlayerSpawn)
{
- if(spawn_spot.msnt_lookat)
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint)
+ {
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death)
+ self.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
+
+ entity team_mate, best_mate = world;
+ vector best_spot = '0 0 0';
+ float pc = 0, best_dist = 0, dist = 0;
+ FOR_EACH_PLAYER(team_mate)
+ {
+ if((autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health >= 0 && team_mate.health >= autocvar_g_balance_health_regenstable) || autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health == 0)
+ if(team_mate.deadflag == DEAD_NO)
+ if(team_mate.msnt_timer < time)
+ if(!IsDifferentTeam(self, team_mate))
+ if(time > team_mate.spawnshieldtime) // spawn shielding
+ if(team_mate.freezetag_frozen == 0)
+ if(team_mate != self)
+ {
+ tracebox(team_mate.origin, PL_MIN, PL_MAX, team_mate.origin - '0 0 100', MOVE_WORLDONLY, team_mate);
+ if(trace_fraction != 1.0)
+ if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+ {
+ pc = pointcontents(trace_endpos + '0 0 1');
+ if(pc == CONTENT_EMPTY)
+ {
+ if(vlen(team_mate.velocity) > 5)
+ fixedmakevectors(vectoangles(team_mate.velocity));
+ else
+ fixedmakevectors(team_mate.angles);
+
+ for(pc = 0; pc != 5; ++pc) // test 5 diffrent spots close to mate
+ {
+ switch(pc)
+ {
+ case 0:
+ tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 128, MOVE_NORMAL, team_mate);
+ break;
+ case 1:
+ tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 128 , MOVE_NORMAL, team_mate);
+ break;
+ case 2:
+ tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
+ break;
+ case 3:
+ tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
+ break;
+ case 4:
+ tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_forward * 128, MOVE_NORMAL, team_mate);
+ break;
+ }
+
+ if(trace_fraction == 1.0)
+ {
+ traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, team_mate);
+ if(trace_fraction != 1.0)
+ {
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath)
+ {
+ dist = vlen(trace_endpos - self.msnt_deathloc);
+ if(dist < best_dist || best_dist == 0)
+ {
+ best_dist = dist;
+ best_spot = trace_endpos;
+ best_mate = team_mate;
+ }
+ }
+ else
+ {
+ setorigin(self, trace_endpos);
+ self.angles = team_mate.angles;
+ team_mate.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath)
+ if(best_dist)
+ {
+ setorigin(self, best_spot);
+ self.angles = best_mate.angles;
+ self.fixangle = TRUE;
+ best_mate.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
+ }
+ }
+ else if(spawn_spot.msnt_lookat)
{
self.angles = vectoangles(spawn_spot.msnt_lookat.origin - self.origin);
self.angles_x = -self.angles_x;
return 0;
}
+MUTATOR_HOOKFUNCTION(msnt_PlayerDies)
+{
+ self.msnt_deathloc = self.origin;
+ return 0;
+}
+
MUTATOR_DEFINITION(mutator_spawn_near_teammate)
{
MUTATOR_HOOK(Spawn_Score, msnt_Spawn_Score, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, msnt_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDies, msnt_PlayerDies, CBC_ORDER_ANY);
return 0;
}
+++ /dev/null
-.float spawnsys_timer;
-.vector spawnsys_deathloc;
-
-MUTATOR_HOOKFUNCTION(spawn_PlayerDies)
-{
- self.spawnsys_deathloc = self.origin;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(spawn_PlayerSpawn)
-{
- if(autocvar_g_spawnsystem_delay_death)
- self.spawnsys_timer = time + autocvar_g_spawnsystem_delay_death;
-
- if not(autocvar_g_spawnsystem)
- return FALSE;
-
- entity team_mate, best_mate = world;
- vector best_spot = '0 0 0';
- float pc = 0, best_dist = 0, dist = 0;
- FOR_EACH_PLAYER(team_mate)
- {
- if((autocvar_g_spawnsystem_check_health >= 0 && team_mate.health >= autocvar_g_balance_health_regenstable) || autocvar_g_spawnsystem_check_health == 0)
- if(team_mate.deadflag == DEAD_NO)
- if(team_mate.spawnsys_timer < time)
- if(!IsDifferentTeam(self, team_mate))
- if(team_mate.freezetag_frozen == 0)
- if(team_mate != self)
- {
- tracebox(team_mate.origin, PL_MIN, PL_MAX, team_mate.origin - '0 0 100', MOVE_WORLDONLY, team_mate);
- if(trace_fraction != 1.0)
- if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
- {
- pc = pointcontents(trace_endpos + '0 0 1');
- if(pc == CONTENT_EMPTY)
- {
- if(vlen(team_mate.velocity) > 5)
- fixedmakevectors(vectoangles(team_mate.velocity));
- else
- fixedmakevectors(team_mate.angles);
-
- for(pc = 0; pc != 5; ++pc) // test 5 diffrent spots close to mate
- {
- switch(pc)
- {
- case 0:
- tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 128, MOVE_NORMAL, team_mate);
- break;
- case 1:
- tracebox(team_mate.origin , PL_MIN, PL_MAX,team_mate.origin - v_right * 128 , MOVE_NORMAL, team_mate);
- break;
- case 2:
- tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
- break;
- case 3:
- tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
- break;
- case 4:
- tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_forward * 128, MOVE_NORMAL, team_mate);
- break;
- }
-
- if(trace_fraction == 1.0)
- {
- traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, team_mate);
- if(trace_fraction != 1.0)
- {
- if(autocvar_g_spawnsystem_closetodeath)
- {
- dist = vlen(trace_endpos - self.spawnsys_deathloc);
- if(dist < best_dist || best_dist == 0)
- {
- best_dist = dist;
- best_spot = trace_endpos;
- best_mate = team_mate;
- }
- }
- else
- {
- setorigin(self, trace_endpos);
- self.angles = team_mate.angles;
- team_mate.spawnsys_timer = time + autocvar_g_spawnsystem_delay;
- return 0;
- }
- }
- }
- }
- }
- }
- }
- }
-
- if(autocvar_g_spawnsystem_closetodeath)
- if(best_dist)
- {
- setorigin(self, best_spot);
- self.angles = best_mate.angles;
- self.fixangle = TRUE;
- best_mate.spawnsys_timer = time + autocvar_g_spawnsystem_delay;
- }
-
- return FALSE;
-}
-
-MUTATOR_DEFINITION(mutator_spawnsystem)
-{
- MUTATOR_HOOK(PlayerDies, spawn_PlayerDies, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerSpawn, spawn_PlayerSpawn, CBC_ORDER_ANY);
-
- return FALSE;
-}
MUTATOR_DECLARATION(mutator_melee_only);
MUTATOR_DECLARATION(mutator_nades);
MUTATOR_DECLARATION(mutator_campcheck);
-MUTATOR_DECLARATION(mutator_spawnsystem);
MUTATOR_DECLARATION(sandbox);
mutators/mutator_melee_only.qc
mutators/mutator_nades.qc
mutators/mutator_campcheck.qc
-mutators/mutator_spawnsystem.qc
../warpzonelib/anglestransform.qc
../warpzonelib/mathlib.qc