107 GameLogEcho(sprintf(
":ctf:%s:%d:%d:%s", mode, flagteam, actor.team, ((actor !=
NULL) ?
ftos(actor.playerid) :
"")));
114 float cap_time = (
time - flag.ctf_pickuptime);
119 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname);
121 Send_Notification(NOTIF_ALL,
NULL, MSG_CHOICE,
APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_TIME), player.netname,
TIME_ENCODE(cap_time));
122 else if(cap_time < cap_record)
159 WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player,
FLAG_WAYPOINT_OFFSET,
NULL, player.team, player,
wps_flagcarrier,
true, RADARICON_FLAG);
162 WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER,
WPCOLOR_FLAGCARRIER(player.team));
164 if(player.flagcarried &&
CTF_SAMETEAM(player, player.flagcarried))
166 if(!player.wps_enemyflagcarrier)
168 entity wp = WaypointSprite_Spawn(((
ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, player,
FLAG_WAYPOINT_OFFSET,
NULL, 0, player,
wps_enemyflagcarrier,
true, RADARICON_FLAG);
173 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_VISIBLE);
176 if(!player.wps_flagreturn)
179 owp.colormod =
'0 0.8 0.8';
188 float current_distance =
vlen(((
'1 0 0' * to.x) + (
'0 1 0' * to.y)) - ((
'1 0 0' * from.x) + (
'0 1 0' * from.y)));
190 float current_height = (initial_height *
min(1, (current_distance / flag.pass_distance)));
196 targpos = (to + (
'0 0 1' * current_height));
208 else { targpos =
to; }
229 h =
vlen(head_center - passer_center);
233 float distance_from_line =
vlen(nearest_to_passer - nearest_on_line);
243 else {
return true; }
253 int s,
s2, s3, s4, se, se2, se3, se4, sr, ser;
254 int players_worseeq, players_total;
264 sr = ((s -
s2) + (s3 + s4));
269 players_total = players_worseeq = 0;
278 ser = ((se - se2) + (se3 + se4));
297 if((wanted_status == player.ctf_captureshielded) && (updated_status != wanted_status))
299 Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((updated_status) ? CENTER_CTF_CAPTURESHIELD_SHIELDED : CENTER_CTF_CAPTURESHIELD_FREE));
300 player.ctf_captureshielded = updated_status;
306 if(!client.ctf_captureshielded) {
return false; }
314 if(!toucher.ctf_captureshielded) {
return; }
318 vector theirmid = (toucher.absmin + toucher.absmax) * 0.5;
321 if(
IS_REAL_CLIENT(toucher)) { Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
326 entity shield =
new(ctf_captureshield);
329 shield.team = flag.team;
335 shield.avelocity =
'7 0 11';
340 setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
351 player = (player ? player : flag.pass_sender);
356 flag.angles =
'0 0 0';
358 flag.ctf_droptime =
time;
359 flag.ctf_dropper = player;
363 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(flag.team, INFO_CTF_LOST), player.netname);
373 entity wp = WaypointSprite_Spawn(WP_FlagDropped, 0, 0, flag,
FLAG_WAYPOINT_OFFSET,
NULL, ((
autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag,
wps_flagdropped,
true, RADARICON_FLAG);
379 WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_health);
387 flag.pass_distance = 0;
388 flag.pass_sender =
NULL;
389 flag.pass_target =
NULL;
395 entity sender = flag.pass_sender;
399 flag.owner.flagcarried = flag;
405 setattachment(flag, player.vehicle,
"");
411 setattachment(flag, player,
"");
417 flag.angles =
'0 0 0';
426 Send_Notification(NOTIF_ONE, it, MSG_CENTER,
APP_NUM(flag.team, CENTER_CTF_PASS_SENT), player.netname);
427 else if(it == player)
428 Send_Notification(NOTIF_ONE, it, MSG_CENTER,
APP_NUM(flag.team, CENTER_CTF_PASS_RECEIVED), sender.netname);
430 Send_Notification(NOTIF_ONE, it, MSG_CENTER,
APP_NUM(flag.team, CENTER_CTF_PASS_OTHER), sender.netname, player.netname);
437 player.throw_antispam = sender.throw_antispam;
439 flag.pass_distance = 0;
440 flag.pass_sender =
NULL;
441 flag.pass_target =
NULL;
446 entity flag = player.flagcarried;
447 vector targ_origin, flag_velocity;
449 if(!flag) {
return; }
450 if((droptype ==
DROP_PASS) && !receiver) {
return; }
452 if(flag.speedrunning)
455 WaypointSprite_Kill(player.wps_flagcarrier);
457 if(player.wps_enemyflagcarrier)
458 WaypointSprite_Kill(player.wps_enemyflagcarrier);
460 if(player.wps_flagreturn)
461 WaypointSprite_Kill(player.wps_flagreturn);
467 setattachment(flag,
NULL,
"");
470 flag.owner.flagcarried =
NULL;
474 flag.ctf_dropper = player;
475 flag.ctf_droptime =
time;
490 flag.pass_distance =
vlen(((
'1 0 0' * targ_origin.x) + (
'0 1 0' * targ_origin.y)) - ((
'1 0 0' * player.origin.x) + (
'0 1 0' * player.origin.y)));
496 flag.pass_sender = player;
497 flag.pass_target = receiver;
520 flag.velocity =
'0 0 0';
535 WaypointSprite_Ping(player.wps_flagcarrier);
536 WaypointSprite_Kill(player.wps_flagcarrier);
538 if(player.wps_enemyflagcarrier)
539 WaypointSprite_Kill(player.wps_enemyflagcarrier);
541 if(player.wps_flagreturn)
542 WaypointSprite_Kill(player.wps_flagreturn);
549 void shockwave_spawn(
string m,
vector org,
float sz,
float t1,
float t2)
551 return modeleffect_spawn(m, 0, 0, org,
'0 0 0',
'0 0 0',
'0 0 0', 0, sz, 1, t1, t2);
566 float old_time, new_time;
568 if(!player) {
return; }
570 if((flag.cnt || enemy_flag.cnt) && flag.cnt != enemy_flag.cnt) {
return; }
572 if (toucher.goalentity == flag.bot_basewaypoint)
573 toucher.goalentity_lock_timeout = 0;
576 for(tmp_entity =
ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
579 player_team_flag = tmp_entity;
585 player.throw_prevtime =
time;
586 player.throw_count = 0;
589 Send_Notification(NOTIF_ONE, player, MSG_CENTER,
APP_NUM(enemy_flag.team, CENTER_CTF_CAPTURE));
602 if(enemy_flag.score_capture || flag.score_capture)
603 pscore =
floor((
max(1, enemy_flag.score_capture) +
max(1, flag.score_capture)) * 0.5);
606 if(enemy_flag.score_team_capture || flag.score_team_capture)
607 capscore =
floor((
max(1, enemy_flag.score_team_capture) +
max(1, flag.score_team_capture)) * 0.5);
612 if(!old_time || new_time < old_time)
616 Send_Effect_(flag.capeffect, flag.origin,
'0 0 0', 1);
618 shockwave_spawn(
"models/ctf/shockwavetransring.md3", flag.origin -
'0 0 15', -0.8, 0, 1);
624 WaypointSprite_Kill(player.wps_flagcarrier);
627 if((enemy_flag.ctf_dropper) && (player != enemy_flag.ctf_dropper))
631 flag.enemy = toucher;
643 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_TEAM_NUM(flag.team, INFO_CTF_RETURN_MONSTER), player.monster_name);
647 Send_Notification(NOTIF_ONE, player, MSG_CENTER,
APP_TEAM_NUM(flag.team, CENTER_CTF_RETURN));
648 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_TEAM_NUM(flag.team, INFO_CTF_RETURN), player.netname);
672 if(player.flagcarried == flag)
673 WaypointSprite_Kill(player.wps_flagcarrier);
684 float pickup_dropped_score;
688 player.flagcarried = flag;
692 setattachment(flag, player.vehicle,
"");
698 setattachment(flag, player,
"");
706 flag.angles =
'0 0 0';
717 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(flag.team, INFO_CTF_PICKUP), player.netname);
719 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER);
721 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_NEUTRAL);
723 Send_Notification(NOTIF_ONE, player, MSG_CENTER,
APP_TEAM_NUM(flag.team, CENTER_CTF_PICKUP));
725 Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((
SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_RETURN : CENTER_CTF_PICKUP_RETURN_ENEMY),
Team_ColorCode(flag.team));
727 Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE,
APP_NUM(flag.team, CHOICE_CTF_PICKUP_TEAM),
Team_ColorCode(player.team), player.netname);
737 Send_Notification(NOTIF_ONE, it, MSG_CHOICE,
APP_TEAM_NUM(flag.team, CHOICE_CTF_PICKUP_TEAM),
Team_ColorCode(player.team), player.netname);
739 Send_Notification(NOTIF_ONE, it, MSG_CHOICE, ((
SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY),
Team_ColorCode(player.team), player.netname);
761 LOG_TRACE(
"pickup_dropped_score is ",
ftos(pickup_dropped_score));
773 flag.speedrunning = player.speedrunning;
779 Send_Effect_(flag.toucheffect, player.origin,
'0 0 0', 1);
782 if(pickuptype ==
PICKUP_DROPPED) { WaypointSprite_Kill(flag.wps_flagdropped); }
784 WaypointSprite_Ping(player.wps_flagcarrier);
796 if(flag.wps_flagdropped) { WaypointSprite_UpdateHealth(flag.wps_flagdropped,
GetResource(flag,
RES_HEALTH)); }
803 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(flag.team, INFO_CTF_FLAGRETURN_DROPPED));
break;
805 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(flag.team, INFO_CTF_FLAGRETURN_DAMAGED));
break;
809 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(flag.team, INFO_CTF_FLAGRETURN_NEEDKILL));
break;
812 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(flag.team, INFO_CTF_FLAGRETURN_TIMEOUT));
break;
825 entity e = WaypointSprite_getviewentity(client);
830 if(
SAME_TEAM(wp_owner, e)) {
return false; }
839 int stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0;
845 for(tmp_entity =
ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
851 tmp_entity.ctf_staleflagnext = ctf_staleflaglist;
852 ctf_staleflaglist = tmp_entity;
854 switch(tmp_entity.team)
860 default: ++stale_neutral_flags;
break;
866 stale_flags = (stale_neutral_flags >= 1);
868 stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
872 else if(stale_flags >= 2)
882 for(tmp_entity = ctf_staleflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_staleflagnext)
884 if((tmp_entity.owner) && (!tmp_entity.owner.wps_enemyflagcarrier))
886 entity wp = WaypointSprite_Spawn(((
ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, tmp_entity.owner,
FLAG_WAYPOINT_OFFSET,
NULL, 0, tmp_entity.owner,
wps_enemyflagcarrier,
true, RADARICON_FLAG);
894 FOREACH_CLIENT(
IS_PLAYER(it) &&
IS_REAL_CLIENT(it), { Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((it.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER)); });
935 if(this.
mins != this.m_mins || this.
maxs != this.m_maxs) {
939 setsize(
this, this.m_mins, this.m_maxs);
949 for(tmp_entity =
ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
1007 CS(this.
owner).impulse = CHIMPULSE_SPEEDRUN.impulse;
1054 LOG_TRACE(
"ctf_FlagThink(): Flag exists with no status?");
1063 if(game_stopped)
return;
1066 bool is_not_monster = (!
IS_MONSTER(toucher));
1076 if(!flag.ctf_flagdamaged_byworld) {
return; }
1080 if(STAT(FROZEN, toucher)) {
return; }
1084 toucher = toucher.owner;
1095 if(
time > flag.wait)
1097 Send_Effect_(flag.toucheffect, flag.origin,
'0 0 0', 1);
1103 else if(
IS_DEAD(toucher)) {
return; }
1105 switch(flag.ctf_status)
1111 if(
CTF_SAMETEAM(toucher, flag) && (toucher.flagcarried) && !toucher.flagcarried.team && is_not_monster)
1113 else if(!flag.team && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (
time > toucher.next_take_time) && is_not_monster)
1116 else if(
CTF_SAMETEAM(toucher, flag) && (toucher.flagcarried) &&
DIFF_TEAM(toucher.flagcarried, flag) && is_not_monster)
1123 else if(
CTF_DIFFTEAM(toucher, flag) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (
time > toucher.next_take_time) && is_not_monster)
1139 LOG_TRACE(
"Someone touched a flag even though it was being carried?");
1145 if((
IS_PLAYER(toucher)) && !
IS_DEAD(toucher) && (toucher != flag.pass_sender))
1147 if(
DIFF_TEAM(toucher, flag.pass_sender))
1151 else if(is_not_monster && (!toucher.flagcarried))
1154 else if(!toucher.flagcarried)
1167 if(flag.last_respawn >
time - 0.5)
1168 {
backtrace(
"flag respawn called twice quickly! please notify Samual about this..."); }
1170 flag.last_respawn =
time;
1173 if((flag.owner) && (flag.owner.flagcarried == flag))
1175 WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
1176 WaypointSprite_Kill(flag.owner.wps_flagreturn);
1177 WaypointSprite_Kill(flag.wps_flagcarrier);
1179 flag.owner.flagcarried =
NULL;
1182 if(flag.speedrunning)
1186 if((flag.owner) && (flag.owner.vehicle))
1190 { WaypointSprite_Kill(flag.wps_flagdropped); }
1193 setattachment(flag,
NULL,
"");
1201 flag.velocity =
'0 0 0';
1202 flag.angles = flag.mangle;
1207 flag.pass_distance = 0;
1208 flag.pass_sender =
NULL;
1209 flag.pass_target =
NULL;
1210 flag.ctf_dropper =
NULL;
1211 flag.ctf_pickuptime = 0;
1212 flag.ctf_droptime = 0;
1213 flag.ctf_flagdamaged_byworld =
false;
1230 entity e = WaypointSprite_getviewentity(client);
1232 entity flag = e.flagcarried;
1235 if(flag && (flag.cnt || wp_owner.cnt) && wp_owner.cnt != flag.cnt)
1250 case NUM_TEAM_1: basename = WP_FlagBaseRed;
break;
1251 case NUM_TEAM_2: basename = WP_FlagBaseBlue;
break;
1252 case NUM_TEAM_3: basename = WP_FlagBaseYellow;
break;
1253 case NUM_TEAM_4: basename = WP_FlagBasePink;
break;
1254 default: basename = WP_FlagBaseNeutral;
break;
1278 setattachment(flag,
NULL,
"");
1281 flag.team = teamnum;
1282 flag.classname =
"item_flag_team";
1283 flag.target =
"###item###";
1292 flag.pushable =
true;
1297 if(flag.damagedbycontents)
1299 flag.velocity =
'0 0 0';
1300 flag.mangle = flag.angles;
1309 flag.cnt = flag.score_assist = flag.score_team_capture = flag.score_capture = flag.score_drop = flag.score_pickup = flag.score_return = 0;
1314 if(flag.skin == 0) { flag.skin =
cvar(sprintf(
"g_ctf_flag_%s_skin", teamname)); }
1315 if(flag.model ==
"") { flag.model =
cvar_string(sprintf(
"g_ctf_flag_%s_model", teamname)); }
1316 if (flag.toucheffect ==
"") { flag.toucheffect =
EFFECT_FLAG_TOUCH(teamnum).eent_eff_name; }
1317 if (flag.passeffect ==
"") { flag.passeffect =
EFFECT_PASS(teamnum).eent_eff_name; }
1318 if (flag.capeffect ==
"") { flag.capeffect =
EFFECT_CAP(teamnum).eent_eff_name; }
1322 if(flag.s == "") flag.s = b; \ 1323 precache_sound(flag.s); 1335 precache_model(flag.model);
1338 _setmodel(flag, flag.model);
1340 flag.m_mins = flag.mins;
1341 flag.m_maxs = flag.maxs;
1348 case NUM_TEAM_1: flag.glow_color = 251;
break;
1349 case NUM_TEAM_2: flag.glow_color = 210;
break;
1350 case NUM_TEAM_3: flag.glow_color = 110;
break;
1351 case NUM_TEAM_4: flag.glow_color = 145;
break;
1352 default: flag.glow_color = 254;
break;
1354 flag.glow_size = 25;
1355 flag.glow_trail = 1;
1373 if((flag.spawnflags & 1) || flag.noalign)
1375 flag.dropped_origin = flag.origin;
1376 flag.noalign =
true;
1381 flag.noalign =
false;
1408 f = f.ctf_worldflagnext;
1424 float m = -(f1.origin.y - f2.origin.y) / (
max(f1.origin.x - f2.origin.x,
FLOAT_EPSILON));
1441 f = f.ctf_worldflagnext;
1461 else if(!bot.flagcarried)
1467 f = f.ctf_worldflagnext;
1483 if(
vdist(it.origin - org, <, tc_radius))
1492 void havocbot_goalrating_ctf_ourflag(
entity this,
float ratingscale)
1500 head = head.ctf_worldflagnext;
1516 if ((this.
flagcarried.cnt || head.cnt) &&
this.flagcarried.cnt != head.cnt)
1518 head = head.ctf_worldflagnext;
1523 head = head.ctf_worldflagnext;
1552 head = head.ctf_worldflagnext;
1559 head = head.tag_entity;
1561 ratingscale += ratingscale * f * 0.1;
1608 if(head.tag_entity==
NULL)
1612 if(
vdist(org - head.origin, <, df_radius))
1619 head = head.ctf_worldflagnext;
1625 float cdefense, cmiddle, coffense;
1673 else if (count == 2)
1690 if(cdefense<=coffense)
1692 else if(coffense<=cmiddle)
1704 if (item.classname !=
"waypoint")
1710 if (item == head.bot_basewaypoint)
1712 head = head.ctf_worldflagnext;
1737 vector base_org = mf.dropped_origin;
1738 float base_rating = (mf.ctf_status ==
FLAG_BASE) ? 10000 : (
vdist(this.
origin - base_org, >, 100) ? 2000 : 1000);
1764 Damage(
this,
this,
this, 100000, DEATH_KILL.m_id,
DMG_NOWEP,
this.origin,
'0 0 0');
1790 this.havocbot_role = this.havocbot_previous_role;
1802 if (mf.ctf_status !=
FLAG_BASE &&
vdist(ef.origin - mf.dropped_origin, <, 900))
1817 this.havocbot_role = this.havocbot_previous_role;
1863 pos = mf.tag_entity.origin;
1879 pos = ef.tag_entity.origin;
1883 if(
vdist(pos - mf.dropped_origin, >, 700))
1936 if (mf.enemy ==
this)
1953 const float RT_RADIUS = 10000;
1962 vector enemy_base_org = ef.dropped_origin;
2067 vector org = mf.dropped_origin;
2073 float distance, bestdistance = 10000;
2075 distance =
vlen(org - it.origin);
2076 if(distance<bestdistance)
2079 bestdistance = distance;
2104 string s =
"(null)";
2110 bot.havocbot_role_timeout = 0;
2111 bot.havocbot_cantfindflag =
time + 10;
2112 if (bot.havocbot_previous_role != bot.havocbot_role)
2118 bot.havocbot_role_timeout = 0;
2123 bot.havocbot_role_timeout = 0;
2128 bot.havocbot_role_timeout = 0;
2132 bot.havocbot_previous_role = bot.havocbot_role;
2134 bot.havocbot_role_timeout =
time + 10;
2135 if (bot.havocbot_previous_role != bot.havocbot_role)
2140 bot.havocbot_previous_role = bot.havocbot_role;
2142 bot.havocbot_role_timeout =
time + 30;
2143 if (bot.havocbot_previous_role != bot.havocbot_role)
2147 LOG_TRACE(bot.netname,
" switched to ", s);
2159 int t = 0, t2 = 0, t3 = 0;
2160 bool b1 =
false, b2 =
false, b3 =
false, b4 =
false, b5 =
false;
2163 STAT(OBJECTIVE_STATUS, player) &= ~(CTF_RED_FLAG_CARRYING | CTF_RED_FLAG_TAKEN | CTF_RED_FLAG_LOST
2164 | CTF_BLUE_FLAG_CARRYING | CTF_BLUE_FLAG_TAKEN | CTF_BLUE_FLAG_LOST
2165 | CTF_YELLOW_FLAG_CARRYING | CTF_YELLOW_FLAG_TAKEN | CTF_YELLOW_FLAG_LOST
2166 | CTF_PINK_FLAG_CARRYING | CTF_PINK_FLAG_TAKEN | CTF_PINK_FLAG_LOST
2167 | CTF_NEUTRAL_FLAG_CARRYING | CTF_NEUTRAL_FLAG_TAKEN | CTF_NEUTRAL_FLAG_LOST
2168 | CTF_FLAG_NEUTRAL | CTF_SHIELDED | CTF_STALEMATE);
2173 if(flag.team ==
NUM_TEAM_1 && !b1) { b1 =
true; t = CTF_RED_FLAG_CARRYING; t2 = CTF_RED_FLAG_TAKEN; t3 = CTF_RED_FLAG_LOST; }
2174 if(flag.team ==
NUM_TEAM_2 && !b2) { b2 =
true; t = CTF_BLUE_FLAG_CARRYING; t2 = CTF_BLUE_FLAG_TAKEN; t3 = CTF_BLUE_FLAG_LOST; }
2175 if(flag.team ==
NUM_TEAM_3 && !b3) { b3 =
true; t = CTF_YELLOW_FLAG_CARRYING; t2 = CTF_YELLOW_FLAG_TAKEN; t3 = CTF_YELLOW_FLAG_LOST; }
2176 if(flag.team ==
NUM_TEAM_4 && !b4) { b4 =
true; t = CTF_PINK_FLAG_CARRYING; t2 = CTF_PINK_FLAG_TAKEN; t3 = CTF_PINK_FLAG_LOST; }
2177 if(flag.team == 0 && !b5) { b5 =
true; t = CTF_NEUTRAL_FLAG_CARRYING; t2 = CTF_NEUTRAL_FLAG_TAKEN; t3 = CTF_NEUTRAL_FLAG_LOST; STAT(OBJECTIVE_STATUS, player) |= CTF_FLAG_NEUTRAL; }
2179 switch(flag.ctf_status)
2184 if((flag.owner == player) || (flag.pass_sender == player))
2185 STAT(OBJECTIVE_STATUS, player) |= t;
2187 STAT(OBJECTIVE_STATUS, player) |= t2;
2192 STAT(OBJECTIVE_STATUS, player) |= t3;
2199 if(player.ctf_captureshielded)
2200 STAT(OBJECTIVE_STATUS, player) |= CTF_SHIELDED;
2203 STAT(OBJECTIVE_STATUS, player) |= CTF_STALEMATE;
2206 if(player.wps_flagcarrier)
2214 float frag_damage =
M_ARGV(4,
float);
2217 if(frag_attacker.flagcarried)
2219 if(frag_target == frag_attacker)
2230 M_ARGV(4,
float) = frag_damage;
2233 else if(frag_target.flagcarried && !
IS_DEAD(frag_target) &&
CTF_DIFFTEAM(frag_target, frag_attacker))
2238 frag_target.wps_helpme_time =
time;
2239 WaypointSprite_HelpMePing(frag_target.wps_flagcarrier);
2250 if((frag_attacker != frag_target) && (
IS_PLAYER(frag_attacker)) && (frag_target.flagcarried))
2256 if(frag_target.flagcarried)
2258 entity tmp_entity = frag_target.flagcarried;
2260 tmp_entity.ctf_dropper =
NULL;
2272 if(player.flagcarried)
2277 if(flag.pass_sender == player) { flag.pass_sender =
NULL; }
2278 if(flag.pass_target == player) { flag.pass_target =
NULL; }
2279 if(flag.ctf_dropper == player) { flag.ctf_dropper =
NULL; }
2299 if(!autocvar_g_ctf_leaderboard)
2309 if(!autocvar_g_ctf_leaderboard)
2321 if(player.flagcarried)
2343 if(head != player &&
SAME_TEAM(head, player))
2344 if(!head.speedrunning && !head.vehicle)
2356 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
2361 Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_CTF_PASS_REQUESTED, player.netname);
2362 Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
2367 else if(player.flagcarried && !head.flagcarried)
2372 if(
vlen2(passer_center - head_center) <
vlen2(passer_center - closest_target_center))
2373 { closest_target = head; }
2375 else { closest_target = head; }
2388 if(player.throw_count == -1)
2392 player.throw_prevtime =
time;
2393 player.throw_count = 1;
2406 else { player.throw_count += 1; }
2409 player.throw_prevtime =
time;
2421 if(player.wps_flagcarrier)
2423 player.wps_helpme_time =
time;
2424 WaypointSprite_HelpMePing(player.wps_flagcarrier);
2428 WaypointSprite_Spawn(WP_Helpme, waypointsprite_deployed_lifetime, waypointsprite_limitedrange, player,
FLAG_WAYPOINT_OFFSET,
NULL, player.team, player,
wps_helpme,
false, RADARICON_HELPME);
2429 WaypointSprite_Ping(player.wps_helpme);
2440 if(player.flagcarried)
2448 player.flagcarried.nodrawtoclient = player;
2449 setattachment(player.flagcarried, veh,
"");
2462 if(player.flagcarried)
2464 setattachment(player.flagcarried, player,
"");
2467 player.flagcarried.angles =
'0 0 0';
2468 player.flagcarried.nodrawtoclient =
NULL;
2477 if(player.flagcarried)
2479 Send_Notification(NOTIF_ALL,
NULL, MSG_INFO,
APP_NUM(player.flagcarried.team, INFO_CTF_FLAGRETURN_ABORTRUN));
2491 switch(flag.ctf_status)
2500 flag.nextthink =
false;
2527 M_ARGV(1,
string) =
"ctf_team";
2532 int record_page =
M_ARGV(0,
int);
2533 string ret_string =
M_ARGV(1,
string);
2535 for(
int i = record_page * 200; i <
MapInfo_count && i < record_page * 200 + 200; ++i)
2550 M_ARGV(1,
string) = ret_string;
2554 void superspec_msg(
string _center_title,
string _con_title,
entity _to,
string _msg,
float _spamlevel);
2563 if(cmd_name ==
"followfc")
2583 if(it.flagcarried && (it.team == _team || _team == 0))
2586 if(_team == 0 && IS_SPEC(player) && player.enemy == it)
2588 return superspec_Spectate(player, it);
2593 superspec_msg(
"",
"", player,
"No active flag carrier\n", 1);
2602 if(frag_target.flagcarried)
2609 if(player.flagcarried)
2631 if(!
g_ctf) {
delete(
this);
return; }
2649 if(!
g_ctf) {
delete(
this);
return; }
2667 if(!
g_ctf) {
delete(
this);
return; }
2685 if(!
g_ctf) {
delete(
this);
return; }
2703 if(!
g_ctf) {
delete(
this);
return; }
2704 if(!
cvar(
"g_ctf_oneflag")) {
delete(
this);
return; }
2717 if(!
g_ctf) {
delete(
this);
return; }
2723 spawnfunc(team_CTF_redflag) { spawnfunc_item_flag_team1(
this); }
2724 spawnfunc(team_CTF_blueflag) { spawnfunc_item_flag_team2(
this); }
2726 spawnfunc(team_CTF_redplayer) { spawnfunc_info_player_team1(
this); }
2727 spawnfunc(team_CTF_redspawn) { spawnfunc_info_player_team1(
this); }
2729 spawnfunc(team_CTF_blueplayer) { spawnfunc_info_player_team2(
this); }
2730 spawnfunc(team_CTF_bluespawn) { spawnfunc_info_player_team2(
this); }
2732 spawnfunc(team_CTF_neutralflag) { spawnfunc_item_flag_neutral(
this); }
2733 spawnfunc(team_neutralobelisk) { spawnfunc_item_flag_neutral(
this); }
2736 spawnfunc(team_redplayer) { spawnfunc_info_player_team1(
this); }
2737 spawnfunc(team_blueplayer) { spawnfunc_info_player_team2(
this); }
2738 spawnfunc(team_ctl_redlolly) { spawnfunc_item_flag_team1(
this); }
2739 spawnfunc(team_CTL_redlolly) { spawnfunc_item_flag_team1(
this); }
2740 spawnfunc(team_ctl_bluelolly) { spawnfunc_item_flag_team2(
this); }
2741 spawnfunc(team_CTL_bluelolly) { spawnfunc_item_flag_team2(
this); }
2755 field(SP_CTF_PICKUPS,
"pickups", 0);
2756 field(SP_CTF_FCKILLS,
"fckills", 0);
2757 field(SP_CTF_RETURNS,
"returns", 0);
2767 this.
cnt = teamcolor - 1;
2768 this.spawnfunc_checked =
true;
2769 this.
team = teamcolor;
2777 for(tmp_entity =
ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
2782 switch(tmp_entity.team)
2806 LOG_TRACE(
"No \"ctf_team\" entities found on this map, creating them anyway.");
void race_SendAll(entity player, bool only_rankings)
#define FLAG_SPAWN_OFFSET
void ctf_FakeTimeLimit(entity e, float t)
bool ctf_Stalemate_Customize(entity this, entity client)
const float WPFE_THINKRATE
bool autocvar_g_ctf_allow_vehicle_touch
const vector FLAG_DROP_OFFSET
#define APP_TEAM_NUM(num, prefix)
#define GameRules_scoring(teams, spprio, stprio, fields)
bool wpforenemy_announced
float havocbot_role_timeout
bool autocvar_g_ctf_oneflag_reverse
float autocvar_g_ctf_pass_directional_min
int autocvar_g_ctf_score_pickup_dropped_late
ERASEABLE void db_put(int db, string key, string value)
float autocvar_g_ctf_flag_collect_delay
int autocvar_g_ctf_score_pickup_base
void havocbot_ctf_reset_role(entity this)
void navigation_goalrating_start(entity this)
ERASEABLE string ftos_decimals(float number, int decimals)
converts a number to a string with the indicated number of decimals
int autocvar_g_ctf_stalemate_endcondition
int autocvar_g_ctf_score_return
bool ctf_CaptureShield_Customize(entity this, entity client)
int havocbot_ctf_teamcount(entity bot, vector org, float tc_radius)
void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius)
float autocvar_g_ctf_drop_velocity_up
void ClientConnect(entity this)
ClientConnect
int autocvar_g_ctf_flag_health
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
const int HAVOCBOT_CTF_ROLE_MIDDLE
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1 f1points s1 s2
#define WPCOLOR_DROPPEDFLAG(t)
void ctf_SpawnTeam(string teamname, int teamcolor)
void navigation_goalrating_end(entity this)
void WarpZone_RefSys_AddInverse(entity me, entity wz)
void havocbot_goalrating_ctf_ourbase(entity this, float ratingscale)
float autocvar_g_ctf_pass_arc_max
bool havocbot_ctf_is_basewaypoint(entity item)
bool superspec_Spectate(entity this, entity targ)
float autocvar_g_ctf_pass_directional_max
float autocvar_g_ctf_shield_force
const int TELEPORT_NORMAL
void ctf_FlagDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
float autocvar_g_ctf_throw_punish_delay
float DPCONTENTS_MONSTERCLIP
vector Team_ColorRGB(int teamid)
float autocvar_g_ctf_flag_damageforcescale
float autocvar_g_ctf_flag_return_time
float TeamScore_AddToTeam(int t, float scorefield, float score)
Adds a score to the given team.
void GameRules_scoring_vip(entity player, bool value)
Mark a player as being 'important' (flag carrier, ball carrier, etc)
const float FLAG_TOUCHRATE
float autocvar_g_ctf_drop_velocity_side
IntrusiveList g_damagedbycontents
const int SFL_SORT_PRIO_SECONDARY
Scoring priority (NOTE: PRIMARY is used for fraglimit)
float goalentity_lock_timeout
void WarpZone_RefSys_Copy(entity me, entity from)
float trace_dphitcontents
void navigation_dynamicgoal_init(entity this, bool initially_static)
bool ctf_CaptureShield_CheckStatus(entity p)
void ctf_FlagcarrierWaypoints(entity player)
const int FLAG_FLOAT_OFFSET_Z
ClientState CS(Client this)
const int HAVOCBOT_CTF_ROLE_RETRIEVER
const vector FLAG_WAYPOINT_OFFSET
#define FOREACH_CLIENT(cond, body)
void havocbot_role_ctf_defense(entity this)
#define GameRules_scoring_add(client, fld, value)
void race_checkAndWriteName(entity player)
bool autocvar_g_ctf_flag_return_when_unreachable
float checkpvs(vector viewpos, entity viewee)
float autocvar_g_ctf_flagcarrier_damagefactor
const int SFL_SORT_PRIO_PRIMARY
float autocvar_g_ctf_dropped_capture_delay
float ctf_captureshield_force
bool autocvar_g_ctf_flag_dropped_floatinwater
void navigation_dynamicgoal_set(entity this, entity dropper)
void ctf_Handle_Capture(entity flag, entity toucher, int capturetype)
bool ctf_FlagBase_Customize(entity this, entity client)
float DPCONTENTS_PLAYERCLIP
const int RETURN_NEEDKILL
void havocbot_goalrating_ctf_enemyflag(entity this, float ratingscale)
float autocvar_g_ctf_flagcarrier_forcefactor
bool MapInfo_Get_ByID(int i)
#define APP_NUM(num, prefix)
float autocvar_g_ctf_flag_return_carried_radius
float autocvar_g_ctf_pass_wait
bool autocvar_g_ctf_pass_request
#define METHOD(cname, name, prototype)
#define WPCOLOR_FLAGCARRIER(t)
float autocvar_g_ctf_pass_timelimit
void ctf_DelayedFlagSetup(entity this)
bool autocvar_g_ctf_allow_monster_touch
float havocbot_middlepoint_radius
void navigation_goalrating_timeout_force(entity this)
bool havocbot_cantfindflag
void havocbot_role_ctf_retriever(entity this)
void PlayerPreThink(entity this)
void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
const int HAVOCBOT_CTF_ROLE_CARRIER
void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnrate)
void havocbot_goalrating_ctf_ourstolenflag(entity this, float ratingscale)
void havocbot_goalrating_ctf_droppedflags(entity this, float ratingscale, vector org, float df_radius)
entity havocbot_ctf_find_enemy_flag(entity bot)
#define Static_Team_ColorName_Lower(teamid)
int autocvar_g_ctf_score_penalty_returned
void write_recordmarker(entity pl, float tstart, float dt)
void havocbot_role_ctf_escort(entity this)
MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
bool autocvar_g_ctf_allow_vehicle_carry
bool ctf_Return_Customize(entity this, entity client)
void ctf_FlagSetup(int teamnum, entity flag)
const int SFL_LOWER_IS_BETTER
Lower scores are better (e.g.
#define BITSET_ASSIGN(a, b)
bool autocvar_g_ctf_fullbrightflags
void navigation_routerating(entity this, entity e, float f, float rangebias)
void ctf_Handle_Drop(entity flag, entity player, int droptype)
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1
int autocvar_g_ctf_score_capture_assist
void havocbot_role_ctf_offense(entity this)
#define IS_REAL_CLIENT(v)
entity EFFECT_PASS(int teamid)
vector WarpZone_UnTransformOrigin(entity wz, vector v)
float autocvar_g_ctf_flagcarrier_selfforcefactor
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
#define CTF_DIFFTEAM(a, b)
bool autocvar_g_ctf_reverse
#define setmodel(this, m)
const vector VEHICLE_FLAG_OFFSET
void ctf_FlagThink(entity this)
entity wps_enemyflagcarrier
bool autocvar_g_ctf_flag_dropped_waypoint
float autocvar_g_ctf_flag_waypoint_maxdistance
const float CONTENT_EMPTY
const float EF_FULLBRIGHT
void havocbot_role_ctf_middle(entity this)
const int HAVOCBOT_CTF_ROLE_ESCORT
void ctf_CaptureShield_Spawn(entity flag)
vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org)
float havocbot_symmetry_axis_q
bool ctf_flagdamaged_byworld
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
float havocbot_symmetry_axis_m
void SV_ParseClientCommand(entity this, string command)
void ctf_CaptureRecord(entity flag, entity player)
float wpforenemy_nextthink
float autocvar_g_ctf_flagcarrier_auto_helpme_damage
float autocvar_g_ctf_pass_arc
const float MOVE_NOMONSTERS
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1 f1points f2
const int HAVOCBOT_CTF_ROLE_OFFENSE
int autocvar_g_ctf_shield_min_negscore
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
void havocbot_goalrating_ctf_enemybase(entity this, float ratingscale)
bool autocvar_g_ctf_flag_return
const float VEHICLE_FLAG_SCALE
float autocvar_g_ctf_throw_velocity_up
int autocvar_g_ctf_throw_punish_count
void waypoint_spawnforitem_force(entity e, vector org)
float autocvar_g_ctf_stalemate_time
bool navigation_goalrating_timeout(entity this)
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
bool ctf_Immediate_Return_Allowed(entity flag, entity toucher)
void GetPressedKeys(entity this)
#define GameRules_scoring_add_team(client, fld, value)
bool autocvar_g_ctf_dynamiclights
void ctf_Handle_Throw(entity player, entity receiver, int droptype)
bool ctf_CheckPassDirection(vector head_center, vector passer_center, vector passer_angle, vector nearest_to_passer)
void PlayerUseKey(entity this)
const float CONTENT_WATER
void ctf_CheckFlagReturn(entity flag, int returntype)
vector havocbot_middlepoint
const vector FLAG_CARRY_OFFSET
float autocvar_g_ctf_shield_max_ratio
float autocvar_g_ctf_pass_turnrate
bool autocvar_g_ctf_stalemate
#define crandom()
Returns a random number between -1.0 and 1.0.
int autocvar_g_ctf_score_capture
float autocvar_g_ctf_throw_angle_min
bool autocvar_g_ctf_throw
void havocbot_role_ctf_carrier(entity this)
float autocvar_g_ctf_throw_punish_time
void GameLogEcho(string s)
const int FLAG_PASS_ARC_OFFSET_Z
ERASEABLE string db_get(int db, string key)
float autocvar_g_ctf_throw_velocity_forward
float ctf_captureshield_min_negscore
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
#define MUTATOR_RETURNVALUE
#define Team_ColorName_Upper(teamid)
void nades_GiveBonus(entity player, float score)
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
void ctf_EventLog(string mode, int flagteam, entity actor)
bool autocvar_g_ctf_flag_waypoint
void navigation_goalrating_timeout_set(entity this)
void ctf_CaptureShield_Touch(entity this, entity toucher)
void navigation_goalrating_timeout_expire(entity this, float seconds)
const int HAVOCBOT_CTF_ROLE_DEFENSE
void ctf_Handle_Pickup(entity flag, entity player, int pickuptype)
float autocvar_g_ctf_flag_return_damage_delay
#define CTF_SAMETEAM(a, b)
void ctf_RespawnFlag(entity flag)
#define CENTER_OR_VIEWOFS(ent)
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define ITEM_DAMAGE_NEEDKILL(dt)
void navigation_dynamicgoal_unset(entity this)
void ctf_DelayedInit(entity this)
float autocvar_g_ctf_flag_return_damage
string Team_ColorCode(int teamid)
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
const float FLAG_THINKRATE
void ctf_Handle_Retrieve(entity flag, entity player)
#define ITEM_TOUCH_NEEDKILL()
int autocvar_g_ctf_score_kill
void InitializeEntity(entity e, void(entity this) func, int order)
string MapInfo_Map_bspname
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
bool autocvar_g_ctf_flag_return_carrying
int autocvar_g_ctf_score_pickup_dropped_early
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
bool autocvar_g_ctf_ignore_frags
#define _sound(e, c, s, v, a)
float autocvar_g_ctf_pass_radius
const float SOLID_TRIGGER
entity EFFECT_FLAG_TOUCH(int teamid)
#define snd_flag_returned
void WarpZone_TrailParticles(entity own, float eff, vector org, vector end)
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
float autocvar_g_ctf_pass_velocity
float autocvar_g_ctf_flagcarrier_auto_helpme_time
float havocbot_symmetry_origin_order
#define new_pure(class)
purely logical entities (.origin doesn't work)
void ctf_Handle_Return(entity flag, entity player)
void ctf_ScoreRules(int teams)
entity havocbot_ctf_find_flag(entity bot)
float ctf_captureshield_max_ratio
float autocvar_g_ctf_dropped_capture_radius
void superspec_msg(string _center_title, string _con_title, entity _to, string _msg, float _spamlevel)
float autocvar_g_ctf_flag_return_dropped
void havocbot_role_ctf_setrole(entity bot, int role)
entity TeamBalance_CheckAllowedTeams(entity for_whom)
Checks whether the player can join teams according to global configuration and mutator settings...
void ctf_RemovePlayer(entity player)
void ctf_FlagTouch(entity this, entity toucher)
vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
bool autocvar_sv_eventlog
float autocvar_g_ctf_throw_strengthmultiplier
#define WPCOLOR_ENEMYFC(t)
void ctf_CaptureShield_Update(entity player, bool wanted_status)
float autocvar_g_balance_armor_blockpercent
const int RETURN_SPEEDRUN
const float FLOAT_EPSILON
bool autocvar_g_ctf_portalteleport
bool autocvar_g_ctf_flag_glowtrails
float autocvar_g_ctf_throw_angle_max
void race_setTime(string map, float t, string myuid, string mynetname, entity e, bool showmessage)
spawnfunc(item_flag_team1)
const int SFL_TIME
Display as mm:ss.s, value is stored as 10ths of a second (AND 0 is the worst possible value!) ...
const int CAPTURE_DROPPED
float autocvar_g_ctf_flagcarrier_selfdamagefactor
void set_movetype(entity this, int mt)
entity EFFECT_CAP(int teamid)
void ctf_CheckStalemate()
#define colormapPaletteColor(c, isPants)
int autocvar_g_ctf_score_penalty_drop
void havocbot_ctf_calculate_middlepoint()
void ImpulseCommands(entity this)
bool autocvar_g_ctf_score_ignore_fields
void ctf_Reset(entity this)