velocitymultiplier 0.5
airfriction 3
+// yellowflag_touch -- effects for touching the yellow flag
+// used nowhere in code
+effect yellowflag_touch
+count 35
+type spark
+tex 40 40
+color 0xFFFF0F 0xFFFF0F
+size 1 3
+alpha 0 256 556
+gravity 1
+bounce 1.5
+originjitter 1 1 1
+velocityjitter 300 300 300
+velocitymultiplier 0.5
+airfriction 3
+
+// pinkflag_touch -- effects for touching the pink flag
+// used nowhere in code
+effect pinkflag_touch
+count 35
+type spark
+tex 40 40
+color 0xFF0FFF 0xFF0FFF
+size 1 3
+alpha 0 256 556
+gravity 1
+bounce 1.5
+originjitter 1 1 1
+velocityjitter 300 300 300
+velocitymultiplier 0.5
+airfriction 3
+
++// neutralflag_touch -- effects for touching the neutral flag
++// used nowhere in code
++effect neutralflag_touch
++count 35
++type spark
++tex 40 40
++color 0xFFFFFF 0xFFFFFF
++size 1 3
++alpha 0 256 556
++gravity 1
++bounce 1.5
++originjitter 1 1 1
++velocityjitter 300 300 300
++velocitymultiplier 0.5
++airfriction 3
++
// red_pass
// used nowhere in code
effect red_pass
alpha 256 256 1280
type static
+// yellow_pass
+// used nowhere in code
+effect yellow_pass
+trailspacing 64
+color 0xFFFF0F 0xFFFF0F
+size 2 2
+tex 32 32
+alpha 64 128 64
+airfriction 5
+sizeincrease 2
+type static
+effect yellow_pass
+trailspacing 12
+color 0xFFFF0F 0xFFFF0F
+size 1 1
+tex 0 8
+alpha 32 64 32
+airfriction 9
+sizeincrease 8
+velocityjitter 64 64 64
+type static
+effect yellow_pass
+trailspacing 12
+color 0xFFFF0F 0xFFFF0F
+size 4 4
+//tex 48 55
+alpha 256 256 1280
+type static
+
+// pink_pass
+// used nowhere in code
+effect pink_pass
+trailspacing 64
+color 0xFFFFFF 0xFFFFFF
+size 2 2
+tex 32 32
+alpha 64 128 64
+airfriction 5
+sizeincrease 2
+type static
+effect pink_pass
+trailspacing 12
+color 0xFFFFFF 0xFFFFFF
+size 1 1
+tex 0 8
+alpha 32 64 32
+airfriction 9
+sizeincrease 8
+velocityjitter 64 64 64
+type static
+effect pink_pass
+trailspacing 12
+color 0xFFFFFF 0xFFFFFF
+size 4 4
+//tex 48 55
+alpha 256 256 1280
+type static
+
++// neutral_pass
++// used nowhere in code
++effect neutral_pass
++trailspacing 64
++color 0xFFFFFF 0xFFFFFF
++size 2 2
++tex 32 32
++alpha 64 128 64
++airfriction 5
++sizeincrease 2
++type static
++effect neutral_pass
++trailspacing 12
++color 0xFFFFFF 0xFFFFFF
++size 1 1
++tex 0 8
++alpha 32 64 32
++airfriction 9
++sizeincrease 8
++velocityjitter 64 64 64
++type static
++effect neutral_pass
++trailspacing 12
++color 0xFFFFFF 0xFFFFFF
++size 4 4
++//tex 48 55
++alpha 256 256 1280
++type static
++
// red_cap -- red team capture effect
effect red_cap
count 500
set g_ctf_flag_red_skin 0
set g_ctf_flag_blue_model "models/ctf/flags.md3"
set g_ctf_flag_blue_skin 1
+set g_ctf_flag_yellow_model "models/ctf/flags.md3"
+set g_ctf_flag_yellow_skin 2
+set g_ctf_flag_pink_model "models/ctf/flags.md3"
+set g_ctf_flag_pink_skin 3
++set g_ctf_flag_neutral_model "models/ctf/flags.md3"
++set g_ctf_flag_neutral_skin 4
set g_ctf_flag_glowtrails 1
set g_ctf_fullbrightflags 0
set g_ctf_dynamiclights 0
--- /dev/null
--- /dev/null
++mesh,models/ctf/flag_neutral.tga
++mesh2,models/ctf/banner_neutral.tga
++mesh3,models/ctf/glow_neutral.tga
}
// CTF HUD modicon section
- float redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe; // status during previous frame
- float redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus; // last remembered status
- float redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time; // time when the status changed
-float redflag_prevframe, blueflag_prevframe; // status during previous frame
-float redflag_prevstatus, blueflag_prevstatus; // last remembered status
-float redflag_statuschange_time, blueflag_statuschange_time; // time when the status changed
++float redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe, neutralflag_prevframe; // status during previous frame
++float redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus, neutralflag_prevstatus; // last remembered status
++float redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time, neutralflag_statuschange_time; // time when the status changed
void HUD_Mod_CTF_Reset(void)
{
- redflag_prevstatus = blueflag_prevstatus = yellowflag_prevstatus = pinkflag_prevstatus = 0;
- redflag_prevframe = blueflag_prevframe = yellowflag_prevframe = pinkflag_prevframe = 0;
- redflag_statuschange_time = blueflag_statuschange_time = yellowflag_statuschange_time = pinkflag_statuschange_time = 0;
- redflag_prevstatus = blueflag_prevstatus = redflag_prevframe = blueflag_prevframe = redflag_statuschange_time = blueflag_statuschange_time = 0;
++ redflag_prevstatus = blueflag_prevstatus = yellowflag_prevstatus = pinkflag_prevstatus = neutralflag_prevstatus = 0;
++ redflag_prevframe = blueflag_prevframe = yellowflag_prevframe = pinkflag_prevframe = neutralflag_prevframe = 0;
++ redflag_statuschange_time = blueflag_statuschange_time = yellowflag_statuschange_time = pinkflag_statuschange_time = neutralflag_statuschange_time = 0;
}
void HUD_Mod_CTF(vector pos, vector mySize)
{
- vector redflag_pos, blueflag_pos, yellowflag_pos, pinkflag_pos;
- vector redflag_pos, blueflag_pos;
++ vector redflag_pos, blueflag_pos, yellowflag_pos, pinkflag_pos, neutralflag_pos;
vector flag_size;
float f; // every function should have that
- float redflag, blueflag, yellowflag, pinkflag; // current status
- float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime, yellowflag_statuschange_elapsedtime, pinkflag_statuschange_elapsedtime; // time since the status changed
- float redflag, blueflag; // current status
- float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime; // time since the status changed
-- float stat_items;
-
- stat_items = getstati(STAT_ITEMS, 0, 24);
- redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3;
- blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3;
-
- if(redflag || blueflag)
++ float redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status
++ float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime, yellowflag_statuschange_elapsedtime, pinkflag_statuschange_elapsedtime, neutralflag_statuschange_elapsedtime; // time since the status changed
++ float ctf_oneflag; // one-flag CTF mode enabled/disabled
++ float stat_items = getstati(STAT_CTF_FLAGSTATUS, 0, 24);
+ float fs, fs2, fs3, size1, size2;
+ vector e1, e2;
+
- stat_items = getstati(STAT_ITEMS, 0, 24);
- redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3;
- blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3;
- yellowflag = (stat_items/IT_YELLOW_FLAG_TAKEN) & 3;
- pinkflag = (stat_items/IT_PINK_FLAG_TAKEN) & 3;
++ redflag = (stat_items/CTF_RED_FLAG_TAKEN) & 3;
++ blueflag = (stat_items/CTF_BLUE_FLAG_TAKEN) & 3;
++ yellowflag = (stat_items/CTF_YELLOW_FLAG_TAKEN) & 3;
++ pinkflag = (stat_items/CTF_PINK_FLAG_TAKEN) & 3;
++ neutralflag = (stat_items/CTF_NEUTRAL_FLAG_TAKEN) & 3;
++
++ ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL);
+
- if(redflag || blueflag || yellowflag || pinkflag)
++ if(redflag || blueflag || yellowflag || pinkflag || neutralflag)
mod_active = 1;
else
mod_active = 0;
{
redflag = 1;
blueflag = 2;
+ if(team_count >= 3)
+ yellowflag = 2;
+ if(team_count >= 4)
+ pinkflag = 3;
++ ctf_oneflag = neutralflag = 0; // disable neutral flag in hud editor?
}
// when status CHANGES, set old status into prevstatus and current status into status
blueflag_prevframe = blueflag;
}
+ if (yellowflag != yellowflag_prevframe)
+ {
+ yellowflag_statuschange_time = time;
+ yellowflag_prevstatus = yellowflag_prevframe;
+ yellowflag_prevframe = yellowflag;
+ }
+
+ if (pinkflag != pinkflag_prevframe)
+ {
+ pinkflag_statuschange_time = time;
+ pinkflag_prevstatus = pinkflag_prevframe;
+ pinkflag_prevframe = pinkflag;
+ }
+
++ if (neutralflag != neutralflag_prevframe)
++ {
++ neutralflag_statuschange_time = time;
++ neutralflag_prevstatus = neutralflag_prevframe;
++ neutralflag_prevframe = neutralflag;
++ }
++
redflag_statuschange_elapsedtime = time - redflag_statuschange_time;
blueflag_statuschange_elapsedtime = time - blueflag_statuschange_time;
+ yellowflag_statuschange_elapsedtime = time - yellowflag_statuschange_time;
+ pinkflag_statuschange_elapsedtime = time - pinkflag_statuschange_time;
++ neutralflag_statuschange_elapsedtime = time - neutralflag_statuschange_time;
float BLINK_FACTOR = 0.15;
float BLINK_BASE = 0.85;
case 2: red_icon = "flag_red_lost"; break;
case 3: red_icon = "flag_red_carrying"; red_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_1))
- if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
++ if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_1))
red_icon = "flag_red_shielded";
else
red_icon = string_null;
default:
if(redflag == 3)
red_icon_prevstatus = "flag_red_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_1))
- else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
++ else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_1))
red_icon_prevstatus = "flag_red_shielded";
else
red_icon_prevstatus = string_null;
case 2: blue_icon = "flag_blue_lost"; break;
case 3: blue_icon = "flag_blue_carrying"; blue_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_2))
- if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
++ if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_2))
blue_icon = "flag_blue_shielded";
else
blue_icon = string_null;
default:
if(blueflag == 3)
blue_icon_prevstatus = "flag_blue_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_2))
- else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
++ else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_2))
blue_icon_prevstatus = "flag_blue_shielded";
else
blue_icon_prevstatus = string_null;
break;
}
- if(mySize_x > mySize_y) {
- if (myteam == NUM_TEAM_1) { // always draw own flag on left
+ string yellow_icon, yellow_icon_prevstatus;
+ float yellow_alpha, yellow_alpha_prevstatus;
+ yellow_alpha = yellow_alpha_prevstatus = 1;
+ switch(yellowflag) {
+ case 1: yellow_icon = "flag_yellow_taken"; break;
+ case 2: yellow_icon = "flag_yellow_lost"; break;
+ case 3: yellow_icon = "flag_yellow_carrying"; yellow_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
+ default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_3))
++ if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_3))
+ yellow_icon = "flag_yellow_shielded";
+ else
+ yellow_icon = string_null;
+ break;
+ }
+ switch(yellowflag_prevstatus) {
+ case 1: yellow_icon_prevstatus = "flag_yellow_taken"; break;
+ case 2: yellow_icon_prevstatus = "flag_yellow_lost"; break;
+ case 3: yellow_icon_prevstatus = "flag_yellow_carrying"; yellow_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
+ default:
+ if(yellowflag == 3)
+ yellow_icon_prevstatus = "flag_yellow_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_3))
++ else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_3))
+ yellow_icon_prevstatus = "flag_yellow_shielded";
+ else
+ yellow_icon_prevstatus = string_null;
+ break;
+ }
+
+ string pink_icon, pink_icon_prevstatus;
+ float pink_alpha, pink_alpha_prevstatus;
+ pink_alpha = pink_alpha_prevstatus = 1;
+ switch(pinkflag) {
+ case 1: pink_icon = "flag_pink_taken"; break;
+ case 2: pink_icon = "flag_pink_lost"; break;
+ case 3: pink_icon = "flag_pink_carrying"; pink_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
+ default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_4))
++ if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_4))
+ pink_icon = "flag_pink_shielded";
+ else
+ pink_icon = string_null;
+ break;
+ }
+ switch(pinkflag_prevstatus) {
+ case 1: pink_icon_prevstatus = "flag_pink_taken"; break;
+ case 2: pink_icon_prevstatus = "flag_pink_lost"; break;
+ case 3: pink_icon_prevstatus = "flag_pink_carrying"; pink_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
+ default:
+ if(pinkflag == 3)
+ pink_icon_prevstatus = "flag_pink_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam != NUM_TEAM_4))
++ else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_4))
+ pink_icon_prevstatus = "flag_pink_shielded";
+ else
+ pink_icon_prevstatus = string_null;
+ break;
+ }
+
- switch(team_count)
++ string neutral_icon, neutral_icon_prevstatus;
++ float neutral_alpha, neutral_alpha_prevstatus;
++ neutral_alpha = neutral_alpha_prevstatus = 1;
++ switch(neutralflag) {
++ case 1: neutral_icon = "flag_neutral_taken"; break;
++ case 2: neutral_icon = "flag_neutral_lost"; break;
++ case 3: neutral_icon = "flag_neutral_carrying"; neutral_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
++ default:
++ if((stat_items & CTF_SHIELDED))
++ neutral_icon = "flag_neutral_shielded";
++ else
++ neutral_icon = string_null;
++ break;
++ }
++ switch(neutralflag_prevstatus) {
++ case 1: neutral_icon_prevstatus = "flag_neutral_taken"; break;
++ case 2: neutral_icon_prevstatus = "flag_neutral_lost"; break;
++ case 3: neutral_icon_prevstatus = "flag_neutral_carrying"; neutral_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
++ default:
++ if(neutralflag == 3)
++ neutral_icon_prevstatus = "flag_neutral_carrying"; // make it more visible
++ else if((stat_items & CTF_SHIELDED))
++ neutral_icon_prevstatus = "flag_neutral_shielded";
++ else
++ neutral_icon_prevstatus = string_null;
++ break;
++ }
++
++ if(ctf_oneflag)
++ {
++ // hacky, but these aren't needed
++ red_icon = red_icon_prevstatus = blue_icon = blue_icon_prevstatus = yellow_icon = yellow_icon_prevstatus = pink_icon = pink_icon_prevstatus = string_null;
++ fs = fs2 = fs3 = 1;
++ }
++ else switch(team_count)
+ {
+ default:
+ case 2: fs = 0.5; fs2 = 0.5; fs3 = 0.5; break;
+ case 3: fs = 1; fs2 = 0.35; fs3 = 0.35; break;
+ case 4: fs = 0.75; fs2 = 0.25; fs3 = 0.5; break;
+ }
+
+ if(mySize_x > mySize_y)
+ {
+ size1 = mySize_x;
+ size2 = mySize_y;
+ e1 = eX;
+ e2 = eY;
+ }
+ else
+ {
+ size1 = mySize_y;
+ size2 = mySize_x;
+ e1 = eY;
+ e2 = eX;
+ }
+
+ switch(myteam)
+ {
+ default:
+ case NUM_TEAM_1:
+ {
redflag_pos = pos;
- blueflag_pos = pos + eX * 0.5 * mySize_x;
- } else {
- blueflag_pos = pos;
- redflag_pos = pos + eX * 0.5 * mySize_x;
+ blueflag_pos = pos + eX * fs2 * size1;
+ yellowflag_pos = pos - eX * fs2 * size1;
+ pinkflag_pos = pos + eX * fs3 * size1;
+ break;
}
- flag_size = eX * 0.5 * mySize_x + eY * mySize_y;
- } else {
- if (myteam == NUM_TEAM_1) { // always draw own flag on left
- redflag_pos = pos;
- blueflag_pos = pos + eY * 0.5 * mySize_y;
- } else {
+ case NUM_TEAM_2:
+ {
+ redflag_pos = pos + eX * fs2 * size1;
blueflag_pos = pos;
- redflag_pos = pos + eY * 0.5 * mySize_y;
+ yellowflag_pos = pos - eX * fs2 * size1;
+ pinkflag_pos = pos + eX * fs3 * size1;
+ break;
+ }
+ case NUM_TEAM_3:
+ {
+ redflag_pos = pos + eX * fs3 * size1;
+ blueflag_pos = pos - eX * fs2 * size1;
+ yellowflag_pos = pos;
+ pinkflag_pos = pos + eX * fs2 * size1;
+ break;
+ }
+ case NUM_TEAM_4:
+ {
+ redflag_pos = pos - eX * fs2 * size1;
+ blueflag_pos = pos + eX * fs3 * size1;
+ yellowflag_pos = pos + eX * fs2 * size1;
+ pinkflag_pos = pos;
+ break;
}
- flag_size = eY * 0.5 * mySize_y + eX * mySize_x;
}
++ neutralflag_pos = pos;
+ flag_size = e1 * fs * size1 + e2 * size2;
f = bound(0, redflag_statuschange_elapsedtime*2, 1);
if(red_icon_prevstatus && f < 1)
drawpic_aspect_skin_expanding(blueflag_pos, blue_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * blue_alpha_prevstatus, DRAWFLAG_NORMAL, f);
if(blue_icon)
drawpic_aspect_skin(blueflag_pos, blue_icon, flag_size, '1 1 1', panel_fg_alpha * blue_alpha * f, DRAWFLAG_NORMAL);
+
+ f = bound(0, yellowflag_statuschange_elapsedtime*2, 1);
+ if(yellow_icon_prevstatus && f < 1)
+ drawpic_aspect_skin_expanding(yellowflag_pos, yellow_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * yellow_alpha_prevstatus, DRAWFLAG_NORMAL, f);
+ if(yellow_icon)
+ drawpic_aspect_skin(yellowflag_pos, yellow_icon, flag_size, '1 1 1', panel_fg_alpha * yellow_alpha * f, DRAWFLAG_NORMAL);
+
+ f = bound(0, pinkflag_statuschange_elapsedtime*2, 1);
+ if(pink_icon_prevstatus && f < 1)
+ drawpic_aspect_skin_expanding(pinkflag_pos, pink_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * pink_alpha_prevstatus, DRAWFLAG_NORMAL, f);
+ if(pink_icon)
+ drawpic_aspect_skin(pinkflag_pos, pink_icon, flag_size, '1 1 1', panel_fg_alpha * pink_alpha * f, DRAWFLAG_NORMAL);
++
++ f = bound(0, neutralflag_statuschange_elapsedtime*2, 1);
++ if(neutral_icon_prevstatus && f < 1)
++ drawpic_aspect_skin_expanding(neutralflag_pos, neutral_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * neutral_alpha_prevstatus, DRAWFLAG_NORMAL, f);
++ if(neutral_icon)
++ drawpic_aspect_skin(neutralflag_pos, neutral_icon, flag_size, '1 1 1', panel_fg_alpha * neutral_alpha * f, DRAWFLAG_NORMAL);
}
// Keyhunt HUD modicon section
projectile.qh
player_skeleton.qh
++../server/mutators/gamemode_ctf.qh // TODO: remove
++
sortlist.qc
miscfunctions.qc
../server/t_items.qc
case "keycarrier-red": return _("Key carrier");
case "keycarrier-yellow": return _("Key carrier");
case "redbase": return _("Red base");
+ case "yellowbase": return _("Yellow base");
++ case "neutralbase": return _("White base");
+ case "pinkbase": return _("Pink base");
case "waypoint": return _("Waypoint");
case "ons-gen-red": return _("Generator");
case "ons-gen-blue": return _("Generator");
const float STAT_MONSTERS_TOTAL = 76;
const float STAT_MONSTERS_KILLED = 77;
++const float STAT_CTF_FLAGSTATUS = 78;
++
// mod stats (1xx)
const float STAT_REDALIVE = 100;
const float STAT_BLUEALIVE = 101;
// for items:
WANT_CONST float IT_KEY1 = 131072;
WANT_CONST float IT_KEY2 = 262144;
-- // for players:
-- const float IT_RED_FLAG_TAKEN = 32768;
-- const float IT_RED_FLAG_LOST = 65536;
- const float IT_RED_FLAG_CARRYING = 98304;
- const float IT_RED_FLAG_CARRYING = 98304;
-- const float IT_BLUE_FLAG_TAKEN = 131072;
-- const float IT_BLUE_FLAG_LOST = 262144;
-- const float IT_BLUE_FLAG_CARRYING = 393216;
- const float IT_YELLOW_FLAG_TAKEN = 524288;
- const float IT_YELLOW_FLAG_LOST = 1048576;
- const float IT_YELLOW_FLAG_CARRYING = 1572864;
- const float IT_PINK_FLAG_TAKEN = 2097152;
- const float IT_PINK_FLAG_LOST = 4194304;
- const float IT_PINK_FLAG_CARRYING = 6291456;
++
// end
const float IT_5HP = 524288;
const float IT_25HP = 1048576;
#define MSG_INFO_NOTIFICATIONS \
MSG_INFO_NOTIF(2, INFO_CHAT_NOSPECTATORS, 0, 0, "", "", "", _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 2, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 2, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") \
- MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 2, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 2, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
- MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 2, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") \
- MULTITEAM_INFO(1, INFO_CTF_LOST_, 2, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 2, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_RETURN_, 2, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
- MULTITEAM_INFO(1, INFO_CTF_RETURN_MONSTER_, 2, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 4, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_BROKEN_, 4, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG%s^BG's previous record of ^F2%s^BG seconds"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_CAPTURE_NEUTRAL, 1, 0, "s1", "s1", "notify_%s_captured", _("^BG%s^BG captured the flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_TIME_, 4, 1, 1, "s1 f1p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_CAPTURE_UNBROKEN_, 4, 2, 2, "s1 f1p2dec s2 f2p2dec", "s1", "notify_%s_captured", _("^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break ^BG%s^BG's previous record of ^F1%s^BG seconds"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_ABORTRUN_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was returned to base by its owner"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL,0, 0, "", "", "", _("^BGThe flag was returned by its owner"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was destroyed and returned to base"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag was destroyed and returned to base"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DROPPED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag was dropped in the base and returned itself"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_NEEDKILL_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to base"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL,0, 0, "", "", "", _("^BGThe flag fell somewhere it couldn't be reached and returned to base"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_SPEEDRUN_, 4, 0, 1, "f1p2dec", "", "", _("^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL,0, 1, "f1p2dec", "", "", _("^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG flag has returned to the base"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL, 0, 0, "", "", "", _("^BGThe flag has returned to the base"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_LOST_, 4, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the ^TC^TT^BG flag"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_LOST_NEUTRAL, 1, 0, "s1", "s1", "notify_%s_lost", _("^BG%s^BG lost the flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 4, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") \
++ MSG_INFO_NOTIF(1, INFO_CTF_PICKUP_NEUTRAL, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_RETURN_, 4, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_RETURN_MONSTER_, 4, 1, 0, "s1", "s1", "notify_%s_returned", _("^BG%s^BG returned the ^TC^TT^BG flag"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_CHEAT, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_DROWN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_water", _("^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FALL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_fall", _("^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_ROUND_OVER, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound over, there's no winner"), "") \
MSG_CENTER_NOTIF(1, CENTER_CAMPCHECK, 0, 0, "", CPID_CAMPCHECK, "0 0", _("^F2Don't camp!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_FREE, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now free.\n^BGFeel free to ^F2try to capture^BG the flag again\n^BGif you think you will succeed."), "") \
- MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 2, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_INACTIVE, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGThis flag is currently inactive"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURESHIELD_SHIELDED, 0, 0, "", CPID_CTF_CAPSHIELD, "0 0", _("^BGYou are now ^F1shielded^BG from the flag(s)\n^BGfor ^F2too many unsuccessful attempts^BG to capture.\n^BGMake some defensive scores before trying again."), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_CAPTURE_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the ^TC^TT^BG flag!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_CAPTURE_NEUTRAL, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou captured the flag!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_FLAG_THROW_PUNISH, 0, 1, "f1secs", CPID_CTF_LOWPRIO, "0 0", _("^BGToo many flag throws! Throwing disabled for %s."), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 2, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 2, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PASS_OTHER_, 4, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the ^TC^TT^BG flag to %s"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_OTHER_NEUTRAL, 2, 0, "s1 s2", CPID_CTF_PASS, "0 0", _("^BG%s^BG passed the flag to %s"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PASS_RECEIVED_, 4, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the ^TC^TT^BG flag from %s"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_RECEIVED_NEUTRAL, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou received the flag from %s"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTED, 1, 0, "s1 pass_key", CPID_CTF_PASS, "0 0", _("^BG%s^BG requests you to pass the flag%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_REQUESTING, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGRequesting %s^BG to pass you the flag"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 2, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 2, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PASS_SENT_, 4, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the ^TC^TT^BG flag to %s"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PASS_SENT_NEUTRAL, 1, 0, "s1", CPID_CTF_PASS, "0 0", _("^BGYou passed the flag to %s"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the ^TC^TT^BG flag!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_NEUTRAL, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the flag!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got your %steam^BG's flag, return it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_ENEMY, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYou got the %senemy^BG's flag, return it!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got your flag! Retrieve it!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_VERBOSE, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"), "") \
- MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
- MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 2, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got the flag! Retrieve it!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE, 2, 0, "s1 s2 s1",CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_TEAM, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy^BG got their flag! Retrieve it!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE,2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_, 4, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"), "") \
- MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_, 4, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "") \
++ MULTITEAM_CENTER(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_, 4, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_NEUTRAL, 1, 0, "s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate^BG got the flag! Protect them!"), "") \
++ MSG_CENTER_NOTIF(1, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL, 2, 0, "s1 s2 s1", CPID_CTF_LOWPRIO, "0 0", _("^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"), "") \
+ MULTITEAM_CENTER(1, CENTER_CTF_RETURN_, 4, 0, 0, "", CPID_CTF_LOWPRIO, "0 0", _("^BGYou returned the ^TC^TT^BG flag!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_CARRIER, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Enemies can now see you on radar!"), "") \
MSG_CENTER_NOTIF(1, CENTER_CTF_STALEMATE_OTHER, 0, 0, "", CPID_STALEMATE, "0 0", _("^BGStalemate! Flag carriers can now be seen by enemies on radar!"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_FRAG, 1, 1, "spree_cen s1", NO_CPID, "0 0", _("^K3%sYou fragged ^BG%s"), _("^K3%sYou scored against ^BG%s")) \
MULTITEAM_CHOICE##teams(default,challow,prefix,chtype,optiona,optionb)
#define MSG_CHOICE_NOTIFICATIONS \
- MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_BROKEN_, 2, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_BROKEN_) \
- MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_TIME_, 2, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_TIME_) \
- MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_UNBROKEN_, 2, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_UNBROKEN_) \
- MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_TEAM, MSG_CENTER, CENTER_CTF_PICKUP_TEAM, CENTER_CTF_PICKUP_TEAM_VERBOSE) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_BROKEN_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_BROKEN_) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_TIME_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_TIME_) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_CAPTURE_UNBROKEN_, 4, MSG_INFO, INFO_CTF_CAPTURE_, INFO_CTF_CAPTURE_UNBROKEN_) \
+ MULTITEAM_CHOICE(1, 2, CHOICE_CTF_PICKUP_TEAM_, 4, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_, CENTER_CTF_PICKUP_TEAM_VERBOSE_) \
++ MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_TEAM_NEUTRAL, MSG_CENTER, CENTER_CTF_PICKUP_TEAM_NEUTRAL, CENTER_CTF_PICKUP_TEAM_VERBOSE_NEUTRAL) \
MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_VERBOSE) \
++ MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_NEUTRAL, CENTER_CTF_PICKUP_ENEMY_NEUTRAL_VERBOSE) \
+ MSG_CHOICE_NOTIF(1, 2, CHOICE_CTF_PICKUP_ENEMY_TEAM, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY_TEAM, CENTER_CTF_PICKUP_ENEMY_TEAM_VERBOSE) \
MSG_CHOICE_NOTIF(1, 1, CHOICE_FRAG, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, CENTER_DEATH_MURDER_FRAG_VERBOSE) \
MSG_CHOICE_NOTIF(1, 1, CHOICE_FRAGGED, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, CENTER_DEATH_MURDER_FRAGGED_VERBOSE) \
MSG_CHOICE_NOTIF(1, 1, CHOICE_TYPEFRAG, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE) \
float autocvar_g_ctf_flag_dropped_floatinwater;
float autocvar_g_ctf_flag_glowtrails;
float autocvar_g_ctf_flag_health;
++string autocvar_g_ctf_flag_neutral_model;
++float autocvar_g_ctf_flag_neutral_skin;
+string autocvar_g_ctf_flag_pink_model;
+float autocvar_g_ctf_flag_pink_skin;
string autocvar_g_ctf_flag_red_model;
float autocvar_g_ctf_flag_red_skin;
+float autocvar_g_ctf_flag_return;
+float autocvar_g_ctf_flag_return_carried_radius;
float autocvar_g_ctf_flag_return_time;
float autocvar_g_ctf_flag_return_when_unreachable;
float autocvar_g_ctf_flag_return_damage;
++float autocvar_g_ctf_flag_return_damage_delay;
float autocvar_g_ctf_flag_return_dropped;
+string autocvar_g_ctf_flag_yellow_model;
+float autocvar_g_ctf_flag_yellow_skin;
float autocvar_g_ctf_flagcarrier_auto_helpme_damage;
float autocvar_g_ctf_flagcarrier_auto_helpme_time;
float autocvar_g_ctf_flagcarrier_selfdamagefactor;
string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
// notify about shit
- if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
- if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_2(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
- else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_2(flag, CHOICE_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
- else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_2(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
++ if(ctf_oneflag) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname); }
++ else if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
+ else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+ else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
// write that shit in the database
++ if(!ctf_oneflag) // but not in 1-flag mode
if((!ctf_captimerecord) || (cap_time < cap_record))
{
ctf_captimerecord = cap_time;
float ctf_CaptureShield_Customize()
{
++ if(self.enemy.active != ACTIVE_ACTIVE) { return TRUE; }
if(!other.ctf_captureshielded) { return FALSE; }
- if(SAME_TEAM(self, other)) { return FALSE; }
+ if(CTF_SAMETEAM(self, other)) { return FALSE; }
return TRUE;
}
void ctf_CaptureShield_Touch()
{
++ if(self.enemy.active != ACTIVE_ACTIVE)
++ {
++ 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);
++ if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_INACTIVE); }
++
++ return;
++ }
++
if(!other.ctf_captureshielded) { return; }
- if(SAME_TEAM(self, other)) { 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);
-- Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED);
++ if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
}
void ctf_CaptureShield_Spawn(entity flag)
flag.ctf_status = FLAG_DROPPED;
// messages and sounds
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_LOST_), player.netname);
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_LOST_), player.netname);
++ 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);
ctf_EventLog("dropped", player.team, player);
flag.owner.flagcarried = flag;
// reset flag
-- setattachment(flag, player, "");
-- setorigin(flag, FLAG_CARRY_OFFSET);
++ if(player.vehicle)
++ {
++ setattachment(flag, player.vehicle, "");
++ setorigin(flag, VEHICLE_FLAG_OFFSET);
++ flag.scale = VEHICLE_FLAG_SCALE;
++ }
++ else
++ {
++ setattachment(flag, player, "");
++ setorigin(flag, FLAG_CARRY_OFFSET);
++ }
flag.movetype = MOVETYPE_NONE;
flag.takedamage = DAMAGE_NO;
flag.solid = SOLID_NOT;
FOR_EACH_REALPLAYER(tmp_player)
{
if(tmp_player == sender)
- Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_SENT_), player.netname);
- Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_SENT_), player.netname);
++ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_SENT_) : CENTER_CTF_PASS_SENT_NEUTRAL), player.netname);
else if(tmp_player == player)
- Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_RECEIVED_), sender.netname);
- Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_RECEIVED_), sender.netname);
++ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_RECEIVED_) : CENTER_CTF_PASS_RECEIVED_NEUTRAL), sender.netname);
else if(SAME_TEAM(tmp_player, sender))
- Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname);
- Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname);
++ Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_) : CENTER_CTF_PASS_OTHER_NEUTRAL), sender.netname, player.netname);
}
// create new waypoint
{
entity enemy_flag = ((capturetype == CAPTURE_NORMAL) ? toucher.flagcarried : toucher);
entity player = ((capturetype == CAPTURE_NORMAL) ? toucher : enemy_flag.ctf_dropper);
++ entity player_team_flag = world, tmp_entity;
float old_time, new_time;
- if (!player) { return; } // without someone to give the reward to, we can't possibly cap
+ if(!player) { return; } // without someone to give the reward to, we can't possibly cap
- if(CTF_DIFFTEAM(player, flag)) { return; }
++ if(ctf_oneflag)
++ {
++ if(CTF_SAMETEAM(player, flag)) { return; }
++ }
++ else 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))
++ {
++ player_team_flag = tmp_entity;
++ break;
++ }
++
++ player.throw_prevtime = time;
++ player.throw_count = 0;
// messages and sounds
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_));
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(enemy_flag, CENTER_CTF_CAPTURE_));
++ 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, ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture), VOL_BASE, ATTEN_NONE);
- sound(player, CH_TRIGGER, 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)
{
// messages and sounds
if(player.flags & FL_MONSTER)
{
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_RETURN_MONSTER_), player.monster_name);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_MONSTER_), player.monster_name);
}
-- else
++ else if(flag.team)
{
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_RETURN_));
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_RETURN_), player.netname);
+ 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);
ctf_EventLog("return", flag.team, player);
// attach the flag to the player
flag.owner = player;
player.flagcarried = flag;
-- setattachment(flag, player, "");
-- setorigin(flag, FLAG_CARRY_OFFSET);
++ if(player.vehicle)
++ {
++ setattachment(flag, player.vehicle, "");
++ setorigin(flag, VEHICLE_FLAG_OFFSET);
++ flag.scale = VEHICLE_FLAG_SCALE;
++ }
++ else
++ {
++ setattachment(flag, player, "");
++ setorigin(flag, FLAG_CARRY_OFFSET);
++ }
// flag setup
flag.movetype = MOVETYPE_NONE;
}
// messages and sounds
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_), player.netname);
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_PICKUP_), player.netname);
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(flag, CENTER_CTF_PICKUP_));
++ Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_) : INFO_CTF_PICKUP_NEUTRAL), player.netname);
if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); }
- if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_)); }
-
- Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, CHOICE_CTF_PICKUP_TEAM, Team_ColorCode(player.team), player.netname);
- Send_Notification(NOTIF_TEAM, flag, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY, Team_ColorCode(player.team), player.netname);
++ if(!flag.team) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_NEUTRAL); }
++ else if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_)); }
+ 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, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname);
-
++ 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)
+ if(CTF_SAMETEAM(flag, tmp_entity))
+ if(SAME_TEAM(player, tmp_entity))
+ Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname);
+ 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);
{
switch(returntype)
{
- case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DROPPED_)); break;
- case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DAMAGED_)); break;
- case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_), ctf_captimerecord); break;
- case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_NEEDKILL_)); break;
- case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DROPPED_)); break;
- case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_DAMAGED_)); break;
- case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_), ctf_captimerecord); break;
- case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_NEEDKILL_)); break;
++ case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DROPPED_) : INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL)); break;
++ case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DAMAGED_) : INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL)); break;
++ case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_) : INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL), ctf_captimerecord); break;
++ case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_NEEDKILL_) : INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL)); break;
default:
case RETURN_TIMEOUT:
- { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
- { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
++ { 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);
ctf_EventLog("returned", flag.team, world);
void ctf_CheckStalemate(void)
{
// declarations
- float stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0;
- float stale_red_flags = 0, stale_blue_flags = 0;
++ float stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0;
entity tmp_entity;
entity ctf_staleflaglist = world; // reset the list, we need to build the list each time this function runs
{
case NUM_TEAM_1: ++stale_red_flags; break;
case NUM_TEAM_2: ++stale_blue_flags; break;
+ case NUM_TEAM_3: ++stale_yellow_flags; break;
+ case NUM_TEAM_4: ++stale_pink_flags; break;
++ default: ++stale_neutral_flags; break;
}
}
}
- stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
- if(stale_red_flags && stale_blue_flags)
++ if(ctf_oneflag)
++ stale_flags = (stale_neutral_flags >= 1);
++ else
++ stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
+
- if(stale_flags == ctf_teams)
++ if(ctf_oneflag && stale_flags == 1)
+ ctf_stalemate = TRUE;
- else if((!stale_red_flags && !stale_blue_flags) && autocvar_g_ctf_stalemate_endcondition == 2)
++ else if(stale_flags == ctf_teams)
+ ctf_stalemate = TRUE;
+ else if(stale_flags == 0 && autocvar_g_ctf_stalemate_endcondition == 2)
{ ctf_stalemate = FALSE; wpforenemy_announced = FALSE; }
- else if((!stale_red_flags || !stale_blue_flags) && autocvar_g_ctf_stalemate_endcondition == 1)
+ else if(stale_flags < ctf_teams && autocvar_g_ctf_stalemate_endcondition == 1)
{ ctf_stalemate = FALSE; wpforenemy_announced = FALSE; }
// if sufficient stalemate, then set up the waypointsprite and announce the stalemate if necessary
for(tmp_entity = ctf_staleflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_staleflagnext)
{
if((tmp_entity.owner) && (!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));
+ {
- WaypointSprite_Spawn("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));
++ 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));
+ tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_Customize;
+ }
}
if (!wpforenemy_announced)
{
if(ITEM_DAMAGE_NEEDKILL(deathtype))
{
-- // automatically kill the flag and return it
-- self.health = 0;
-- ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
++ if(autocvar_g_ctf_flag_return_damage_delay)
++ {
++ self.ctf_flagdamaged = TRUE;
++ }
++ else
++ {
++ self.health = 0;
++ ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
++ }
return;
}
if(autocvar_g_ctf_flag_return_damage)
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");
tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self);
-- if(!trace_startsolid) // can we resize it without getting stuck?
++ if(!trace_startsolid || self.noalign) // can we resize it without getting stuck?
setsize(self, FLAG_MIN, FLAG_MAX); }
switch(self.ctf_status) // reset flag angles in case warpzones adjust it
return;
}
}
-- if(autocvar_g_ctf_flag_return_time)
++ if(self.ctf_flagdamaged)
++ {
++ self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE);
++ ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
++ return;
++ }
++ else if(autocvar_g_ctf_flag_return_time)
{
self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE);
ctf_CheckFlagReturn(self, RETURN_TIMEOUT);
wpforenemy_nextthink = time + WPFE_THINKRATE; // waypoint for enemy think rate (to reduce unnecessary spam of this check)
}
}
- if(CTF_SAMETEAM(self, self.owner))
++ if(CTF_SAMETEAM(self, self.owner) && self.team)
+ {
+ if(autocvar_g_ctf_flag_return) // drop the flag if reverse status has changed
+ ctf_Handle_Throw(self.owner, world, DROP_THROW);
+ else if(vlen(self.owner.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_carried_radius)
+ ctf_Handle_Return(self, self.owner);
+ }
return;
}
void ctf_FlagTouch()
{
if(gameover) { return; }
++ if(self.active != ACTIVE_ACTIVE) { return; }
-- entity toucher = other;
-- float is_not_monster = (!(toucher.flags & FL_MONSTER));
++ entity toucher = other, tmp_entity;
++ float is_not_monster = (!(toucher.flags & FL_MONSTER)), num_perteam = 0;
// automatically kill the flag and return it if it touched lava/slime/nodrop surfaces
if(ITEM_TOUCH_NEEDKILL())
{
-- self.health = 0;
-- ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
++ if(!autocvar_g_ctf_flag_return_damage_delay)
++ {
++ self.health = 0;
++ ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
++ }
return;
}
++ FOR_EACH_PLAYER(tmp_entity) if(SAME_TEAM(toucher, tmp_entity)) { ++num_perteam; }
++
// special touch behaviors
if(toucher.vehicle_flags & VHF_ISVEHICLE)
{
{
case FLAG_BASE:
{
- if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self) && is_not_monster)
- if(SAME_TEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self) && is_not_monster)
++ if(ctf_oneflag)
++ {
++ if(CTF_DIFFTEAM(toucher, self) && (toucher.flagcarried) && !toucher.flagcarried.team && is_not_monster)
++ ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the neutral flag to enemy base
++ else if(!self.team && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
++ ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the neutral flag
++ }
++ else if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self) && is_not_monster)
ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the enemies flag to his base
- else if(DIFF_TEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
+ else if(CTF_DIFFTEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the enemies flag
break;
}
case FLAG_DROPPED:
{
- if(CTF_SAMETEAM(toucher, self) && autocvar_g_ctf_flag_return)
- if(SAME_TEAM(toucher, self))
++ if(CTF_SAMETEAM(toucher, self) && (autocvar_g_ctf_flag_return || num_perteam <= 1) && self.team) // automatically return if there's only 1 player on the team
ctf_Handle_Return(self, toucher); // toucher just returned his own flag
else if(is_not_monster && (!toucher.flagcarried) && ((toucher != self.ctf_dropper) || (time > self.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
ctf_Handle_Pickup(self, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
ctf_FakeTimeLimit(flag.owner, -1);
}
- if((flag.ctf_status == FLAG_DROPPED) && (flag.wps_flagdropped))
++ if((flag.owner) && (flag.owner.vehicle))
++ flag.scale = FLAG_SCALE;
++
+ if(flag.ctf_status == FLAG_DROPPED)
{ WaypointSprite_Kill(flag.wps_flagdropped); }
// reset the flag
flag.ctf_dropper = world;
flag.ctf_pickuptime = 0;
flag.ctf_droptime = 0;
++ flag.ctf_flagdamaged = 0;
++
++ ctf_CheckStalemate();
}
void ctf_Reset()
ctf_RespawnFlag(self);
}
++void ctf_Use()
++{
++ if(self.ctf_status != FLAG_BASE) { return; }
++
++ entity flag;
++ float flag_cnt = 0;
++
++ for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
++ {
++ if(flag != self)
++ if(SAME_TEAM(flag, self))
++ if(flag.active == ACTIVE_ACTIVE)
++ ++flag_cnt;
++ }
++
++ if(self.active == ACTIVE_ACTIVE)
++ if(flag_cnt < 1)
++ {
++ dprint("ctf_Use: Unable to deactivate flag (not enough active flags on the map)\n");
++ return;
++ }
++
++ self.active = ((self.active) ? ACTIVE_NOT : ACTIVE_ACTIVE);
++
++ if(self.active == ACTIVE_ACTIVE)
++ WaypointSprite_Ping(self.wps_flagbase);
++}
++
++float ctf_FlagWaypoint_Customize()
++{
++ if(self.owner.active != ACTIVE_ACTIVE) { return FALSE; }
++ return TRUE;
++}
++
void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf_FlagSetup()
{
// bot waypoints
self.bot_basewaypoint = self.nearestwaypoint;
// waypointsprites
- WaypointSprite_SpawnFixed(((self.team == NUM_TEAM_1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
- WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
+ string basename = "base";
+
+ 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;
+ }
+
- WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
- WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, FALSE));
++ WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, ((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'));
++ self.wps_flagbase.customizeentityforclient = ctf_FlagWaypoint_Customize;
// captureshield setup
ctf_CaptureShield_Spawn(self);
setattachment(flag, world, "");
- flag.netname = ((teamnumber == NUM_TEAM_1) ? "^1RED^7 flag" : ((teamnumber == NUM_TEAM_2) ? "^4BLUE^7 flag" : ((teamnumber == NUM_TEAM_3) ? "^3YELLOW^7 flag" : "^6PINK^7 flag")));
- flag.netname = ((teamnumber) ? "^1RED^7 flag" : "^4BLUE^7 flag"); // Primarily only used for debugging or when showing nearby item name
- flag.team = ((teamnumber) ? NUM_TEAM_1 : NUM_TEAM_2); // NUM_TEAM_1: color 4 team (red) - NUM_TEAM_2: color 13 team (blue)
- flag.items = ((teamnumber) ? IT_KEY2 : IT_KEY1); // IT_KEY2: gold key (redish enough) - IT_KEY1: silver key (bluish enough)
++ flag.netname = ((teamnumber == NUM_TEAM_1) ? "^1RED^7 flag" : ((teamnumber == NUM_TEAM_2) ? "^4BLUE^7 flag" : ((teamnumber == NUM_TEAM_3) ? "^3YELLOW^7 flag" : ((teamnumber == NUM_TEAM_4) ? "^6PINK^7 flag" : "^7NEUTRAL flag"))));
+ flag.team = teamnumber;
flag.classname = "item_flag_team";
flag.target = "###item###"; // wut?
flag.flags = FL_ITEM | FL_NOTARGET;
flag.velocity = '0 0 0';
flag.mangle = flag.angles;
flag.reset = ctf_Reset;
++ flag.use = ctf_Use;
flag.touch = ctf_FlagTouch;
flag.think = ctf_FlagThink;
flag.nextthink = time + FLAG_THINKRATE;
flag.ctf_status = FLAG_BASE;
// appearence
- if(flag.model == "") { flag.model = ((teamnumber == NUM_TEAM_1) ? autocvar_g_ctf_flag_red_model : ((teamnumber == NUM_TEAM_2) ? autocvar_g_ctf_flag_blue_model : ((teamnumber == NUM_TEAM_3) ? autocvar_g_ctf_flag_yellow_model : autocvar_g_ctf_flag_pink_model))); }
- if(flag.model == "") { flag.model = ((teamnumber) ? autocvar_g_ctf_flag_red_model : autocvar_g_ctf_flag_blue_model); }
++ if(flag.model == "") { flag.model = ((teamnumber == NUM_TEAM_1) ? autocvar_g_ctf_flag_red_model : ((teamnumber == NUM_TEAM_2) ? autocvar_g_ctf_flag_blue_model : ((teamnumber == NUM_TEAM_3) ? autocvar_g_ctf_flag_yellow_model : ((teamnumber == NUM_TEAM_4) ? autocvar_g_ctf_flag_pink_model : autocvar_g_ctf_flag_neutral_model)))); }
if(!flag.scale) { flag.scale = FLAG_SCALE; }
- if(!flag.skin) { flag.skin = ((teamnumber == NUM_TEAM_1) ? autocvar_g_ctf_flag_red_skin : ((teamnumber == NUM_TEAM_2) ? autocvar_g_ctf_flag_blue_skin : ((teamnumber == NUM_TEAM_3) ? autocvar_g_ctf_flag_yellow_skin : autocvar_g_ctf_flag_pink_skin))); }
- if(flag.toucheffect == "") { flag.toucheffect = ((teamnumber == NUM_TEAM_1) ? "redflag_touch" : ((teamnumber == NUM_TEAM_2) ? "blueflag_touch" : ((teamnumber == NUM_TEAM_3) ? "yellowflag_touch" : "pinkflag_touch"))); }
- if(flag.passeffect == "") { flag.passeffect = ((teamnumber == NUM_TEAM_1) ? "red_pass" : ((teamnumber == NUM_TEAM_2) ? "blue_pass" : ((teamnumber == NUM_TEAM_3) ? "yellow_pass" : "pink_pass"))); }
- if(flag.capeffect == "") { flag.capeffect = ((teamnumber == NUM_TEAM_1) ? "red_cap" : ((teamnumber == NUM_TEAM_2) ? "blue_cap" : ((teamnumber == NUM_TEAM_3) ? "yellow_cap" : "pink_cap"))); }
- if(!flag.skin) { flag.skin = ((teamnumber) ? autocvar_g_ctf_flag_red_skin : autocvar_g_ctf_flag_blue_skin); }
- if(flag.toucheffect == "") { flag.toucheffect = ((teamnumber) ? "redflag_touch" : "blueflag_touch"); }
- if(flag.passeffect == "") { flag.passeffect = ((teamnumber) ? "red_pass" : "blue_pass"); }
- if(flag.capeffect == "") { flag.capeffect = ((teamnumber) ? "red_cap" : "blue_cap"); }
++ if(!flag.skin) { flag.skin = ((teamnumber == NUM_TEAM_1) ? autocvar_g_ctf_flag_red_skin : ((teamnumber == NUM_TEAM_2) ? autocvar_g_ctf_flag_blue_skin : ((teamnumber == NUM_TEAM_3) ? autocvar_g_ctf_flag_yellow_skin : ((teamnumber == NUM_TEAM_4) ? autocvar_g_ctf_flag_pink_skin : autocvar_g_ctf_flag_neutral_skin)))); }
++ if(flag.toucheffect == "") { flag.toucheffect = ((teamnumber == NUM_TEAM_1) ? "redflag_touch" : ((teamnumber == NUM_TEAM_2) ? "blueflag_touch" : ((teamnumber == NUM_TEAM_3) ? "yellowflag_touch" : ((teamnumber == NUM_TEAM_4) ? "pinkflag_touch" : "neutralflag_touch")))); }
++ if(flag.passeffect == "") { flag.passeffect = ((teamnumber == NUM_TEAM_1) ? "red_pass" : ((teamnumber == NUM_TEAM_2) ? "blue_pass" : ((teamnumber == NUM_TEAM_3) ? "yellow_pass" : ((teamnumber == NUM_TEAM_4) ? "pink_pass" : "neutral_pass")))); }
++ if(flag.capeffect == "") { flag.capeffect = ((teamnumber == NUM_TEAM_1) ? "red_cap" : ((teamnumber == NUM_TEAM_2) ? "blue_cap" : ((teamnumber == NUM_TEAM_3) ? "yellow_cap" : ((teamnumber == NUM_TEAM_4) ? "pink_cap" : "")))); } // neutral flag cant be capped itself
++ if(!flag.active) { flag.active = ACTIVE_ACTIVE; }
// sound
- if(flag.snd_flag_taken == "") { flag.snd_flag_taken = ((teamnumber == NUM_TEAM_1) ? "ctf/red_taken.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_taken.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_taken.wav" : "ctf/pink_taken.wav"))); }
- if(flag.snd_flag_returned == "") { flag.snd_flag_returned = ((teamnumber == NUM_TEAM_1) ? "ctf/red_returned.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_returned.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_returned.wav" : "ctf/pink_returned.wav"))); }
- if(flag.snd_flag_capture == "") { flag.snd_flag_capture = ((teamnumber == NUM_TEAM_1) ? "ctf/red_capture.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_capture.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_capture.wav" : "ctf/pink_capture.wav"))); }
- if(flag.snd_flag_dropped == "") { flag.snd_flag_dropped = ((teamnumber == NUM_TEAM_1) ? "ctf/red_dropped.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_dropped.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_dropped.wav" : "ctf/pink_dropped.wav"))); }
- if(flag.snd_flag_taken == "") { flag.snd_flag_taken = ((teamnumber) ? "ctf/red_taken.wav" : "ctf/blue_taken.wav"); }
- if(flag.snd_flag_returned == "") { flag.snd_flag_returned = ((teamnumber) ? "ctf/red_returned.wav" : "ctf/blue_returned.wav"); }
- if(flag.snd_flag_capture == "") { flag.snd_flag_capture = ((teamnumber) ? "ctf/red_capture.wav" : "ctf/blue_capture.wav"); } // blue team scores by capturing the red flag
++ if(flag.snd_flag_taken == "") { flag.snd_flag_taken = ((teamnumber == NUM_TEAM_1) ? "ctf/red_taken.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_taken.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_taken.wav" : ((teamnumber == NUM_TEAM_4) ? "ctf/pink_taken.wav" : "ctf/neutral_taken.wav")))); }
++ if(flag.snd_flag_returned == "") { flag.snd_flag_returned = ((teamnumber == NUM_TEAM_1) ? "ctf/red_returned.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_returned.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_returned.wav" : ((teamnumber == NUM_TEAM_4) ? "ctf/pink_returned.wav" : "")))); } // neutral flag can't be returned by players
++ if(flag.snd_flag_capture == "") { flag.snd_flag_capture = ((teamnumber == NUM_TEAM_1) ? "ctf/red_capture.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_capture.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_capture.wav" : ((teamnumber == NUM_TEAM_4) ? "ctf/pink_capture.wav" : "")))); } // again can't be captured
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_dropped == "") { flag.snd_flag_dropped = ((teamnumber) ? "ctf/red_dropped.wav" : "ctf/blue_dropped.wav"); }
++ if(flag.snd_flag_dropped == "") { flag.snd_flag_dropped = ((teamnumber == NUM_TEAM_1) ? "ctf/red_dropped.wav" : ((teamnumber == NUM_TEAM_2) ? "ctf/blue_dropped.wav" : ((teamnumber == NUM_TEAM_3) ? "ctf/yellow_dropped.wav" : ((teamnumber == NUM_TEAM_4) ? "ctf/pink_dropped.wav" : "ctf/neutral_dropped.wav")))); }
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
if(autocvar_g_ctf_flag_glowtrails)
{
- flag.glow_color = ((teamnumber == NUM_TEAM_1) ? 251 : ((teamnumber == NUM_TEAM_2) ? 210 : ((teamnumber == NUM_TEAM_3) ? 110 : 145)));
- flag.glow_color = ((teamnumber) ? 251 : 210); // 251: red - 210: blue
++ flag.glow_color = ((teamnumber == NUM_TEAM_1) ? 251 : ((teamnumber == NUM_TEAM_2) ? 210 : ((teamnumber == NUM_TEAM_3) ? 110 : ((teamnumber == NUM_TEAM_4) ? 145 : 254))));
flag.glow_size = 25;
flag.glow_trail = 1;
}
flag.effects |= EF_LOWPRECISION;
if(autocvar_g_ctf_fullbrightflags) { flag.effects |= EF_FULLBRIGHT; }
- if(autocvar_g_ctf_dynamiclights) { flag.effects |= ((teamnumber) ? EF_RED : EF_BLUE); }
-
+ if(autocvar_g_ctf_dynamiclights)
+ {
+ switch(teamnumber)
+ {
+ case NUM_TEAM_1: flag.effects |= EF_RED; break;
+ case NUM_TEAM_2: flag.effects |= EF_BLUE; break;
+ case NUM_TEAM_3: flag.effects |= EF_DIMLIGHT; break;
+ case NUM_TEAM_4: flag.effects |= EF_RED; break;
++ default: flag.effects |= EF_DIMLIGHT; break;
+ }
+ }
-
++
// flag placement
if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location
{
f = ctf_worldflaglist;
while (f)
{
- if (CTF_DIFFTEAM(bot, f))
- if (bot.team != f.team)
++ if(ctf_oneflag)
++ {
++ if(CTF_DIFFTEAM(bot, f))
++ {
++ if(f.team)
++ {
++ if(bot.flagcarried)
++ return f;
++ }
++ else if(!bot.flagcarried)
++ return f;
++ }
++ }
++ else if (CTF_DIFFTEAM(bot, f))
return f;
f = f.ctf_worldflagnext;
}
head = ctf_worldflaglist;
while (head)
{
- if(CTF_DIFFTEAM(self, head))
- if (self.team != head.team)
++ if(ctf_oneflag)
++ {
++ if(CTF_DIFFTEAM(self, head))
++ {
++ if(head.team)
++ {
++ if(self.flagcarried)
++ break;
++ }
++ else if(!self.flagcarried)
++ break;
++ }
++ }
++ else if(CTF_DIFFTEAM(self, head))
break;
head = head.ctf_worldflagnext;
}
self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
navigation_goalrating_start();
-- havocbot_goalrating_ctf_ourbase(50000);
++ if(ctf_oneflag)
++ havocbot_goalrating_ctf_enemybase(50000);
++ else
++ havocbot_goalrating_ctf_ourbase(50000);
if(self.health<100)
havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
{
entity flag;
+
+ float t = 0, t2 = 0, t3 = 0;
+
// initially clear items so they can be set as necessary later.
- self.items &= ~(IT_RED_FLAG_CARRYING | IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST
- | IT_BLUE_FLAG_CARRYING | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST
- | IT_YELLOW_FLAG_CARRYING | IT_YELLOW_FLAG_TAKEN | IT_YELLOW_FLAG_LOST
- | IT_PINK_FLAG_CARRYING | IT_PINK_FLAG_TAKEN | IT_PINK_FLAG_LOST
- | IT_CTF_SHIELDED);
- self.items &= ~(IT_RED_FLAG_CARRYING | IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST
- | IT_BLUE_FLAG_CARRYING | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST | IT_CTF_SHIELDED);
++ 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
++ | CTF_NEUTRAL_FLAG_CARRYING | CTF_NEUTRAL_FLAG_TAKEN | CTF_NEUTRAL_FLAG_LOST
++ | CTF_FLAG_NEUTRAL | CTF_SHIELDED);
// scan through all the flags and notify the client about them
for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
{
- if(flag.team == NUM_TEAM_1) { t = IT_RED_FLAG_CARRYING; t2 = IT_RED_FLAG_TAKEN; t3 = IT_RED_FLAG_LOST; }
- if(flag.team == NUM_TEAM_2) { t = IT_BLUE_FLAG_CARRYING; t2 = IT_BLUE_FLAG_TAKEN; t3 = IT_BLUE_FLAG_LOST; }
- if(flag.team == NUM_TEAM_3) { t = IT_YELLOW_FLAG_CARRYING; t2 = IT_YELLOW_FLAG_TAKEN; t3 = IT_YELLOW_FLAG_LOST; }
- if(flag.team == NUM_TEAM_4) { t = IT_PINK_FLAG_CARRYING; t2 = IT_PINK_FLAG_TAKEN; t3 = IT_PINK_FLAG_LOST; }
++ if(flag.team == NUM_TEAM_1) { t = CTF_RED_FLAG_CARRYING; t2 = CTF_RED_FLAG_TAKEN; t3 = CTF_RED_FLAG_LOST; }
++ if(flag.team == NUM_TEAM_2) { t = CTF_BLUE_FLAG_CARRYING; t2 = CTF_BLUE_FLAG_TAKEN; t3 = CTF_BLUE_FLAG_LOST; }
++ if(flag.team == NUM_TEAM_3) { t = CTF_YELLOW_FLAG_CARRYING; t2 = CTF_YELLOW_FLAG_TAKEN; t3 = CTF_YELLOW_FLAG_LOST; }
++ if(flag.team == NUM_TEAM_4) { t = CTF_PINK_FLAG_CARRYING; t2 = CTF_PINK_FLAG_TAKEN; t3 = CTF_PINK_FLAG_LOST; }
++ if(flag.team == 0) { t = CTF_NEUTRAL_FLAG_CARRYING; t2 = CTF_NEUTRAL_FLAG_TAKEN; t3 = CTF_NEUTRAL_FLAG_LOST; self.ctf_flagstatus |= CTF_FLAG_NEUTRAL; }
+
switch(flag.ctf_status)
{
case FLAG_PASSING:
case FLAG_CARRY:
{
if((flag.owner == self) || (flag.pass_sender == self))
- self.items |= t; // carrying: self is currently carrying the flag
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_CARRYING : IT_BLUE_FLAG_CARRYING); // carrying: self is currently carrying the flag
-- else
- self.items |= t2; // taken: someone else is carrying the flag
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_TAKEN : IT_BLUE_FLAG_TAKEN); // taken: someone on self's team is carrying the flag
++ self.ctf_flagstatus |= t; // carrying: self is currently carrying the flag
++ else
++ self.ctf_flagstatus |= t2; // taken: someone else is carrying the flag
break;
}
case FLAG_DROPPED:
{
- self.items |= t3; // lost: the flag is dropped somewhere on the map
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_LOST : IT_BLUE_FLAG_LOST); // lost: the flag is dropped somewhere on the map
++ self.ctf_flagstatus |= t3; // lost: the flag is dropped somewhere on the map
break;
}
}
// item for stopping players from capturing the flag too often
if(self.ctf_captureshielded)
-- self.items |= IT_CTF_SHIELDED;
++ self.ctf_flagstatus |= CTF_SHIELDED;
// update the health of the flag carrier waypointsprite
if(self.wps_flagcarrier)
}
if(frag_target.flagcarried)
-- { ctf_Handle_Throw(frag_target, world, DROP_NORMAL); }
++ {
++ entity tmp_entity = frag_target.flagcarried;
++ ctf_Handle_Throw(frag_target, world, DROP_NORMAL);
++ tmp_entity.ctf_dropper = world;
++ }
return FALSE;
}
{
if(self.flagcarried)
{
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_));
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_));
++ 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));
ctf_RespawnFlag(self.flagcarried);
return TRUE;
}
return TRUE;
}
- ret_float = ctf_teams;
- return 0;
+MUTATOR_HOOKFUNCTION(ctf_GetTeamCount)
+{
++ //ret_float = ctf_teams;
++ ret_string = "ctf_team";
++ return TRUE;
++}
++
++MUTATOR_HOOKFUNCTION(ctf_SpectateCopy)
++{
++ self.ctf_flagstatus = other.ctf_flagstatus;
++ return FALSE;
+}
+
+
// ==========
// Spawnfuncs
// ==========
{
if(!g_ctf) { remove(self); return; }
- ctf_FlagSetup(0, self); // the 0 is misleading, but -- 0 = blue.
+ ctf_FlagSetup(NUM_TEAM_2, self);
+}
+
+/*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)...
+"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...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+void spawnfunc_item_flag_team3()
+{
+ if(!g_ctf) { remove(self); return; }
+
+ ctf_FlagSetup(NUM_TEAM_3, self);
+}
+
+/*QUAKED spawnfunc_item_flag_team4 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
- CTF flag for team two (Pink).
++CTF flag for team four (Pink).
+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...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+void spawnfunc_item_flag_team4()
+{
+ if(!g_ctf) { remove(self); return; }
+
+ ctf_FlagSetup(NUM_TEAM_4, self);
+}
+
++/*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)...
++"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...
++"noise4" sound played when flag is dropped by a player...
++"noise5" sound played when flag touches the ground... */
++void spawnfunc_item_flag_neutral()
++{
++ if(!g_ctf) { remove(self); return; }
++
++ ctf_FlagSetup(0, self);
+ }
+
/*QUAKED spawnfunc_ctf_team (0 .5 .8) (-16 -16 -24) (16 16 32)
Team declaration for CTF gameplay, this allows you to decide what team names and control point models are used in your map.
Note: If you use spawnfunc_ctf_team entities you must define at least 2! However, unlike domination, you don't need to make a blank one too.
void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
{
+ ctf_teams = 2;
+
+ entity tmp_entity;
+ for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
+ {
+ if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); }
+ if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); }
++ if(tmp_entity.team == 0) { ctf_oneflag = TRUE; }
+ }
+
+ ctf_teams = bound(2, ctf_teams, 4);
+
// if no teams are found, spawn defaults
if(find(world, classname, "ctf_team") == world)
{
ctf_captureshield_min_negscore = autocvar_g_ctf_shield_min_negscore;
ctf_captureshield_max_ratio = autocvar_g_ctf_shield_max_ratio;
ctf_captureshield_force = autocvar_g_ctf_shield_force;
++
++ addstat(STAT_CTF_FLAGSTATUS, AS_INT, ctf_flagstatus);
InitializeEntity(world, ctf_DelayedInit, INITPRIO_GAMETYPE);
}
MUTATOR_HOOK(VehicleExit, ctf_VehicleExit, CBC_ORDER_ANY);
MUTATOR_HOOK(AbortSpeedrun, ctf_AbortSpeedrun, CBC_ORDER_ANY);
MUTATOR_HOOK(HavocBot_ChooseRule, ctf_BotRoles, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetTeamCount, ctf_GetTeamCount, CBC_ORDER_ANY);
++ MUTATOR_HOOK(SpectateCopy, ctf_SpectateCopy, CBC_ORDER_ANY);
MUTATOR_ONADD
{
#define VEHICLE_FLAG_SCALE 1.0
// waypoint colors
--#define WPCOLOR_ENEMYFC(t) (colormapPaletteColor(t - 1, FALSE) * 0.75)
++#define WPCOLOR_ENEMYFC(t) ((t) ? colormapPaletteColor(t - 1, FALSE) * 0.75 : '1 1 1')
#define WPCOLOR_FLAGCARRIER(t) ('0.8 0.8 0')
--#define WPCOLOR_DROPPEDFLAG(t) (('0.25 0.25 0.25' + colormapPaletteColor(t - 1, FALSE)) * 0.5)
++#define WPCOLOR_DROPPEDFLAG(t) ((t) ? ('0.25 0.25 0.25' + colormapPaletteColor(t - 1, FALSE)) * 0.5 : '1 1 1')
// sounds
#define snd_flag_taken noise
.entity ctf_dropper; // don't allow spam of dropping the flag
.float max_flag_health;
.float next_take_time;
++.float ctf_flagdamaged;
+float ctf_teams;
// passing/throwing properties
.float pass_distance;
float ctf_captureshield_max_ratio; // punish at most 30% of each team
float ctf_captureshield_force; // push force of the shield
++// 1 flag ctf
++float ctf_oneflag; // indicates whether or not a neutral flag has been found
++
// bot player logic
#define HAVOCBOT_CTF_ROLE_NONE 0
#define HAVOCBOT_CTF_ROLE_DEFENSE 2
float havocbot_ctf_middlepoint_radius;
void havocbot_role_ctf_setrole(entity bot, float role);
+
+// team checking
+#define CTF_SAMETEAM(a,b) (autocvar_g_ctf_reverse ? DIFF_TEAM(a,b) : SAME_TEAM(a,b))
+#define CTF_DIFFTEAM(a,b) (autocvar_g_ctf_reverse ? SAME_TEAM(a,b) : DIFF_TEAM(a,b))
++
#endif
++
++// networked flag statuses
++.float ctf_flagstatus;
++
++const float CTF_RED_FLAG_TAKEN = 1;
++const float CTF_RED_FLAG_LOST = 2;
++const float CTF_RED_FLAG_CARRYING = 3;
++const float CTF_BLUE_FLAG_TAKEN = 4;
++const float CTF_BLUE_FLAG_LOST = 8;
++const float CTF_BLUE_FLAG_CARRYING = 12;
++const float CTF_YELLOW_FLAG_TAKEN = 16;
++const float CTF_YELLOW_FLAG_LOST = 32;
++const float CTF_YELLOW_FLAG_CARRYING = 48;
++const float CTF_PINK_FLAG_TAKEN = 64;
++const float CTF_PINK_FLAG_LOST = 128;
++const float CTF_PINK_FLAG_CARRYING = 192;
++const float CTF_NEUTRAL_FLAG_TAKEN = 256;
++const float CTF_NEUTRAL_FLAG_LOST = 512;
++const float CTF_NEUTRAL_FLAG_CARRYING = 768;
++const float CTF_FLAG_NEUTRAL = 2048;
++const float CTF_SHIELDED = 4096;
tcMod scroll 0.1 -0.04
tcMod rotate 0.1
}
+}
+models/ctf/glow_yellow
+{
+ {
+ map models/ctf/glow_yellow.tga
+ tcMod scale 0.03 0.03
+ tcMod scroll 0.1 -0.04
+ tcMod rotate 0.1
+ }
+}
+models/ctf/glow_pink
+{
+ {
+ map models/ctf/glow_pink.tga
+ tcMod scale 0.03 0.03
+ tcMod scroll 0.1 -0.04
+ tcMod rotate 0.1
+ }
++}
++models/ctf/glow_neutral
++{
++ {
++ map models/ctf/glow_neutral.tga
++ tcMod scale 0.03 0.03
++ tcMod scroll 0.1 -0.04
++ tcMod rotate 0.1
++ }
}