REGISTER_MONSTER(
/* MON_##id */ ANIMUS,
/* function */ m_animus,
-/* spawnflags */ MONSTER_SIZE_BROKEN,
+/* spawnflags */ MONSTER_SIZE_BROKEN | MON_FLAG_MELEE,
/* mins,maxs */ '-41 -41 -31', '41 41 31',
/* model */ "demon.mdl",
/* netname */ "animus",
REGISTER_MONSTER(
/* MON_##id */ BRUISER,
/* function */ m_bruiser,
-/* spawnflags */ MONSTER_SIZE_BROKEN,
+/* spawnflags */ MONSTER_SIZE_BROKEN | MON_FLAG_MELEE,
/* mins,maxs */ '-20 -20 -31', '20 20 53',
/* model */ "knight.mdl",
/* netname */ "bruiser",
REGISTER_MONSTER(
/* MON_##id */ BRUTE,
/* function */ m_brute,
-/* spawnflags */ 0,
+/* spawnflags */ MON_FLAG_MELEE | MON_FLAG_RANGED,
/* mins,maxs */ '-36 -36 -20', '36 36 50',
/* model */ "ogre.dpm",
/* netname */ "brute",
REGISTER_MONSTER(
/* MON_##id */ CERBERUS,
/* function */ m_cerberus,
-/* spawnflags */ 0,
+/* spawnflags */ MON_FLAG_MELEE,
/* mins,maxs */ '-16 -16 -24', '16 16 12',
/* model */ "dog.dpm",
/* netname */ "cerberus",
REGISTER_MONSTER(
/* MON_##id */ KNIGHT,
/* function */ m_knight,
-/* spawnflags */ MONSTER_SIZE_BROKEN,
+/* spawnflags */ MONSTER_SIZE_BROKEN | MON_FLAG_MELEE | MON_FLAG_RANGED,
/* mins,maxs */ '-20 -20 -32', '20 20 41',
/* model */ "hknight.mdl",
/* netname */ "knight",
REGISTER_MONSTER(
/* MON_##id */ MAGE,
/* function */ m_mage,
-/* spawnflags */ 0,
+/* spawnflags */ MON_FLAG_MELEE | MON_FLAG_RANGED,
/* mins,maxs */ '-36 -36 -24', '36 36 50',
/* model */ "mage.dpm",
/* netname */ "mage",
REGISTER_MONSTER(
/* MON_##id */ SHAMBLER,
/* function */ m_shambler,
-/* spawnflags */ MONSTER_SIZE_BROKEN | MON_FLAG_SUPERMONSTER,
+/* spawnflags */ MONSTER_SIZE_BROKEN | MON_FLAG_SUPERMONSTER | MON_FLAG_MELEE | MON_FLAG_RANGED,
/* mins,maxs */ '-41 -41 -31', '41 41 65',
/* model */ "shambler.mdl",
/* netname */ "shambler",
REGISTER_MONSTER(
/* MON_##id */ SPIDER,
/* function */ m_spider,
-/* spawnflags */ 0,
+/* spawnflags */ MON_FLAG_MELEE | MON_FLAG_RANGED,
/* mins,maxs */ '-18 -18 -25', '18 18 30',
/* model */ "spider.dpm",
/* netname */ "spider",
REGISTER_MONSTER(
/* MON_##id */ STINGRAY,
/* function */ m_stingray,
-/* spawnflags */ MONSTER_TYPE_SWIM | MONSTER_SIZE_BROKEN,
+/* spawnflags */ MONSTER_TYPE_SWIM | MONSTER_SIZE_BROKEN | MON_FLAG_MELEE,
/* mins,maxs */ '-20 -20 -31', '20 20 20',
/* model */ "fish.mdl",
/* netname */ "stingray",
REGISTER_MONSTER(
/* MON_##id */ WYVERN,
/* function */ m_wyvern,
-/* spawnflags */ MONSTER_TYPE_FLY | MONSTER_SIZE_BROKEN,
+/* spawnflags */ MONSTER_TYPE_FLY | MONSTER_SIZE_BROKEN | MON_FLAG_RANGED,
/* mins,maxs */ '-20 -20 -58', '20 20 20',
/* model */ "wizard.mdl",
/* netname */ "wyvern",
REGISTER_MONSTER(
/* MON_##id */ ZOMBIE,
/* function */ m_zombie,
-/* spawnflags */ 0,
+/* spawnflags */ MON_FLAG_MELEE,
/* mins,maxs */ '-18 -18 -25', '18 18 47',
/* model */ "zombie.dpm",
/* netname */ "zombie",
entity get_monsterinfo(float id);
// special spawn flags
-const float MONSTER_RESPAWN_DEATHPOINT = 128; // re-spawn where we died
-const float MONSTER_TYPE_FLY = 256;
-const float MONSTER_TYPE_SWIM = 512;
-const float MONSTER_SIZE_BROKEN = 1024; // TODO: remove when bad models are replaced
-const float MON_FLAG_SUPERMONSTER = 2048; // incredibly powerful monster
+const float MONSTER_RESPAWN_DEATHPOINT = 2; // re-spawn where we died
+const float MONSTER_TYPE_FLY = 4;
+const float MONSTER_TYPE_SWIM = 8;
+const float MONSTER_SIZE_BROKEN = 16; // TODO: remove when bad models are replaced
+const float MON_FLAG_SUPERMONSTER = 32; // incredibly powerful monster
+const float MON_FLAG_RANGED = 64; // monster shoots projectiles
+const float MON_FLAG_MELEE = 128;
// entity properties of monsterinfo:
.float monsterid; // MON_...
if(targ == ent)
return FALSE; // don't attack ourselves
+ traceline(ent.origin, targ.origin, MOVE_NORMAL, ent);
+
+ if(trace_ent != targ)
+ {
+ if(trace_ent != world)
+ targ = trace_ent;
+ else
+ return FALSE;
+ }
+
+ if(targ.vehicle_flags & VHF_ISVEHICLE)
+ if not((get_monsterinfo(ent.monsterid)).spawnflags & MON_FLAG_RANGED)
+ return FALSE; // melee attacks are useless against vehicles
+
if(time < game_starttime)
return FALSE; // monsters do nothing before the match has started
-
- WarpZone_TraceLine(ent.origin, targ.origin, MOVE_NORMAL, ent);
if(vlen(targ.origin - ent.origin) >= ent.target_range)
return FALSE; // enemy is too far away
-
- if(trace_ent != targ)
- return FALSE; // we can't see the enemy
if(targ.takedamage == DAMAGE_NO)
return FALSE; // enemy can't be damaged
if(IS_SPEC(targ) || IS_OBSERVER(targ))
return FALSE; // enemy is a spectator
+ if not(targ.vehicle_flags & VHF_ISVEHICLE)
if(targ.deadflag != DEAD_NO || ent.deadflag != DEAD_NO || targ.health <= 0 || ent.health <= 0)
return FALSE; // enemy/self is dead
if(targ.monster_owner == ent)
return FALSE; // don't attack our pet
+ if not(targ.vehicle_flags & VHF_ISVEHICLE)
if(targ.flags & FL_NOTARGET)
return FALSE; // enemy can't be targeted
// enemy is always preferred target
if(self.enemy)
{
+ makevectors(self.angles);
self.monster_movestate = MONSTER_MOVE_ENEMY;
self.last_trace = time + 1.2;
- return self.enemy.origin;
+ return self.enemy.origin * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
}
switch(self.monster_moveflags)
if(self.state == MONSTER_STATE_ATTACK_MELEE)
self.moveto = self.origin;
- else if(self.enemy)
- self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
+
+ if(self.enemy && self.enemy.vehicle)
+ runspeed = 0;
if not(self.flags & FL_FLY || self.flags & FL_SWIM)
self.moveto_z = self.origin_z;