X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fgamemodes%2Fgamemode%2Fkeepaway%2Fsv_keepaway.qc;h=0066af45156cd820fe160513edf5d5b01b3d6f36;hb=969dc49d01d650a812706aba16c765af488605d0;hp=133050b0005a483caefb27bc281dd9e55a84d9f3;hpb=5b47b78775c2559fc9b4f0f643a2625c48c410d4;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/gamemodes/gamemode/keepaway/sv_keepaway.qc b/qcsrc/common/gamemodes/gamemode/keepaway/sv_keepaway.qc index 133050b00..0066af451 100644 --- a/qcsrc/common/gamemodes/gamemode/keepaway/sv_keepaway.qc +++ b/qcsrc/common/gamemodes/gamemode/keepaway/sv_keepaway.qc @@ -1,6 +1,8 @@ #include "sv_keepaway.qh" #include +#include +#include .entity ballcarried; @@ -62,7 +64,7 @@ void ka_RespawnBall(entity this) // runs whenever the ball needs to be relocated settouch(this, ka_TouchEvent); setthink(this, ka_RespawnBall); this.nextthink = time + autocvar_g_keepawayball_respawntime; - navigation_dynamicgoal_set(this); + navigation_dynamicgoal_set(this, NULL); Send_Effect(EFFECT_ELECTRO_COMBO, oldballorigin, '0 0 0', 1); Send_Effect(EFFECT_ELECTRO_COMBO, this.origin, '0 0 0', 1); @@ -87,8 +89,9 @@ void ka_TimeScoring(entity this) void ka_TouchEvent(entity this, entity toucher) // runs any time that the ball comes in contact with something { - if(game_stopped) return; - if(!this) return; + if (!this || game_stopped) + return; + if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) { // The ball fell off the map, respawn it since players can't get to it ka_RespawnBall(this); @@ -144,6 +147,17 @@ void ka_TouchEvent(entity this, entity toucher) // runs any time that the ball c WaypointSprite_Kill(this.waypointsprite_attachedforcarrier); } +void ka_PlayerReset(entity plyr) +{ + plyr.ballcarried = NULL; + GameRules_scoring_vip(plyr, false); + WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier); + + // reset the player effects + plyr.glow_trail = false; + plyr.effects &= ~autocvar_g_keepaway_ballcarrier_effects; +} + void ka_DropEvent(entity plyr) // runs any time that a player is supposed to lose the ball { entity ball; @@ -162,14 +176,8 @@ void ka_DropEvent(entity plyr) // runs any time that a player is supposed to los ball.effects &= ~EF_NODRAW; setorigin(ball, plyr.origin + '0 0 10'); ball.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom(); - entity e = ball.owner; ball.owner = NULL; - e.ballcarried = NULL; - GameRules_scoring_vip(e, false); - navigation_dynamicgoal_set(ball); - - // reset the player effects - plyr.glow_trail = false; - plyr.effects &= ~autocvar_g_keepaway_ballcarrier_effects; + ball.owner = NULL; + navigation_dynamicgoal_set(ball, plyr); // messages and sounds ka_EventLog("dropped", plyr); @@ -177,30 +185,72 @@ void ka_DropEvent(entity plyr) // runs any time that a player is supposed to los Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_KEEPAWAY_DROPPED, plyr.netname); sound(NULL, CH_TRIGGER, SND_KA_DROPPED, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere) - // scoring - // GameRules_scoring_add(plyr, KEEPAWAY_DROPS, 1); Not anymore, this is 100% the same as pickups and is useless. - // waypoints WaypointSprite_Spawn(WP_KaBall, 0, 0, ball, '0 0 64', NULL, ball.team, ball, waypointsprite_attachedforcarrier, false, RADARICON_FLAGCARRIER); WaypointSprite_UpdateRule(ball.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); WaypointSprite_Ping(ball.waypointsprite_attachedforcarrier); - WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier); + + ka_PlayerReset(plyr); } -/** used to clear the ballcarrier whenever the match switches from warmup to normal */ -void ka_Reset(entity this) +.bool pushable; + +MODEL(KA_BALL, "models/orbs/orbblue.md3"); + +void ka_RemoveBall() { - if((this.owner) && (IS_PLAYER(this.owner))) - ka_DropEvent(this.owner); + entity plyr = ka_ball.owner; + if (plyr) // it was attached + ka_PlayerReset(plyr); + else + WaypointSprite_DetachCarrier(ka_ball); + delete(ka_ball); + ka_ball = NULL; +} +void ka_SpawnBall() +{ + entity e = new(keepawayball); + setmodel(e, MDL_KA_BALL); + setsize(e, '-16 -16 -20', '16 16 20'); // 20 20 20 was too big, player is only 16 16 24... gotta cheat with the Z (20) axis so that the particle isn't cut off + e.damageforcescale = autocvar_g_keepawayball_damageforcescale; + e.takedamage = DAMAGE_YES; + e.solid = SOLID_TRIGGER; + set_movetype(e, MOVETYPE_BOUNCE); + e.glow_color = autocvar_g_keepawayball_trail_color; + e.glow_trail = true; + e.flags = FL_ITEM; + IL_PUSH(g_items, e); + e.pushable = true; + settouch(e, ka_TouchEvent); + e.owner = NULL; + ka_ball = e; + navigation_dynamicgoal_init(ka_ball, false); + + InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So. +} + +void ka_Handler_CheckBall(entity this) +{ if(time < game_starttime) { - setthink(this, ka_RespawnBall); - settouch(this, func_null); - this.nextthink = game_starttime; + if (ka_ball) + ka_RemoveBall(); } else - ka_RespawnBall(this); + { + if (!ka_ball) + ka_SpawnBall(); + } + + this.nextthink = time; +} + +void ka_Initialize() // run at the start of a match, initiates game mode +{ + ka_Handler = new(ka_Handler); + setthink(ka_Handler, ka_Handler_CheckBall); + ka_Handler.nextthink = time; } @@ -210,20 +260,15 @@ void ka_Reset(entity this) void havocbot_goalrating_ball(entity this, float ratingscale, vector org) { - float t; entity ball_owner; ball_owner = ka_ball.owner; if (ball_owner == this) return; - // If ball is carried by player then hunt them down. if (ball_owner) - { - t = (GetResourceAmount(this, RESOURCE_HEALTH) + GetResourceAmount(this, RESOURCE_ARMOR)) / (GetResourceAmount(ball_owner, RESOURCE_HEALTH) + GetResourceAmount(ball_owner, RESOURCE_ARMOR)); - navigation_routerating(this, ball_owner, t * ratingscale, 2000); - } - else // Ball has been dropped so collect. + navigation_routerating(this, ball_owner, ratingscale, 2000); + else navigation_routerating(this, ka_ball, ratingscale, 2000); } @@ -236,7 +281,7 @@ void havocbot_role_ka_carrier(entity this) { navigation_goalrating_start(this); havocbot_goalrating_items(this, 10000, this.origin, 10000); - havocbot_goalrating_enemyplayers(this, 20000, this.origin, 10000); + havocbot_goalrating_enemyplayers(this, 10000, this.origin, 10000); havocbot_goalrating_waypoints(this, 1, this.origin, 3000); navigation_goalrating_end(this); @@ -259,8 +304,8 @@ void havocbot_role_ka_collector(entity this) { navigation_goalrating_start(this); havocbot_goalrating_items(this, 10000, this.origin, 10000); - havocbot_goalrating_enemyplayers(this, 1000, this.origin, 10000); - havocbot_goalrating_ball(this, 20000, this.origin); + havocbot_goalrating_enemyplayers(this, 500, this.origin, 10000); + havocbot_goalrating_ball(this, 8000, this.origin); navigation_goalrating_end(this); navigation_goalrating_timeout_set(this); @@ -307,6 +352,12 @@ MUTATOR_HOOKFUNCTION(ka, GiveFragsForKill) return true; // you deceptive little bugger ;3 This needs to be true in order for this function to even count. } +MUTATOR_HOOKFUNCTION(ka, Scores_CountFragsRemaining) +{ + // announce remaining frags, but only when timed scoring is off + return !autocvar_g_keepaway_score_timepoints; +} + MUTATOR_HOOKFUNCTION(ka, PlayerPreThink) { entity player = M_ARGV(0, entity); @@ -351,7 +402,7 @@ MUTATOR_HOOKFUNCTION(ka, Damage_Calculate) // for changing damage and force valu frag_force *= autocvar_g_keepaway_ballcarrier_force; } } - else if (!frag_target.ballcarried) // if the target is a noncarrier + else if (IS_PLAYER(frag_attacker) && !frag_target.ballcarried) // if the target is a noncarrier { if(frag_target == frag_attacker) // damage done to yourself { @@ -434,39 +485,3 @@ MUTATOR_HOOKFUNCTION(ka, DropSpecialItems) if(frag_target.ballcarried) ka_DropEvent(frag_target); } - -.bool pushable; - -// ============== -// Initialization -// ============== - -MODEL(KA_BALL, "models/orbs/orbblue.md3"); - -void ka_SpawnBall() // loads various values for the ball, runs only once at start of match -{ - entity e = new(keepawayball); - setmodel(e, MDL_KA_BALL); - setsize(e, '-16 -16 -20', '16 16 20'); // 20 20 20 was too big, player is only 16 16 24... gotta cheat with the Z (20) axis so that the particle isn't cut off - e.damageforcescale = autocvar_g_keepawayball_damageforcescale; - e.takedamage = DAMAGE_YES; - e.solid = SOLID_TRIGGER; - set_movetype(e, MOVETYPE_BOUNCE); - e.glow_color = autocvar_g_keepawayball_trail_color; - e.glow_trail = true; - e.flags = FL_ITEM; - IL_PUSH(g_items, e); - e.pushable = true; - e.reset = ka_Reset; - settouch(e, ka_TouchEvent); - e.owner = NULL; - ka_ball = e; - navigation_dynamicgoal_init(ka_ball, false); - - InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So. -} - -void ka_Initialize() // run at the start of a match, initiates game mode -{ - ka_SpawnBall(); -}