-void ka_SpawnBall(void);
-void ka_TouchEvent(void);
-void ka_RespawnBall(void);
-void ka_DropEvent(entity);
-void ka_TimeScoring(void);
-void ka_EventLog(string, entity);
+// ===========================================================
+// Keepaway game mode coding, written by Samual and Diabolik
+// Last updated: September, 2012
+// ===========================================================
-entity ka_ball;
-
-float ka_ballcarrier_waypointsprite_visible_for_player(entity);
-
-void ka_Initialize() // run at the start of a match, initiates game mode
+float ka_ballcarrier_waypointsprite_visible_for_player(entity e) // runs on waypoints which are attached to ballcarriers, updates once per frame
{
- if(!g_keepaway)
- return;
+ if(e.ballcarried)
+ if(other.classname == "spectator")
+ return FALSE; // we don't want spectators of the ballcarrier to see the attached waypoint on the top of their screen
- precache_sound("keepaway/pickedup.wav");
- precache_sound("keepaway/dropped.wav");
- precache_sound("keepaway/respawn.wav");
- precache_sound("keepaway/touch.wav");
-
- ScoreRules_keepaway();
- ka_SpawnBall();
-}
-
-void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
-{
- if(self.owner)
- if(self.owner.classname == "player")
- ka_DropEvent(self.owner);
+ // TODO: Make the ballcarrier lack a waypointsprite whenever they have the invisibility powerup
- ka_RespawnBall();
+ return TRUE;
}
-void ka_SpawnBall() // loads various values for the ball, runs only once at start of match
+void ka_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
{
- if(!g_keepaway) { return; }
-
- entity e;
- e = spawn();
- e.model = "models/orbs/orbblue.md3";
- 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.flags = FL_ITEM;
- e.reset = ka_Reset;
- e.touch = ka_TouchEvent;
- e.owner = world;
- ka_ball = e;
-
- InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So.
+ if(autocvar_sv_eventlog)
+ GameLogEcho(strcat(":ka:", mode, ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
}
void ka_RespawnBall() // runs whenever the ball needs to be relocated
}
}
+void ka_TimeScoring()
+{
+ 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_BCTIME, (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;
+ }
+}
+
void ka_TouchEvent() // runs any time that the ball comes in contact with something
{
if(gameover) { return; }
WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier);
}
-float ka_ballcarrier_waypointsprite_visible_for_player(entity e) // runs on waypoints which are attached to ballcarriers, updates once per frame
+void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
{
- if(e.ballcarried)
- if(other.classname == "spectator")
- return FALSE; // we don't want spectators of the ballcarrier to see the attached waypoint on the top of their screen
-
- // TODO: Make the ballcarrier lack a waypointsprite whenever they have the invisibility powerup
+ if((self.owner) && (self.owner.classname == "player"))
+ ka_DropEvent(self.owner);
- return TRUE;
+ ka_RespawnBall();
}
-void ka_TimeScoring()
-{
- 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_BCTIME, (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;
- }
-}
-void ka_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
-{
- if(autocvar_sv_eventlog)
- GameLogEcho(strcat(":ka:", mode, ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
-}
+// ==============
+// Hook Functions
+// ==============
MUTATOR_HOOKFUNCTION(ka_Scoring)
{
return 0;
}
+
+// ==============
+// Initialization
+// ==============
+
+void ka_SpawnBall() // loads various values for the ball, runs only once at start of match
+{
+ if(!g_keepaway) { return; }
+
+ entity e;
+ e = spawn();
+ e.model = "models/orbs/orbblue.md3";
+ 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.flags = FL_ITEM;
+ e.reset = ka_Reset;
+ e.touch = ka_TouchEvent;
+ e.owner = world;
+ ka_ball = e;
+
+ InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So.
+}
+
+void ka_ScoreRules()
+{
+ ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, 0, TRUE); // SFL_SORT_PRIO_PRIMARY
+ ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_PICKUPS, "pickups", 0);
+ ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_CARRIERKILLS, "bckills", 0);
+ ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_BCTIME, "bctime", SFL_SORT_PRIO_SECONDARY);
+ ScoreRules_basics_end();
+}
+
+void ka_Initialize() // run at the start of a match, initiates game mode
+{
+ if(!g_keepaway)
+ return;
+
+ precache_sound("keepaway/pickedup.wav");
+ precache_sound("keepaway/dropped.wav");
+ precache_sound("keepaway/respawn.wav");
+ precache_sound("keepaway/touch.wav");
+
+ ka_ScoreRules();
+ ka_SpawnBall();
+}
+
+
MUTATOR_DEFINITION(gamemode_keepaway)
{
MUTATOR_HOOK(MakePlayerObserver, ka_RemovePlayer, CBC_ORDER_ANY);