]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/tarbaby.qc
Merge branch 'master' into mario/monsters
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / tarbaby.qc
1 // size
2 const vector TARBABY_MIN = '-16 -16 -24';
3 const vector TARBABY_MAX = '16 16 16';
4
5 // cvars
6 float autocvar_g_monster_tarbaby;
7 float autocvar_g_monster_tarbaby_health;
8 float autocvar_g_monster_tarbaby_speed_walk;
9 float autocvar_g_monster_tarbaby_speed_run;
10
11 // animations
12 #define tarbaby_anim_walk               0
13 #define tarbaby_anim_run                1
14 #define tarbaby_anim_jump               2
15 #define tarbaby_anim_fly                3
16 #define tarbaby_anim_explode    4
17
18 void tarbaby_think ()
19 {
20         self.think = tarbaby_think;
21         self.nextthink = time + 0.1;
22         
23         monster_move(autocvar_g_monster_tarbaby_speed_run, autocvar_g_monster_tarbaby_speed_walk, 20, tarbaby_anim_run, tarbaby_anim_walk, tarbaby_anim_walk);
24 }
25
26 void Tar_JumpTouch ()
27 {
28         // dunno why this would be called when dead, but to be safe
29         if (self.health <= 0)
30                 return;
31                 
32         if (other.takedamage)
33         if (vlen(self.velocity) > 200)
34         {
35                 // make the monster die
36                 self.event_damage(self, self, self.health + self.max_health, DEATH_TOUCHEXPLODE, self.origin, '0 0 0');
37                         
38                 return;
39         }
40
41         if (trace_dphitcontents)
42         {
43                 if not(self.flags & FL_ONGROUND)
44                 {
45                         self.touch = MonsterTouch;
46                         self.flags |= FL_ONGROUND;
47                         self.movetype = MOVETYPE_WALK;
48                 }
49         }
50 }
51
52 void tarbaby_jump ()
53 {
54         if not(self.flags & FL_ONGROUND)
55                 return;
56         self.frame = tarbaby_anim_jump;
57         // dunno why this would be called when dead, but to be safe
58         if (self.health <= 0)
59                 return;
60         self.movetype = MOVETYPE_BOUNCE;
61         self.touch = Tar_JumpTouch;
62         makevectors (self.angles);
63         self.origin_z += 1;
64         self.velocity = v_forward * 600 + '0 0 200';
65         self.velocity_z += random()*150;
66         if (self.flags & FL_ONGROUND)
67                 self.flags -= FL_ONGROUND;
68                 
69         self.attack_finished_single = time + 0.5;
70 }
71
72 float tbaby_jump ()
73 {
74         tarbaby_jump();
75         return TRUE;
76 }
77
78 void tarbaby_blowup ()
79 {
80         float bigboom = 250 * (self.scale * 0.7);
81         RadiusDamage(self, self, 250 * monster_skill, 15, bigboom * (monster_skill * 0.7), world, 250, DEATH_MONSTER_TARBABY_BLOWUP, world);
82         pointparticles(particleeffectnum(((self.scale > 3) ? "explosion_big" : "explosion_medium")), self.origin, '0 0 0', 1);
83         sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
84         
85         Monster_CheckDropCvars ("tarbaby"); // drop items after exploding to prevent player picking up item before dying
86         
87         setmodel(self, "");
88 }
89
90 void tarbaby_explode()
91 {
92         tarbaby_blowup();
93         
94         monster_hook_death(); // calling this next frame should be ok...
95 }
96
97 void tarbaby_die ()
98 {
99         self.solid                      = SOLID_NOT;
100         self.takedamage         = DAMAGE_NO;
101         self.event_damage   = func_null;
102         self.movetype           = MOVETYPE_NONE;
103         self.enemy                      = world;
104         self.think                      = tarbaby_explode;
105         self.nextthink          = time + 0.1;
106 }
107
108 void tarbaby_spawn ()
109 {
110         if not(self.health)
111                 self.health = autocvar_g_monster_tarbaby_health * self.scale;
112         
113         self.damageforcescale   = 0.003;
114         self.classname                  = "monster_tarbaby";
115         self.checkattack                = GenericCheckAttack;
116         self.attack_ranged              = tbaby_jump;
117         self.attack_melee               = tarbaby_jump;
118         self.nextthink                  = time + random() * 0.5 + 0.1;
119         self.think                              = tarbaby_think;
120         self.sprite_height              = 20 * self.scale;
121         self.frame                              = tarbaby_anim_walk;
122         
123         monster_hook_spawn(); // for post-spawn mods
124 }
125
126 void spawnfunc_monster_tarbaby ()
127 {       
128         if not(autocvar_g_monster_tarbaby)
129         {
130                 remove(self);
131                 return;
132         }
133         
134         self.monster_spawnfunc = spawnfunc_monster_tarbaby;
135         
136         if(self.spawnflags & MONSTERFLAG_APPEAR)
137         {
138                 self.think = func_null;
139                 self.nextthink = -1;
140                 self.use = Monster_Appear;
141                 return;
142         }
143         
144         self.scale = 1.3;
145         
146         if not (monster_initialize(
147                          "Spawn",
148                          "models/monsters/tarbaby.mdl",
149                          TARBABY_MIN, TARBABY_MAX,
150                          FALSE,
151                          tarbaby_die, tarbaby_spawn))
152         {
153                 remove(self);
154                 return;
155         }
156         
157         precache_sound ("weapons/rocket_impact.wav");
158 }
159
160 // compatibility with old spawns
161 void spawnfunc_monster_spawn () { spawnfunc_monster_tarbaby(); }