]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/demon.qc
Replace enforcer model with e-wheel
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / demon.qc
1 // cvars
2 float autocvar_g_monster_demon;
3 float autocvar_g_monster_demon_health;
4 float autocvar_g_monster_demon_attack_jump_damage;
5 float autocvar_g_monster_demon_damage;
6 float autocvar_g_monster_demon_speed_walk;
7 float autocvar_g_monster_demon_speed_run;
8
9 // size
10 const vector DEMON_MIN = '-32 -32 -24';
11 const vector DEMON_MAX = '32 32 24';
12
13 // animation
14 #define demon_anim_stand  0
15 #define demon_anim_walk   1
16 #define demon_anim_run  2
17 #define demon_anim_leap   3
18 #define demon_anim_pain   4
19 #define demon_anim_death  5
20 #define demon_anim_attack 6
21
22 void demon_think ()
23 {
24         self.think = demon_think;
25         self.nextthink = time + 0.1;
26         
27         monster_move(autocvar_g_monster_demon_speed_run, autocvar_g_monster_demon_speed_walk, 100, demon_anim_run, demon_anim_walk, demon_anim_stand);
28 }
29
30 void demon_attack_melee ()
31 {
32         float bigdmg = autocvar_g_monster_demon_damage * self.scale;
33         
34         self.frame = demon_anim_attack;
35         self.attack_finished_single = time + 1;
36         
37         monster_melee(self.enemy, bigdmg * monster_skill, 120, DEATH_MONSTER_DEMON_MELEE);
38 }
39
40 void Demon_JumpTouch ()
41 {
42         if (self.health <= 0)
43                 return;
44                 
45         float bigdmg = autocvar_g_monster_demon_attack_jump_damage * self.scale;
46
47         if (monster_isvalidtarget(other, self, FALSE))
48         {
49                 if (vlen(self.velocity) > 300)
50                 {
51                         Damage(other, self, self, bigdmg * monster_skill, DEATH_MONSTER_DEMON_JUMP, other.origin, normalize(other.origin - self.origin));
52                         self.touch = MonsterTouch; // instantly turn it off to stop damage spam
53                 }
54         }
55
56         if(self.flags & FL_ONGROUND)
57                 self.touch = MonsterTouch;
58 }
59
60 float demon_jump ()
61 {
62         makevectors(self.angles);
63         if(monster_leap(demon_anim_leap, Demon_JumpTouch, v_forward * 700 + '0 0 300', 0.8))
64                 return TRUE;
65                 
66         return FALSE;
67 }
68
69 void demon_die ()
70 {
71         Monster_CheckDropCvars ("demon");
72         
73         self.frame                      = demon_anim_death;
74         self.think                      = Monster_Fade; 
75         self.solid                      = SOLID_NOT;
76         self.takedamage         = DAMAGE_NO;
77         self.event_damage   = func_null;
78         self.movetype           = MOVETYPE_TOSS;
79         self.enemy                      = world;
80         self.nextthink          = time + 3;
81         self.pain_finished  = self.nextthink;
82         
83         monster_hook_death(); // for post-death mods
84 }
85
86 void demon_spawn ()
87 {
88         if not(self.health)
89                 self.health = autocvar_g_monster_demon_health * self.scale;
90
91         self.damageforcescale   = 0;
92         self.classname                  = "monster_demon";
93         self.checkattack                = GenericCheckAttack;
94         self.attack_melee               = demon_attack_melee;
95         self.attack_ranged              = demon_jump;
96         self.nextthink                  = time + random() * 0.5 + 0.1;
97         self.frame                              = demon_anim_stand;
98         self.think                              = demon_think;
99         self.sprite_height              = 30 * self.scale;
100         
101         monster_hook_spawn(); // for post-spawn mods
102 }
103
104 /* QUAKED monster_demon (1 0 0) (-32 -32 -24) (32 32 64) Ambush */
105 void spawnfunc_monster_demon ()
106 {       
107         if not(autocvar_g_monster_demon) { remove(self); return; }
108         
109         self.monster_spawnfunc = spawnfunc_monster_demon;
110         
111         if(self.spawnflags & MONSTERFLAG_APPEAR)
112         {
113                 self.think = func_null;
114                 self.nextthink = -1;
115                 self.use = Monster_Appear;
116                 return;
117         }
118         
119         self.scale = 1.3;
120         
121         if not (monster_initialize(
122                          "Fiend",
123                          "models/monsters/demon.mdl",
124                          DEMON_MIN, DEMON_MAX,
125                          FALSE,
126                          demon_die, demon_spawn))
127         {
128                 remove(self);
129                 return;
130         }
131 }
132
133 // Compatibility with old spawns
134 void spawnfunc_monster_demon1 () { spawnfunc_monster_demon(); }