]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/ogre.qc
Remove unused float from ogre chainsaw function
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / ogre.qc
1 #ifndef MENUQC
2 // size
3 const vector OGRE_MIN = '-36 -36 -20';
4 const vector OGRE_MAX = '36 36 50';
5
6 // model
7 string OGRE_MODEL = "models/monsters/ogre.dpm";
8
9 #endif
10
11 #ifdef SVQC
12 // cvars
13 float autocvar_g_monster_ogre;
14 float autocvar_g_monster_ogre_health;
15 float autocvar_g_monster_ogre_chainsaw_damage;
16 float autocvar_g_monster_ogre_speed_walk;
17 float autocvar_g_monster_ogre_speed_run;
18 float autocvar_g_monster_ogre_attack_uzi_bullets;
19 float autocvar_g_monster_ogre_attack_uzi_damage;
20 float autocvar_g_monster_ogre_attack_uzi_force;
21 float autocvar_g_monster_ogre_attack_uzi_chance;
22 float autocvar_g_monster_ogre_attack_grenade_damage;
23 float autocvar_g_monster_ogre_attack_grenade_edgedamage;
24 float autocvar_g_monster_ogre_attack_grenade_force;
25 float autocvar_g_monster_ogre_attack_grenade_radius;
26
27 // animations
28 const float ogre_anim_idle              = 0;
29 const float ogre_anim_walk              = 1;
30 const float ogre_anim_run               = 2;
31 const float ogre_anim_pain              = 3;
32 const float ogre_anim_swing     = 4;
33 const float ogre_anim_die               = 5;
34
35 void chainsaw()
36 {
37         if (!self.enemy)
38                 return;
39
40         if (vlen(self.enemy.origin - self.origin) > 100 * self.scale)
41                 return;
42
43         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));
44 }
45
46 void ogre_think()
47 {
48         self.think = ogre_think;
49         self.nextthink = time + self.ticrate;
50         
51         if(self.delay != -1)
52                 self.nextthink = self.delay;
53         
54         monster_move(autocvar_g_monster_ogre_speed_run, autocvar_g_monster_ogre_speed_walk, 300, ogre_anim_run, ogre_anim_walk, ogre_anim_idle);
55 }
56
57 .float ogre_cycles;
58 void ogre_swing()
59 {
60         self.ogre_cycles += 1;
61         monsters_setframe(ogre_anim_swing);
62         if(self.ogre_cycles == 1)
63                 self.attack_finished_single = time + 1.3;
64         self.angles_y = self.angles_y + random()* 25;
65         self.nextthink = time + 0.2;
66         self.think = ogre_swing;
67         
68         if(self.ogre_cycles <= 2)
69                 chainsaw();
70         else if(self.ogre_cycles <= 4)
71                 chainsaw();
72         else
73                 chainsaw();
74         
75         if(self.ogre_cycles >= 4)
76                 self.think = ogre_think;
77 }
78
79 void ogre_uzi_fire()
80 {
81         self.ogre_cycles += 1;
82         
83         if(self.ogre_cycles > autocvar_g_monster_ogre_attack_uzi_bullets)
84         {
85                 self.monster_delayedattack = func_null;
86                 self.delay = -1;
87                 return;
88         }
89         
90         W_SetupShot (self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CH_WEAPON_A, autocvar_g_monster_ogre_attack_uzi_damage);
91         fireBallisticBullet(w_shotorg, w_shotdir, 0.02, 18000, 5, autocvar_g_monster_ogre_attack_uzi_damage, autocvar_g_monster_ogre_attack_uzi_force, DEATH_MONSTER_OGRE_UZI, 0, 1, 115);
92         endFireBallisticBullet();
93         
94         self.delay = time + 0.1;
95         self.monster_delayedattack = ogre_uzi_fire;
96 }
97
98 void ogre_uzi()
99 {
100         monsters_setframe(ogre_anim_pain);
101         self.attack_finished_single = time + 0.8;
102         self.delay = time + 0.1;
103         self.monster_delayedattack = ogre_uzi_fire;
104 }
105
106 void ogre_grenade_explode()
107 {
108         pointparticles(particleeffectnum("grenade_explode"), self.origin, '0 0 0', 1);
109         sound(self, CH_SHOTS, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
110
111         self.event_damage = func_null;
112         self.takedamage = DAMAGE_NO;
113
114         if(self.movetype == MOVETYPE_NONE)
115                 self.velocity = self.oldvelocity;
116
117         RadiusDamage (self, self.realowner, autocvar_g_monster_ogre_attack_grenade_damage, autocvar_g_monster_ogre_attack_grenade_edgedamage, autocvar_g_monster_ogre_attack_grenade_radius, world, autocvar_g_monster_ogre_attack_grenade_force, self.projectiledeathtype, other);
118
119         remove (self);
120 }
121
122 void ogre_grenade_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
123 {
124         if (self.health <= 0)
125                 return;
126                 
127         if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
128                 return; // g_projectiles_damage says to halt
129                 
130         self.health = self.health - damage;
131         
132         if (self.health <= 0)
133                 W_PrepareExplosionByDamage(attacker, self.use);
134 }
135
136 void ogre_grenade_touch()
137 {
138         PROJECTILE_TOUCH;
139         
140         self.use ();
141 }
142
143 void ogre_grenade_think()
144 {
145         self.nextthink = time;
146         if (time > self.cnt)
147         {
148                 other = world;
149                 ogre_grenade_explode();
150                 return;
151         }
152 }
153
154 void ogre_gl()
155 {
156         entity gren;
157
158         W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", CH_WEAPON_A, autocvar_g_monster_ogre_attack_grenade_damage);
159         w_shotdir = v_forward; // no TrueAim for grenades please
160
161         gren = spawn ();
162         gren.owner = gren.realowner = self;
163         gren.classname = "grenade";
164         gren.bot_dodge = TRUE;
165         gren.bot_dodgerating = autocvar_g_monster_ogre_attack_grenade_damage;
166         gren.movetype = MOVETYPE_BOUNCE;
167         PROJECTILE_MAKETRIGGER(gren);
168         gren.projectiledeathtype = DEATH_MONSTER_OGRE_GRENADE;
169         setorigin(gren, w_shotorg);
170         setsize(gren, '-3 -3 -3', '3 3 3');
171
172         gren.cnt = time + 5;
173         gren.nextthink = time;
174         gren.think = ogre_grenade_think;
175         gren.use = ogre_grenade_explode;
176         gren.touch = ogre_grenade_touch;
177
178         gren.takedamage = DAMAGE_YES;
179         gren.health = autocvar_g_balance_grenadelauncher_primary_health;
180         gren.damageforcescale = autocvar_g_balance_grenadelauncher_primary_damageforcescale;
181         gren.event_damage = ogre_grenade_damage;
182         gren.damagedbycontents = TRUE;
183         gren.missile_flags = MIF_SPLASH | MIF_ARC;
184         W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
185
186         gren.angles = vectoangles (gren.velocity);
187         gren.flags = FL_PROJECTILE;
188
189         CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
190         
191         
192         monsters_setframe(ogre_anim_pain);
193         self.attack_finished_single = time + 0.8;
194 }
195
196 float ogre_missile()
197 {
198         self.ogre_cycles = 0;
199         if (random() <= autocvar_g_monster_ogre_attack_uzi_chance)
200         {
201                 ogre_uzi();
202                 return TRUE;
203         }
204         else
205         {
206                 ogre_gl();
207                 return TRUE;
208         }
209 }
210
211 void ogre_melee()
212 {
213         self.ogre_cycles = 0;
214         ogre_swing();
215 }
216
217 void ogre_die()
218 {
219         Monster_CheckDropCvars ("ogre");
220         
221         self.think = monster_dead_think;
222         self.nextthink = time + self.ticrate;
223         self.ltime = time + 5;
224         monsters_setframe(ogre_anim_die);
225                 
226         monster_hook_death(); // for post-death mods
227 }
228
229 void ogre_spawn()
230 {
231         if not(self.health)
232                 self.health = autocvar_g_monster_ogre_health * self.scale;
233
234         self.damageforcescale   = 0.003;
235         self.classname                  = "monster_ogre";
236         self.checkattack                = GenericCheckAttack;
237         self.attack_melee               = ogre_melee;
238         self.attack_ranged              = ogre_missile;
239         self.nextthink                  = time + 0.1;
240         self.think                              = ogre_think;
241         self.sprite_height              = 65;
242         self.weapon                             = WEP_GRENADE_LAUNCHER;
243         
244         monsters_setframe(ogre_anim_idle);
245         
246         monster_setupsounds("ogre");
247         
248         monster_hook_spawn(); // for post-spawn mods
249 }
250
251 void spawnfunc_monster_ogre()
252 {       
253         if not(autocvar_g_monster_ogre) { remove(self); return; }
254         
255         self.monster_spawnfunc = spawnfunc_monster_ogre;
256         
257         if(Monster_CheckAppearFlags(self))
258                 return;
259         
260         if not (monster_initialize(
261                          "Ogre", MONSTER_OGRE,
262                          OGRE_MIN, OGRE_MAX,
263                          FALSE,
264                          ogre_die, ogre_spawn))
265         {
266                 remove(self);
267                 return;
268         }
269         
270         weapon_action(WEP_GRENADE_LAUNCHER, WR_PRECACHE);
271 }
272
273 #endif // SVQC