// keepaway
set g_keepaway 0 "game mode which focuses around a ball, look at g_keepaway_win_mode for further details"
-set g_keepaway_bckillscore 0 "enable scoring points (y/n) for ball carrier kills"
-set g_keepaway_pointlimit -1 "total amount of points you can get, -1 for unlimited"
-set g_keepaway_pointleadlimit -1 "mercy rule, -1 for unlimited"
-set g_keepaway_ballcarrier_alpha 0.6 "alpha when the player is the ballcarrier"
-set g_keepaway_ballcarrier_highspeed 1.5 "speed multiplier done to the person holding the ball"
+set g_keepaway_score_bckill 1 "enable scoring points (y/n) for ball carrier kills (value is how many points to award)"
+set g_keepaway_score_killac 1 "amount of points to give when you kill someone while you have the ball"
+set g_keepaway_score_timeinterval 1 "amount of time it takes between intervals for timepoints to be added to the score"
+set g_keepaway_score_timepoints 0 "points to add to score per timeinterval, 0 for no points"
+set g_keepaway_ballcarrier_effects 40 "Add together the numbers you want: EF_ADDITIVE (32) / EF_NODEPTHTEST (8192) / EF_DIMLIGHT (8)"
+set g_keepaway_ballcarrier_highspeed 1 "speed multiplier done to the person holding the ball (recommended when used with some mutators)"
set g_keepaway_ballcarrier_damage 1.5 "damage multiplier while holding the ball"
set g_keepaway_ballcarrier_force 1.5 "force multiplier while holding the ball"
set g_keepaway_ballcarrier_selfdamage 1 "self damage multiplier while holding the ball"
set g_keepaway_ballcarrier_selfforce 1.5 "self force multiplier while holding the ball"
-set g_keepaway_noncarrier_warn 0 "warn players when they kill without holding the ball"
+set g_keepaway_noncarrier_warn 1 "warn players when they kill without holding the ball"
set g_keepaway_noncarrier_damage 0.5 "damage done to other players if both you and they don't have the ball"
set g_keepaway_noncarrier_force 0.5 "force done to other players if both you and they don't have the ball"
set g_keepaway_noncarrier_selfdamage 1 "self damage if you don't have the ball"
set g_keepaway_noncarrier_selfforce 1 "self force if you don't have the ball"
+set g_keepawayball_effects 0 "Add together the numbers you want: EF_ADDITIVE (32) / EF_NODEPTHTEST (8192) / EF_DIMLIGHT (8)"
set g_keepawayball_trail_color 254 "particle trail color from player/ball"
-set g_keepawayball_damageforcescale 2 "Scale of force which is applied to the ball by weapons/explosions/etc"
-set g_keepawayball_respawntime 15 "if no one picks up the ball, how long to wait until the ball respawns"
+set g_keepawayball_damageforcescale 4 "Scale of force which is applied to the ball by weapons/explosions/etc"
+set g_keepawayball_respawntime 10 "if no one picks up the ball, how long to wait until the ball respawns"
seta g_keepaway_teams_override 0
set g_keepaway_teams 0
void ka_TouchEvent(void);
void ka_RespawnBall(void);
void ka_DropEvent(entity);
+void ka_TimeScoring(void);
float ka_ballcarrier_waypointsprite_visible_for_player(entity);
entity e;
e = spawn();
e.model = "models/orbs/orbblue.md3";
- e.scale = 1;
precache_model(e.model);
setmodel(e, e.model);
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.classname = "keepawayball";
e.damageforcescale = autocvar_g_keepawayball_damageforcescale;
e.takedamage = DAMAGE_YES;
+ e.solid = SOLID_TRIGGER;
+ e.movetype = MOVETYPE_BOUNCE;
e.glow_color = autocvar_g_keepawayball_trail_color;
e.glow_trail = TRUE;
- e.movetype = MOVETYPE_BOUNCE;
- e.touch = ka_TouchEvent;
e.flags = FL_ITEM;
e.reset = ka_Reset;
+ e.touch = ka_TouchEvent;
e.owner = world;
InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So.
void ka_RespawnBall() // runs whenever the ball needs to be relocated
{
+ if(gameover) { return; }
vector oldballorigin = self.origin;
-
+
if(MoveToRandomMapLocation(self, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
{
makevectors(self.angles);
self.movetype = MOVETYPE_BOUNCE;
self.velocity = '0 0 200';
self.angles = '0 0 0';
- self.solid = SOLID_TRIGGER;
+ self.effects = autocvar_g_keepawayball_effects;
self.think = ka_RespawnBall;
self.nextthink = time + autocvar_g_keepawayball_respawntime;
void ka_TouchEvent() // runs any time that the ball comes in contact with something
{
+ if(gameover) { return; }
if(!self) { return; }
if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
{ // The ball fell off the map, respawn it since players can't get to it
self.owner = other;
other.ballcarried = self;
setattachment(self, other, "");
- setorigin(self, '3 0 20'); // wtf why is this not '0 0 0' ?
+ setorigin(self, '0 0 0');
- // make the ball invisible/unable to do anything
+ // make the ball invisible/unable to do anything/set up time scoring
self.velocity = '0 0 0';
self.movetype = MOVETYPE_NONE;
- self.touch = SUB_Null;
self.effects |= EF_NODRAW;
- self.think = SUB_Null;
- self.nextthink = 0;
+ self.touch = SUB_Null;
+ self.think = ka_TimeScoring;
+ self.nextthink = time + autocvar_g_keepaway_score_timeinterval;
self.takedamage = DAMAGE_NO;
// apply effects to player
other.glow_color = autocvar_g_keepawayball_trail_color;
other.glow_trail = TRUE;
- other.effects |= EF_DIMLIGHT;
- other.alpha = autocvar_g_keepaway_ballcarrier_alpha;
- other.exteriorweaponentity.alpha = autocvar_g_keepaway_ballcarrier_alpha;
-
+ other.effects |= autocvar_g_keepaway_ballcarrier_effects;
+
// messages and sounds
Send_KillNotification(other.netname, "", "", KA_PICKUPBALL, MSG_KA);
WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
// reset the ball
setattachment(ball, world, "");
ball.movetype = MOVETYPE_BOUNCE;
- ball.solid = SOLID_TRIGGER; // is this needed?
ball.wait = time + 1;
+ ball.touch = ka_TouchEvent;
ball.think = ka_RespawnBall;
ball.nextthink = time + autocvar_g_keepawayball_respawntime;
- ball.touch = ka_TouchEvent;
ball.takedamage = DAMAGE_YES;
ball.effects &~= EF_NODRAW;
setorigin(ball, plyr.origin + '0 0 10');
// reset the player effects
plyr.glow_trail = FALSE;
- plyr.effects &~= EF_DIMLIGHT;
- plyr.alpha = default_player_alpha;
- plyr.exteriorweaponentity.alpha = default_weapon_alpha;
-
+ plyr.effects &~= autocvar_g_keepaway_ballcarrier_effects;
+
// messages and sounds
Send_KillNotification(plyr.netname, "", "", KA_DROPBALL, MSG_KA);
WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
return TRUE;
}
-MUTATOR_HOOKFUNCTION(ka_RemovePlayer)
+void ka_TimeScoring()
{
- if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has left the match, drop it
- return 0;
+ if(self.owner.ballcarried)
+ { // add points for holding the ball after a certain amount of time
+ if(autocvar_g_keepaway_score_timepoints)
+ PlayerScore_Add(self.owner, SP_SCORE, autocvar_g_keepaway_score_timepoints);
+
+ PlayerScore_Add(self.owner, SP_KEEPAWAY_TIME, (autocvar_g_keepaway_score_timeinterval / 1)); // interval is divided by 1 so that time always shows "seconds"
+ self.nextthink = time + autocvar_g_keepaway_score_timeinterval;
+ }
}
MUTATOR_HOOKFUNCTION(ka_Scoring)
{
if(frag_target.ballcarried) { // add to amount of times killing carrier
PlayerScore_Add(frag_attacker, SP_KEEPAWAY_CARRIERKILLS, 1);
- if(autocvar_g_keepaway_bckillscore) // add bckills to the score
- PlayerScore_Add(frag_attacker, SP_KEEPAWAY_SCORE, 1);
+ if(autocvar_g_keepaway_score_bckill) // add bckills to the score
+ PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_bckill);
}
else if(!frag_attacker.ballcarried)
if(autocvar_g_keepaway_noncarrier_warn)
centerprint_atprio(frag_attacker, (CENTERPRIO_SPAM + 5), "Killing people while you don't have the ball gives no points!");
if(frag_attacker.ballcarried) // add to amount of kills while ballcarrier
- PlayerScore_Add(frag_attacker, SP_KEEPAWAY_SCORE, 1);
+ PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_killac);
}
if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has died, drop it
MUTATOR_HOOKFUNCTION(ka_GiveFragsForKill)
{
frag_score = 0; // no frags counted in keepaway
- return 0;
+ return 1; // you deceptive little bugger ;3 This needs to be true in order for this function to even count.
}
MUTATOR_HOOKFUNCTION(ka_PlayerPreThink)
return 0;
}
+MUTATOR_HOOKFUNCTION(ka_RemovePlayer)
+{
+ if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has left the match, drop it
+ return 0;
+}
+
MUTATOR_HOOKFUNCTION(ka_PlayerPowerups)
{
- // right now this hook doesn't make much sense (It's actually useless this way except for minstagib invisibility alpha)
- // but in the future it's supposed to allow me to do some extra stuff with waypointsprites and invisibility powerup
+ // In the future this hook is supposed to allow me to do some extra stuff with waypointsprites and invisibility powerup
// So bare with me until I can fix a certain bug with ka_ballcarrier_waypointsprite_visible_for_player()
- // also note that this structure makes no sense (Rather there is a better way to do it) the way it's currently applied
- // again just bare with me as this is for a future feature.
+ self.effects &~= autocvar_g_keepaway_ballcarrier_effects;
if(self.ballcarried)
- {
- // force the default ballcarrier alpha on the player if they have the ball
- self.alpha = autocvar_g_keepaway_ballcarrier_alpha;
- self.exteriorweaponentity.alpha = autocvar_g_keepaway_ballcarrier_alpha;
-
- if(g_minstagib)
- {
- if(olditems & IT_STRENGTH)
- { // if the player has the ball and they also have the invisibility powerup, apply alpha accordingly
- self.alpha = g_minstagib_invis_alpha;
- self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
- }
- }
- }
- else if(g_minstagib)
- {
- // if we're in minstagib and a noncarrier has invisibility, assure that we apply the invisibility effects normally
- if(olditems & IT_STRENGTH)
- {
- self.alpha = g_minstagib_invis_alpha;
- self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
- }
- }
- else
- {
- // if we're a normal player with no powerups that edit alpha make sure the alpha is default.
- // (normal powerups just use EF_ADDITIVE)
- self.alpha = default_player_alpha;
- self.exteriorweaponentity.alpha = default_weapon_alpha;
- }
+ self.effects |= autocvar_g_keepaway_ballcarrier_effects;
return 0;
}
MUTATOR_DEFINITION(gamemode_keepaway)
{
- // I don't quite understand these orders, perhaps someone could enlighten me?
MUTATOR_HOOK(MakePlayerObserver, ka_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientDisconnect, ka_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDies, ka_Scoring, CBC_ORDER_ANY);
MUTATOR_HOOK(GiveFragsForKill, ka_GiveFragsForKill, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerPreThink, ka_PlayerPreThink, CBC_ORDER_FIRST);
+ MUTATOR_HOOK(PlayerPreThink, ka_PlayerPreThink, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDamage_Calculate, ka_PlayerDamage, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPowerups, ka_PlayerPowerups, CBC_ORDER_ANY);