]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/monsters/monster/animus.qc
Add a cvar to control monster attack range
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / monsters / monster / animus.qc
1 #ifdef REGISTER_MONSTER
2 REGISTER_MONSTER(
3 /* MON_##id   */ ANIMUS,
4 /* function   */ m_animus,
5 /* spawnflags */ MONSTER_SIZE_BROKEN,
6 /* mins,maxs  */ '-41 -41 -31', '41 41 31',
7 /* model      */ "demon.mdl",
8 /* netname    */ "animus",
9 /* fullname   */ _("Animus")
10 );
11
12 #define ANIMUS_SETTINGS(monster) \
13         MON_ADD_CVAR(monster, health) \
14         MON_ADD_CVAR(monster, attack_jump_damage) \
15         MON_ADD_CVAR(monster, attack_melee_damage) \
16         MON_ADD_CVAR(monster, speed_stop) \
17         MON_ADD_CVAR(monster, speed_run) \
18         MON_ADD_CVAR(monster, speed_walk) 
19
20 #ifdef SVQC
21 ANIMUS_SETTINGS(animus)
22 #endif // SVQC
23 #else
24 #ifdef SVQC
25 const float animus_anim_stand   = 0;
26 const float animus_anim_walk    = 1;
27 const float animus_anim_run             = 2;
28 const float animus_anim_leap    = 3;
29 const float animus_anim_pain    = 4;
30 const float animus_anim_death   = 5;
31 const float animus_anim_attack  = 6;
32
33 void animus_touch_jump()
34 {
35         if (self.health <= 0)
36                 return;
37
38         if (monster_isvalidtarget(other, self))
39         {
40                 if (vlen(self.velocity) > 300)
41                 {
42                         Damage(other, self, self, MON_CVAR(animus, attack_jump_damage) * monster_skill, DEATH_MONSTER_ANIMUS, other.origin, normalize(other.origin - self.origin));
43                         self.touch = MonsterTouch; // instantly turn it off to stop damage spam
44                 }
45         }
46
47         if(trace_dphitcontents)
48                 self.touch = MonsterTouch;
49 }
50
51 float animus_attack(float attack_type)
52 {
53         switch(attack_type)
54         {
55                 case MONSTER_ATTACK_MELEE:
56                 {
57                         monsters_setframe(animus_anim_attack);
58                         self.attack_finished_single = time + 1;
59                         monster_melee(self.enemy, MON_CVAR(animus, attack_melee_damage), self.attack_range, DEATH_MONSTER_ANIMUS, TRUE);
60                         
61                         return TRUE;
62                 }
63                 case MONSTER_ATTACK_RANGED:
64                 {
65                         makevectors(self.angles);
66                         if(monster_leap(animus_anim_leap, animus_touch_jump, v_forward * 700 + '0 0 300', 0.8))
67                                 return TRUE;
68                 }
69         }
70         
71         return FALSE;
72 }
73
74 void spawnfunc_monster_animus()
75 {
76         self.classname = "monster_animus";
77         
78         self.monster_spawnfunc = spawnfunc_monster_animus;
79         
80         if(Monster_CheckAppearFlags(self))
81                 return;
82         
83         if not(monster_initialize(MON_ANIMUS, FALSE)) { remove(self); return; }
84 }
85
86 // compatibility with old spawns
87 void spawnfunc_monster_demon1() { spawnfunc_monster_animus(); }
88 void spawnfunc_monster_demon() { spawnfunc_monster_animus(); }
89
90 float m_animus(float req)
91 {
92         switch(req)
93         {
94                 case MR_THINK:
95                 {
96                         monster_move(MON_CVAR(animus, speed_run), MON_CVAR(animus, speed_walk), MON_CVAR(animus, speed_stop), animus_anim_run, animus_anim_walk, animus_anim_stand);
97                         return TRUE;
98                 }
99                 case MR_DEATH:
100                 {
101                         monsters_setframe(animus_anim_death);
102                         return TRUE;
103                 }
104                 case MR_SETUP:
105                 {
106                         if not(self.health) self.health = MON_CVAR(animus, health);
107                         
108                         self.monster_loot = spawnfunc_item_health_medium;
109                         self.monster_attackfunc = animus_attack;
110                         monsters_setframe(animus_anim_stand);
111                         
112                         return TRUE;
113                 }
114                 case MR_INIT:
115                 {
116                         // nothing
117                         return TRUE;
118                 }
119                 case MR_CONFIG:
120                 {
121                         MON_CONFIG_SETTINGS(ANIMUS_SETTINGS(animus))
122                         return TRUE;
123                 }
124         }
125         
126         return TRUE;
127 }
128
129 #endif // SVQC
130 #ifdef CSQC
131 float m_animus(float req)
132 {
133         switch(req)
134         {
135                 case MR_DEATH:
136                 {
137                         // nothing
138                         return TRUE;
139                 }
140                 case MR_INIT:
141                 {
142                         precache_model ("models/monsters/demon.mdl");
143                         return TRUE;
144                 }
145         }
146         
147         return TRUE;
148 }
149
150 #endif // CSQC
151 #endif // REGISTER_MONSTER