MODEL(VEH_SPIDERBOT_TOP, "models/vehicles/spiderbot_top.dpm");
MODEL(VEH_SPIDERBOT_VIEW, "models/vehicles/spiderbot_cockpit.dpm");
-MODEL(MON_MAGE, "models/monsters/mage.dpm");
-MODEL(MON_SHAMBLER, "models/monsters/shambler.mdl");
-MODEL(MON_SPIDER, "models/monsters/spider.dpm");
-MODEL(MON_WYVERN, "models/monsters/wizard.mdl");
-MODEL(MON_ZOMBIE, "models/monsters/zombie.dpm");
-
MODEL(CHAT, "models/misc/chatbubble.spr");
MODEL(0, "models/sprites/0.spr32");
#ifndef MONSTERS_ALL_C
#define MONSTERS_ALL_C
-#include "all.qh"
-
-REGISTER_MONSTER(Null, NEW(Monster)) {
- this.netname = "";
- this.monster_name = "Monster";
- this.monster_func = m_null;
- this.mdl = "";
- this.mins = '-0 -0 -0';
- this.maxs = '0 0 0';
- this.model = "";
-}
-#include "all.inc"
+#include "all.qh"
entity get_monsterinfo(int id)
{
- if (id >= MON_FIRST && id <= MON_LAST)
- {
+ if (id >= MON_FIRST && id <= MON_LAST) {
entity m = monster_info[id];
if (m) return m;
}
return MON_Null;
}
+#define IMPLEMENTATION
+#include "all.inc"
+#undef IMPLEMENTATION
+
#endif
#ifndef MONSTERS_ALL_H
#define MONSTERS_ALL_H
+#include "monster.qh"
+
void RegisterMonsters();
const int MON_MAXCOUNT = 24;
entity monster_info[MON_MAXCOUNT], monster_info_first, monster_info_last;
#define MON_LAST (MON_FIRST + MON_COUNT - 1)
/** If you register a new monster, make sure to add it to all.inc */
#define REGISTER_MONSTER(id, inst) REGISTER(RegisterMonsters, MON, monster_info, MON_COUNT, id, monsterid, inst)
-#include "monster.qh"
-#define REGISTER_MONSTER_SIMPLE(id, monsterflags, min_s, max_s, modelname, shortname, mname) \
- REGISTER_MONSTER(id, NEW(Monster)) { \
- this.netname = shortname; \
- this.monster_name = mname; \
- this.mdl = modelname; \
- this.spawnflags = monsterflags; \
- this.mins = min_s; \
- this.maxs = max_s; \
- this.model = strzone(strcat("models/monsters/", modelname)); \
- } \
- REGISTER_INIT(MON, id)
REGISTER_REGISTRY(RegisterMonsters)
-#include "../util.qh"
-
-// special spawn flags
-const int MONSTER_RESPAWN_DEATHPOINT = 16; // re-spawn where we died
-const int MONSTER_TYPE_FLY = 32;
-const int MONSTER_TYPE_SWIM = 64;
-const int MONSTER_SIZE_BROKEN = 128; // TODO: remove when bad models are replaced
-const int MON_FLAG_SUPERMONSTER = 256; // incredibly powerful monster
-const int MON_FLAG_RANGED = 512; // monster shoots projectiles
-const int MON_FLAG_MELEE = 1024;
-const int MON_FLAG_CRUSH = 2048; // monster can be stomped in special modes
-const int MON_FLAG_RIDE = 4096; // monster can be ridden in special modes
+entity get_monsterinfo(int id);
-// entity properties of monsterinfo:
-.string netname; // short name
-.string mdl; // currently a copy of the model
-.string model; // full name of model
-.int spawnflags;
-.vector mins, maxs; // monster hitbox size
-.bool(int) monster_attackfunc;
+REGISTER_MONSTER(Null, NEW(Monster));
-// animations
-.vector anim_blockend;
-.vector anim_blockstart;
-.vector anim_melee1;
-.vector anim_melee2;
-.vector anim_melee3;
-.vector anim_pain3;
-.vector anim_pain4;
-.vector anim_pain5;
-.vector anim_walk;
-.vector anim_spawn;
+#include "all.inc"
#endif
#ifndef MONSTER_H
#define MONSTER_H
+// special spawn flags
+const int MONSTER_RESPAWN_DEATHPOINT = 16; // re-spawn where we died
+const int MONSTER_TYPE_FLY = 32;
+const int MONSTER_TYPE_SWIM = 64;
+const int MONSTER_SIZE_BROKEN = 128; // TODO: remove when bad models are replaced
+const int MON_FLAG_SUPERMONSTER = 256; // incredibly powerful monster
+const int MON_FLAG_RANGED = 512; // monster shoots projectiles
+const int MON_FLAG_MELEE = 1024;
+const int MON_FLAG_CRUSH = 2048; // monster can be stomped in special modes
+const int MON_FLAG_RIDE = 4096; // monster can be ridden in special modes
+
+// entity properties of monsterinfo:
+.bool(int) monster_attackfunc;
+
+// animations
+.vector anim_blockend;
+.vector anim_blockstart;
+.vector anim_melee1;
+.vector anim_melee2;
+.vector anim_melee3;
+.vector anim_pain3;
+.vector anim_pain4;
+.vector anim_pain5;
+.vector anim_walk;
+.vector anim_spawn;
+
bool m_null(entity thismon, int) { return false; }
bool m_new(entity thismon, int);
/** If you register a new monster, make sure to add it to all.inc */
CLASS(Monster, Object)
ATTRIB(Monster, monsterid, int, 0)
- ATTRIB(Monster, classname, string, "monster_info")
- /** human readable name */
- ATTRIB(Monster, monster_name, string, string_null)
ATTRIB(Monster, monster_func, bool(Monster, int), m_new)
+ /** attributes */
+ ATTRIB(Monster, spawnflags, int, 0)
+ /** human readable name */
+ ATTRIB(Monster, monster_name, string, "Monster")
+ /** short name */
+ ATTRIB(Monster, netname, string, "")
+ /** model */
+ ATTRIB(Monster, m_model, entity, NULL)
+ /** hitbox size */
+ ATTRIB(Monster, mins, vector, '-0 -0 -0')
+ /** hitbox size */
+ ATTRIB(Monster, maxs, vector, '0 0 0')
ENDCLASS(Monster)
// monster requests
+#ifndef MAGE_H
+#define MAGE_H
+
+#ifndef MENUQC
+MODEL(MON_MAGE, "models/monsters/mage.dpm");
+#endif
+
CLASS(Mage, Monster)
ATTRIB(Mage, spawnflags, int, MON_FLAG_MELEE | MON_FLAG_RANGED);
ATTRIB(Mage, mins, vector, '-36 -36 -24');
ATTRIB(Mage, maxs, vector, '36 36 50');
- ATTRIB(Mage, mdl, string, "mage.dpm");
- ATTRIB(Mage, model, string, strzone(strcat("models/monsters/", this.mdl)));
+#ifndef MENUQC
+ ATTRIB(Mage, m_model, Model, MDL_MON_MAGE);
+#endif
ATTRIB(Mage, netname, string, "mage");
ATTRIB(Mage, monster_name, string, _("Mage"));
ENDCLASS(Mage)
ENDCLASS(MageSpike)
REGISTER_WEAPON(MAGE_SPIKE, NEW(MageSpike));
+#endif
+
+#ifdef IMPLEMENTATION
+
#ifdef SVQC
void M_Mage_Attack_Spike(vector dir);
return true;
}
#endif
+
+#endif
+#ifndef SHAMBLER_H
+#define SHAMBLER_H
+
+#ifndef MENUQC
+MODEL(MON_SHAMBLER, "models/monsters/shambler.mdl");
+#endif
+
CLASS(Shambler, Monster)
ATTRIB(Shambler, spawnflags, int, MONSTER_SIZE_BROKEN | MON_FLAG_SUPERMONSTER | MON_FLAG_MELEE | MON_FLAG_RANGED);
ATTRIB(Shambler, mins, vector, '-41 -41 -31');
ATTRIB(Shambler, maxs, vector, '41 41 65');
- ATTRIB(Shambler, mdl, string, "shambler.mdl");
- ATTRIB(Shambler, model, string, strzone(strcat("models/monsters/", this.mdl)));
+#ifndef MENUQC
+ ATTRIB(Shambler, m_model, Model, MDL_MON_SHAMBLER);
+#endif
ATTRIB(Shambler, netname, string, "shambler");
ATTRIB(Shambler, monster_name, string, _("Shambler"));
ENDCLASS(Shambler)
#endif
}
+#endif
+
+#ifdef IMPLEMENTATION
+
#ifdef SVQC
float autocvar_g_monster_shambler_health;
float autocvar_g_monster_shambler_damageforcescale = 0.1;
return true;
}
#endif
+
+#endif
+#ifndef SPIDER_H
+#define SPIDER_H
+
+#ifndef MENUQC
+MODEL(MON_SPIDER, "models/monsters/spider.dpm");
+#endif
+
CLASS(Spider, Monster)
ATTRIB(Spider, spawnflags, int, MON_FLAG_MELEE | MON_FLAG_RANGED | MON_FLAG_RIDE);
ATTRIB(Spider, mins, vector, '-18 -18 -25');
ATTRIB(Spider, maxs, vector, '18 18 30');
- ATTRIB(Spider, mdl, string, "spider.dpm");
- ATTRIB(Spider, model, string, strzone(strcat("models/monsters/", this.mdl)));
+#ifndef MENUQC
+ ATTRIB(Spider, m_model, Model, MDL_MON_SPIDER);
+#endif
ATTRIB(Spider, netname, string, "spider");
ATTRIB(Spider, monster_name, string, _("Spider"));
ENDCLASS(Spider)
#endif
}
+#endif
+
+#ifdef IMPLEMENTATION
+
#ifdef SVQC
float autocvar_g_monster_spider_health;
float autocvar_g_monster_spider_damageforcescale = 0.6;
return true;
}
#endif
+
+#endif
+#ifndef WYVERN_H
+#define WYVERN_H
+
+#ifndef MENUQC
+MODEL(MON_WYVERN, "models/monsters/wizard.mdl");
+#endif
+
CLASS(Wyvern, Monster)
ATTRIB(Wyvern, spawnflags, int, MONSTER_TYPE_FLY | MONSTER_SIZE_BROKEN | MON_FLAG_RANGED | MON_FLAG_RIDE);
ATTRIB(Wyvern, mins, vector, '-20 -20 -58');
ATTRIB(Wyvern, maxs, vector, '20 20 20');
- ATTRIB(Wyvern, mdl, string, "wizard.mdl");
- ATTRIB(Wyvern, model, string, strzone(strcat("models/monsters/", this.mdl)));
+#ifndef MENUQC
+ ATTRIB(Wyvern, m_model, Model, MDL_MON_WYVERN);
+#endif
ATTRIB(Wyvern, netname, string, "wyvern");
ATTRIB(Wyvern, monster_name, string, _("Wyvern"));
ENDCLASS(Wyvern)
#endif
}
+#endif
+
+#ifdef IMPLEMENTATION
+
#ifdef SVQC
float autocvar_g_monster_wyvern_health;
float autocvar_g_monster_wyvern_damageforcescale = 0.6;
return true;
}
#endif
+
+#endif
+#ifndef ZOMBIE_H
+#define ZOMBIE_H
+
+#ifndef MENUQC
+MODEL(MON_ZOMBIE, "models/monsters/zombie.dpm");
+#endif
+
CLASS(Zombie, Monster)
ATTRIB(Zombie, spawnflags, int, MON_FLAG_MELEE | MON_FLAG_RIDE);
ATTRIB(Zombie, mins, vector, '-18 -18 -25');
ATTRIB(Zombie, maxs, vector, '18 18 47');
- ATTRIB(Zombie, mdl, string, "zombie.dpm");
- ATTRIB(Zombie, model, string, strzone(strcat("models/monsters/", this.mdl)));
+#ifndef MENUQC
+ ATTRIB(Zombie, m_model, Model, MDL_MON_ZOMBIE);
+#endif
ATTRIB(Zombie, netname, string, "zombie");
ATTRIB(Zombie, monster_name, string, _("Zombie"));
ENDCLASS(Zombie)
#endif
}
+#endif
+
+#ifdef IMPLEMENTATION
+
#ifdef SVQC
float autocvar_g_monster_zombie_health;
float autocvar_g_monster_zombie_damageforcescale = 0.55;
return true;
}
#endif
+
+#endif
void Monster_Sounds_Precache()
{SELFPARAM();
- string m = (get_monsterinfo(self.monsterid)).model;
+ string m = (get_monsterinfo(self.monsterid)).m_model.model_str();
float globhandle, n, i;
string f;
if(!autocvar_g_monsters) { Monster_Remove(self); return false; }
- self.mdl = mon.model;
if(Monster_Appear_Check(self, mon_id)) { return true; } // return true so the monster isn't removed
if(!self.monster_skill)
if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) // don't count re-spawning monsters either
monsters_total += 1;
- _setmodel(self, self.mdl);
+ setmodel(self, mon.m_model);
self.flags = FL_MONSTER;
self.classname = "monster";
self.takedamage = DAMAGE_AIM;
{
for (entity head = world; (head = nextent(head)); )
{
- if (clienttype(head) != CLIENTTYPE_NOTACLIENT || !(head.weapons & WEPSET_SUPERWEAPONS) || head.classname == "weapon_info")
+ if (clienttype(head) != CLIENTTYPE_NOTACLIENT || !(head.weapons & WEPSET_SUPERWEAPONS) || head.instanceOfWeapon)
continue;
if (e == head)
continue;
}
void register_weapon(entity this, int id, WepSet bit)
{
- this.classname = "weapon_info";
this.weapon = id;
this.weapons = bit;
this.wpmodel = strzone(strcat("wpn-", ftos(id)));
return nearest;
}
-float WarpZoneLib_BadClassname(string myclassname)
+bool WarpZoneLib_BadEntity(entity e)
{
+ string myclassname = e.classname;
+ if (e.instanceOfObject) return true;
switch(myclassname)
{
- case "weapon_info":
- case "monster_info":
case "deathtype":
- case "callback":
- case "callbackchain":
case "weaponentity":
case "exteriorweaponentity":
case "csqc_score_team":
for(e = e0; e; e = e.chain)
{
- if(WarpZoneLib_BadClassname(e.classname))
+ if(WarpZoneLib_BadEntity(e))
continue;
p = WarpZoneLib_NearestPointOnBox(e.origin + e.mins, e.origin + e.maxs, org0);
if(needlineofsight)
}
for(e = wz; e; e = e.WarpZone_findradius_next)
{
- if(WarpZoneLib_BadClassname(e.classname))
+ if(WarpZoneLib_BadEntity(e))
continue;
org0_new = WarpZone_TransformOrigin(e, org);