// capture the flag
// ==================
set g_ctf 0 "Capture The Flag: take the enemy flag and bring it to yours at your base to score"
++set g_ctf_flag_return 1 "auto return the flag to base when touched by a teammate"
++set g_ctf_flag_return_carried_radius 100 "allow flags to be returned by carrier if base is within this radius"
set g_ctf_flag_return_time 15
set g_ctf_flag_return_dropped 100
set g_ctf_flag_return_damage 0
vector flag_size;
float f; // every function should have that
- float redflag, blueflag; // current status
- float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime; // time since the status changed
+ 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 stat_items;
-
+ float teams_count = 0;
+ float fs, fs2, fs3, size1, size2;
+ vector e1, e2;
+ entity tm;
++
+ for(tm = teams.sort_next; tm; tm = tm.sort_next)
+ if(tm.team != NUM_SPECTATOR)
+ ++teams_count;
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;
- if(redflag || blueflag)
+
+ if(redflag || blueflag || yellowflag || pinkflag)
mod_active = 1;
else
mod_active = 0;
blueflag_prevstatus = blueflag_prevframe;
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;
+ }
+
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;
float BLINK_FACTOR = 0.15;
float BLINK_BASE = 0.85;
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))
+ 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))
+ 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))
+ 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))
+ pink_icon_prevstatus = "flag_pink_shielded";
+ else
+ pink_icon_prevstatus = string_null;
+ break;
+ }
-
++
+ switch(teams_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;
}
+ 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);
}
// Keyhunt HUD modicon section
MSG_ANNCE_NOTIF(2, ANNCE_VOTE_CALL, CH_INFO, "votecall", VOL_BASEVOICE, ATTEN_NONE) \
MSG_ANNCE_NOTIF(2, ANNCE_VOTE_FAIL, CH_INFO, "votefail", VOL_BASEVOICE, ATTEN_NONE)
- #define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
+ #define MULTITEAM_INFO2(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) \
+ MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
+ MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2)))
+ #define MULTITEAM_INFO3(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) \
MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \
- #if teams >= 3 \
- MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \
- #endif \
- #if teams >= 4 \
- MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) \
- #endif
+ MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3)))
+ #define MULTITEAM_INFO4(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle) \
+ MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
+ MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \
+ MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \
+ MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4)))
+ #define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
+ MULTITEAM_INFO##teams(default,prefix,strnum,flnum,args,hudargs,icon,normal,gentle)
+
#define MSG_INFO_NOTIFICATIONS \
- 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_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"), "") \
+ 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"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_DAMAGED_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG 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"), "") \
+ 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"), "") \
+ 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"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_FLAGRETURN_TIMEOUT_, 4, 0, 0, "", "", "", _("^BGThe ^TC^TT^BG 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"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_PICKUP_, 4, 1, 0, "s1", "s1", "notify_%s_taken", _("^BG%s^BG got the ^TC^TT^BG flag"), "") \
+ MULTITEAM_INFO(1, INFO_CTF_RETURN_, 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_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_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"), "") \
+ 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_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"), "") \
+ 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_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_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_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")) \
MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SNIPE, NO_MSG, INFO_WEAPON_UZI_MURDER_SNIPE, NO_MSG) \
MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SPRAY, NO_MSG, INFO_WEAPON_UZI_MURDER_SPRAY, NO_MSG)
- #define MULTITEAM_CHOICE(default,challow,prefix,teams,chtype,optiona,optionb) \
+ #define MULTITEAM_CHOICE2(default,challow,prefix,chtype,optiona,optionb) \
+ MSG_CHOICE_NOTIF(default, challow, prefix##RED, chtype, optiona##RED, optionb##RED) \
+ MSG_CHOICE_NOTIF(default, challow, prefix##BLUE, chtype, optiona##BLUE, optionb##BLUE)
+ #define MULTITEAM_CHOICE3(default,challow,prefix,chtype,optiona,optionb) \
MSG_CHOICE_NOTIF(default, challow, prefix##RED, chtype, optiona##RED, optionb##RED) \
MSG_CHOICE_NOTIF(default, challow, prefix##BLUE, chtype, optiona##BLUE, optionb##BLUE) \
- #if teams >= 3 \
- MSG_CHOICE_NOTIF(default, challow, prefix##YELLOW, chtype, optiona##YELLOW, optionb##YELLOW) \
- #endif \
- #if teams >= 4 \
- MSG_CHOICE_NOTIF(default, challow, prefix##PINK, chtype, optiona##PINK, optionb##PINK) \
- #endif
+ MSG_CHOICE_NOTIF(default, challow, prefix##YELLOW, chtype, optiona##YELLOW, optionb##YELLOW)
+ #define MULTITEAM_CHOICE4(default,challow,prefix,chtype,optiona,optionb) \
+ MSG_CHOICE_NOTIF(default, challow, prefix##RED, chtype, optiona##RED, optionb##RED) \
+ MSG_CHOICE_NOTIF(default, challow, prefix##BLUE, chtype, optiona##BLUE, optionb##BLUE) \
+ MSG_CHOICE_NOTIF(default, challow, prefix##YELLOW, chtype, optiona##YELLOW, optionb##YELLOW) \
+ MSG_CHOICE_NOTIF(default, challow, prefix##PINK, chtype, optiona##PINK, optionb##PINK)
+ #define MULTITEAM_CHOICE(default,challow,prefix,teams,chtype,optiona,optionb) \
+ 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_ENEMY, MSG_CENTER, CENTER_CTF_PICKUP_ENEMY, CENTER_CTF_PICKUP_ENEMY_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_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 cap_record = ctf_captimerecord;
float cap_time = (time - flag.ctf_pickuptime);
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_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_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_captimerecord) || (cap_time < cap_record))
{
else { return TRUE; }
}
-
+float ctf_Stalemate_customizeentityforclient()
+{
+ // make spectators see what the player would see
+ entity e, wp_owner;
+ e = WaypointSprite_getviewentity(other);
+ wp_owner = self.owner;
-
++
+ // team waypoints
+ if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner))
+ return FALSE;
-
- if not(IS_PLAYER(e))
++
+ if(SAME_TEAM(wp_owner, e))
+ return FALSE;
-
++
++ if(!IS_PLAYER(e))
+ return FALSE;
++
+ return TRUE;
+}
+
// =======================
- // CaptureShield Functions
+ // CaptureShield Functions
// =======================
- float ctf_CaptureShield_CheckStatus(entity p)
+ float ctf_CaptureShield_CheckStatus(entity p)
{
- float s, se;
+ float s, s2, s3, s4, se, se2, se3, se4, sr, ser;
entity e;
float players_worseeq, players_total;
if(ctf_captureshield_max_ratio <= 0)
return FALSE;
-
+
- s = PlayerScore_Add(p, SP_SCORE, 0);
- if(s >= -ctf_captureshield_min_negscore)
+ s = PlayerScore_Add(p, SP_CTF_CAPS, 0);
+ s2 = PlayerScore_Add(p, SP_CTF_PICKUPS, 0);
+ s3 = PlayerScore_Add(p, SP_CTF_RETURNS, 0);
+ s4 = PlayerScore_Add(p, SP_CTF_FCKILLS, 0);
-
++
+ sr = ((s - s2) + (s3 + s4));
-
++
+ if(sr >= -ctf_captureshield_min_negscore)
return FALSE;
players_total = players_worseeq = 0;
{
if(DIFF_TEAM(e, p))
continue;
- se = PlayerScore_Add(e, SP_SCORE, 0);
- if(se <= s)
+ se = PlayerScore_Add(e, SP_CTF_CAPS, 0);
+ se2 = PlayerScore_Add(e, SP_CTF_PICKUPS, 0);
+ se3 = PlayerScore_Add(e, SP_CTF_RETURNS, 0);
+ se4 = PlayerScore_Add(e, SP_CTF_FCKILLS, 0);
-
++
+ ser = ((se - se2) + (se3 + se4));
-
++
+ if(ser <= sr)
++players_worseeq;
++players_total;
}
float ctf_CaptureShield_Customize()
{
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(!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;
flag.ctf_droptime = time;
flag.ctf_dropper = player;
flag.ctf_status = FLAG_DROPPED;
-
+
// messages and sounds
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_LOST_), player.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_LOST_), player.netname);
sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
ctf_EventLog("dropped", player.team, player);
FOR_EACH_REALPLAYER(tmp_player)
{
if(tmp_player == sender)
- 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, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_SENT_), player.netname);
else if(tmp_player == player)
- 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, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_RECEIVED_), sender.netname);
else if(SAME_TEAM(tmp_player, sender))
- 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, APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_), sender.netname, player.netname);
}
-
+
// create new waypoint
ctf_FlagcarrierWaypoints(player);
-
+
sender.throw_antispam = time + autocvar_g_ctf_pass_wait;
player.throw_antispam = sender.throw_antispam;
{
entity enemy_flag = ((capturetype == CAPTURE_NORMAL) ? toucher.flagcarried : toucher);
entity player = ((capturetype == CAPTURE_NORMAL) ? toucher : enemy_flag.ctf_dropper);
- float old_time, new_time;
-
- if not(player) { return; } // without someone to give the reward to, we can't possibly cap
+ 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; }
-
+
// messages and sounds
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(enemy_flag, CENTER_CTF_CAPTURE_));
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_));
ctf_CaptureRecord(enemy_flag, player);
- sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTEN_NONE);
+ sound(player, CH_TRIGGER, ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture), VOL_BASE, ATTEN_NONE);
-
+
switch(capturetype)
{
case CAPTURE_NORMAL: ctf_EventLog("capture", enemy_flag.team, player); break;
PlayerScore_Add(player, SP_CTF_RETURNS, 1); // add to count of returns
TeamScore_AddToTeam(flag.team, ST_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the team who was last carrying it
-
- if(flag.ctf_dropper)
+
+ if(flag.ctf_dropper)
{
PlayerScore_Add(flag.ctf_dropper, SP_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the player who dropped the flag
- ctf_CaptureShield_Update(flag.ctf_dropper, 0); // shield player from picking up flag
+ ctf_CaptureShield_Update(flag.ctf_dropper, 0); // shield player from picking up flag
flag.ctf_dropper.next_take_time = time + autocvar_g_ctf_flag_collect_delay; // set next take time
}
+
++ // other
++ if(player.flagcarried == flag)
++ WaypointSprite_Kill(player.wps_flagcarrier);
+
// reset the flag
ctf_RespawnFlag(flag);
}
{
// declarations
float pickup_dropped_score; // used to calculate dropped pickup score
-
+ entity tmp_entity; // temporary entity
+
// attach the flag to the player
flag.owner = player;
player.flagcarried = flag;
}
// messages and sounds
- Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_), player.netname);
- Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_));
- 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, APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_), 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_)); }
++ 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, 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);
+ 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);
-
+
// scoring
PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
switch(pickuptype)
{
switch(returntype)
{
- 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, 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;
-
+
default:
case RETURN_TIMEOUT:
- { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
+ { Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_)); break; }
}
sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
ctf_EventLog("returned", flag.team, world);
}
}
}
-
+
- if(stale_red_flags && stale_blue_flags)
+ stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
-
++
+ if(stale_flags == ctf_teams)
ctf_stalemate = TRUE;
- else if((!stale_red_flags && !stale_blue_flags) && autocvar_g_ctf_stalemate_endcondition == 2)
+ 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
if(ctf_stalemate)
{
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));
+ tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_customizeentityforclient;
+ }
}
-
- if not(wpforenemy_announced)
+
+ if (!wpforenemy_announced)
{
FOR_EACH_REALPLAYER(tmp_entity)
Send_Notification(NOTIF_ONE, tmp_entity, MSG_CENTER, ((tmp_entity.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER));
wpforenemy_nextthink = time + WPFE_THINKRATE; // waypoint for enemy think rate (to reduce unnecessary spam of this check)
}
}
- // drop the flag if reverse status has changed
- ctf_Handle_Throw(self.owner, world, DROP_THROW);
+ if(CTF_SAMETEAM(self, self.owner))
+ {
++ 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;
}
-
+
case FLAG_PASSING:
{
vector targ_origin = ((self.pass_target.absmin + self.pass_target.absmax) * 0.5);
targ_origin = WarpZone_RefSys_TransformOrigin(self.pass_target, self, targ_origin); // origin of target as seen by the flag (us)
WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
-
+
if((self.pass_target == world)
|| (self.pass_target.deadflag != DEAD_NO)
+ || (self.pass_target.flagcarried)
|| (vlen(self.origin - targ_origin) > autocvar_g_ctf_pass_radius)
|| ((trace_fraction < 1) && (trace_ent != self.pass_target))
|| (time > self.ctf_droptime + autocvar_g_ctf_pass_timelimit))
}
else if(toucher.deadflag != DEAD_NO) { return; }
- switch(self.ctf_status)
- {
+ switch(self.ctf_status)
+ {
case FLAG_BASE:
{
- if(SAME_TEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self))
+ if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self))
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))
+ else if(CTF_DIFFTEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time))
ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the enemies flag
break;
}
-
+
case FLAG_DROPPED:
{
- if(CTF_SAMETEAM(toucher, self))
- if(SAME_TEAM(toucher, self))
++ if(CTF_SAMETEAM(toucher, self) && autocvar_g_ctf_flag_return)
ctf_Handle_Return(self, toucher); // toucher just returned his own flag
else if((!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
// reset the player (if there is one)
if((flag.owner) && (flag.owner.flagcarried == flag))
{
- if(flag.owner.wps_enemyflagcarrier)
- WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
-
+ WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
WaypointSprite_Kill(flag.wps_flagcarrier);
-
+
flag.owner.flagcarried = world;
if(flag.speedrunning)
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));
+ 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;
+ }
-
++
+ 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));
// captureshield setup
ctf_CaptureShield_Spawn(self);
}
-void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
+void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
{
// declarations
- teamnumber = fabs(teamnumber - bound(0, autocvar_g_ctf_reverse, 1)); // if we were originally 1, this will become 0. If we were originally 0, this will become 1.
self = flag; // for later usage with droptofloor()
-
+
// main setup
flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
ctf_worldflaglist = flag;
setattachment(flag, world, "");
-
+
- 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) ? "^2BLUE^7 flag" : ((teamnumber == NUM_TEAM_3) ? "^3YELLOW^7 flag" : "^6PINK^7 flag")));
+ flag.team = teamnumber;
flag.classname = "item_flag_team";
flag.target = "###item###"; // wut?
flag.flags = FL_ITEM | FL_NOTARGET;
flag.ctf_status = FLAG_BASE;
// appearence
- 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 : autocvar_g_ctf_flag_pink_model))); }
+ if(!flag.scale) { flag.scale = FLAG_SCALE; }
- 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 : 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.scale) { flag.scale = FLAG_SCALE; }
-
+
// sound
- 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" : "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_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_touch == "") { flag.snd_flag_touch = "ctf/touch.wav"; } // again has no team-based sound
if(flag.snd_flag_pass == "") { flag.snd_flag_pass = "ctf/pass.wav"; } // same story here
-
+
// precache
precache_sound(flag.snd_flag_taken);
precache_sound(flag.snd_flag_returned);
setmodel(flag, flag.model); // precision set below
setsize(flag, FLAG_MIN, FLAG_MAX);
setorigin(flag, (flag.origin + FLAG_SPAWN_OFFSET));
-
+
if(autocvar_g_ctf_flag_glowtrails)
{
- 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 : 145)));
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;
+ }
+ }
-
+
// flag placement
if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location
- {
- flag.dropped_origin = flag.origin;
+ {
+ flag.dropped_origin = flag.origin;
flag.noalign = TRUE;
flag.movetype = MOVETYPE_NONE;
}
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_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_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);
- // scan through all the flags and notify the client about them
+ // 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; }
++
switch(flag.ctf_status)
{
case FLAG_PASSING:
case FLAG_CARRY:
{
if((flag.owner == self) || (flag.pass_sender == self))
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_CARRYING : IT_BLUE_FLAG_CARRYING); // carrying: self is currently carrying the flag
+ self.items |= t; // carrying: self is currently carrying the flag
- else
+ else
- self.items |= ((flag.items & IT_KEY2) ? IT_RED_FLAG_TAKEN : IT_BLUE_FLAG_TAKEN); // taken: someone on self's team is carrying the flag
+ self.items |= t2; // taken: someone else is carrying the flag
break;
}
case FLAG_DROPPED:
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); }
+ }
++
+ ctf_teams = bound(2, ctf_teams, 4);
+
// if no teams are found, spawn defaults
if(find(world, classname, "ctf_team") == world)
{
print("No ""ctf_team"" entities found on this map, creating them anyway.\n");
ctf_SpawnTeam("Red", NUM_TEAM_1 - 1);
ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1);
+ if(ctf_teams >= 3)
+ ctf_SpawnTeam("Yellow", NUM_TEAM_3 - 1);
+ if(ctf_teams >= 4)
+ ctf_SpawnTeam("Pink", NUM_TEAM_4 - 1);
}
-
+
- ctf_ScoreRules();
+ ctf_ScoreRules(ctf_teams);
}
void ctf_Initialize()
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_ONADD
{
if(time > 1) // game loads at time 1