X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fgamemodes%2Fgamemode%2Fctf%2Fsv_ctf.qc;h=ec296a9c9cec51484a6c66e97c4e091928ca36f9;hb=258867c634125e1d048869b4a5d8ef279e8b8228;hp=939c70e29ea858597260439a21ea3db98c19f78c;hpb=5f22a2a699389fbdff74a80d48559f52106999fa;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc b/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc index 939c70e29..ec296a9c9 100644 --- a/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc +++ b/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc @@ -1,7 +1,16 @@ #include "sv_ctf.qh" #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -48,6 +57,8 @@ bool 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; +bool autocvar_g_ctf_flag_waypoint = true; +float autocvar_g_ctf_flag_waypoint_maxdistance; float autocvar_g_ctf_flagcarrier_auto_helpme_damage; float autocvar_g_ctf_flagcarrier_auto_helpme_time; float autocvar_g_ctf_flagcarrier_selfdamagefactor; @@ -436,11 +447,24 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype) if(!flag) { return; } if((droptype == DROP_PASS) && !receiver) { return; } - if(flag.speedrunning) { ctf_RespawnFlag(flag); return; } + if(flag.speedrunning) + { + // ensure old waypoints are removed before resetting the flag + WaypointSprite_Kill(player.wps_flagcarrier); + + if(player.wps_enemyflagcarrier) + WaypointSprite_Kill(player.wps_enemyflagcarrier); + + if(player.wps_flagreturn) + WaypointSprite_Kill(player.wps_flagreturn); + ctf_RespawnFlag(flag); + return; + } // reset the flag setattachment(flag, NULL, ""); - setorigin(flag, player.origin + FLAG_DROP_OFFSET); + tracebox(player.origin - FLAG_DROP_OFFSET, flag.m_mins, flag.m_maxs, player.origin + FLAG_DROP_OFFSET, MOVE_NOMONSTERS, flag); + setorigin(flag, trace_endpos); flag.owner.flagcarried = NULL; GameRules_scoring_vip(flag.owner, false); flag.owner = NULL; @@ -519,10 +543,12 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype) ctf_CaptureShield_Update(player, 0); // shield player from picking up flag } +#if 0 void shockwave_spawn(string m, vector org, float sz, float t1, float t2) { return modeleffect_spawn(m, 0, 0, org, '0 0 0', '0 0 0', '0 0 0', 0, sz, 1, t1, t2); } +#endif // ============== // Event Handlers @@ -586,7 +612,9 @@ void ctf_Handle_Capture(entity flag, entity toucher, int capturetype) // effects Send_Effect_(flag.capeffect, flag.origin, '0 0 0', 1); - //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1); +#if 0 + shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1); +#endif // other if(capturetype == CAPTURE_NORMAL) @@ -1132,6 +1160,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher)) .float last_respawn; void ctf_RespawnFlag(entity flag) { + flag.watertype = CONTENT_EMPTY; // TODO: it is unclear why this workaround is needed, likely many other potential breakage points!! // check for flag respawn being called twice in a row if(flag.last_respawn > time - 0.5) { backtrace("flag respawn called twice quickly! please notify Samual about this..."); } @@ -1223,10 +1252,14 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map default: basename = WP_FlagBaseNeutral; break; } - 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); + if(autocvar_g_ctf_flag_waypoint) + { + 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'); + wp.fade_rate = autocvar_g_ctf_flag_waypoint_maxdistance; + 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); @@ -1234,7 +1267,7 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map .bool pushable; -void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc +void ctf_FlagSetup(int teamnum, entity flag) // called when spawning a flag entity on the map as a spawnfunc { // main setup flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist @@ -1242,8 +1275,8 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e setattachment(flag, NULL, ""); - flag.netname = strzone(sprintf("%s%s^7 flag", Team_ColorCode(teamnumber), Team_ColorName_Upper(teamnumber))); - flag.team = teamnumber; + flag.netname = strzone(sprintf("%s%s^7 flag", Team_ColorCode(teamnum), Team_ColorName_Upper(teamnum))); + flag.team = teamnum; flag.classname = "item_flag_team"; flag.target = "###item###"; // for finding the nearest item using findnearest flag.flags = FL_ITEM | FL_NOTARGET; @@ -1273,24 +1306,24 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e if(autocvar_g_ctf_score_ignore_fields) flag.cnt = flag.score_assist = flag.score_team_capture = flag.score_capture = flag.score_drop = flag.score_pickup = flag.score_return = 0; - string teamname = Static_Team_ColorName_Lower(teamnumber); + string teamname = Static_Team_ColorName_Lower(teamnum); // appearence if(!flag.scale) { flag.scale = FLAG_SCALE; } if(flag.skin == 0) { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); } if(flag.model == "") { flag.model = cvar_string(sprintf("g_ctf_flag_%s_model", teamname)); } - if (flag.toucheffect == "") { flag.toucheffect = EFFECT_FLAG_TOUCH(teamnumber).eent_eff_name; } - if (flag.passeffect == "") { flag.passeffect = EFFECT_PASS(teamnumber).eent_eff_name; } - if (flag.capeffect == "") { flag.capeffect = EFFECT_CAP(teamnumber).eent_eff_name; } + if (flag.toucheffect == "") { flag.toucheffect = EFFECT_FLAG_TOUCH(teamnum).eent_eff_name; } + if (flag.passeffect == "") { flag.passeffect = EFFECT_PASS(teamnum).eent_eff_name; } + if (flag.capeffect == "") { flag.capeffect = EFFECT_CAP(teamnum).eent_eff_name; } // sounds #define X(s,b) \ if(flag.s == "") flag.s = b; \ precache_sound(flag.s); - X(snd_flag_taken, strzone(SND(CTF_TAKEN(teamnumber)))) - X(snd_flag_returned, strzone(SND(CTF_RETURNED(teamnumber)))) - X(snd_flag_capture, strzone(SND(CTF_CAPTURE(teamnumber)))) - X(snd_flag_dropped, strzone(SND(CTF_DROPPED(teamnumber)))) + X(snd_flag_taken, strzone(SND(CTF_TAKEN(teamnum)))) + X(snd_flag_returned, strzone(SND(CTF_RETURNED(teamnum)))) + X(snd_flag_capture, strzone(SND(CTF_CAPTURE(teamnum)))) + X(snd_flag_dropped, strzone(SND(CTF_DROPPED(teamnum)))) X(snd_flag_respawn, strzone(SND(CTF_RESPAWN))) X(snd_flag_touch, strzone(SND(CTF_TOUCH))) X(snd_flag_pass, strzone(SND(CTF_PASS))) @@ -1308,7 +1341,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e if(autocvar_g_ctf_flag_glowtrails) { - switch(teamnumber) + switch(teamnum) { case NUM_TEAM_1: flag.glow_color = 251; break; case NUM_TEAM_2: flag.glow_color = 210; break; @@ -1324,7 +1357,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e if(autocvar_g_ctf_fullbrightflags) { flag.effects |= EF_FULLBRIGHT; } if(autocvar_g_ctf_dynamiclights) { - switch(teamnumber) + switch(teamnum) { case NUM_TEAM_1: flag.effects |= EF_RED; break; case NUM_TEAM_2: flag.effects |= EF_BLUE; break; @@ -1386,7 +1419,7 @@ void havocbot_ctf_calculate_middlepoint() // for symmetrical editing of waypoints entity f1 = ctf_worldflaglist; entity f2 = f1.ctf_worldflagnext; - float m = -(f1.origin.y - f2.origin.y) / (f1.origin.x - f2.origin.x); + float m = -(f1.origin.y - f2.origin.y) / (max(f1.origin.x - f2.origin.x, FLOAT_EPSILON)); float q = havocbot_middlepoint.y - m * havocbot_middlepoint.x; havocbot_symmetry_axis_m = m; havocbot_symmetry_axis_q = q;