]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/ogre.qc
Move all monster deathtypes to the notifications system
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / ogre.qc
1 // size
2 const vector OGRE_MIN = '-32 -32 -24';
3 const vector OGRE_MAX = '32 32 32';
4  
5 // cvars
6 float autocvar_g_monster_ogre;
7 float autocvar_g_monster_ogre_health;
8 float autocvar_g_monster_ogre_chainsaw_damage;
9 float autocvar_g_monster_ogre_speed_walk;
10 float autocvar_g_monster_ogre_speed_run;
11 float autocvar_g_monster_ogre_attack_uzi_bullets;
12
13 // animations
14 #define ogre_anim_stand         0
15 #define ogre_anim_walk          1
16 #define ogre_anim_run           2
17 #define ogre_anim_swing         3
18 #define ogre_anim_smash         4
19 #define ogre_anim_shoot         5
20 #define ogre_anim_pain1         6
21 #define ogre_anim_pain2         7
22 #define ogre_anim_pain3         8
23 #define ogre_anim_pain4         9
24 #define ogre_anim_pain5         10
25 #define ogre_anim_death1        11
26 #define ogre_anim_death2        12
27 #define ogre_anim_pull          13
28
29 void chainsaw (float side)
30 {
31         if (!self.enemy)
32                 return;
33
34         if (enemy_range() > 100 * self.scale)
35                 return;
36
37         Damage(self.enemy, self, self, autocvar_g_monster_ogre_chainsaw_damage * monster_skill, DEATH_MONSTER_OGRE_CHAINSAW, self.enemy.origin, normalize(self.enemy.origin - self.origin));
38 }
39
40 void ogre_think ()
41 {
42         self.think = ogre_think;
43         self.nextthink = time + 0.1;
44         
45         if(self.delay != -1)
46                 self.nextthink = self.delay;
47         
48         monster_move(autocvar_g_monster_ogre_speed_run, autocvar_g_monster_ogre_speed_walk, 300, ogre_anim_run, ogre_anim_walk, ogre_anim_stand);
49 }
50
51 .float ogre_cycles;
52 void ogre_swing ()
53 {
54         self.ogre_cycles += 1;
55         self.frame = ogre_anim_swing;
56         if(self.ogre_cycles == 1)
57                 self.attack_finished_single = time + 1.3;
58         self.angles_y = self.angles_y + random()* 25;
59         self.nextthink = time + 0.2;
60         self.think = ogre_swing;
61         
62         if(self.ogre_cycles <= 2)
63                 chainsaw(200);
64         else if(self.ogre_cycles <= 4)
65                 chainsaw(-200);
66         else
67                 chainsaw(0);
68         
69         if(self.ogre_cycles >= 4)
70                 self.think = ogre_think;
71 }
72
73 void ogre_uzi_fire ()
74 {
75         self.ogre_cycles += 1;
76         
77         if(self.ogre_cycles > autocvar_g_monster_ogre_attack_uzi_bullets)
78         {
79                 self.monster_delayedattack = func_null;
80                 self.delay = -1;
81                 return;
82         }
83         W_UZI_Attack(DEATH_MONSTER_OGRE_UZI);
84         self.delay = time + 0.1;
85         self.monster_delayedattack = ogre_uzi_fire;
86 }
87
88 void ogre_uzi ()
89 {
90         self.frame = ogre_anim_shoot;
91         self.attack_finished_single = time + 0.8;
92         self.delay = time + 0.1;
93         self.monster_delayedattack = ogre_uzi_fire;
94 }
95
96 void ogre_gl ()
97 {
98         W_Grenade_Attack2();
99         self.frame = ogre_anim_shoot;
100         self.attack_finished_single = time + 0.8;
101 }
102
103 float ogre_missile ()
104 {
105         self.ogre_cycles = 0;
106         if (random() < 0.20)
107         {
108                 ogre_uzi();
109                 return TRUE;
110         }
111         else
112         {
113                 ogre_gl();
114                 return TRUE;
115         }
116 }
117
118 void ogre_melee ()
119 {
120         self.ogre_cycles = 0;
121         ogre_swing();
122 }
123
124 void ogre_die()
125 {
126         Monster_CheckDropCvars ("ogre");
127         
128         self.solid                      = SOLID_NOT;
129         self.takedamage         = DAMAGE_NO;
130         self.event_damage   = func_null;
131         self.enemy                      = world;
132         self.nextthink          = time + 2.1;
133         self.movetype           = MOVETYPE_TOSS;
134         self.think                      = Monster_Fade;
135         
136         W_ThrowNewWeapon(self, WEP_GRENADE_LAUNCHER, 0, self.origin, self.velocity);
137         if (random() < 0.5)
138                 self.frame = ogre_anim_death1;
139         else
140                 self.frame = ogre_anim_death2;
141                 
142         monster_hook_death(); // for post-death mods
143 }
144
145 void ogre_spawn ()
146 {
147         if not(self.health)
148                 self.health = autocvar_g_monster_ogre_health * self.scale;
149
150         self.damageforcescale   = 0.003;
151         self.classname                  = "monster_ogre";
152         self.checkattack                = GenericCheckAttack;
153         self.attack_melee               = ogre_melee;
154         self.frame                              = ogre_anim_pull;
155         self.attack_ranged              = ogre_missile;
156         self.nextthink                  = time + 1;
157         self.think                              = ogre_think;
158         self.sprite_height              = 40 * self.scale;
159         
160         monster_hook_spawn(); // for post-spawn mods
161 }
162
163 void spawnfunc_monster_ogre ()
164 {       
165         if not(autocvar_g_monster_ogre) { remove(self); return; }
166         
167         self.monster_spawnfunc = spawnfunc_monster_ogre;
168         
169         if(self.spawnflags & MONSTERFLAG_APPEAR)
170         {
171                 self.think = func_null;
172                 self.nextthink = -1;
173                 self.use = Monster_Appear;
174                 return;
175         }
176         
177         self.scale = 1.3;
178         
179         if not (monster_initialize(
180                          "Ogre",
181                          "models/monsters/ogre.mdl",
182                          OGRE_MIN, OGRE_MAX,
183                          FALSE,
184                          ogre_die, ogre_spawn))
185         {
186                 remove(self);
187                 return;
188         }
189         
190         weapon_action(WEP_GRENADE_LAUNCHER, WR_PRECACHE);
191 }