WaypointSprite_Kill(player.wps_flagcarrier);
if(player.wps_enemyflagcarrier)
- WaypointSprite_Kill(player.wps_enemyflagcarrier);
+ WaypointSprite_Kill(player.wps_enemyflagcarrier);
// captureshield
ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
}
}
+void ctf_CheckStalemate(void)
+{
+ // declarations
+ float stale_red_flags, stale_blue_flags;
+ entity tmp_entity;
+
+ // build list of stale flags
+ for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
+ {
+ if(autocvar_g_ctf_flagcarrier_waypointforenemy_stalemate)
+ if(time >= tmp_entity.ctf_pickuptime + autocvar_g_ctf_flagcarrier_waypointforenemy_stalemate)
+ {
+ tmp_entity.ctf_staleflagnext = ctf_staleflaglist; // link flag into staleflaglist
+ ctf_staleflaglist = tmp_entity;
+
+ switch(tmp_entity.team)
+ {
+ case COLOR_TEAM1: ++stale_red_flags; break;
+ case COLOR_TEAM2: ++stale_blue_flags; break;
+ }
+ }
+ }
+
+ // if sufficient stalemate, then set up the waypointsprite and announce the stalemate if necessary
+ if(stale_red_flags && stale_blue_flags)
+ {
+ for(tmp_entity = ctf_staleflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_staleflagnext)
+ {
+ if not(tmp_entity.owner.wps_enemyflagcarrier)
+ WaypointSprite_Spawn("enemyflagcarrier", 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, tmp_entity.team, tmp_entity.owner, wps_enemyflagcarrier, TRUE, RADARICON_FLAG, WPCOLOR_ENEMYFC(tmp_entity.owner.team));
+ }
+
+ if not(wpforenemy_announced)
+ {
+ FOR_EACH_REALPLAYER(tmp_entity)
+ if(tmp_entity.flagcarried)
+ centerprint(tmp_entity, "Stalemate! Enemies can now see you on radar!");
+ else
+ centerprint(tmp_entity, "Stalemate! Flag carriers can now be seen by enemies on radar!");
+
+ wpforenemy_announced = TRUE;
+ }
+ }
+}
+
void ctf_FlagDamage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
if(ITEM_DAMAGE_NEEDKILL(deathtype))
ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
return;
}
-
if(autocvar_g_ctf_flag_return_damage)
{
// reduce health and check if it should be returned
case FLAG_DROPPED:
{
if(autocvar_g_ctf_flag_dropped_floatinwater && (self.flags & FL_INWATER))
- self.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater;
+ self.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater;
if(autocvar_g_ctf_flag_return_dropped)
{
ImpulseCommands();
self = tmp_entity;
}
-
- if(autocvar_g_ctf_flagcarrier_waypointforenemy_time)
- if((time >= self.ctf_pickuptime + autocvar_g_ctf_flagcarrier_waypointforenemy_time) && !self.owner.wps_enemyflagcarrier)
+ if(autocvar_g_ctf_flagcarrier_waypointforenemy_stalemate)
{
- WaypointSprite_Spawn("enemyflagcarrier", 0, 0, self.owner, FLAG_WAYPOINT_OFFSET, world, self.team, self.owner, wps_enemyflagcarrier, TRUE, RADARICON_FLAG, WPCOLOR_ENEMYFC(self.owner.team));
-
- if(!self.wpforenemy_announced)
+ if(time >= wpforenemy_nextthink)
{
- FOR_EACH_REALPLAYER(tmp_entity)
- {
- if(tmp_entity == self.owner)
- centerprint(tmp_entity, strcat("Enemies can now see you on radar! (held ", self.netname, " for ", ftos(autocvar_g_ctf_flagcarrier_waypointforenemy_time), " seconds)"));
- else if(IsDifferentTeam(tmp_entity, self.owner))
- centerprint(tmp_entity, strcat("You can now see the enemy flag carrier on radar! (held ", self.netname, " for ", ftos(autocvar_g_ctf_flagcarrier_waypointforenemy_time), " seconds)"));
- else
- centerprint(tmp_entity, strcat("Enemies can now see your flag carrier on radar! (held ", self.netname, " for ", ftos(autocvar_g_ctf_flagcarrier_waypointforenemy_time), " seconds)"));
- }
-
- self.wpforenemy_announced = TRUE;
+ ctf_CheckStalemate();
+ wpforenemy_nextthink = time + WPFE_THINKRATE; // waypoint for enemy think rate (to reduce unnecessary spam of this check)
}
}
return;
}
break;
}
-
- default: // this should never happen
- {
- dprint("Touch: Flag exists with no status?\n");
- break;
- }
}
}
flag.ctf_dropper = world;
flag.ctf_pickuptime = 0;
flag.ctf_droptime = 0;
- flag.wpforenemy_announced = FALSE;
+
+ wpforenemy_announced = FALSE;
}
void ctf_Reset()
// scan through all the flags and notify the client about them
for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
{
- if(flag.ctf_status == FLAG_CARRY)
- if(flag.owner == self)
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_CARRYING : IT_BLUE_FLAG_CARRYING); // carrying: self is currently carrying the flag
- else
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_TAKEN : IT_BLUE_FLAG_TAKEN); // taken: someone on self's team is carrying the flag
- else if(flag.ctf_status == FLAG_DROPPED)
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_LOST : IT_BLUE_FLAG_LOST); // lost: the flag is dropped somewhere on the map
+ switch(flag.ctf_status)
+ {
+ case FLAG_CARRY:
+ {
+ if(flag.owner == self)
+ self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_CARRYING : IT_BLUE_FLAG_CARRYING); // carrying: self is currently carrying the flag
+ else
+ self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_TAKEN : IT_BLUE_FLAG_TAKEN); // taken: someone on self's team is carrying the flag
+ break;
+ }
+ case FLAG_DROPPED:
+ {
+ self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_LOST : IT_BLUE_FLAG_LOST); // lost: the flag is dropped somewhere on the map
+ break;
+ }
+ }
}
// item for stopping players from capturing the flag too often
frag_damage *= autocvar_g_ctf_flagcarrier_selfdamagefactor;
frag_force *= autocvar_g_ctf_flagcarrier_selfforcefactor;
}
- else // damage done everyone else
+ else // damage done to everyone else
{
frag_damage *= autocvar_g_ctf_flagcarrier_damagefactor;
frag_force *= autocvar_g_ctf_flagcarrier_forcefactor;
}
}
+ else if(frag_target.flagcarried && (frag_target.deadflag == DEAD_NO) && IsDifferentTeam(frag_target, frag_attacker)) // if the target is a flagcarrier
+ {
+ if(autocvar_g_ctf_flagcarrier_auto_helpme_when_damaged > frag_target.health)
+ WaypointSprite_HelpMePing(frag_target.wps_flagcarrier); // TODO: only do this if there is a significant loss of health?
+ }
return 0;
}