From cde9cae5db84a11a8460d26a6d23bcaa02fa627d Mon Sep 17 00:00:00 2001 From: Jakob MG Date: Fri, 27 Jul 2012 01:25:55 +0200 Subject: [PATCH] Make ons a proper mutator, give it a optional, alternative spawnsystem. --- .../gamemode_onslaught.qc} | 216 ++++++++++++++++-- qcsrc/server/mutators/mutators.qh | 1 + qcsrc/server/progs.src | 3 +- qcsrc/server/teamplay.qc | 1 + 4 files changed, 195 insertions(+), 26 deletions(-) rename qcsrc/server/{mode_onslaught.qc => mutators/gamemode_onslaught.qc} (90%) diff --git a/qcsrc/server/mode_onslaught.qc b/qcsrc/server/mutators/gamemode_onslaught.qc similarity index 90% rename from qcsrc/server/mode_onslaught.qc rename to qcsrc/server/mutators/gamemode_onslaught.qc index 09888f785..87a059d72 100644 --- a/qcsrc/server/mode_onslaught.qc +++ b/qcsrc/server/mutators/gamemode_onslaught.qc @@ -1,3 +1,6 @@ +float autocvar_g_onslaught_spawn_at_controlpoints = FALSE; +float autocvar_g_onslaught_spawn_at_generator = FALSE; + void onslaught_generator_updatesprite(entity e); void onslaught_controlpoint_updatesprite(entity e); void onslaught_link_checkupdate(); @@ -17,6 +20,9 @@ void onslaught_link_checkupdate(); .float lastcaptured; .string model1, model2, model3; + +entity ons_red_generator; +entity ons_blue_generator; void ons_gib_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) { @@ -399,29 +405,29 @@ void onslaught_generator_think() if (e.islinked) d = d + 1; e = e.chain; - } + } if(autocvar_g_campaign && autocvar__campaign_testrun) d = d * self.max_health; else d = d * self.max_health / max(30, 60 * autocvar_timelimit_suddendeath); - + Damage(self, self, self, d, DEATH_HURTTRIGGER, self.origin, '0 0 0'); } else if (overtime_msg_time) - overtime_msg_time = 0; - - if(!self.isshielded && self.wait < time) - { - self.wait = time + 5; - FOR_EACH_PLAYER(e) - { - if(e.team == self.team) - { - centerprint(e, "^1Your generator is NOT shielded!\n^7Re-capture controlpoints to shield it!"); - soundto(MSG_ONE, e, CHAN_AUTO, "kh/alarm.wav", VOL_BASE, ATTN_NONE); - } - } + overtime_msg_time = 0; + + if(!self.isshielded && self.wait < time) + { + self.wait = time + 5; + FOR_EACH_PLAYER(e) + { + if(e.team == self.team) + { + centerprint(e, "^1Your generator is NOT shielded!\n^7Re-capture controlpoints to shield it!"); + soundto(MSG_ONE, e, CHAN_AUTO, "kh/alarm.wav", VOL_BASE, ATTN_NONE); // FIXME: Uniqe sound? + } + } } } } @@ -846,10 +852,10 @@ void onslaught_generator_reset() self.nextthink = time + 0.2; setmodel(self, "models/onslaught/generator.md3"); setsize(self, '-52 -52 -14', '52 52 75'); - + if (!self.noalign) droptofloor(); - + WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health); WaypointSprite_UpdateHealth(self.sprite, self.health); } @@ -900,6 +906,13 @@ void spawnfunc_onslaught_generator() precache_sound("onslaught/electricity_explode.wav"); if (!self.team) objerror("team must be set"); + + if(self.team == COLOR_TEAM1) + ons_red_generator = self; + + if(self.team == COLOR_TEAM2) + ons_blue_generator = self; + self.team_saved = self.team; self.colormap = 1024 + (self.team - 1) * 17; self.solid = SOLID_BBOX; @@ -918,7 +931,7 @@ void spawnfunc_onslaught_generator() onslaught_generator_damage_spawn(self); // spawn shield model which indicates whether this can be damaged self.enemy = spawn(); - setattachment(self.enemy , self, ""); + setattachment(self.enemy , self, ""); self.enemy.classname = "onslaught_generator_shield"; self.enemy.solid = SOLID_NOT; self.enemy.movetype = MOVETYPE_NONE; @@ -939,7 +952,7 @@ void spawnfunc_onslaught_generator() waypoint_spawnforitem(self); onslaught_updatelinks(); - + self.reset = onslaught_generator_reset; } @@ -1318,8 +1331,8 @@ void spawnfunc_onslaught_controlpoint() setmodel(self, "models/onslaught/controlpoint_pad.md3"); //setsize(self, '-32 -32 0', '32 32 8'); if (!self.noalign) - droptofloor(); - + droptofloor(); + setorigin(self, self.origin); self.touch = onslaught_controlpoint_touch; self.team = 0; @@ -1333,11 +1346,11 @@ void spawnfunc_onslaught_controlpoint() self.enemy.solid = SOLID_NOT; self.enemy.movetype = MOVETYPE_NONE; self.enemy.effects = EF_ADDITIVE; - setmodel(self.enemy , "models/onslaught/controlpoint_shield.md3"); - + setmodel(self.enemy , "models/onslaught/controlpoint_shield.md3"); + setattachment(self.enemy , self, ""); //setsize(e, '-32 -32 0', '32 32 128'); - + //setorigin(e, self.origin); self.enemy.colormap = self.colormap; @@ -1346,7 +1359,7 @@ void spawnfunc_onslaught_controlpoint() WaypointSprite_SpawnFixed(string_null, self.origin + '0 0 128', self, sprite, RADARICON_NONE, '0 0 0'); WaypointSprite_UpdateRule(self.sprite, COLOR_TEAM2, SPRITERULE_TEAMPLAY); - onslaught_updatelinks(); + onslaught_updatelinks(); self.reset = onslaught_controlpoint_reset; } @@ -1453,4 +1466,157 @@ void spawnfunc_onslaught_link() objerror("target and target2 must be set\n"); InitializeEntity(self, onslaught_link_delayed, INITPRIO_FINDTARGET); Net_LinkEntity(self, FALSE, 0, onslaught_link_send); +} + +MUTATOR_HOOKFUNCTION(ons_BuildMutatorsString) +{ + ret_string = strcat(ret_string, ":ONS"); + return 0; +} + +MUTATOR_HOOKFUNCTION(ons_BuildMutatorsPrettyString) +{ + ret_string = strcat(ret_string, ", Onslught"); + return 0; +} + +MUTATOR_HOOKFUNCTION(ons_Spawn_Score) +{ + + /* + float _neer_home = (random() > 0.5 ? TRUE : FALSE); + + RandomSelection_Init(); + + if(self.team == COLOR_TEAM1) + RandomSelection_Add(ons_red_generator, 0, string_null, 1, 1); + + if(self.team == COLOR_TEAM2) + RandomSelection_Add(ons_blue_generator, 0, string_null, 1, 1); + + entity _cp = findchain(classname, "onslaught_controlpoint"): + while _cp; + { + if(_cp.team == self.team) + RandomSelection_Add(_cp, 0, string_null, 1, 1); + + _cp = _cp.chain; + } + + if(RandomSelection_chosen_ent) + { + self.tur_head = RandomSelection_chosen_ent; + spawn_score_x += SPAWN_PRIO_NEAR_TEAMMATE_FOUND; + } + else if(self.team == spawn_spot.team) + spawn_score_x += SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM; // prefer same team, if we can't find a spawn near teammate + + */ + + return 0; +} + +MUTATOR_HOOKFUNCTION(ons_PlayerSpawn) +{ + if(!autocvar_g_onslaught_spawn_at_controlpoints) + return 0; + + if(random() < 0.5) // 50/50 chane to use default spawnsystem. + return 0; + + float _close_to_home = ((random() > 0.5) ? TRUE : FALSE); + entity _best, _trg_gen; + float _score, _best_score = MAX_SHOT_DISTANCE; + + RandomSelection_Init(); + + if(self.team == COLOR_TEAM1) + { + if(!_close_to_home) + _trg_gen = ons_blue_generator; + else + _trg_gen = ons_red_generator; + } + + if(self.team == COLOR_TEAM2) + { + if(_close_to_home) + _trg_gen = ons_blue_generator; + else + _trg_gen = ons_red_generator; + } + + entity _cp = findchain(classname, "onslaught_controlpoint"); + while(_cp) + { + if(_cp.team == self.team) + { + _score = vlen(_trg_gen.origin - _cp.origin); + if(_score < _best_score) + { + _best = _cp; + _best_score = _score; + } + } + _cp = _cp.chain; + } + + vector _loc; + float i; + if(_best) + { + for(i = 0; i < 10; ++i) + { + _loc = _best.origin + '0 0 96'; + _loc += ('0 1 0' * random()) * 128; + tracebox(_loc, PL_MIN, PL_MAX, _loc, MOVE_NORMAL, self); + if(trace_fraction == 1.0 && !trace_startsolid) + { + setorigin(self, _loc); + self.angles = normalize(_loc - _best.origin) * RAD2DEG; + return 0; + } + } + } + else + { + if(!autocvar_g_onslaught_spawn_at_generator) + return 0; + + _trg_gen = ((self.team == COLOR_TEAM1) ? ons_red_generator : ons_blue_generator); + + for(i = 0; i < 10; ++i) + { + _loc = _trg_gen.origin + '0 0 96'; + _loc += ('0 1 0' * random()) * 128; + tracebox(_loc, PL_MIN, PL_MAX, _loc, MOVE_NORMAL, self); + if(trace_fraction == 1.0 && !trace_startsolid) + { + setorigin(self, _loc); + self.angles = normalize(_loc - _trg_gen.origin) * RAD2DEG; + return 0; + } + } + } + + return 0; +} + +MUTATOR_DEFINITION(gamemode_onslaught) +{ + //MUTATOR_HOOK(PlayerDies, nexball_BallDrop, CBC_ORDER_ANY); + //MUTATOR_HOOK(MakePlayerObserver, nexball_BallDrop, CBC_ORDER_ANY); + //MUTATOR_HOOK(ClientDisconnect, nexball_BallDrop, CBC_ORDER_ANY); + //MUTATOR_HOOK(PlayerPreThink, nexball_PlayerPreThink, CBC_ORDER_ANY); + MUTATOR_HOOK(BuildMutatorsPrettyString, ons_BuildMutatorsPrettyString, CBC_ORDER_ANY); + MUTATOR_HOOK(BuildMutatorsString, ons_BuildMutatorsString, CBC_ORDER_ANY); + MUTATOR_HOOK(PlayerSpawn, ons_PlayerSpawn, CBC_ORDER_ANY); + //MUTATOR_HOOK(Spawn_Score, ons_Spawn_Score, CBC_ORDER_ANY); + + MUTATOR_ONADD + { + //InitializeEntity(world, nb_delayedinit, INITPRIO_GAMETYPE); + } + + return 0; } diff --git a/qcsrc/server/mutators/mutators.qh b/qcsrc/server/mutators/mutators.qh index 4e7d9a651..8ba7320f2 100644 --- a/qcsrc/server/mutators/mutators.qh +++ b/qcsrc/server/mutators/mutators.qh @@ -2,6 +2,7 @@ MUTATOR_DECLARATION(gamemode_keyhunt); MUTATOR_DECLARATION(gamemode_freezetag); MUTATOR_DECLARATION(gamemode_keepaway); MUTATOR_DECLARATION(gamemode_nexball); +MUTATOR_DECLARATION(gamemode_onslaught); MUTATOR_DECLARATION(mutator_dodging); MUTATOR_DECLARATION(mutator_invincibleprojectiles); diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 1890eddd9..4dde8f22b 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -140,7 +140,7 @@ antilag.qc ctf.qc domination.qc -mode_onslaught.qc +//mode_onslaught.qc //nexball.qc g_hook.qc @@ -209,6 +209,7 @@ mutators/gamemode_nexball.qc mutators/gamemode_keyhunt.qc mutators/gamemode_freezetag.qc mutators/gamemode_keepaway.qc +mutators/gamemode_onslaught.qc mutators/mutator_invincibleproj.qc mutators/mutator_new_toys.qc mutators/mutator_nix.qc diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index f37167a49..ee80f812b 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -213,6 +213,7 @@ void InitGameplayMode() { ActivateTeamplay(); have_team_spawns = -1; // request team spawns + MUTATOR_ADD(gamemode_onslaught); } if(g_race) -- 2.39.2