1 const vector SPIDER_MIN = '-18 -18 -25';
2 const vector SPIDER_MAX = '18 18 30';
4 string SPIDER_MODEL = "models/monsters/spider.dpm";
7 float autocvar_g_monster_spider;
8 float autocvar_g_monster_spider_stopspeed;
9 float autocvar_g_monster_spider_attack_leap_delay;
10 float autocvar_g_monster_spider_attack_stand_damage;
11 float autocvar_g_monster_spider_attack_stand_delay;
12 float autocvar_g_monster_spider_attack_fire_time;
13 float autocvar_g_monster_spider_health;
14 float autocvar_g_monster_spider_speed_walk;
15 float autocvar_g_monster_spider_speed_run;
16 float autocvar_g_monster_spider_attack_type;
18 const float spider_anim_idle = 0;
19 const float spider_anim_walk = 1;
20 const float spider_anim_attack = 2;
21 const float spider_anim_attack2 = 3;
23 .float spider_type; // used to switch between fire & ice attacks
24 const float SPIDER_TYPE_ICE = 0;
25 const float SPIDER_TYPE_FIRE = 1;
29 self.think = spider_think;
30 self.nextthink = time + self.ticrate;
32 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);
35 void spider_web_explode()
40 float damg = 0, edamg = 0, rad = 1;
41 switch(self.realowner.spider_type)
45 pointparticles(particleeffectnum("electro_impact"), self.origin, '0 0 0', 1);
47 case SPIDER_TYPE_FIRE:
48 pointparticles(particleeffectnum("fireball_explode"), self.origin, '0 0 0', 1);
55 RadiusDamage(self, self.realowner, damg, edamg, 0, world, rad, DEATH_MONSTER_SPIDER_FIRE, world); // ice deals no damage anyway
57 for(e = findradius(self.origin, rad); e; e = e.chain) if(e.takedamage && e.deadflag == DEAD_NO)
59 switch(self.realowner.spider_type)
62 Freeze(e, 0.3, 2, FALSE);
64 case SPIDER_TYPE_FIRE:
65 Fire_AddDamage(e, self.realowner, 5 * monster_skill, autocvar_g_monster_spider_attack_fire_time, DEATH_MONSTER_SPIDER_FIRE);
74 void spider_web_touch()
81 void spider_shootweb(float ptype)
88 p = PROJECTILE_ELECTRO;
89 snd = "weapons/electro_fire2.wav";
91 case SPIDER_TYPE_FIRE:
92 p = PROJECTILE_FIREMINE;
93 snd = "weapons/fireball_fire.wav";
97 vector fmins = '-4 -4 -4', fmaxs = '4 4 4';
99 W_SetupShot_ProjectileSize(self, fmins, fmaxs, FALSE, 2, snd, CH_WEAPON_A, 0);
101 w_shotdir = v_forward; // no TrueAim for grenades please
103 entity proj = spawn ();
104 proj.classname = "plasma";
105 proj.owner = proj.realowner = self;
106 proj.use = spider_web_touch;
107 proj.think = adaptor_think2use_hittype_splash;
108 proj.bot_dodge = TRUE;
109 proj.bot_dodgerating = 0;
110 proj.nextthink = time + 5;
111 PROJECTILE_MAKETRIGGER(proj);
112 proj.projectiledeathtype = DEATH_MONSTER_SPIDER_FIRE;
113 setorigin(proj, w_shotorg);
115 //proj.glow_size = 50;
116 //proj.glow_color = 45;
117 proj.movetype = MOVETYPE_BOUNCE;
118 W_SETUPPROJECTILEVELOCITY_UP(proj, g_monster_spider_attack_web);
119 proj.touch = spider_web_touch;
120 setsize(proj, fmins, fmaxs);
121 proj.takedamage = DAMAGE_NO;
122 proj.damageforcescale = 0;
124 proj.event_damage = func_null;
125 proj.flags = FL_PROJECTILE;
126 proj.damagedbycontents = TRUE;
128 proj.bouncefactor = 0.3;
129 proj.bouncestop = 0.05;
130 proj.missile_flags = MIF_SPLASH | MIF_ARC;
132 CSQCProjectile(proj, TRUE, p, TRUE);
135 float spider_attack(float attack_type)
139 case MONSTER_ATTACK_MELEE:
141 monster_melee(self.enemy, autocvar_g_monster_spider_attack_stand_damage, 0.3, DEATH_MONSTER_SPIDER, TRUE);
142 monsters_setframe((random() > 0.5) ? spider_anim_attack : spider_anim_attack2);
143 self.attack_finished_single = time + autocvar_g_monster_spider_attack_stand_delay;
147 case MONSTER_ATTACK_RANGED:
149 if(self.enemy.frozen)
152 monsters_setframe(spider_anim_attack2);
153 self.attack_finished_single = time + autocvar_g_monster_spider_attack_leap_delay;
154 monster_makevectors(self.enemy);
155 spider_shootweb(self.spider_type);
166 Monster_CheckDropCvars ("spider");
168 self.think = monster_dead_think;
169 self.nextthink = time + self.ticrate;
170 self.ltime = time + 5;
171 monsters_setframe(spider_anim_attack);
172 self.angles += '180 0 0';
174 monster_hook_death(); // for post-death mods
180 self.health = autocvar_g_monster_spider_health;
182 self.classname = "monster_spider";
183 self.nextthink = time + random() * 0.5 + 0.1;
184 self.monster_attackfunc = spider_attack;
185 self.think = spider_think;
187 monsters_setframe(spider_anim_idle);
189 monster_setupsounds("spider");
191 if not(self.spider_type)
192 self.spider_type = autocvar_g_monster_spider_attack_type;
194 monster_hook_spawn(); // for post-spawn mods
197 void spawnfunc_monster_spider()
199 if not(autocvar_g_monster_spider) { remove(self); return; }
201 self.monster_spawnfunc = spawnfunc_monster_spider;
203 if(Monster_CheckAppearFlags(self))
206 if not (monster_initialize(
207 "Spider", MONSTER_SPIDER,
208 SPIDER_MIN, SPIDER_MAX,
210 spider_die, spider_spawn))