]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/ogre.qc
Merge branch 'master' into mario/monsters
[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_NAIL);
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.pain_finished  = self.nextthink;
134         self.movetype           = MOVETYPE_TOSS;
135         self.think                      = Monster_Fade;
136         
137         W_ThrowNewWeapon(self, WEP_GRENADE_LAUNCHER, 0, self.origin, self.velocity);
138         if (random() < 0.5)
139                 self.frame = ogre_anim_death1;
140         else
141                 self.frame = ogre_anim_death2;
142                 
143         monster_hook_death(); // for post-death mods
144 }
145
146 void ogre_spawn ()
147 {
148         if not(self.health)
149                 self.health = autocvar_g_monster_ogre_health * self.scale;
150
151         self.damageforcescale   = 0.003;
152         self.classname                  = "monster_ogre";
153         self.checkattack                = GenericCheckAttack;
154         self.attack_melee               = ogre_melee;
155         self.frame                              = ogre_anim_pull;
156         self.attack_ranged              = ogre_missile;
157         self.nextthink                  = time + 1;
158         self.think                              = ogre_think;
159         self.sprite_height              = 40 * self.scale;
160         
161         monster_hook_spawn(); // for post-spawn mods
162 }
163
164 void spawnfunc_monster_ogre ()
165 {       
166         if not(autocvar_g_monster_ogre) { remove(self); return; }
167         
168         self.monster_spawnfunc = spawnfunc_monster_ogre;
169         
170         if(self.spawnflags & MONSTERFLAG_APPEAR)
171         {
172                 self.think = func_null;
173                 self.nextthink = -1;
174                 self.use = Monster_Appear;
175                 return;
176         }
177         
178         self.scale = 1.3;
179         
180         if not (monster_initialize(
181                          "Ogre",
182                          "models/monsters/ogre.mdl",
183                          OGRE_MIN, OGRE_MAX,
184                          FALSE,
185                          ogre_die, ogre_spawn))
186         {
187                 remove(self);
188                 return;
189         }
190         
191         weapon_action(WEP_GRENADE_LAUNCHER, WR_PRECACHE);
192 }