3 const vector SPIDER_MIN = '-18 -18 -25';
4 const vector SPIDER_MAX = '18 18 30';
7 string SPIDER_MODEL = "models/monsters/spider.dpm";
13 float autocvar_g_monster_spider;
14 float autocvar_g_monster_spider_stopspeed;
15 float autocvar_g_monster_spider_attack_leap_delay;
16 float autocvar_g_monster_spider_attack_stand_damage;
17 float autocvar_g_monster_spider_attack_stand_delay;
18 float autocvar_g_monster_spider_attack_fire_time;
19 float autocvar_g_monster_spider_health;
20 float autocvar_g_monster_spider_speed_walk;
21 float autocvar_g_monster_spider_speed_run;
22 float autocvar_g_monster_spider_attack_type;
25 const float spider_anim_idle = 0;
26 const float spider_anim_walk = 1;
27 const float spider_anim_attack = 2;
28 const float spider_anim_attack2 = 3;
30 .float spider_type; // used to switch between fire & ice attacks
31 const float SPIDER_TYPE_ICE = 0;
32 const float SPIDER_TYPE_FIRE = 1;
34 void spider_attack_standing()
36 float dot = 0, bigdmg = autocvar_g_monster_spider_attack_stand_damage * self.scale;
41 makevectors (self.angles);
42 dot = normalize (self.enemy.origin - self.origin) * v_forward;
44 Damage(self.enemy, self, self, bigdmg * monster_skill, DEATH_MONSTER_SPIDER, self.origin, '0 0 0');
46 monsters_setframe((random() > 0.5) ? spider_anim_attack : spider_anim_attack2);
48 self.attack_finished_single = time + autocvar_g_monster_spider_attack_stand_delay;
51 void spider_web_explode ()
53 float damg = 0, edamg = 0, rad = 1;
54 switch(self.realowner.spider_type)
58 case SPIDER_TYPE_FIRE:
65 RadiusDamage (self, self.realowner, damg, edamg, rad, world, 0, self.projectiledeathtype, other);
70 void spider_web_touch ()
74 if(other.takedamage == DAMAGE_AIM)
75 switch(self.realowner.spider_type)
80 case SPIDER_TYPE_FIRE:
81 Fire_AddDamage(other, self.realowner, 5 * monster_skill, autocvar_g_monster_spider_attack_fire_time, DEATH_MONSTER_SPIDER_FIRE);
88 void spider_shootweb(float ptype)
95 p = PROJECTILE_ELECTRO;
97 snd = "weapons/electro_fire2.wav";
99 case SPIDER_TYPE_FIRE:
100 p = ((self.scale >= 2) ? PROJECTILE_FIREBALL : PROJECTILE_FIREMINE);
102 snd = "weapons/fireball_fire.wav";
106 vector fmins = ((self.scale >= 2) ? '-16 -16 -16' : '-4 -4 -4'), fmaxs = ((self.scale >= 2) ? '16 16 16' : '4 4 4');
110 makevectors(self.angles);
112 W_SetupShot_ProjectileSize(self, fmins, fmaxs, FALSE, 2, snd, CH_WEAPON_A, 0);
114 w_shotdir = v_forward; // no TrueAim for grenades please
117 proj.classname = "plasma";
118 proj.owner = proj.realowner = self;
119 proj.use = spider_web_touch;
120 proj.think = adaptor_think2use_hittype_splash;
121 proj.bot_dodge = TRUE;
122 proj.bot_dodgerating = 0;
123 proj.nextthink = time + 5;
124 PROJECTILE_MAKETRIGGER(proj);
125 proj.projectiledeathtype = dt | HITTYPE_SECONDARY;
126 setorigin(proj, w_shotorg);
128 //proj.glow_size = 50;
129 //proj.glow_color = 45;
130 proj.movetype = MOVETYPE_BOUNCE;
131 W_SETUPPROJECTILEVELOCITY_UP(proj, g_monster_spider_attack_web);
132 proj.touch = spider_web_touch;
133 setsize(proj, fmins, fmaxs);
134 proj.takedamage = DAMAGE_NO;
135 proj.damageforcescale = 0;
137 proj.event_damage = func_null;
138 proj.flags = FL_PROJECTILE;
139 proj.damagedbycontents = TRUE;
141 proj.bouncefactor = 0.3;
142 proj.bouncestop = 0.05;
143 proj.missile_flags = MIF_SPLASH | MIF_ARC;
145 CSQCProjectile(proj, TRUE, p, FALSE); // no culling, it has sound
148 void spider_attack_leap()
150 vector angles_face = vectoangles(self.enemy.origin - self.origin);
153 monsters_setframe(spider_anim_attack2);
154 self.angles_y = angles_face_y ;
155 self.attack_finished_single = time + autocvar_g_monster_spider_attack_leap_delay;
157 makevectors(self.angles);
159 spider_shootweb(self.spider_type);
162 float spider_attack_ranged()
164 if(self.enemy.frozen || self.enemy.freezetag_frozen)
167 spider_attack_leap();
173 self.think = spider_think;
174 self.nextthink = time + self.ticrate;
176 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);
181 Monster_CheckDropCvars ("spider");
183 self.think = Monster_Fade;
184 self.nextthink = time + 5;
185 monsters_setframe(spider_anim_attack);
186 self.angles += '180 0 0';
188 monster_hook_death(); // for post-death mods
194 self.health = autocvar_g_monster_spider_health * self.scale;
196 self.classname = "monster_spider";
197 self.nextthink = time + random() * 0.5 + 0.1;
198 self.checkattack = GenericCheckAttack;
199 self.attack_melee = spider_attack_standing;
200 self.attack_ranged = spider_attack_ranged;
201 self.think = spider_think;
202 self.sprite_height = 40;
204 monsters_setframe(spider_anim_idle);
206 monster_setupsounds("spider");
208 if not(self.spider_type)
209 self.spider_type = autocvar_g_monster_spider_attack_type;
211 monster_hook_spawn(); // for post-spawn mods
214 void spawnfunc_monster_spider()
216 if not(autocvar_g_monster_spider) { remove(self); return; }
218 self.monster_spawnfunc = spawnfunc_monster_spider;
220 if(Monster_CheckAppearFlags(self))
223 if not (monster_initialize(
224 "Spider", MONSTER_SPIDER,
225 SPIDER_MIN, SPIDER_MAX,
227 spider_die, spider_spawn))