// {{{ #2: Spider
set g_monster_spider_attack_bite_damage 35
set g_monster_spider_attack_bite_delay 1.2
-set g_monster_spider_attack_type 0
-set g_monster_spider_attack_web_damagetime 2
+set g_monster_spider_attack_web_damagetime 4
set g_monster_spider_attack_web_delay 1.5
set g_monster_spider_attack_web_speed 1000
set g_monster_spider_attack_web_speed_up 150
set g_monster_spider_health 160
-set g_monster_spider_speed_run 400
+set g_monster_spider_speed_run 450
set g_monster_spider_speed_stop 100
set g_monster_spider_speed_walk 150
// }}}
DEATHTYPE(DEATH_MONSTER_SHAMBLER_SMASH, DEATH_SELF_MON_SHAMBLER_SMASH, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_SHAMBLER_ZAP, DEATH_SELF_MON_SHAMBLER_ZAP, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_SPIDER, DEATH_SELF_MON_SPIDER, DEATH_MURDER_MONSTER, NORMAL_POS) \
- DEATHTYPE(DEATH_MONSTER_SPIDER_FIRE, DEATH_SELF_MON_SPIDER_FIRE, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_WYVERN, DEATH_SELF_MON_WYVERN, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_ZOMBIE_JUMP, DEATH_SELF_MON_ZOMBIE_JUMP, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_ZOMBIE_MELEE, DEATH_SELF_MON_ZOMBIE_MELEE, DEATH_MURDER_MONSTER, DEATH_MONSTER_LAST) \
MON_ADD_CVAR(monster, attack_web_speed) \
MON_ADD_CVAR(monster, attack_web_speed_up) \
MON_ADD_CVAR(monster, attack_web_delay) \
- MON_ADD_CVAR(monster, attack_type) \
MON_ADD_CVAR(monster, speed_stop) \
MON_ADD_CVAR(monster, speed_run) \
MON_ADD_CVAR(monster, speed_walk)
const float spider_anim_attack = 2;
const float spider_anim_attack2 = 3;
-.float spider_type; // used to switch between fire & ice attacks
-const float SPIDER_TYPE_ICE = 0;
-const float SPIDER_TYPE_FIRE = 1;
+.float spider_web_delay;
void spider_web_explode()
{
entity e;
if(self)
{
- float damg = 0, edamg = 0, rad = 1;
- switch(self.realowner.spider_type)
- {
- case SPIDER_TYPE_ICE:
- rad = 25;
- pointparticles(particleeffectnum("electro_impact"), self.origin, '0 0 0', 1);
- break;
- case SPIDER_TYPE_FIRE:
- pointparticles(particleeffectnum("fireball_explode"), self.origin, '0 0 0', 1);
- damg = 15;
- rad = 25;
- edamg = 6;
- break;
- }
+ pointparticles(particleeffectnum("electro_impact"), self.origin, '0 0 0', 1);
+ RadiusDamage(self, self.realowner, 0, 0, 25, world, 25, self.projectiledeathtype, world);
- RadiusDamage(self, self.realowner, damg, edamg, rad, world, rad, DEATH_MONSTER_SPIDER_FIRE, world); // ice deals no damage anyway
-
- for(e = findradius(self.origin, rad); e; e = e.chain) if(e != self) if(e.takedamage && e.deadflag == DEAD_NO) if(e.health > 0)
- {
- switch(self.realowner.spider_type)
- {
- case SPIDER_TYPE_ICE:
- Freeze(e, 0.3, 2, FALSE);
- break;
- case SPIDER_TYPE_FIRE:
- Fire_AddDamage(e, self.realowner, 5 * Monster_SkillModifier(), MON_CVAR(spider, attack_web_damagetime), DEATH_MONSTER_SPIDER_FIRE);
- break;
- }
- }
+ for(e = findradius(self.origin, 25); e; e = e.chain) if(e != self) if(e.takedamage && e.deadflag == DEAD_NO) if(e.health > 0)
+ e.spider_slowness = time + MON_CVAR(spider, attack_web_damagetime);
remove(self);
}
spider_web_explode();
}
-void spider_shootweb(float ptype)
+void spider_shootweb()
{
- float p = 0;
- string snd = "";
- switch(ptype)
- {
- case SPIDER_TYPE_ICE:
- p = PROJECTILE_ELECTRO;
- snd = "weapons/electro_fire2.wav";
- break;
- case SPIDER_TYPE_FIRE:
- p = PROJECTILE_FIREMINE;
- snd = "weapons/fireball_fire.wav";
- break;
- }
-
monster_makevectors(self.enemy);
- sound(self, CH_SHOTS, snd, VOL_BASE, ATTEN_NORM);
+ sound(self, CH_SHOTS, "weapons/electro_fire2.wav", VOL_BASE, ATTEN_NORM);
entity proj = spawn ();
proj.classname = "plasma";
proj.bot_dodgerating = 0;
proj.nextthink = time + 5;
PROJECTILE_MAKETRIGGER(proj);
- proj.projectiledeathtype = DEATH_MONSTER_SPIDER_FIRE;
+ proj.projectiledeathtype = DEATH_MONSTER_SPIDER;
setorigin(proj, CENTER_OR_VIEWOFS(self));
//proj.glow_size = 50;
proj.bouncestop = 0.05;
proj.missile_flags = MIF_SPLASH | MIF_ARC;
- CSQCProjectile(proj, TRUE, p, TRUE);
+ CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO, TRUE);
}
float spider_attack(float attack_type)
}
case MONSTER_ATTACK_RANGED:
{
- if(self.enemy.frozen)
- return FALSE;
-
- self.frame = spider_anim_attack2;
- self.attack_finished_single = time + MON_CVAR(spider, attack_web_delay);
- spider_shootweb(self.spider_type);
+ if(time >= self.spider_web_delay)
+ {
+ self.frame = spider_anim_attack2;
+ self.attack_finished_single = time + MON_CVAR(spider, attack_web_delay);
+ spider_shootweb();
+ self.spider_web_delay = time + 3;
+ return TRUE;
+ }
- return TRUE;
+ return FALSE;
}
}
case MR_SETUP:
{
if not(self.health) self.health = MON_CVAR(spider, health);
- if not(self.spider_type) self.spider_type = MON_CVAR(spider, attack_type);
self.monster_loot = spawnfunc_item_health_medium;
self.monster_attackfunc = spider_attack;
case MR_PRECACHE:
{
precache_model ("models/monsters/spider.dpm");
- precache_model ("models/ice/ice.md3");
precache_sound ("weapons/electro_fire2.wav");
- precache_sound ("weapons/fireball_fire.wav");
return TRUE;
}
case MR_CONFIG:
if(SAME_TEAM(targ, ent))
return FALSE; // enemy is on our team
- if (targ.frozen == 1 || (targ.frozen == 2 && ent.monsterid != MON_SPIDER))
+ if (targ.frozen)
return FALSE; // ignore frozen
if(autocvar_g_monsters_target_infront || ent.spawnflags & MONSTERFLAG_INFRONT)
void monsters_setstatus(); // monsters.qc
.float monster_moveflags; // checks where to move when not attacking
+.float spider_slowness; // special spider timer
+
void monster_remove(entity mon); // removes a monster
.float(float attack_type) monster_attackfunc;
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was smashed by a Shambler%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was zapped to death by a Shambler%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was bitten by a Spider%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SPIDER_FIRE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was incinerated by a Spider%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SHAMBLER_SMASH, NO_MSG, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SHAMBLER_ZAP, NO_MSG, INFO_DEATH_SELF_MON_SHAMBLER_ZAP, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SPIDER, NO_MSG, INFO_DEATH_SELF_MON_SPIDER, CENTER_DEATH_SELF_MONSTER) \
- MSG_MULTI_NOTIF(1, DEATH_SELF_MON_SPIDER_FIRE, NO_MSG, INFO_DEATH_SELF_MON_SPIDER_FIRE, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_WYVERN, NO_MSG, INFO_DEATH_SELF_MON_WYVERN, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_JUMP, NO_MSG, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_MELEE, NO_MSG, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, CENTER_DEATH_SELF_MONSTER) \
if(time < self.ladder_time)
self.disableclientprediction = 1;
+ if(time < self.spider_slowness)
+ {
+ self.stat_sv_maxspeed *= 0.5; // half speed while slow from spider
+ self.stat_sv_airspeedlimit_nonqw *= 0.5;
+ }
+
if(self.frozen)
{
if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
mirrorforce *= g_weaponforcefactor;
}
- if(((targ.frozen == 2 && attacker.monsterid != MON_SPIDER) || (targ.frozen == 1)) && deathtype != DEATH_HURTTRIGGER)
+ if(targ.frozen && deathtype != DEATH_HURTTRIGGER)
{
damage = 0;
force *= 0.2;