]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/spider.qc
Remove useless ifdef check
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / spider.qc
1 // size
2 const vector SPIDER_MIN = '-18 -18 -25';
3 const vector SPIDER_MAX = '18 18 30';
4
5 // model
6 string SPIDER_MODEL = "models/monsters/spider.dpm";
7
8 #ifdef SVQC
9 // cvars
10 float autocvar_g_monster_spider;
11 float autocvar_g_monster_spider_stopspeed;
12 float autocvar_g_monster_spider_attack_leap_delay;
13 float autocvar_g_monster_spider_attack_stand_damage;
14 float autocvar_g_monster_spider_attack_stand_delay;
15 float autocvar_g_monster_spider_attack_fire_time;
16 float autocvar_g_monster_spider_health;
17 float autocvar_g_monster_spider_speed_walk;
18 float autocvar_g_monster_spider_speed_run;
19 float autocvar_g_monster_spider_attack_type;
20
21 // animations
22 const float spider_anim_idle            = 0;
23 const float spider_anim_walk            = 1;
24 const float spider_anim_attack          = 2;
25 const float spider_anim_attack2         = 3;
26
27 .float spider_type; // used to switch between fire & ice attacks
28 const float SPIDER_TYPE_ICE             = 0;
29 const float SPIDER_TYPE_FIRE    = 1;
30
31 void spider_attack_standing()
32 {
33         float dot = 0, bigdmg = autocvar_g_monster_spider_attack_stand_damage * self.scale;
34
35         self.velocity_x = 0;
36         self.velocity_y = 0;
37
38         makevectors (self.angles);
39         dot = normalize (self.enemy.origin - self.origin) * v_forward;
40         if(dot > 0.3)
41                 Damage(self.enemy, self, self, bigdmg * monster_skill, DEATH_MONSTER_SPIDER, self.origin, '0 0 0');
42         
43         monsters_setframe((random() > 0.5) ? spider_anim_attack : spider_anim_attack2);
44
45         self.attack_finished_single = time + autocvar_g_monster_spider_attack_stand_delay;
46 }
47
48 void spider_web_explode ()
49 {
50         float damg = 0, edamg = 0, rad = 1;
51         switch(self.realowner.spider_type)
52         {
53                 case SPIDER_TYPE_ICE:
54                         break; // no change
55                 case SPIDER_TYPE_FIRE:
56                         damg = 15;
57                         rad = 25;
58                         edamg = 6;
59                         break;
60         }
61         
62         RadiusDamage (self, self.realowner, damg, edamg, rad, world, 0, self.projectiledeathtype, other);
63         
64         remove (self);
65 }
66
67 void spider_web_touch ()
68 {
69         PROJECTILE_TOUCH;
70         
71         if(other.takedamage == DAMAGE_AIM)
72         if(other.health > 0)
73         switch(self.realowner.spider_type)
74         {
75                 case SPIDER_TYPE_ICE:
76                         Freeze(other, 0.3);
77                         break;
78                 case SPIDER_TYPE_FIRE:
79                         Fire_AddDamage(other, self.realowner, 5 * monster_skill, autocvar_g_monster_spider_attack_fire_time, DEATH_MONSTER_SPIDER_FIRE);
80                         break;
81         }
82                 
83         spider_web_explode();
84 }
85
86 void spider_shootweb(float ptype)
87 {
88         float p = 0, dt = 0;
89         string snd = "";
90         switch(ptype)
91         {
92                 case SPIDER_TYPE_ICE:
93                         p = PROJECTILE_ELECTRO;
94                         dt = WEP_ELECTRO;
95                         snd = "weapons/electro_fire2.wav";
96                         break;
97                 case SPIDER_TYPE_FIRE:
98                         p = ((self.scale >= 2) ? PROJECTILE_FIREBALL : PROJECTILE_FIREMINE);
99                         dt = WEP_FIREBALL;
100                         snd = "weapons/fireball_fire.wav";
101                         break;
102         }
103         
104         vector fmins = ((self.scale >= 2) ? '-16 -16 -16' : '-4 -4 -4'), fmaxs = ((self.scale >= 2) ? '16 16 16' : '4 4 4');    
105         
106         entity proj = world;
107         
108         makevectors(self.angles);
109
110         W_SetupShot_ProjectileSize(self, fmins, fmaxs, FALSE, 2, snd, CH_WEAPON_A, 0);
111
112         w_shotdir = v_forward; // no TrueAim for grenades please
113
114         proj = spawn ();
115         proj.classname = "plasma";
116         proj.owner = proj.realowner = self;
117         proj.use = spider_web_touch;
118         proj.think = adaptor_think2use_hittype_splash;
119         proj.bot_dodge = TRUE;
120         proj.bot_dodgerating = 0;
121         proj.nextthink = time + 5;
122         PROJECTILE_MAKETRIGGER(proj);
123         proj.projectiledeathtype = dt | HITTYPE_SECONDARY;
124         setorigin(proj, w_shotorg);
125
126         //proj.glow_size = 50;
127         //proj.glow_color = 45;
128         proj.movetype = MOVETYPE_BOUNCE;
129         W_SETUPPROJECTILEVELOCITY_UP(proj, g_monster_spider_attack_web);
130         proj.touch = spider_web_touch;
131         setsize(proj, fmins, fmaxs);
132         proj.takedamage = DAMAGE_NO;
133         proj.damageforcescale = 0;
134         proj.health = 500;
135         proj.event_damage = func_null;
136         proj.flags = FL_PROJECTILE;
137         proj.damagedbycontents = TRUE;
138
139         proj.bouncefactor = 0.3;
140         proj.bouncestop = 0.05;
141         proj.missile_flags = MIF_SPLASH | MIF_ARC;
142
143         CSQCProjectile(proj, TRUE, p, FALSE); // no culling, it has sound
144 }
145
146 void spider_attack_leap()
147 {
148         vector angles_face = vectoangles(self.enemy.origin - self.origin);
149
150         // face the enemy
151         monsters_setframe(spider_anim_attack2);
152         self.angles_y = angles_face_y ;
153         self.attack_finished_single = time + autocvar_g_monster_spider_attack_leap_delay;
154         
155         makevectors(self.angles);
156         
157         spider_shootweb(self.spider_type);
158 }
159
160 float spider_attack_ranged()
161 {
162         if(self.enemy.frozen || self.enemy.freezetag_frozen)
163                 return FALSE;
164                 
165         spider_attack_leap();
166         return TRUE;
167 }
168
169 void spider_think()
170 {
171         self.think = spider_think;
172         self.nextthink = time + self.ticrate;
173         
174         monster_move(autocvar_g_monster_spider_speed_run, autocvar_g_monster_spider_speed_walk, autocvar_g_monster_spider_stopspeed, spider_anim_walk, spider_anim_walk, spider_anim_idle);
175 }
176
177 void spider_die ()
178 {
179         Monster_CheckDropCvars ("spider");
180         
181         self.think = monster_dead_think;
182         self.nextthink = time + self.ticrate;
183         self.ltime = time + 5;
184         monsters_setframe(spider_anim_attack);
185         self.angles += '180 0 0';
186         
187         monster_hook_death(); // for post-death mods
188 }
189
190 void spider_spawn() 
191 {
192         if not(self.health)
193                 self.health = autocvar_g_monster_spider_health * self.scale;
194         
195         self.classname                  = "monster_spider";
196         self.nextthink                  = time + random() * 0.5 + 0.1;
197         self.checkattack                = GenericCheckAttack;
198         self.attack_melee               = spider_attack_standing;
199         self.attack_ranged              = spider_attack_ranged;
200         self.think                              = spider_think;
201         
202         monsters_setframe(spider_anim_idle);
203         
204         monster_setupsounds("spider");
205         
206         if not(self.spider_type)
207                 self.spider_type = autocvar_g_monster_spider_attack_type;
208         
209         monster_hook_spawn(); // for post-spawn mods
210 }
211
212 void spawnfunc_monster_spider() 
213 {
214         if not(autocvar_g_monster_spider) { remove(self); return; }
215         
216         self.monster_spawnfunc = spawnfunc_monster_spider;
217         
218         if(Monster_CheckAppearFlags(self))
219                 return;
220         
221         if not (monster_initialize(
222                          "Spider", MONSTER_SPIDER,
223                          SPIDER_MIN, SPIDER_MAX,
224                          FALSE,
225                          spider_die, spider_spawn))
226         {
227                 remove(self);
228                 return;
229         }
230 }
231
232 #endif // SVQC