#include "gamemode_ctf.qh"
-#include "../_all.qh"
#include "gamemode.qh"
#ifdef SVQC
-#include "../vehicles/vehicle.qh"
+#include "../../common/vehicles/all.qh"
+#include "../teamplay.qh"
#endif
-#include "../../warpzonelib/common.qh"
-#include "../../warpzonelib/mathlib.qh"
+#include "../../lib/warpzone/common.qh"
void ctf_FakeTimeLimit(entity e, float t)
{
void ctf_FlagcarrierWaypoints(entity player)
{
- WaypointSprite_Spawn("flagcarrier", 0, 0, player, FLAG_WAYPOINT_OFFSET, world, player.team, player, wps_flagcarrier, true, RADARICON_FLAG, WPCOLOR_FLAGCARRIER(player.team));
- WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON) * 2);
- WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON));
+ WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player, FLAG_WAYPOINT_OFFSET, world, player.team, player, wps_flagcarrier, true, RADARICON_FLAG);
+ WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2);
+ WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER, WPCOLOR_FLAGCARRIER(player.team));
}
}
bool ctf_CaptureShield_Customize()
-{
+{SELFPARAM();
if(!other.ctf_captureshielded) { return false; }
if(CTF_SAMETEAM(self, other)) { return false; }
}
void ctf_CaptureShield_Touch()
-{
+{SELFPARAM();
if(!other.ctf_captureshielded) { return; }
if(CTF_SAMETEAM(self, other)) { return; }
vector mymid = (self.absmin + self.absmax) * 0.5;
vector othermid = (other.absmin + other.absmax) * 0.5;
- Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
+ Damage(other, self, self, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
}
void ctf_CaptureShield_Spawn(entity flag)
-{
+{SELFPARAM();
entity shield = spawn();
shield.enemy = self;
shield.scale = 0.5;
setorigin(shield, self.origin);
- setmodel(shield, "models/ctf/shield.md3");
+ setmodel(shield, MDL_CTF_SHIELD);
setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
}
// messages and sounds
Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_LOST_) : INFO_CTF_LOST_NEUTRAL), player.netname);
- sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
+ _sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
ctf_EventLog("dropped", player.team, player);
// scoring
PlayerScore_Add(player, SP_CTF_DROPS, 1);
// waypoints
- if(autocvar_g_ctf_flag_dropped_waypoint)
- WaypointSprite_Spawn("flagdropped", 0, 0, flag, FLAG_WAYPOINT_OFFSET, world, ((autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag, wps_flagdropped, true, RADARICON_FLAG, WPCOLOR_DROPPEDFLAG(flag.team));
+ if(autocvar_g_ctf_flag_dropped_waypoint) {
+ entity wp = WaypointSprite_Spawn(WP_FlagDropped, 0, 0, flag, FLAG_WAYPOINT_OFFSET, world, ((autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag, wps_flagdropped, true, RADARICON_FLAG);
+ wp.colormod = WPCOLOR_DROPPEDFLAG(flag.team);
+ }
if(autocvar_g_ctf_flag_return_time || (autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health))
{
flag.ctf_status = FLAG_CARRY;
// messages and sounds
- sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
+ _sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
ctf_EventLog("receive", flag.team, player);
FOR_EACH_REALPLAYER(tmp_player)
flag.ctf_status = FLAG_PASSING;
// other
- sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
- WarpZone_TrailParticles(world, particleeffectnum(flag.passeffect), player.origin, targ_origin);
+ _sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
+ WarpZone_TrailParticles(world, _particleeffectnum(flag.passeffect), player.origin, targ_origin);
ctf_EventLog("pass", flag.team, player);
break;
}
{
makevectors((player.v_angle.y * '0 1 0') + (bound(autocvar_g_ctf_throw_angle_min, player.v_angle.x, autocvar_g_ctf_throw_angle_max) * '1 0 0'));
- flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & IT_STRENGTH) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
+ flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & ITEM_Strength.m_itemid) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
flag.velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, false);
ctf_Handle_Drop(flag, player, droptype);
break;
if(!player) { return; } // without someone to give the reward to, we can't possibly cap
if(CTF_DIFFTEAM(player, flag)) { return; }
-
+
if(ctf_oneflag)
for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
if(SAME_TEAM(tmp_entity, player))
// messages and sounds
Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_) : CENTER_CTF_CAPTURE_NEUTRAL));
ctf_CaptureRecord(enemy_flag, player);
- sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE);
+ _sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE);
switch(capturetype)
{
PlayerScore_Add(player, SP_CTF_CAPTIME, new_time - old_time);
// effects
- pointparticles(particleeffectnum(flag.capeffect), flag.origin, '0 0 0', 1);
+ Send_Effect_(flag.capeffect, flag.origin, '0 0 0', 1);
//shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
// other
void ctf_Handle_Return(entity flag, entity player)
{
// messages and sounds
- if(player.flags & FL_MONSTER)
+ if(IS_MONSTER(player))
{
Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_MONSTER_), player.monster_name);
}
Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_RETURN_));
Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_), player.netname);
}
- sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE);
+ _sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE);
ctf_EventLog("return", flag.team, player);
// scoring
else { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_TEAM : CENTER_CTF_PICKUP_TEAM_ENEMY), Team_ColorCode(flag.team)); }
Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, ((flag.team) ? APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname);
-
+
if(!flag.team)
FOR_EACH_PLAYER(tmp_entity)
if(tmp_entity != player)
if(DIFF_TEAM(player, tmp_entity))
Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, Team_ColorCode(player.team), player.netname);
-
+
if(flag.team)
FOR_EACH_PLAYER(tmp_entity)
if(tmp_entity != player)
else
Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname);
- sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
+ _sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
// scoring
PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
{
pickup_dropped_score = (autocvar_g_ctf_flag_return_time ? bound(0, ((flag.ctf_droptime + autocvar_g_ctf_flag_return_time) - time) / autocvar_g_ctf_flag_return_time, 1) : 1);
pickup_dropped_score = floor((autocvar_g_ctf_score_pickup_dropped_late * (1 - pickup_dropped_score) + autocvar_g_ctf_score_pickup_dropped_early * pickup_dropped_score) + 0.5);
- dprint("pickup_dropped_score is ", ftos(pickup_dropped_score), "\n");
+ LOG_TRACE("pickup_dropped_score is ", ftos(pickup_dropped_score), "\n");
PlayerTeamScore_AddScore(player, pickup_dropped_score);
ctf_EventLog("pickup", flag.team, player);
break;
}
// effects
- pointparticles(particleeffectnum(flag.toucheffect), player.origin, '0 0 0', 1);
+ Send_Effect_(flag.toucheffect, player.origin, '0 0 0', 1);
// waypoints
if(pickuptype == PICKUP_DROPPED) { WaypointSprite_Kill(flag.wps_flagdropped); }
case RETURN_TIMEOUT:
{ Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; }
}
- sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
+ _sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
ctf_EventLog("returned", flag.team, world);
ctf_RespawnFlag(flag);
}
}
bool ctf_Stalemate_Customize()
-{
+{SELFPARAM();
// make spectators see what the player would see
entity e, wp_owner;
e = WaypointSprite_getviewentity(other);
{
if((tmp_entity.owner) && (!tmp_entity.owner.wps_enemyflagcarrier))
{
- WaypointSprite_Spawn(((ctf_oneflag) ? "flagcarrier" : "enemyflagcarrier"), 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, 0, tmp_entity.owner, wps_enemyflagcarrier, true, RADARICON_FLAG, WPCOLOR_ENEMYFC(tmp_entity.owner.team));
+ entity wp = WaypointSprite_Spawn(((ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, 0, tmp_entity.owner, wps_enemyflagcarrier, true, RADARICON_FLAG);
+ wp.colormod = WPCOLOR_ENEMYFC(tmp_entity.owner.team);
tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_Customize;
}
}
}
void ctf_FlagDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{
+{SELFPARAM();
if(ITEM_DAMAGE_NEEDKILL(deathtype))
{
if(autocvar_g_ctf_flag_return_damage_delay)
}
void ctf_FlagThink()
-{
+{SELFPARAM();
// declarations
entity tmp_entity;
// sanity checks
if(self.mins != FLAG_MIN || self.maxs != FLAG_MAX) { // reset the flag boundaries in case it got squished
- dprint("wtf the flag got squashed?\n");
+ LOG_TRACE("wtf the flag got squashed?\n");
tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self);
if(!trace_startsolid || self.noalign) // can we resize it without getting stuck?
setsize(self, FLAG_MIN, FLAG_MAX); }
self.health = 0;
ctf_CheckFlagReturn(self, RETURN_SPEEDRUN);
- tmp_entity = self;
- self = self.owner;
+ setself(self.owner);
self.impulse = CHIMPULSE_SPEEDRUN; // move the player back to the waypoint they set
ImpulseCommands();
- self = tmp_entity;
+ setself(this);
}
if(autocvar_g_ctf_stalemate)
{
default: // this should never happen
{
- dprint("ctf_FlagThink(): Flag exists with no status?\n");
+ LOG_TRACE("ctf_FlagThink(): Flag exists with no status?\n");
return;
}
}
}
void ctf_FlagTouch()
-{
+{SELFPARAM();
if(gameover) { return; }
if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
entity toucher = other, tmp_entity;
- bool is_not_monster = (!(toucher.flags & FL_MONSTER)), num_perteam = 0;
+ bool is_not_monster = (!IS_MONSTER(toucher)), num_perteam = 0;
// automatically kill the flag and return it if it touched lava/slime/nodrop surfaces
if(ITEM_TOUCH_NEEDKILL())
// special touch behaviors
if(toucher.frozen) { return; }
- else if(toucher.vehicle_flags & VHF_ISVEHICLE)
+ else if(IS_VEHICLE(toucher))
{
if(autocvar_g_ctf_allow_vehicle_touch && toucher.owner)
toucher = toucher.owner; // the player is actually the vehicle owner, not other
else
return; // do nothing
}
- else if(toucher.flags & FL_MONSTER)
+ else if(IS_MONSTER(toucher))
{
if(!autocvar_g_ctf_allow_monster_touch)
return; // do nothing
{
if(time > self.wait) // if we haven't in a while, play a sound/effect
{
- pointparticles(particleeffectnum(self.toucheffect), self.origin, '0 0 0', 1);
- sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
+ Send_Effect_(self.toucheffect, self.origin, '0 0 0', 1);
+ _sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
self.wait = time + FLAG_TOUCHRATE;
}
return;
case FLAG_CARRY:
{
- dprint("Someone touched a flag even though it was being carried?\n");
+ LOG_TRACE("Someone touched a flag even though it was being carried?\n");
break;
}
}
void ctf_Reset()
-{
+{SELFPARAM();
if(self.owner)
if(IS_PLAYER(self.owner))
ctf_Handle_Throw(self.owner, world, DROP_RESET);
}
void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf_FlagSetup()
-{
+{SELFPARAM();
// bot waypoints
waypoint_spawnforitem_force(self, self.origin);
self.nearestwaypointtimeout = 0; // activate waypointing again
self.bot_basewaypoint = self.nearestwaypoint;
// waypointsprites
- string basename = "base";
-
- switch(self.team)
+ entity basename;
+ switch (self.team)
{
- case NUM_TEAM_1: basename = "redbase"; break;
- case NUM_TEAM_2: basename = "bluebase"; break;
- case NUM_TEAM_3: basename = "yellowbase"; break;
- case NUM_TEAM_4: basename = "pinkbase"; break;
- default: basename = "neutralbase"; break;
+ case NUM_TEAM_1: basename = WP_FlagBaseRed; break;
+ case NUM_TEAM_2: basename = WP_FlagBaseBlue; break;
+ case NUM_TEAM_3: basename = WP_FlagBaseYellow; break;
+ case NUM_TEAM_4: basename = WP_FlagBasePink; break;
+ default: basename = WP_FlagBaseNeutral; break;
}
- WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, ((self.team) ? Team_ColorRGB(self.team) : '1 1 1'));
+ entity wp = WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG);
+ wp.colormod = ((self.team) ? Team_ColorRGB(self.team) : '1 1 1');
WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, ((self.team) ? colormapPaletteColor(self.team - 1, false) : '1 1 1'));
// captureshield setup
void set_flag_string(entity flag, .string field, string value, string teamname)
{
- if(flag.field == "")
- flag.field = strzone(sprintf(value,teamname));
+ if(flag.(field) == "")
+ flag.(field) = strzone(sprintf(value,teamname));
}
void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
-{
+{SELFPARAM();
// declarations
- string teamname = Static_Team_ColorName_Lower(teamnumber);
- self = flag; // for later usage with droptofloor()
+ setself(flag); // for later usage with droptofloor()
// main setup
flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
flag.nextthink = time + FLAG_THINKRATE;
flag.ctf_status = FLAG_BASE;
+ string teamname = Static_Team_ColorName_Lower(teamnumber);
// appearence
if(!flag.scale) { flag.scale = FLAG_SCALE; }
if(flag.skin == 0) { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); }
set_flag_string(flag, capeffect, "%s_cap", teamname);
// sounds
- set_flag_string(flag, snd_flag_taken, "ctf/%s_taken.wav", teamname);
- set_flag_string(flag, snd_flag_returned, "ctf/%s_returned.wav", teamname);
- set_flag_string(flag, snd_flag_capture, "ctf/%s_capture.wav", teamname);
- set_flag_string(flag, snd_flag_dropped, "ctf/%s_dropped.wav", teamname);
- if(flag.snd_flag_respawn == "") { flag.snd_flag_respawn = "ctf/flag_respawn.wav"; } // if there is ever a team-based sound for this, update the code to match.
- if(flag.snd_flag_touch == "") { flag.snd_flag_touch = "ctf/touch.wav"; } // again has no team-based sound
- if(flag.snd_flag_pass == "") { flag.snd_flag_pass = "ctf/pass.wav"; } // same story here
-
- // precache
- precache_sound(flag.snd_flag_taken);
- precache_sound(flag.snd_flag_returned);
- precache_sound(flag.snd_flag_capture);
+ flag.snd_flag_taken = SND(CTF_TAKEN(teamnumber));
+ flag.snd_flag_returned = SND(CTF_RETURNED(teamnumber));
+ flag.snd_flag_capture = SND(CTF_CAPTURE(teamnumber));
+ flag.snd_flag_dropped = SND(CTF_DROPPED(teamnumber));
+ if (flag.snd_flag_respawn == "") flag.snd_flag_respawn = SND(CTF_RESPAWN); // if there is ever a team-based sound for this, update the code to match.
precache_sound(flag.snd_flag_respawn);
- precache_sound(flag.snd_flag_dropped);
+ if (flag.snd_flag_touch == "") flag.snd_flag_touch = SND(CTF_TOUCH); // again has no team-based sound
precache_sound(flag.snd_flag_touch);
+ if (flag.snd_flag_pass == "") flag.snd_flag_pass = SND(CTF_PASS); // same story here
precache_sound(flag.snd_flag_pass);
+
+ // precache
precache_model(flag.model);
- precache_model("models/ctf/shield.md3");
- precache_model("models/ctf/shockwavetransring.md3");
// appearence
- setmodel(flag, flag.model); // precision set below
+ _setmodel(flag, flag.model); // precision set below
setsize(flag, FLAG_MIN, FLAG_MAX);
setorigin(flag, (flag.origin + FLAG_SPAWN_OFFSET));
default: flag.effects |= EF_DIMLIGHT; break;
}
}
-
+
// flag placement
if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location
{
else // drop to floor, automatically find a platform and set that as spawn origin
{
flag.noalign = false;
- self = flag;
+ setself(flag);
droptofloor();
flag.movetype = MOVETYPE_TOSS;
}
}
void havocbot_goalrating_ctf_ourflag(float ratingscale)
-{
+{SELFPARAM();
entity head;
head = ctf_worldflaglist;
while (head)
}
void havocbot_goalrating_ctf_ourbase(float ratingscale)
-{
+{SELFPARAM();
entity head;
head = ctf_worldflaglist;
while (head)
}
void havocbot_goalrating_ctf_enemyflag(float ratingscale)
-{
+{SELFPARAM();
entity head;
head = ctf_worldflaglist;
while (head)
}
void havocbot_goalrating_ctf_enemybase(float ratingscale)
-{
+{SELFPARAM();
if (!bot_waypoints_for_items)
{
havocbot_goalrating_ctf_enemyflag(ratingscale);
}
void havocbot_goalrating_ctf_ourstolenflag(float ratingscale)
-{
+{SELFPARAM();
entity mf;
mf = havocbot_ctf_find_flag(self);
}
void havocbot_goalrating_ctf_carrieritems(float ratingscale, vector org, float sradius)
-{
+{SELFPARAM();
entity head;
float t;
head = findchainfloat(bot_pickup, true);
}
void havocbot_role_ctf_carrier()
-{
+{SELFPARAM();
if(self.deadflag != DEAD_NO)
{
havocbot_ctf_reset_role(self);
{
// Can't navigate to my own base, suicide!
// TODO: drop it and wander around
- Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
+ Damage(self, self, self, 100000, DEATH_KILL.m_id, self.origin, '0 0 0');
return;
}
}
}
void havocbot_role_ctf_escort()
-{
+{SELFPARAM();
entity mf, ef;
if(self.deadflag != DEAD_NO)
}
void havocbot_role_ctf_offense()
-{
+{SELFPARAM();
entity mf, ef;
vector pos;
// Retriever (temporary role):
void havocbot_role_ctf_retriever()
-{
+{SELFPARAM();
entity mf;
if(self.deadflag != DEAD_NO)
}
void havocbot_role_ctf_middle()
-{
+{SELFPARAM();
entity mf;
if(self.deadflag != DEAD_NO)
}
void havocbot_role_ctf_defense()
-{
+{SELFPARAM();
entity mf;
if(self.deadflag != DEAD_NO)
void havocbot_role_ctf_setrole(entity bot, int role)
{
- dprint(strcat(bot.netname," switched to "));
+ LOG_TRACE(strcat(bot.netname," switched to "));
switch(role)
{
case HAVOCBOT_CTF_ROLE_CARRIER:
- dprint("carrier");
+ LOG_TRACE("carrier");
bot.havocbot_role = havocbot_role_ctf_carrier;
bot.havocbot_role_timeout = 0;
bot.havocbot_cantfindflag = time + 10;
bot.bot_strategytime = 0;
break;
case HAVOCBOT_CTF_ROLE_DEFENSE:
- dprint("defense");
+ LOG_TRACE("defense");
bot.havocbot_role = havocbot_role_ctf_defense;
bot.havocbot_role_timeout = 0;
break;
case HAVOCBOT_CTF_ROLE_MIDDLE:
- dprint("middle");
+ LOG_TRACE("middle");
bot.havocbot_role = havocbot_role_ctf_middle;
bot.havocbot_role_timeout = 0;
break;
case HAVOCBOT_CTF_ROLE_OFFENSE:
- dprint("offense");
+ LOG_TRACE("offense");
bot.havocbot_role = havocbot_role_ctf_offense;
bot.havocbot_role_timeout = 0;
break;
case HAVOCBOT_CTF_ROLE_RETRIEVER:
- dprint("retriever");
+ LOG_TRACE("retriever");
bot.havocbot_previous_role = bot.havocbot_role;
bot.havocbot_role = havocbot_role_ctf_retriever;
bot.havocbot_role_timeout = time + 10;
bot.bot_strategytime = 0;
break;
case HAVOCBOT_CTF_ROLE_ESCORT:
- dprint("escort");
+ LOG_TRACE("escort");
bot.havocbot_previous_role = bot.havocbot_role;
bot.havocbot_role = havocbot_role_ctf_escort;
bot.havocbot_role_timeout = time + 30;
bot.bot_strategytime = 0;
break;
}
- dprint("\n");
+ LOG_TRACE("\n");
}
// ==============
MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
-{
+{SELFPARAM();
entity flag;
int t = 0, t2 = 0, t3 = 0;
// initially clear items so they can be set as necessary later.
- self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING | CTF_RED_FLAG_TAKEN | CTF_RED_FLAG_LOST
+ self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING | CTF_RED_FLAG_TAKEN | CTF_RED_FLAG_LOST
| CTF_BLUE_FLAG_CARRYING | CTF_BLUE_FLAG_TAKEN | CTF_BLUE_FLAG_LOST
| CTF_YELLOW_FLAG_CARRYING | CTF_YELLOW_FLAG_TAKEN | CTF_YELLOW_FLAG_LOST
| CTF_PINK_FLAG_CARRYING | CTF_PINK_FLAG_TAKEN | CTF_PINK_FLAG_LOST
{
if((flag.owner == self) || (flag.pass_sender == self))
self.ctf_flagstatus |= t; // carrying: self is currently carrying the flag
- else
+ else
self.ctf_flagstatus |= t2; // taken: someone else is carrying the flag
break;
}
// update the health of the flag carrier waypointsprite
if(self.wps_flagcarrier)
- WaypointSprite_UpdateHealth(self.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON));
+ WaypointSprite_UpdateHealth(self.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
return false;
}
}
else if(frag_target.flagcarried && (frag_target.deadflag == DEAD_NO) && CTF_DIFFTEAM(frag_target, frag_attacker)) // if the target is a flagcarrier
{
- if(autocvar_g_ctf_flagcarrier_auto_helpme_damage > ('1 0 0' * healtharmor_maxdamage(frag_target.health, frag_target.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON)))
+ if(autocvar_g_ctf_flagcarrier_auto_helpme_damage > ('1 0 0' * healtharmor_maxdamage(frag_target.health, frag_target.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)))
if(time > frag_target.wps_helpme_time + autocvar_g_ctf_flagcarrier_auto_helpme_time)
{
frag_target.wps_helpme_time = time;
}
MUTATOR_HOOKFUNCTION(ctf_RemovePlayer)
-{
+{SELFPARAM();
entity flag; // temporary entity for the search method
if(self.flagcarried)
}
MUTATOR_HOOKFUNCTION(ctf_PortalTeleport)
-{
+{SELFPARAM();
if(self.flagcarried)
if(!autocvar_g_ctf_portalteleport)
{ ctf_Handle_Throw(self, world, DROP_NORMAL); }
}
MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
-{
+{SELFPARAM();
if(MUTATOR_RETURNVALUE || gameover) { return false; }
entity player = self;
}
MUTATOR_HOOKFUNCTION(ctf_HelpMePing)
-{
+{SELFPARAM();
if(self.wps_flagcarrier) // update the flagcarrier waypointsprite with "NEEDING HELP" notification
{
self.wps_helpme_time = time;
}
else // create a normal help me waypointsprite
{
- WaypointSprite_Spawn("helpme", waypointsprite_deployed_lifetime, waypointsprite_limitedrange, self, FLAG_WAYPOINT_OFFSET, world, self.team, self, wps_helpme, false, RADARICON_HELPME, '1 0.5 0');
+ WaypointSprite_Spawn(WP_Helpme, waypointsprite_deployed_lifetime, waypointsprite_limitedrange, self, FLAG_WAYPOINT_OFFSET, world, self.team, self, wps_helpme, false, RADARICON_HELPME);
WaypointSprite_Ping(self.wps_helpme);
}
}
MUTATOR_HOOKFUNCTION(ctf_AbortSpeedrun)
-{
+{SELFPARAM();
if(self.flagcarried)
{
Send_Notification(NOTIF_ALL, world, MSG_INFO, ((self.flagcarried.team) ? APP_TEAM_ENT_4(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL));
}
MUTATOR_HOOKFUNCTION(ctf_BotRoles)
-{
+{SELFPARAM();
havocbot_ctf_reset_role(self);
return true;
}
}
MUTATOR_HOOKFUNCTION(ctf_SpectateCopy)
-{
+{SELFPARAM();
self.ctf_flagstatus = other.ctf_flagstatus;
return false;
}
// Spawnfuncs
// ==========
-/*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24)
-CTF Starting point for a player in team one (Red).
-Keys: "angle" viewing angle when spawning. */
-void spawnfunc_info_player_team1()
-{
- if(g_assault) { remove(self); return; }
-
- self.team = NUM_TEAM_1; // red
- spawnfunc_info_player_deathmatch();
-}
-
-
-/*QUAKED spawnfunc_info_player_team2 (1 0 0) (-16 -16 -24) (16 16 24)
-CTF Starting point for a player in team two (Blue).
-Keys: "angle" viewing angle when spawning. */
-void spawnfunc_info_player_team2()
-{
- if(g_assault) { remove(self); return; }
-
- self.team = NUM_TEAM_2; // blue
- spawnfunc_info_player_deathmatch();
-}
-
-/*QUAKED spawnfunc_info_player_team3 (1 0 0) (-16 -16 -24) (16 16 24)
-CTF Starting point for a player in team three (Yellow).
-Keys: "angle" viewing angle when spawning. */
-void spawnfunc_info_player_team3()
-{
- if(g_assault) { remove(self); return; }
-
- self.team = NUM_TEAM_3; // yellow
- spawnfunc_info_player_deathmatch();
-}
-
-
-/*QUAKED spawnfunc_info_player_team4 (1 0 0) (-16 -16 -24) (16 16 24)
-CTF Starting point for a player in team four (Purple).
-Keys: "angle" viewing angle when spawning. */
-void spawnfunc_info_player_team4()
-{
- if(g_assault) { remove(self); return; }
-
- self.team = NUM_TEAM_4; // purple
- spawnfunc_info_player_deathmatch();
-}
-
/*QUAKED spawnfunc_item_flag_team1 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
CTF flag for team one (Red).
Keys:
"noise3" sound played when flag is lost in the field and respawns itself...
"noise4" sound played when flag is dropped by a player...
"noise5" sound played when flag touches the ground... */
-void spawnfunc_item_flag_team1()
+spawnfunc(item_flag_team1)
{
if(!g_ctf) { remove(self); return; }
"noise3" sound played when flag is lost in the field and respawns itself...
"noise4" sound played when flag is dropped by a player...
"noise5" sound played when flag touches the ground... */
-void spawnfunc_item_flag_team2()
+spawnfunc(item_flag_team2)
{
if(!g_ctf) { remove(self); return; }
/*QUAKED spawnfunc_item_flag_team3 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
CTF flag for team three (Yellow).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
"noise" sound played when flag is picked up...
"noise1" sound played when flag is returned by a teammate...
"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
+"noise3" sound played when flag is lost in the field and respawns itself...
"noise4" sound played when flag is dropped by a player...
"noise5" sound played when flag touches the ground... */
-void spawnfunc_item_flag_team3()
+spawnfunc(item_flag_team3)
{
if(!g_ctf) { remove(self); return; }
/*QUAKED spawnfunc_item_flag_team4 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
CTF flag for team four (Pink).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
"noise" sound played when flag is picked up...
"noise1" sound played when flag is returned by a teammate...
"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
+"noise3" sound played when flag is lost in the field and respawns itself...
"noise4" sound played when flag is dropped by a player...
"noise5" sound played when flag touches the ground... */
-void spawnfunc_item_flag_team4()
+spawnfunc(item_flag_team4)
{
if(!g_ctf) { remove(self); return; }
/*QUAKED spawnfunc_item_flag_neutral (0 0.5 0.8) (-48 -48 -37) (48 48 37)
CTF flag (Neutral).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
"noise" sound played when flag is picked up...
"noise1" sound played when flag is returned by a teammate...
"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
+"noise3" sound played when flag is lost in the field and respawns itself...
"noise4" sound played when flag is dropped by a player...
"noise5" sound played when flag touches the ground... */
-void spawnfunc_item_flag_neutral()
+spawnfunc(item_flag_neutral)
{
if(!g_ctf) { remove(self); return; }
if(!cvar("g_ctf_oneflag")) { remove(self); return; }
Keys:
"netname" Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc)...
"cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
-void spawnfunc_ctf_team()
+spawnfunc(ctf_team)
{
if(!g_ctf) { remove(self); return; }
}
// compatibility for quake maps
-void spawnfunc_team_CTF_redflag() { spawnfunc_item_flag_team1(); }
-void spawnfunc_team_CTF_blueflag() { spawnfunc_item_flag_team2(); }
-void spawnfunc_team_CTF_redplayer() { spawnfunc_info_player_team1(); }
-void spawnfunc_team_CTF_blueplayer() { spawnfunc_info_player_team2(); }
-void spawnfunc_team_CTF_redspawn() { spawnfunc_info_player_team1(); }
-void spawnfunc_team_CTF_bluespawn() { spawnfunc_info_player_team2(); }
+spawnfunc(team_CTF_redflag) { spawnfunc_item_flag_team1(this); }
+spawnfunc(team_CTF_blueflag) { spawnfunc_item_flag_team2(this); }
+spawnfunc(info_player_team1);
+spawnfunc(team_CTF_redplayer) { spawnfunc_info_player_team1(this); }
+spawnfunc(team_CTF_redspawn) { spawnfunc_info_player_team1(this); }
+spawnfunc(info_player_team2);
+spawnfunc(team_CTF_blueplayer) { spawnfunc_info_player_team2(this); }
+spawnfunc(team_CTF_bluespawn) { spawnfunc_info_player_team2(this); }
-void team_CTF_neutralflag() { spawnfunc_item_flag_neutral(); }
-void team_neutralobelisk() { spawnfunc_item_flag_neutral(); }
+void team_CTF_neutralflag() { SELFPARAM(); spawnfunc_item_flag_neutral(self); }
+void team_neutralobelisk() { SELFPARAM(); spawnfunc_item_flag_neutral(self); }
// ==============
// code from here on is just to support maps that don't have flag and team entities
void ctf_SpawnTeam (string teamname, int teamcolor)
{
- entity oldself;
- oldself = self;
- self = spawn();
- self.classname = "ctf_team";
- self.netname = teamname;
- self.cnt = teamcolor;
-
- spawnfunc_ctf_team();
-
- self = oldself;
+ entity this = new(ctf_team);
+ this.netname = teamname;
+ this.cnt = teamcolor;
+ this.spawnfunc_checked = true;
+ WITH(entity, self, this, spawnfunc_ctf_team(this));
}
void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
// if no teams are found, spawn defaults
if(find(world, classname, "ctf_team") == world)
{
- print("No ""ctf_team"" entities found on this map, creating them anyway.\n");
+ LOG_INFO("No ""ctf_team"" entities found on this map, creating them anyway.\n");
ctf_SpawnTeam("Red", NUM_TEAM_1 - 1);
ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1);
if(ctf_teams >= 3)
MUTATOR_ONREMOVE
{
- print("This is a game type and it cannot be removed at runtime.");
+ LOG_INFO("This is a game type and it cannot be removed at runtime.");
return -1;
}