]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/shambler.qc
Remove some remaining scale modifiers
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / shambler.qc
1 // size
2 const vector SHAMBLER_MIN = '-32 -32 -24';
3 const vector SHAMBLER_MAX = '32 32 50';
4
5 // model
6 string SHAMBLER_MODEL = "models/monsters/shambler.mdl";
7
8 #ifdef SVQC
9 // cvars
10 float autocvar_g_monster_shambler;
11 float autocvar_g_monster_shambler_health;
12 float autocvar_g_monster_shambler_damage;
13 float autocvar_g_monster_shambler_attack_lightning_damage;
14 float autocvar_g_monster_shambler_attack_claw_damage;
15 float autocvar_g_monster_shambler_speed_walk;
16 float autocvar_g_monster_shambler_speed_run;
17
18 // animations
19 const float shambler_anim_stand         = 0;
20 const float shambler_anim_walk          = 1;
21 const float shambler_anim_run           = 2;
22 const float shambler_anim_smash         = 3;
23 const float shambler_anim_swingr        = 4;
24 const float shambler_anim_swingl        = 5;
25 const float shambler_anim_magic         = 6;
26 const float shambler_anim_pain          = 7;
27 const float shambler_anim_death         = 8;
28
29 void shambler_think ()
30 {
31         self.think = shambler_think;
32         self.nextthink = time + self.ticrate;
33         
34         monster_move(autocvar_g_monster_shambler_speed_run, autocvar_g_monster_shambler_speed_walk, 300, shambler_anim_run, shambler_anim_walk, shambler_anim_stand);
35 }
36
37 void shambler_smash ()
38 {
39         self.monster_delayedattack = func_null;
40         self.delay = -1;
41         
42         monster_melee(self.enemy, autocvar_g_monster_shambler_damage, 0.3, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
43 }
44
45 void shambler_delayedsmash ()
46 {
47         monsters_setframe(shambler_anim_smash);
48         self.monster_delayedattack = shambler_smash;
49         self.delay = time + 0.7;
50         self.attack_finished_single = time + 1.1;
51 }
52
53 void() shambler_swing_right;
54 void shambler_swing_left ()
55 {
56         monsters_setframe(shambler_anim_swingl);
57         monster_melee(self.enemy, autocvar_g_monster_shambler_attack_claw_damage, 0.3, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
58         self.attack_finished_single = time + 0.8;
59         self.delay = -1;
60         self.monster_delayedattack = func_null;
61         if(random() < 0.5)
62         {
63                 self.monster_delayedattack = shambler_swing_right;
64                 self.delay = time + 0.5;
65         }
66 }
67
68 void shambler_swing_right ()
69 {
70         monsters_setframe(shambler_anim_swingr);
71         monster_melee(self.enemy, autocvar_g_monster_shambler_attack_claw_damage, 0.3, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
72         self.attack_finished_single = time + 0.8;
73         self.monster_delayedattack = func_null;
74         self.delay = -1;
75         if(random() < 0.5)
76         {
77                 self.monster_delayedattack = shambler_swing_left;
78                 self.delay = time + 0.5;
79         }
80 }
81
82 void sham_melee ()
83 {
84         local float chance = random();
85
86         if (chance > 0.6)
87                 shambler_delayedsmash();
88         else if (chance > 0.3)
89                 shambler_swing_right ();
90         else
91                 shambler_swing_left ();
92 }
93
94 void CastLightning ()
95 {
96         self.monster_delayedattack = func_null;
97         self.delay = -1;
98
99         local vector org = '0 0 0', dir = '0 0 0';
100         vector v = '0 0 0';
101
102         self.effects |= EF_MUZZLEFLASH;
103
104         org = self.origin + '0 0 40';
105
106         dir = self.enemy.origin + '0 0 16' - org;
107         dir = normalize (dir);
108
109         traceline (org, self.origin + dir * 1000, TRUE, self);
110                 
111         FireRailgunBullet (org, org + dir * 1000, autocvar_g_monster_shambler_attack_lightning_damage * monster_skill, 0, 0, 0, 0, 0, DEATH_MONSTER_SHAMBLER_ZAP);
112         
113         // teamcolor / hit beam effect
114         v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
115         WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), org, v);
116 }
117
118 void shambler_magic ()
119 {
120         monsters_setframe(shambler_anim_magic);
121         self.attack_finished_single = time + 1.1;
122         self.monster_delayedattack = CastLightning;
123         self.delay = time + 0.6;
124 }
125         
126 float sham_lightning ()
127 {
128         shambler_magic();
129         return TRUE;
130 }
131
132 void shambler_die ()
133 {
134         Monster_CheckDropCvars ("shambler");
135         
136         self.think = monster_dead_think;
137         self.nextthink = time + self.ticrate;
138         self.ltime = time + 5;
139         monsters_setframe(shambler_anim_death);
140         
141         monster_hook_death(); // for post-death mods
142 }
143
144 void shambler_spawn ()
145 {
146         if not(self.health)
147                 self.health = autocvar_g_monster_shambler_health;
148
149         self.damageforcescale   = 0.003;
150         self.classname                  = "monster_shambler";
151         self.attack_melee               = sham_melee;
152         self.checkattack                = GenericCheckAttack;
153         self.attack_ranged              = sham_lightning;
154         self.nextthink                  = time + random() * 0.5 + 0.1;
155         self.think                              = shambler_think;
156         self.weapon                             = WEP_NEX;
157         
158         monsters_setframe(shambler_anim_stand);
159         
160         monster_setupsounds("shambler");
161         
162         monster_hook_spawn(); // for post-spawn mods
163 }
164
165 void spawnfunc_monster_shambler ()
166 {       
167         if not(autocvar_g_monster_shambler) { remove(self); return; }
168         
169         self.monster_spawnfunc = spawnfunc_monster_shambler;
170         
171         if(Monster_CheckAppearFlags(self))
172                 return;
173         
174         self.scale = 1.3;
175         
176         if not (monster_initialize(
177                          "Shambler", MONSTER_SHAMBLER,
178                          SHAMBLER_MIN, SHAMBLER_MAX,
179                          FALSE,
180                          shambler_die, shambler_spawn))
181         {
182                 remove(self);
183                 return;
184         }
185 }
186
187 #endif // SVQC