From e692ffcee5604a9df1c7870a94f3024ab504bdc2 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 12 Apr 2014 15:27:13 +1000 Subject: [PATCH] Some minor improvements to monsters (auto precache default model, use monster kills as main point limit in invasion) --- gamemodes.cfg | 2 +- monsters.cfg | 1 + qcsrc/common/mapinfo.qh | 2 +- qcsrc/common/monsters/monster/mage.qc | 5 -- qcsrc/common/monsters/monster/shambler.qc | 5 -- qcsrc/common/monsters/monster/spider.qc | 7 +-- qcsrc/common/monsters/monster/wyvern.qc | 5 -- qcsrc/common/monsters/monster/zombie.qc | 5 -- qcsrc/common/monsters/monsters.qc | 3 +- qcsrc/common/monsters/sv_monsters.qc | 56 ++++++++++++++-------- qcsrc/server/autocvars.qh | 3 +- qcsrc/server/mutators/gamemode_invasion.qc | 44 +++++++++-------- qcsrc/server/teamplay.qc | 9 +--- 13 files changed, 70 insertions(+), 77 deletions(-) diff --git a/gamemodes.cfg b/gamemodes.cfg index 30352bba7..c67f29d81 100644 --- a/gamemodes.cfg +++ b/gamemodes.cfg @@ -80,7 +80,7 @@ seta g_keyhunt_point_leadlimit -1 "Keyhunt point lead limit overriding the mapin seta g_race_laps_limit -1 "Race laps limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_nexball_goallimit -1 "Nexball goal limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" seta g_nexball_goalleadlimit -1 "Nexball goal lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" -seta g_invasion_round_limit -1 "Invasion round limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" +seta g_invasion_point_limit -1 "Invasion point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" // ================================= diff --git a/monsters.cfg b/monsters.cfg index 296d24b19..3ff25a404 100644 --- a/monsters.cfg +++ b/monsters.cfg @@ -90,6 +90,7 @@ set g_monsters_owners 1 set g_monsters_teams 1 set g_monsters_score_kill 0 set g_monsters_score_spawned 0 +set g_monsters_sounds 1 set g_monsters_spawnshieldtime 2 set g_monsters_typefrag 1 set g_monsters_target_range 2000 diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index dc3776328..97b3349f8 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -75,7 +75,7 @@ REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,"timelimit=20 pointli REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,"timelimit=20 pointlimit=30"); #define g_keepaway IS_GAMETYPE(KEEPAWAY) -REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,"pointlimit=5"); +REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,"pointlimit=50"); #define g_invasion IS_GAMETYPE(INVASION) const float MAPINFO_FEATURE_WEAPONS = 1; // not defined for minstagib-only maps diff --git a/qcsrc/common/monsters/monster/mage.qc b/qcsrc/common/monsters/monster/mage.qc index 889a88123..0f027b244 100644 --- a/qcsrc/common/monsters/monster/mage.qc +++ b/qcsrc/common/monsters/monster/mage.qc @@ -336,9 +336,6 @@ void spawnfunc_monster_mage() { self.classname = "monster_mage"; - if(Monster_CheckAppearFlags(self, MON_MAGE)) - return; - if(!monster_initialize(MON_MAGE)) { remove(self); return; } } @@ -396,7 +393,6 @@ float m_mage(float req) } case MR_PRECACHE: { - precache_model ("models/monsters/mage.dpm"); precache_sound ("weapons/grenade_impact.wav"); precache_sound ("weapons/tagexp1.wav"); return TRUE; @@ -414,7 +410,6 @@ float m_mage(float req) { case MR_PRECACHE: { - precache_model ("models/monsters/mage.dpm"); return TRUE; } } diff --git a/qcsrc/common/monsters/monster/shambler.qc b/qcsrc/common/monsters/monster/shambler.qc index c95fbebdb..b93312be6 100644 --- a/qcsrc/common/monsters/monster/shambler.qc +++ b/qcsrc/common/monsters/monster/shambler.qc @@ -197,9 +197,6 @@ void spawnfunc_monster_shambler() { self.classname = "monster_shambler"; - if(Monster_CheckAppearFlags(self, MON_SHAMBLER)) - return; - if(!monster_initialize(MON_SHAMBLER)) { remove(self); return; } } @@ -231,7 +228,6 @@ float m_shambler(float req) } case MR_PRECACHE: { - precache_model ("models/monsters/shambler.mdl"); return TRUE; } } @@ -247,7 +243,6 @@ float m_shambler(float req) { case MR_PRECACHE: { - precache_model ("models/monsters/shambler.mdl"); return TRUE; } } diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc index 9acffb5f4..1941be550 100644 --- a/qcsrc/common/monsters/monster/spider.qc +++ b/qcsrc/common/monsters/monster/spider.qc @@ -37,7 +37,7 @@ void spider_web_explode() pointparticles(particleeffectnum("electro_impact"), self.origin, '0 0 0', 1); RadiusDamage(self, self.realowner, 0, 0, 25, world, 25, self.projectiledeathtype, world); - for(e = findradius(self.origin, 25); e; e = e.chain) if(e != self) if(e.takedamage && e.deadflag == DEAD_NO) if(e.health > 0) + for(e = findradius(self.origin, 25); e; e = e.chain) if(e != self) if(e.takedamage && e.deadflag == DEAD_NO) if(e.health > 0) if(e.monsterid != MON_SPIDER) e.spider_slowness = time + (autocvar_g_monster_spider_attack_web_damagetime); remove(self); @@ -119,9 +119,6 @@ void spawnfunc_monster_spider() { self.classname = "monster_spider"; - if(Monster_CheckAppearFlags(self, MON_SPIDER)) - return; - if(!monster_initialize(MON_SPIDER)) { remove(self); return; } } @@ -152,7 +149,6 @@ float m_spider(float req) } case MR_PRECACHE: { - precache_model ("models/monsters/spider.dpm"); precache_sound ("weapons/electro_fire2.wav"); return TRUE; } @@ -169,7 +165,6 @@ float m_spider(float req) { case MR_PRECACHE: { - precache_model ("models/monsters/spider.dpm"); return TRUE; } } diff --git a/qcsrc/common/monsters/monster/wyvern.qc b/qcsrc/common/monsters/monster/wyvern.qc index 26dbb186c..4f845883d 100644 --- a/qcsrc/common/monsters/monster/wyvern.qc +++ b/qcsrc/common/monsters/monster/wyvern.qc @@ -96,9 +96,6 @@ void spawnfunc_monster_wyvern() { self.classname = "monster_wyvern"; - if(Monster_CheckAppearFlags(self, MON_WYVERN)) - return; - if(!monster_initialize(MON_WYVERN)) { remove(self); return; } } @@ -134,7 +131,6 @@ float m_wyvern(float req) } case MR_PRECACHE: { - precache_model ("models/monsters/wizard.mdl"); return TRUE; } } @@ -150,7 +146,6 @@ float m_wyvern(float req) { case MR_PRECACHE: { - precache_model ("models/monsters/wizard.mdl"); return TRUE; } } diff --git a/qcsrc/common/monsters/monster/zombie.qc b/qcsrc/common/monsters/monster/zombie.qc index 4efb7cc1b..08735dc35 100644 --- a/qcsrc/common/monsters/monster/zombie.qc +++ b/qcsrc/common/monsters/monster/zombie.qc @@ -130,9 +130,6 @@ void spawnfunc_monster_zombie() { self.classname = "monster_zombie"; - if(Monster_CheckAppearFlags(self, MON_ZOMBIE)) - return; - if(!monster_initialize(MON_ZOMBIE)) { remove(self); return; } } @@ -172,7 +169,6 @@ float m_zombie(float req) } case MR_PRECACHE: { - precache_model ("models/monsters/zombie.dpm"); return TRUE; } } @@ -188,7 +184,6 @@ float m_zombie(float req) { case MR_PRECACHE: { - precache_model ("models/monsters/zombie.dpm"); return TRUE; } } diff --git a/qcsrc/common/monsters/monsters.qc b/qcsrc/common/monsters/monsters.qc index 70802dbbd..58d80ad04 100644 --- a/qcsrc/common/monsters/monsters.qc +++ b/qcsrc/common/monsters/monsters.qc @@ -20,6 +20,7 @@ void register_monster(float id, float(float) func, float monsterflags, vector mi e.model = strzone(strcat("models/monsters/", modelname)); #ifndef MENUQC + precache_model(e.model); func(MR_PRECACHE); #endif } @@ -46,4 +47,4 @@ entity get_monsterinfo(float id) if(m) return m; return dummy_monster_info; -} \ No newline at end of file +} diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index 15fa1608e..6392d8506 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -274,6 +274,8 @@ void UpdateMonsterSounds() void MonsterSound(.string samplefield, float sound_delay, float delaytoo, float chan) { + if(!autocvar_g_monsters_sounds) { return; } + if(delaytoo) if(time < self.msound_delay) return; // too early @@ -353,13 +355,11 @@ float Monster_CanRespawn(entity ent) return TRUE; } -float Monster_CheckAppearFlags(entity ent, float monster_id); float monster_initialize(float mon_id); void monster_respawn() { // is this function really needed? - if(!Monster_CheckAppearFlags(self, self.monsterid)) - monster_initialize(self.monsterid); + monster_initialize(self.monsterid); } void Monster_Fade () @@ -552,8 +552,7 @@ vector monster_pickmovetarget(entity targ) makevectors(self.angles); pos = self.origin + v_forward * self.wander_distance; - if((self.flags & FL_FLY) || (self.flags & FL_SWIM)) - if(self.spawnflags & MONSTERFLAG_FLY_VERTICAL) + if(((self.flags & FL_FLY) && (self.spawnflags & MONSTERFLAG_FLY_VERTICAL)) || (self.flags & FL_SWIM)) { pos_z = random() * 200; if(random() >= 0.5) @@ -595,13 +594,14 @@ void monster_CalculateVelocity(entity mon, vector to, vector from, float turnrat vector desired_direction = normalize(targpos - from); if(turnrate) { mon.velocity = (normalize(normalize(mon.velocity) + (desired_direction * 50)) * movespeed); } else { mon.velocity = (desired_direction * movespeed); } - - mon.angles = vectoangles(mon.velocity); + + //mon.steerto = steerlib_attract2(targpos, 0.5, 500, 0.95); + //mon.angles = vectoangles(mon.velocity); } void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_run, float manim_walk, float manim_idle) { - fixedmakevectors(self.angles); + //fixedmakevectors(self.angles); if(self.target2) self.goalentity = find(world, targetname, self.target2); @@ -717,9 +717,9 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_ if(self.enemy && self.enemy.vehicle) runspeed = 0; - if(((self.flags & FL_FLY) || (self.flags & FL_SWIM)) && (self.spawnflags & MONSTERFLAG_FLY_VERTICAL)) - v_forward = normalize(self.moveto - self.origin); - else + if(!(((self.flags & FL_FLY) && (self.spawnflags & MONSTERFLAG_FLY_VERTICAL)) || (self.flags & FL_SWIM))) + //v_forward = normalize(self.moveto - self.origin); + //else self.moveto_z = self.origin_z; if(vlen(self.origin - self.moveto) > 64) @@ -753,6 +753,18 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_ if (vlen(self.velocity) <= 30) self.frame = manim_idle; } + + self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95); + + vector real_angle = vectoangles(self.steerto) - self.angles; + float turny = 25; + if(self.state == MONSTER_STATE_ATTACK_MELEE) + turny = 0; + if(turny) + { + turny = bound(turny * -1, shortangle_f(real_angle_y, self.angles_y), turny); + self.angles_y += turny; + } monster_checkattack(self, self.enemy); } @@ -795,7 +807,7 @@ void monsters_setstatus() void Monster_Appear() { self.enemy = activator; - //self.spawnflags &= ~MONSTERFLAG_APPEAR; + self.spawnflags &= ~MONSTERFLAG_APPEAR; // otherwise, we get an endless loop monster_initialize(self.monsterid); } @@ -889,7 +901,7 @@ void monster_die(entity attacker, float gibbed) self.state = 0; self.attack_finished_single = 0; - if(!(self.flags & FL_FLY)) + if(!((self.flags & FL_FLY) || (self.flags & FL_SWIM))) self.velocity = '0 0 0'; MON_ACTION(self.monsterid, MR_DEATH); @@ -1057,8 +1069,9 @@ float monster_spawn() float monster_initialize(float mon_id) { - if(!autocvar_g_monsters) - return FALSE; + if(!autocvar_g_monsters) { return FALSE; } + + if(Monster_CheckAppearFlags(self, mon_id)) { return TRUE; } // return true so the monster isn't removed entity mon = get_monsterinfo(mon_id); @@ -1078,7 +1091,7 @@ float monster_initialize(float mon_id) monsters_total += 1; setmodel(self, mon.model); - setsize(self, mon.mins, mon.maxs); + //setsize(self, mon.mins, mon.maxs); self.flags = FL_MONSTER; self.takedamage = DAMAGE_AIM; self.bot_attack = TRUE; @@ -1106,13 +1119,15 @@ float monster_initialize(float mon_id) self.oldtarget2 = self.target2; self.pass_distance = 0; self.deadflag = DEAD_NO; - self.scale = 1; - self.noalign = (mon.spawnflags & MONSTER_TYPE_FLY); + self.noalign = ((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM)); self.spawn_time = time; self.spider_slowness = 0; self.gravity = 1; self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP; + if(!self.scale) + self.scale = 1; + if(autocvar_g_monsters_edit) self.grab = 1; // owner may carry their monster @@ -1132,7 +1147,10 @@ float monster_initialize(float mon_id) } if(mon.spawnflags & MONSTER_SIZE_BROKEN) - self.scale = 1.3; + if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) + self.scale *= 1.3; + + setsize(self, mon.mins * self.scale, mon.maxs * self.scale); if(!self.ticrate) self.ticrate = autocvar_g_monsters_think_delay; diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index 674c95b14..53fc5f530 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -1221,6 +1221,7 @@ float autocvar_g_physical_items_damageforcescale; float autocvar_g_physical_items_reset; float autocvar_g_monsters; float autocvar_g_monsters_edit; +float autocvar_g_monsters_sounds; float autocvar_g_monsters_think_delay; float autocvar_g_monsters_max; float autocvar_g_monsters_max_perplayer; @@ -1244,7 +1245,7 @@ float autocvar_g_touchexplode_damage; float autocvar_g_touchexplode_edgedamage; float autocvar_g_touchexplode_force; float autocvar_g_invasion_round_timelimit; -#define autocvar_g_invasion_round_limit cvar("g_invasion_round_limit") +#define autocvar_g_invasion_point_limit cvar("g_invasion_point_limit") float autocvar_g_invasion_warmup; float autocvar_g_invasion_monster_count; float autocvar_g_invasion_zombies_only; diff --git a/qcsrc/server/mutators/gamemode_invasion.qc b/qcsrc/server/mutators/gamemode_invasion.qc index 1242ecbd9..7a3f0c058 100644 --- a/qcsrc/server/mutators/gamemode_invasion.qc +++ b/qcsrc/server/mutators/gamemode_invasion.qc @@ -34,7 +34,13 @@ entity invasion_PickSpawn() RandomSelection_Init(); for(e = world;(e = find(e, classname, "invasion_spawnpoint")); ) - RandomSelection_Add(e, 0, string_null, 1, 1); + { + if(time >= e.spawnshieldtime) + { + e.spawnshieldtime = time + 2; + RandomSelection_Add(e, 0, string_null, 1, 1); + } + } return RandomSelection_chosen_ent; } @@ -51,9 +57,10 @@ void invasion_SpawnChosenMonster(float mon) return; } - monster = spawnmonster("", mon, spawn_point, spawn_point, spawn_point.origin, FALSE, FALSE, 2); + monster = spawnmonster("", ((spawn_point.monsterid) ? spawn_point.monsterid : mon), spawn_point, spawn_point, spawn_point.origin, FALSE, FALSE, 2); monster.target2 = spawn_point.target2; + monster.spawnshieldtime = time; if(inv_roundcnt >= inv_maxrounds) monster.spawnflags |= MONSTERFLAG_MINIBOSS; // last round spawns minibosses @@ -74,12 +81,6 @@ float Invasion_CheckWinner() FOR_EACH_MONSTER(head) monster_remove(head); - if(inv_roundcnt >= inv_maxrounds) - { - NextLevel(); - return 1; - } - Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER); Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER); round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit); @@ -95,7 +96,7 @@ float Invasion_CheckWinner() ++total_alive_monsters; } - if((total_alive_monsters + inv_numkilled) < inv_maxspawned && inv_maxcurrent < 10) // 10 at a time should be plenty + if((total_alive_monsters + inv_numkilled) < inv_maxspawned && inv_maxcurrent < inv_maxspawned) { if(time >= inv_lastcheck) { @@ -109,12 +110,6 @@ float Invasion_CheckWinner() if(inv_numspawned < 1 || inv_numkilled < inv_maxspawned) return 0; // nothing has spawned yet, or there are still alive monsters - if(inv_roundcnt >= inv_maxrounds) - { - NextLevel(); - return 1; - } - entity winner = world; float winning_score = 0; @@ -157,7 +152,8 @@ void Invasion_RoundStart() ++numplayers; } - inv_roundcnt += 1; + if(inv_roundcnt < inv_maxrounds) + inv_roundcnt += 1; // a limiter to stop crazy counts inv_monsterskill = inv_roundcnt + max(1, numplayers * 0.3); @@ -185,10 +181,7 @@ MUTATOR_HOOKFUNCTION(invasion_MonsterDies) MUTATOR_HOOKFUNCTION(invasion_MonsterSpawn) { if(!(self.spawnflags & MONSTERFLAG_SPAWNED)) - { - monster_remove(self); - return FALSE; - } + return TRUE; if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) { @@ -206,6 +199,15 @@ MUTATOR_HOOKFUNCTION(invasion_MonsterSpawn) return FALSE; } +MUTATOR_HOOKFUNCTION(invasion_OnEntityPreSpawn) +{ + if(startsWith(self.classname, "monster_")) + if(!(self.spawnflags & MONSTERFLAG_SPAWNED)) + return TRUE; + + return FALSE; +} + MUTATOR_HOOKFUNCTION(invasion_PlayerThink) { monsters_total = inv_maxspawned; // TODO: make sure numspawned never exceeds maxspawned @@ -300,12 +302,14 @@ void invasion_Initialize() allowed_to_spawn = TRUE; inv_roundcnt = 0; + inv_maxrounds = 15; // 15? } MUTATOR_DEFINITION(gamemode_invasion) { MUTATOR_HOOK(MonsterDies, invasion_MonsterDies, CBC_ORDER_ANY); MUTATOR_HOOK(MonsterSpawn, invasion_MonsterSpawn, CBC_ORDER_ANY); + MUTATOR_HOOK(OnEntityPreSpawn, invasion_OnEntityPreSpawn, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerPreThink, invasion_PlayerThink, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerRegen, invasion_PlayerRegen, CBC_ORDER_ANY); MUTATOR_HOOK(PlayerSpawn, invasion_PlayerSpawn, CBC_ORDER_ANY); diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index e332e55ed..932dcc12a 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -197,8 +197,7 @@ void InitGameplayMode() if(g_invasion) { - timelimit_override = 0; // no timelimit in invasion, round based - fraglimit_override = autocvar_g_invasion_round_limit; + fraglimit_override = autocvar_g_invasion_point_limit; MUTATOR_ADD(gamemode_invasion); } @@ -241,12 +240,6 @@ void InitGameplayMode() else g_race_qualifying = 0; } - - if(g_invasion) - { - inv_maxrounds = cvar("fraglimit"); - cvar_set("fraglimit", "0"); - } if(g_race || g_cts) { -- 2.39.2