X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fmutator%2Fgamemode_ctf.qc;h=8120e1cb348a77e35e545eaa2c78733f41a2ea02;hb=8c965aa90470cfa8cbfaff88db71b6b5899a90ce;hp=e39968b3ae4fbaff58e317ad8a53411f2a388b4b;hpb=ee7a78f942624de2ab30112a798e3f663cf9cc2f;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mutators/mutator/gamemode_ctf.qc b/qcsrc/server/mutators/mutator/gamemode_ctf.qc index e39968b3a..8120e1cb3 100644 --- a/qcsrc/server/mutators/mutator/gamemode_ctf.qc +++ b/qcsrc/server/mutators/mutator/gamemode_ctf.qc @@ -1,6 +1,5 @@ #include "gamemode_ctf.qh" -#ifdef IMPLEMENTATION #ifndef CSQC void ctf_Initialize(); @@ -136,10 +135,14 @@ void ctf_CaptureRecord(entity flag, entity player) string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname")); // notify about shit - if(ctf_oneflag) { Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname); } - else if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_CAPTURE_TIME), player.netname, (cap_time * 100)); } - else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_CAPTURE_BROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100)); } - else { Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_CAPTURE_UNBROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100)); } + if(ctf_oneflag) + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname); + else if(!ctf_captimerecord) + Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_TIME), player.netname, (cap_time * 100)); + else if(cap_time < cap_record) + Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_CAPTURE_BROKEN), player.netname, refername, (cap_time * 100), (cap_record * 100)); + else + Send_Notification(NOTIF_ALL, NULL, MSG_CHOICE, APP_TEAM_NUM(flag.team, 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 @@ -152,12 +155,39 @@ void ctf_CaptureRecord(entity flag, entity player) } } +bool ctf_Return_Customize(entity this, entity client) +{ + // only to the carrier + return boolean(client == this.owner); +} + void ctf_FlagcarrierWaypoints(entity player) { WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player, FLAG_WAYPOINT_OFFSET, NULL, player.team, player, wps_flagcarrier, true, RADARICON_FLAG); WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2); WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)); WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER, WPCOLOR_FLAGCARRIER(player.team)); + + if(player.flagcarried && CTF_SAMETEAM(player, player.flagcarried)) + { + if(!player.wps_enemyflagcarrier) + { + entity wp = WaypointSprite_Spawn(((ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, player, FLAG_WAYPOINT_OFFSET, NULL, 0, player, wps_enemyflagcarrier, true, RADARICON_FLAG); + wp.colormod = WPCOLOR_ENEMYFC(player.team); + setcefc(wp, ctf_Stalemate_Customize); + + if(IS_REAL_CLIENT(player) && !ctf_stalemate) + Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_VISIBLE); + } + + if(!player.wps_flagreturn) + { + entity owp = WaypointSprite_SpawnFixed(WP_FlagReturn, player.flagcarried.ctf_spawnorigin + FLAG_WAYPOINT_OFFSET, player, wps_flagreturn, RADARICON_FLAG); + owp.colormod = '0 0.8 0.8'; + //WaypointSprite_UpdateTeamRadar(player.wps_flagreturn, RADARICON_FLAG, ((player.team) ? colormapPaletteColor(player.team - 1, false) : '1 1 1')); + setcefc(owp, ctf_Return_Customize); + } + } } void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnrate) @@ -233,7 +263,7 @@ bool ctf_CaptureShield_CheckStatus(entity p) if(ctf_captureshield_max_ratio <= 0) return false; - s = PlayerScore_Add(p, SP_CTF_CAPS, 0); + 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); @@ -247,7 +277,7 @@ bool ctf_CaptureShield_CheckStatus(entity p) FOREACH_CLIENT(IS_PLAYER(it), LAMBDA( if(DIFF_TEAM(it, p)) continue; - se = PlayerScore_Add(it, SP_CTF_CAPS, 0); + se = PlayerScore_Add(it, SP_CTF_CAPS, 0); se2 = PlayerScore_Add(it, SP_CTF_PICKUPS, 0); se3 = PlayerScore_Add(it, SP_CTF_RETURNS, 0); se4 = PlayerScore_Add(it, SP_CTF_FCKILLS, 0); @@ -307,7 +337,7 @@ void ctf_CaptureShield_Spawn(entity flag) settouch(shield, ctf_CaptureShield_Touch); setcefc(shield, ctf_CaptureShield_Customize); shield.effects = EF_ADDITIVE; - shield.movetype = MOVETYPE_NOCLIP; + set_movetype(shield, MOVETYPE_NOCLIP); shield.solid = SOLID_TRIGGER; shield.avelocity = '7 0 11'; shield.scale = 0.5; @@ -328,7 +358,7 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype) player = (player ? player : flag.pass_sender); // main - flag.movetype = MOVETYPE_TOSS; + set_movetype(flag, MOVETYPE_TOSS); flag.takedamage = DAMAGE_YES; flag.angles = '0 0 0'; flag.health = flag.max_flag_health; @@ -337,7 +367,7 @@ void ctf_Handle_Drop(entity flag, entity player, int droptype) flag.ctf_status = FLAG_DROPPED; // messages and sounds - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_LOST) : INFO_CTF_LOST_NEUTRAL), player.netname); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_LOST), player.netname); _sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE); ctf_EventLog("dropped", player.team, player); @@ -387,7 +417,7 @@ void ctf_Handle_Retrieve(entity flag, entity player) setattachment(flag, player, ""); setorigin(flag, FLAG_CARRY_OFFSET); } - flag.movetype = MOVETYPE_NONE; + set_movetype(flag, MOVETYPE_NONE); flag.takedamage = DAMAGE_NO; flag.solid = SOLID_NOT; flag.angles = '0 0 0'; @@ -399,11 +429,11 @@ void ctf_Handle_Retrieve(entity flag, entity player) FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), LAMBDA( if(it == sender) - Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT(flag, CENTER_CTF_PASS_SENT) : CENTER_CTF_PASS_SENT_NEUTRAL), player.netname); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_NUM(flag.team, CENTER_CTF_PASS_SENT), player.netname); else if(it == player) - Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT(flag, CENTER_CTF_PASS_RECEIVED) : CENTER_CTF_PASS_RECEIVED_NEUTRAL), sender.netname); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_NUM(flag.team, CENTER_CTF_PASS_RECEIVED), sender.netname); else if(SAME_TEAM(it, sender)) - Send_Notification(NOTIF_ONE, it, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT(flag, CENTER_CTF_PASS_OTHER) : CENTER_CTF_PASS_OTHER_NEUTRAL), sender.netname, player.netname); + Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_NUM(flag.team, CENTER_CTF_PASS_OTHER), sender.netname, player.netname); )); // create new waypoint @@ -453,7 +483,7 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype) ctf_CalculatePassVelocity(flag, targ_origin, player.origin, false); // main - flag.movetype = MOVETYPE_FLY; + set_movetype(flag, MOVETYPE_FLY); flag.takedamage = DAMAGE_NO; flag.pass_sender = player; flag.pass_target = receiver; @@ -498,6 +528,9 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype) if(player.wps_enemyflagcarrier) WaypointSprite_Kill(player.wps_enemyflagcarrier); + if(player.wps_flagreturn) + WaypointSprite_Kill(player.wps_flagreturn); + // captureshield ctf_CaptureShield_Update(player, 0); // shield player from picking up flag } @@ -537,7 +570,7 @@ void ctf_Handle_Capture(entity flag, entity toucher, int capturetype) player.throw_count = 0; // messages and sounds - Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT(enemy_flag, CENTER_CTF_CAPTURE) : CENTER_CTF_CAPTURE_NEUTRAL)); + Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_NUM(enemy_flag.team, CENTER_CTF_CAPTURE)); ctf_CaptureRecord(enemy_flag, player); _sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE); @@ -581,12 +614,12 @@ void ctf_Handle_Return(entity flag, entity player) // messages and sounds if(IS_MONSTER(player)) { - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_ENT(flag, INFO_CTF_RETURN_MONSTER), player.monster_name); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(flag.team, INFO_CTF_RETURN_MONSTER), player.monster_name); } else if(flag.team) { - Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT(flag, CENTER_CTF_RETURN)); - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_ENT(flag, INFO_CTF_RETURN), player.netname); + Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_NUM(flag.team, CENTER_CTF_RETURN)); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(flag.team, INFO_CTF_RETURN), player.netname); } _sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE); ctf_EventLog("return", flag.team, player); @@ -638,7 +671,7 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) } // flag setup - flag.movetype = MOVETYPE_NONE; + set_movetype(flag, MOVETYPE_NONE); flag.takedamage = DAMAGE_NO; flag.solid = SOLID_NOT; flag.angles = '0 0 0'; @@ -652,13 +685,17 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) } // messages and sounds - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(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(!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(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_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_PICKUP), player.netname); + if(ctf_stalemate) + Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); + 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_NUM(flag.team, 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, ((flag.team) ? APP_TEAM_ENT(flag, CHOICE_CTF_PICKUP_TEAM) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname); + Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, APP_NUM(flag.team, CHOICE_CTF_PICKUP_TEAM), Team_ColorCode(player.team), player.netname); if(!flag.team) FOREACH_CLIENT(IS_PLAYER(it) && it != player && DIFF_TEAM(it, player), LAMBDA(Send_Notification(NOTIF_ONE, it, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, Team_ColorCode(player.team), player.netname))); @@ -667,7 +704,7 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) FOREACH_CLIENT(IS_PLAYER(it) && it != player, LAMBDA( if(CTF_SAMETEAM(flag, it)) if(SAME_TEAM(player, it)) - Send_Notification(NOTIF_ONE, it, MSG_CHOICE, APP_TEAM_ENT(flag, CHOICE_CTF_PICKUP_TEAM), Team_ColorCode(player.team), player.netname); + Send_Notification(NOTIF_ONE, it, MSG_CHOICE, APP_TEAM_NUM(flag.team, CHOICE_CTF_PICKUP_TEAM), Team_ColorCode(player.team), player.netname); else Send_Notification(NOTIF_ONE, it, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname); )); @@ -690,7 +727,7 @@ void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) { pickup_dropped_score = (autocvar_g_ctf_flag_return_time ? bound(0, ((flag.ctf_droptime + autocvar_g_ctf_flag_return_time) - time) / autocvar_g_ctf_flag_return_time, 1) : 1); pickup_dropped_score = floor((autocvar_g_ctf_score_pickup_dropped_late * (1 - pickup_dropped_score) + autocvar_g_ctf_score_pickup_dropped_early * pickup_dropped_score) + 0.5); - LOG_TRACE("pickup_dropped_score is ", ftos(pickup_dropped_score), "\n"); + LOG_TRACE("pickup_dropped_score is ", ftos(pickup_dropped_score)); PlayerTeamScore_AddScore(player, pickup_dropped_score); ctf_EventLog("pickup", flag.team, player); break; @@ -731,14 +768,17 @@ void ctf_CheckFlagReturn(entity flag, int returntype) { switch(returntype) { - case RETURN_DROPPED: Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_DROPPED) : INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL)); break; - case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_DAMAGED) : INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL)); break; - case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_SPEEDRUN) : INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL), ctf_captimerecord); break; - case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_NEEDKILL) : INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL)); break; - + case RETURN_DROPPED: + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_DROPPED)); break; + case RETURN_DAMAGE: + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_DAMAGED)); break; + case RETURN_SPEEDRUN: + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_SPEEDRUN), ctf_captimerecord); break; + case RETURN_NEEDKILL: + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_NEEDKILL)); break; default: case RETURN_TIMEOUT: - { Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((flag.team) ? APP_TEAM_ENT(flag, INFO_CTF_FLAGRETURN_TIMEOUT) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; } + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(flag.team, INFO_CTF_FLAGRETURN_TIMEOUT)); break; } _sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE); ctf_EventLog("returned", flag.team, NULL); @@ -750,12 +790,11 @@ void ctf_CheckFlagReturn(entity flag, int returntype) bool ctf_Stalemate_Customize(entity this, entity client) { // make spectators see what the player would see - entity e, wp_owner; - e = WaypointSprite_getviewentity(client); - wp_owner = this.owner; + entity e = WaypointSprite_getviewentity(client); + entity wp_owner = this.owner; // team waypoints - if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; } + //if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; } if(SAME_TEAM(wp_owner, e)) { return false; } if(!IS_PLAYER(e)) { return false; } @@ -864,7 +903,7 @@ void ctf_FlagThink(entity this) // sanity checks if(this.mins != CTF_FLAG.m_mins || this.maxs != CTF_FLAG.m_maxs) { // reset the flag boundaries in case it got squished - LOG_TRACE("wtf the flag got squashed?\n"); + LOG_TRACE("wtf the flag got squashed?"); tracebox(this.origin, CTF_FLAG.m_mins, CTF_FLAG.m_maxs, this.origin, MOVE_NOMONSTERS, this); if(!trace_startsolid || this.noalign) // can we resize it without getting stuck? setsize(this, CTF_FLAG.m_mins, CTF_FLAG.m_maxs); } @@ -908,9 +947,9 @@ void ctf_FlagThink(entity this) if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER) { this.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; } else - { this.movetype = MOVETYPE_FLY; } + { set_movetype(this, MOVETYPE_FLY); } } - else if(this.movetype == MOVETYPE_FLY) { this.movetype = MOVETYPE_TOSS; } + else if(this.move_movetype == MOVETYPE_FLY) { set_movetype(this, MOVETYPE_TOSS); } } if(autocvar_g_ctf_flag_return_dropped) { @@ -973,7 +1012,7 @@ void ctf_FlagThink(entity this) if((this.pass_target == NULL) || (IS_DEAD(this.pass_target)) || (this.pass_target.flagcarried) - || (vdist(this.origin - targ_origin, <, autocvar_g_ctf_pass_radius)) + || (vdist(this.origin - targ_origin, >, autocvar_g_ctf_pass_radius)) || ((trace_fraction < 1) && (trace_ent != this.pass_target)) || (time > this.ctf_droptime + autocvar_g_ctf_pass_timelimit)) { @@ -990,7 +1029,7 @@ void ctf_FlagThink(entity this) default: // this should never happen { - LOG_TRACE("ctf_FlagThink(): Flag exists with no status?\n"); + LOG_TRACE("ctf_FlagThink(): Flag exists with no status?"); return; } } @@ -1078,7 +1117,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher)) case FLAG_CARRY: { - LOG_TRACE("Someone touched a flag even though it was being carried?\n"); + LOG_TRACE("Someone touched a flag even though it was being carried?"); break; } @@ -1109,6 +1148,7 @@ void ctf_RespawnFlag(entity flag) if((flag.owner) && (flag.owner.flagcarried == flag)) { WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier); + WaypointSprite_Kill(flag.owner.wps_flagreturn); WaypointSprite_Kill(flag.wps_flagcarrier); flag.owner.flagcarried = NULL; @@ -1127,7 +1167,7 @@ void ctf_RespawnFlag(entity flag) setattachment(flag, NULL, ""); setorigin(flag, flag.ctf_spawnorigin); - flag.movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS); + set_movetype(flag, ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS)); flag.takedamage = DAMAGE_NO; flag.health = flag.max_flag_health; flag.solid = SOLID_TRIGGER; @@ -1156,6 +1196,13 @@ void ctf_Reset(entity this) ctf_RespawnFlag(this); } +bool ctf_FlagBase_Customize(entity this, entity client) +{ + if(client.flagcarried && CTF_SAMETEAM(client, client.flagcarried)) + return false; + return true; +} + void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map by ctf_FlagSetup() { // bot waypoints @@ -1177,6 +1224,7 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map entity wp = WaypointSprite_SpawnFixed(basename, this.origin + FLAG_WAYPOINT_OFFSET, this, wps_flagbase, RADARICON_FLAG); wp.colormod = ((this.team) ? Team_ColorRGB(this.team) : '1 1 1'); WaypointSprite_UpdateTeamRadar(this.wps_flagbase, RADARICON_FLAG, ((this.team) ? colormapPaletteColor(this.team - 1, false) : '1 1 1')); + setcefc(wp, ctf_FlagBase_Customize); // captureshield setup ctf_CaptureShield_Spawn(this); @@ -1197,6 +1245,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e flag.classname = "item_flag_team"; flag.target = "###item###"; // wut? flag.flags = FL_ITEM | FL_NOTARGET; + IL_PUSH(g_items, flag); flag.solid = SOLID_TRIGGER; flag.takedamage = DAMAGE_NO; flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale; @@ -1208,6 +1257,8 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e flag.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP; flag.damagedbytriggers = autocvar_g_ctf_flag_return_when_unreachable; flag.damagedbycontents = autocvar_g_ctf_flag_return_when_unreachable; + if(flag.damagedbycontents) + IL_PUSH(g_damagedbycontents, flag); flag.velocity = '0 0 0'; flag.mangle = flag.angles; flag.reset = ctf_Reset; @@ -1280,13 +1331,13 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e { flag.dropped_origin = flag.origin; flag.noalign = true; - flag.movetype = MOVETYPE_NONE; + set_movetype(flag, MOVETYPE_NONE); } else // drop to floor, automatically find a platform and set that as spawn origin { flag.noalign = false; droptofloor(flag); - flag.movetype = MOVETYPE_TOSS; + set_movetype(flag, MOVETYPE_NONE); } InitializeEntity(flag, ctf_DelayedFlagSetup, INITPRIO_SETLOCATION); @@ -1490,23 +1541,19 @@ void havocbot_goalrating_ctf_droppedflags(entity this, float ratingscale, vector void havocbot_goalrating_ctf_carrieritems(entity this, float ratingscale, vector org, float sradius) { - entity head; - float t; - head = findchainfloat(bot_pickup, true); - while (head) + IL_EACH(g_items, it.bot_pickup, { // gather health and armor only - if (head.solid) - if (head.health || head.armorvalue) - if (vdist(head.origin - org, <, sradius)) + if (it.solid) + if (it.health || it.armorvalue) + if (vdist(it.origin - org, <, sradius)) { // get the value of the item - t = head.bot_pickupevalfunc(this, head) * 0.0001; + float t = it.bot_pickupevalfunc(this, it) * 0.0001; if (t > 0) - navigation_routerating(this, head, t * ratingscale, 500); + navigation_routerating(this, it, t * ratingscale, 500); } - head = head.chain; - } + }); } void havocbot_ctf_reset_role(entity this) @@ -1927,47 +1974,47 @@ void havocbot_role_ctf_defense(entity this) void havocbot_role_ctf_setrole(entity bot, int role) { - LOG_TRACE(strcat(bot.netname," switched to ")); + string s = "(null)"; switch(role) { case HAVOCBOT_CTF_ROLE_CARRIER: - LOG_TRACE("carrier"); + s = "carrier"; bot.havocbot_role = havocbot_role_ctf_carrier; bot.havocbot_role_timeout = 0; bot.havocbot_cantfindflag = time + 10; bot.bot_strategytime = 0; break; case HAVOCBOT_CTF_ROLE_DEFENSE: - LOG_TRACE("defense"); + s = "defense"; bot.havocbot_role = havocbot_role_ctf_defense; bot.havocbot_role_timeout = 0; break; case HAVOCBOT_CTF_ROLE_MIDDLE: - LOG_TRACE("middle"); + s = "middle"; bot.havocbot_role = havocbot_role_ctf_middle; bot.havocbot_role_timeout = 0; break; case HAVOCBOT_CTF_ROLE_OFFENSE: - LOG_TRACE("offense"); + s = "offense"; bot.havocbot_role = havocbot_role_ctf_offense; bot.havocbot_role_timeout = 0; break; case HAVOCBOT_CTF_ROLE_RETRIEVER: - LOG_TRACE("retriever"); + s = "retriever"; bot.havocbot_previous_role = bot.havocbot_role; bot.havocbot_role = havocbot_role_ctf_retriever; bot.havocbot_role_timeout = time + 10; bot.bot_strategytime = 0; break; case HAVOCBOT_CTF_ROLE_ESCORT: - LOG_TRACE("escort"); + s = "escort"; bot.havocbot_previous_role = bot.havocbot_role; bot.havocbot_role = havocbot_role_ctf_escort; bot.havocbot_role_timeout = time + 30; bot.bot_strategytime = 0; break; } - LOG_TRACE("\n"); + LOG_TRACE(bot.netname, " switched to ", s); } @@ -1987,7 +2034,7 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink) | 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); + | CTF_FLAG_NEUTRAL | CTF_SHIELDED | CTF_STALEMATE); // scan through all the flags and notify the client about them for(entity flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext) @@ -2021,6 +2068,9 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink) if(player.ctf_captureshielded) player.ctf_flagstatus |= CTF_SHIELDED; + if(ctf_stalemate) + player.ctf_flagstatus |= CTF_STALEMATE; + // update the health of the flag carrier waypointsprite if(player.wps_flagcarrier) WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)); @@ -2275,7 +2325,7 @@ MUTATOR_HOOKFUNCTION(ctf, AbortSpeedrun) if(player.flagcarried) { - Send_Notification(NOTIF_ALL, NULL, MSG_INFO, ((player.flagcarried.team) ? APP_TEAM_ENT(player.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL)); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_NUM(player.flagcarried.team, INFO_CTF_FLAGRETURN_ABORTRUN)); ctf_RespawnFlag(player.flagcarried); return true; } @@ -2293,7 +2343,7 @@ MUTATOR_HOOKFUNCTION(ctf, MatchEnd) case FLAG_PASSING: { // lock the flag, game is over - flag.movetype = MOVETYPE_NONE; + set_movetype(flag, MOVETYPE_NONE); flag.takedamage = DAMAGE_NO; flag.solid = SOLID_NOT; flag.nextthink = false; // stop thinking @@ -2321,7 +2371,7 @@ MUTATOR_HOOKFUNCTION(ctf, HavocBot_ChooseRole) return true; } -MUTATOR_HOOKFUNCTION(ctf, GetTeamCount) +MUTATOR_HOOKFUNCTION(ctf, CheckAllowedTeams) { //M_ARGV(0, float) = ctf_teams; M_ARGV(1, string) = "ctf_team"; @@ -2407,7 +2457,7 @@ MUTATOR_HOOKFUNCTION(ctf, SV_ParseClientCommand) MUTATOR_HOOKFUNCTION(ctf, DropSpecialItems) { entity frag_target = M_ARGV(0, entity); - + if(frag_target.flagcarried) ctf_Handle_Throw(frag_target, NULL, DROP_THROW); } @@ -2430,7 +2480,7 @@ Keys: "noise5" sound played when flag touches the ground... */ spawnfunc(item_flag_team1) { - if(!g_ctf) { remove(this); return; } + if(!g_ctf) { delete(this); return; } ctf_FlagSetup(NUM_TEAM_1, this); } @@ -2448,7 +2498,7 @@ Keys: "noise5" sound played when flag touches the ground... */ spawnfunc(item_flag_team2) { - if(!g_ctf) { remove(this); return; } + if(!g_ctf) { delete(this); return; } ctf_FlagSetup(NUM_TEAM_2, this); } @@ -2466,7 +2516,7 @@ Keys: "noise5" sound played when flag touches the ground... */ spawnfunc(item_flag_team3) { - if(!g_ctf) { remove(this); return; } + if(!g_ctf) { delete(this); return; } ctf_FlagSetup(NUM_TEAM_3, this); } @@ -2484,7 +2534,7 @@ Keys: "noise5" sound played when flag touches the ground... */ spawnfunc(item_flag_team4) { - if(!g_ctf) { remove(this); return; } + if(!g_ctf) { delete(this); return; } ctf_FlagSetup(NUM_TEAM_4, this); } @@ -2502,8 +2552,8 @@ Keys: "noise5" sound played when flag touches the ground... */ spawnfunc(item_flag_neutral) { - if(!g_ctf) { remove(this); return; } - if(!cvar("g_ctf_oneflag")) { remove(this); return; } + if(!g_ctf) { delete(this); return; } + if(!cvar("g_ctf_oneflag")) { delete(this); return; } ctf_FlagSetup(0, this); } @@ -2516,7 +2566,7 @@ Keys: "cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */ spawnfunc(ctf_team) { - if(!g_ctf) { remove(this); return; } + if(!g_ctf) { delete(this); return; } this.classname = "ctf_team"; this.team = this.cnt + 1; @@ -2546,12 +2596,12 @@ void ctf_ScoreRules(int teams) CheckAllowedTeams(NULL); ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true); ScoreInfo_SetLabel_TeamScore (ST_CTF_CAPS, "caps", SFL_SORT_PRIO_PRIMARY); - ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS, "caps", SFL_SORT_PRIO_SECONDARY); - ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME, "captime", SFL_LOWER_IS_BETTER | SFL_TIME); - ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS, "pickups", 0); - ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS, "fckills", 0); - ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS, "returns", 0); - ScoreInfo_SetLabel_PlayerScore(SP_CTF_DROPS, "drops", SFL_LOWER_IS_BETTER); + ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS, "caps", SFL_SORT_PRIO_SECONDARY); + ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME, "captime", SFL_LOWER_IS_BETTER | SFL_TIME); + ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS, "pickups", 0); + ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS, "fckills", 0); + ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS, "returns", 0); + ScoreInfo_SetLabel_PlayerScore(SP_CTF_DROPS, "drops", SFL_LOWER_IS_BETTER); ScoreRules_basics_end(); } @@ -2597,7 +2647,7 @@ void ctf_DelayedInit(entity this) // Do this check with a delay so we can wait f // if no teams are found, spawn defaults if(find(NULL, classname, "ctf_team") == NULL) { - LOG_TRACE("No \"ctf_team\" entities found on this map, creating them anyway.\n"); + LOG_TRACE("No \"ctf_team\" entities found on this map, creating them anyway."); if(ctf_teams & BIT(0)) ctf_SpawnTeam("Red", NUM_TEAM_1); if(ctf_teams & BIT(1)) @@ -2621,5 +2671,3 @@ void ctf_Initialize() InitializeEntity(NULL, ctf_DelayedInit, INITPRIO_GAMETYPE); } - -#endif