From: Samual Date: Sun, 27 Mar 2011 18:12:01 +0000 (-0400) Subject: Bringing it closer and closer... gotta create the event handles now and wheel it... X-Git-Tag: xonotic-v0.7.0~240^2~191 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=f28a4d976c468a803d8c508ad97534bc3febf073;p=xonotic%2Fxonotic-data.pk3dir.git Bringing it closer and closer... gotta create the event handles now and wheel it together to finally make it compilable --- diff --git a/qcsrc/server/mutators/gamemode_ctf.qc b/qcsrc/server/mutators/gamemode_ctf.qc index 2988f9bc8..fa5297141 100644 --- a/qcsrc/server/mutators/gamemode_ctf.qc +++ b/qcsrc/server/mutators/gamemode_ctf.qc @@ -1,6 +1,6 @@ // ================================================================ // Official capture the flag game mode coding, reworked by Samual -// Last updated: March 25th, 2011 +// Last updated: March 27th, 2011 // ================================================================ // Flag constants @@ -33,114 +33,22 @@ float captureshield_min_negscore; // punish at -20 points float captureshield_max_ratio; // punish at most 30% of each team float captureshield_force; // push force of the shield -// =================== -// Main Flag Functions -// =================== - -float ctf_CaptureShield_CheckStatus(entity p) // check to see -{ - float s, se; - entity e; - float players_worseeq, players_total; - - if(captureshield_max_ratio <= 0) - return FALSE; - - s = PlayerScore_Add(p, SP_SCORE, 0); - if(s >= -captureshield_min_negscore) - return FALSE; - - players_total = players_worseeq = 0; - FOR_EACH_PLAYER(e) - { - if(e.team != p.team) - continue; - se = PlayerScore_Add(e, SP_SCORE, 0); - if(se <= s) - ++players_worseeq; - ++players_total; - } - - // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse - // use this rule here - - if(players_worseeq >= players_total * captureshield_max_ratio) - return FALSE; - - return TRUE; -} - -void ctf_CaptureShield_Update(entity p, float dir) -{ - float should; - if(dir == p.ctf_captureshielded) // 0: shield only, 1: unshield only - { - should = ctf_captureshield_shielded(p); - if(should != dir) - { - if(should) - { - centerprint_atprio(p, CENTERPRIO_SHIELDING, "^3You are now ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Make some defensive scores before trying again."); - // TODO csqc notifier for this - } - else - { - centerprint_atprio(p, CENTERPRIO_SHIELDING, "^3You are now free.\n\n^3Feel free to ^1try to capture^3 the flag again\n^3if you think you will succeed."); - // TODO csqc notifier for this - } - p.ctf_captureshielded = should; - } - } -} -float ctf_CaptureShield_customize() -{ - if not(other.ctf_captureshielded) - return FALSE; - if(self.team == other.team) - return FALSE; - return TRUE; -} +// declare functions so they can be used in any order in the file +void ctf_TouchEvent(void); +void ctf_FlagThink(void); +void ctf_SetupFlag(float, entity); -void ctf_CaptureShield_touch() -{ - if not(other.ctf_captureshielded) - return; - if(self.team == other.team) - return; - vector mymid; - vector othermid; - mymid = (self.absmin + self.absmax) * 0.5; - othermid = (other.absmin + other.absmax) * 0.5; - Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * captureshield_force); - centerprint_atprio(other, CENTERPRIO_SHIELDING, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again."); -} -void ctf_flag_spawnstuff() +void ctf_CreateBaseWaypoints(float teamnumber) { - entity e; - e = spawn(); - e.enemy = self; - e.team = self.team; - e.touch = ctf_captureshield_touch; - e.customizeentityforclient = ctf_captureshield_customize; - e.classname = "ctf_captureshield"; - e.effects = EF_ADDITIVE; - e.movetype = MOVETYPE_NOCLIP; - e.solid = SOLID_TRIGGER; - e.avelocity = '7 0 11'; - setorigin(e, self.origin); - setmodel(e, "models/ctf/shield.md3"); - e.scale = 0.5; - setsize(e, e.scale * e.mins, e.scale * e.maxs); - waypoint_spawnforitem_force(self, self.origin); self.nearestwaypointtimeout = 0; // activate waypointing again self.basewaypoint = self.nearestwaypoint; if(self.team == COLOR_TEAM1) { - WaypointSprite_SpawnFixed("redbase", self.origin + '0 0 61', self, sprite); + WaypointSprite_SpawnFixed(((self.team == COLOR_TEAM1) ? "redbase" : "bluebase"), self.origin + '0 0 61', self, sprite); WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_FLAG, colormapPaletteColor(COLOR_TEAM1 - 1, FALSE)); } else @@ -150,6 +58,7 @@ void ctf_flag_spawnstuff() } } + // ================== // Misc CTF functions // ================== @@ -250,13 +159,11 @@ void ctf_SetStatus() void ctf_Reset() { DropFlag(self, world, world); - - if(self.waypointsprite_attachedforcarrier) - WaypointSprite_DetachCarrier(self); ReturnFlag(self); } + // =================== // Main Flag Functions // =================== @@ -306,7 +213,7 @@ void ctf_SetupFlag(float teamnumber, entity flag) // called when spawning a flag if(!flag.noise) { flag.noise = ((teamnumber) ? "ctf/red_taken.wav" : "ctf/blue_taken.wav"); } if(!flag.noise1) { flag.noise1 = ((teamnumber) ? "ctf/red_returned.wav" : "ctf/blue_returned.wav"); } if(!flag.noise2) { flag.noise2 = ((teamnumber) ? "ctf/red_capture.wav" : "ctf/blue_capture.wav"); } // blue team scores by capturing the red flag - if(!flag.noise3) { flag.noise3 = "ctf/flag_respawn.wav"; } + if(!flag.noise3) { flag.noise3 = "ctf/flag_respawn.wav"; } // if there is ever a team-based sound for this, update the code to match. if(!flag.noise4) { flag.noise4 = ((teamnumber) ? "ctf/red_dropped.wav" : "ctf/blue_dropped.wav"); } // precache @@ -322,46 +229,34 @@ void ctf_SetupFlag(float teamnumber, entity flag) // called when spawning a flag void ctf_PlaceFlag() { - if(self.classname != "item_flag_team") - { - backtrace("PlaceFlag a non-flag"); - return; - } + if(self.classname != "item_flag_team") { backtrace("ctf_PlaceFlag was called incorrectly."); return; } setattachment(self, world, ""); - self.mdl = self.model; + self.mdl = self.model; // why? self.flags = FL_ITEM; self.solid = SOLID_TRIGGER; self.movetype = MOVETYPE_NONE; self.velocity = '0 0 0'; - self.origin_z = self.origin_z + 6; - self.think = FlagThink; - self.touch = FlagTouch; - self.nextthink = time + 0.1; + self.origin_z = self.origin_z + 6; // why 6? + self.think = ctf_FlagThink; + self.touch = ctf_TouchEvent; + self.nextthink = time + 0.1; // why? self.cnt = FLAG_BASE; self.mangle = self.angles; self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; //self.effects = self.effects | EF_DIMLIGHT; - if(self.noalign) - { - self.dropped_origin = self.origin; - } - else - { - droptofloor(); - self.movetype = MOVETYPE_TOSS; - } + + if(self.noalign) { self.dropped_origin = self.origin; } + else { droptofloor(); self.movetype = MOVETYPE_TOSS; } - InitializeEntity(self, ctf_flag_spawnstuff, INITPRIO_SETLOCATION); + ctf_CreateBaseWaypoints(); + ctf_CaptureShield_Spawn(); + //InitializeEntity(self, ctf_CaptureShield_Spawn, INITPRIO_SETLOCATION); } void ctf_RegenFlag(entity e) { - if(e.classname != "item_flag_team") - { - backtrace("RegenFlag a non-flag"); - return; - } + if(self.classname != "item_flag_team") { backtrace("ctf_RegenFlag was called incorrectly."); return; } if(e.waypointsprite_attachedforcarrier) WaypointSprite_DetachCarrier(e); @@ -384,11 +279,7 @@ void ctf_RegenFlag(entity e) void ctf_ReturnFlag(entity e) { - if(e.classname != "item_flag_team") - { - backtrace("ReturnFlag a non-flag"); - return; - } + if(e.classname != "item_flag_team") { backtrace("ctf_ReturnFlag was called incorrectly."); return; } if(e.owner) if(e.owner.flagcarried == e) @@ -403,7 +294,7 @@ void ctf_ReturnFlag(entity e) RegenFlag(e); } -void ctf_DropFlag(entity flag, entity penalty_receiver, entity attacker) +void ctf_DropEvent(entity flag, entity penalty_receiver, entity attacker) { local entity carrier = flag.owner; @@ -534,7 +425,7 @@ void ctf_FlagThink() { bprint("The ", self.netname, " has returned to base\n"); sound (self, CHAN_TRIGGER, self.noise3, VOL_BASE, ATTN_NONE); - LogCTF("returned", self.team, world); + ctf_EventLog("returned", self.team, world); ReturnFlag(self); } return; @@ -553,16 +444,17 @@ void ctf_FlagThink() DropFlag(self, e, world); } -void FlagTouch() +void ctf_TouchEvent() { - if(gameover) return; - + if(gameover) { return; } + if(!self) { return; } + local float t; local entity player; local string s, s0, h0, h1; if(other.classname != "player") return; - if(other.health < 1) // ignore dead players + if(other.health < 1) return; if(self.cnt == FLAG_CARRY) @@ -573,6 +465,9 @@ void FlagTouch() if(other.flagcarried) // he's got a flag if(other.flagcarried.team != self.team) // capture { + ctf_Handle_Capture(self, other); + + /* if(other.flagcarried == world) { return; @@ -615,7 +510,7 @@ void FlagTouch() Send_KillNotification (other.netname, other.flagcarried.netname, s, INFO_CAPTUREFLAG, MSG_INFO); PlayerTeamScore_Add(other, SP_CTF_CAPS, ST_CTF_CAPS, 1); - LogCTF("capture", other.flagcarried.team, other); + ctf_EventLog("capture", other.flagcarried.team, other); // give credit to the individual player UpdateFrags(other, ctf_score_value("score_capture")); @@ -637,14 +532,18 @@ void FlagTouch() RegenFlag (other.flagcarried); other.flagcarried = world; other.next_take_time = time + 1; + */ } if(self.cnt == FLAG_BASE) - if(other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2) // only red and blue team can steal flags + if(other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2) // only red and blue team can steal flags // todo: needed still if rogues are gone? if(other.team != self.team) if(!other.flagcarried) if(!other.ctf_captureshielded) { + ctf_Handle_Pickup(self, other); + + /* if(other.next_take_time > time) return; @@ -668,7 +567,7 @@ void FlagTouch() UpdateFrags(other, ctf_score_value("score_pickup_base")); self.ctf_dropperid = other.playerid; PlayerScore_Add(other, SP_CTF_PICKUPS, 1); - LogCTF("steal", self.team, other); + ctf_EventLog("steal", self.team, other); sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NONE); FOR_EACH_PLAYER(player) @@ -683,6 +582,7 @@ void FlagTouch() WaypointSprite_Ping(self.sprite); return; + */ } if(self.cnt == FLAG_DROPPED) @@ -724,7 +624,7 @@ void FlagTouch() UpdateFrags(other, ctf_score_value("score_return_rogue")); } PlayerScore_Add(other, SP_CTF_RETURNS, 1); - LogCTF("return", self.team, other); + ctf_EventLog("return", self.team, other); sound (other, CHAN_AUTO, self.noise1, VOL_BASE, ATTN_NONE); ReturnFlag(self); } @@ -756,7 +656,7 @@ void FlagTouch() UpdateFrags(other, f); PlayerScore_Add(other, SP_CTF_PICKUPS, 1); - LogCTF("pickup", self.team, other); + ctf_EventLog("pickup", self.team, other); sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NONE); FOR_EACH_PLAYER(player) @@ -775,6 +675,115 @@ void FlagTouch() } +// ======================= +// CaptureShield Functions +// ======================= + +float ctf_CaptureShield_CheckStatus(entity p) // check to see +{ + float s, se; + entity e; + float players_worseeq, players_total; + + if(captureshield_max_ratio <= 0) + return FALSE; + + s = PlayerScore_Add(p, SP_SCORE, 0); + if(s >= -captureshield_min_negscore) + return FALSE; + + players_total = players_worseeq = 0; + FOR_EACH_PLAYER(e) + { + if(e.team != p.team) + continue; + se = PlayerScore_Add(e, SP_SCORE, 0); + if(se <= s) + ++players_worseeq; + ++players_total; + } + + // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse + // use this rule here + + if(players_worseeq >= players_total * captureshield_max_ratio) + return FALSE; + + return TRUE; +} + +void ctf_CaptureShield_Update(entity p, float dir) +{ + float should; + if(dir == p.ctf_captureshielded) // 0: shield only, 1: unshield only + { + should = ctf_CaptureShield_CheckStatus(p); + if(should != dir) + { + if(should) // TODO csqc notifier for this + centerprint_atprio(p, CENTERPRIO_SHIELDING, "^3You are now ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Make some defensive scores before trying again."); + else + centerprint_atprio(p, CENTERPRIO_SHIELDING, "^3You are now free.\n\n^3Feel free to ^1try to capture^3 the flag again\n^3if you think you will succeed."); + + p.ctf_captureshielded = should; + } + } +} + +float ctf_CaptureShield_Customize() +{ + if not(other.ctf_captureshielded) + return FALSE; + if(self.team == other.team) + return FALSE; + return TRUE; +} + +void ctf_CaptureShield_Touch() +{ + if not(other.ctf_captureshielded) + return; + if(self.team == other.team) + return; + vector mymid; + vector othermid; + mymid = (self.absmin + self.absmax) * 0.5; + othermid = (other.absmin + other.absmax) * 0.5; + Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * captureshield_force); + centerprint_atprio(other, CENTERPRIO_SHIELDING, "^3You are ^4shielded^3 from the flag\n^3for ^1too many unsuccessful attempts^3 to capture.\n\n^3Get some defensive scores before trying again."); +} + +void ctf_CaptureShield_Spawn() +{ + entity e; + e = spawn(); + e.enemy = self; + e.team = self.team; + e.touch = ctf_CaptureShield_Touch; + e.customizeentityforclient = ctf_CaptureShield_Customize; + e.classname = "ctf_captureshield"; + e.effects = EF_ADDITIVE; + e.movetype = MOVETYPE_NOCLIP; + e.solid = SOLID_TRIGGER; + e.avelocity = '7 0 11'; + setorigin(e, self.origin); + setmodel(e, "models/ctf/shield.md3"); + e.scale = 0.5; + setsize(e, e.scale * e.mins, e.scale * e.maxs); +} + + +// ============== +// Hook Functions +// ============== + +MUTATOR_HOOKFUNCTION(ctf_RemovePlayer) +{ + if(self.flagcarried) { ctf_DropEvent(self); } // figure this out + + return TRUE; +} + // ========== // Spawnfuncs @@ -792,7 +801,7 @@ void spawnfunc_info_player_team1() } -/*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24) +/*QUAKED spawnfunc_info_player_team2 (1 0 0) (-16 -16 -24) (16 16 24) CTF Starting point for a player in team two (Blue). Keys: "angle" viewing angle when spawning. */ void spawnfunc_info_player_team2() @@ -803,7 +812,7 @@ void spawnfunc_info_player_team2() spawnfunc_info_player_deathmatch(); } -/*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24) +/*QUAKED spawnfunc_info_player_team3 (1 0 0) (-16 -16 -24) (16 16 24) CTF Starting point for a player in team three (Yellow). Keys: "angle" viewing angle when spawning. */ void spawnfunc_info_player_team3() @@ -815,7 +824,7 @@ void spawnfunc_info_player_team3() } -/*QUAKED spawnfunc_info_player_team1 (1 0 0) (-16 -16 -24) (16 16 24) +/*QUAKED spawnfunc_info_player_team4 (1 0 0) (-16 -16 -24) (16 16 24) CTF Starting point for a player in team four (Purple). Keys: "angle" viewing angle when spawning. */ void spawnfunc_info_player_team4() @@ -842,7 +851,7 @@ void spawnfunc_item_flag_team1() ctf_SetupFlag(1, self); } -/*QUAKED spawnfunc_item_flag_team1 (0 0.5 0.8) (-48 -48 -37) (48 48 37) +/*QUAKED spawnfunc_item_flag_team2 (0 0.5 0.8) (-48 -48 -37) (48 48 37) CTF flag for team two (Blue). Multiple flags are allowed. Keys: "angle" Angle the flag will point (minus 90 degrees)... @@ -872,6 +881,7 @@ void spawnfunc_ctf_team() self.team = self.cnt + 1; } + // ============== // Initialization // ============== @@ -921,7 +931,7 @@ MUTATOR_DEFINITION(gamemode_ctf) { MUTATOR_HOOK(MakePlayerObserver, ctf_RemovePlayer, CBC_ORDER_ANY); MUTATOR_HOOK(ClientDisconnect, ctf_RemovePlayer, CBC_ORDER_ANY); - MUTATOR_HOOK(PlayerDies, ctf_Scoring, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerDies, ctf_RemovePlayer, CBC_ORDER_ANY); //MUTATOR_HOOK(GiveFragsForKill, ctf_GiveFragsForKill, CBC_ORDER_ANY); //MUTATOR_HOOK(PlayerPreThink, ctf_PlayerPreThink, CBC_ORDER_ANY); //MUTATOR_HOOK(PlayerDamage_Calculate, ctf_PlayerDamage, CBC_ORDER_ANY);