]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/slime.qc
Merge branch 'master' into Mario/monsters
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / slime.qc
1 // size
2 const vector SLIME_MIN = '-16 -16 -24';
3 const vector SLIME_MAX = '16 16 16';
4
5 // model
6 string SLIME_MODEL = "models/monsters/slime.dpm";
7
8 #ifdef SVQC
9 // cvars
10 float autocvar_g_monster_slime;
11 float autocvar_g_monster_slime_health;
12 float autocvar_g_monster_slime_speed_walk;
13 float autocvar_g_monster_slime_speed_run;
14
15 // animations
16 const float slime_anim_walk             = 0;
17 const float slime_anim_idle             = 1;
18 const float slime_anim_jump             = 2;
19 const float slime_anim_fly              = 3;
20 const float slime_anim_die              = 4;
21 const float slime_anim_pain             = 5;
22
23 void() slime_dead;
24
25 void slime_think()
26 {
27         self.think = slime_think;
28         self.nextthink = time + self.ticrate;
29         
30         monster_move(autocvar_g_monster_slime_speed_run, autocvar_g_monster_slime_speed_walk, 20, slime_anim_walk, slime_anim_walk, slime_anim_idle);
31 }
32
33 void slime_touch_jump()
34 {
35         if(self.health > 0)
36         if(other.health > 0)
37         if(other.takedamage)
38         if(vlen(self.velocity) > 200)
39         {
40                 slime_dead();
41                         
42                 return;
43         }
44
45         if(trace_dphitcontents)
46         {
47                 self.touch = MonsterTouch;
48                 self.movetype = MOVETYPE_WALK;
49         }
50 }
51
52 float slime_attack(float attack_type)
53 {
54         switch(attack_type)
55         {
56                 case MONSTER_ATTACK_MELEE:
57                 case MONSTER_ATTACK_RANGED:
58                 {
59                         makevectors(self.angles);
60                         if(monster_leap(slime_anim_jump, slime_touch_jump, v_forward * 600 + '0 0 200', 0.5))
61                                 return TRUE;
62                 }
63         }
64         
65         return FALSE;
66 }
67
68 void slime_explode()
69 {
70         RadiusDamage(self, self, 250 * monster_skill, 15, 250 * (monster_skill * 0.7), world, 250, DEATH_MONSTER_SLIME, world);
71         pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
72         sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
73         
74         Monster_CheckDropCvars ("slime"); // drop items after exploding to prevent player picking up item before dying
75         
76         setmodel(self, "");
77 }
78
79 void slime_dead()
80 {
81         self.health = -100; // gibbed
82         slime_explode();
83         
84         self.think = Monster_Fade;
85         self.nextthink = time;
86         
87         monster_hook_death();
88         
89         self.event_damage = func_null; // reset by monster_hook_death
90         self.takedamage = DAMAGE_NO;
91 }
92
93 void slime_die()
94 {
95         self.think                      = slime_dead;
96         self.nextthink          = time;
97         self.event_damage   = func_null;
98         self.movetype           = MOVETYPE_NONE;
99         self.enemy                      = world;
100         self.health                     = 0;
101         
102         self.SendFlags |= MSF_MOVE | MSF_STATUS;
103 }
104
105 void slime_spawn()
106 {
107         if not(self.health)
108                 self.health = autocvar_g_monster_slime_health;
109         
110         self.damageforcescale   = 0.003;
111         self.classname                  = "monster_slime";
112         self.monster_attackfunc = slime_attack;
113         self.nextthink                  = time + random() * 0.5 + 0.1;
114         self.think                              = slime_think;
115         
116         monsters_setframe(slime_anim_idle);
117         
118         monster_setupsounds("slime");
119         
120         monster_hook_spawn(); // for post-spawn mods
121 }
122
123 void spawnfunc_monster_slime()
124 {       
125         if not(autocvar_g_monster_slime) { remove(self); return; }
126         
127         self.monster_spawnfunc = spawnfunc_monster_slime;
128         
129         if(Monster_CheckAppearFlags(self))
130                 return;
131         
132         if not (monster_initialize(
133                          "Slime", MONSTER_SLIME,
134                          SLIME_MIN, SLIME_MAX,
135                          FALSE,
136                          slime_die, slime_spawn))
137         {
138                 remove(self);
139                 return;
140         }
141 }
142
143 // compatibility with old spawns
144 void spawnfunc_monster_tarbaby() { spawnfunc_monster_slime(); }
145
146 #endif // SVQC