From 8fe62c973b0c08bf204dbcbac1e201a7c8b487b4 Mon Sep 17 00:00:00 2001
From: Mario <mario.mario@y7mail.com>
Date: Sun, 13 Oct 2013 09:49:22 +1100
Subject: [PATCH] Replace spider attacks with a slowness effect

---
 monsters.cfg                            |  5 +-
 qcsrc/common/deathtypes.qh              |  1 -
 qcsrc/common/monsters/monster/spider.qc | 78 ++++++-------------------
 qcsrc/common/monsters/sv_monsters.qc    |  2 +-
 qcsrc/common/monsters/sv_monsters.qh    |  2 +
 qcsrc/common/notifications.qh           |  2 -
 qcsrc/server/cl_physics.qc              |  6 ++
 qcsrc/server/g_damage.qc                |  2 +-
 8 files changed, 30 insertions(+), 68 deletions(-)

diff --git a/monsters.cfg b/monsters.cfg
index 2aa5f4dd5b..2b9e515245 100644
--- a/monsters.cfg
+++ b/monsters.cfg
@@ -13,13 +13,12 @@ set g_monster_zombie_speed_walk 150
 // {{{ #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
 // }}}
diff --git a/qcsrc/common/deathtypes.qh b/qcsrc/common/deathtypes.qh
index 9e16697742..e4404f94e8 100644
--- a/qcsrc/common/deathtypes.qh
+++ b/qcsrc/common/deathtypes.qh
@@ -20,7 +20,6 @@
 	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) \
diff --git a/qcsrc/common/monsters/monster/spider.qc b/qcsrc/common/monsters/monster/spider.qc
index ab35a63b8e..4c52c07dcf 100644
--- a/qcsrc/common/monsters/monster/spider.qc
+++ b/qcsrc/common/monsters/monster/spider.qc
@@ -17,7 +17,6 @@ REGISTER_MONSTER(
 	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) 
@@ -32,44 +31,18 @@ const float spider_anim_walk		= 1;
 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);
 	}
@@ -82,25 +55,11 @@ void spider_web_touch()
 	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";
@@ -111,7 +70,7 @@ void spider_shootweb(float ptype)
 	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;
@@ -131,7 +90,7 @@ void spider_shootweb(float ptype)
 	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)
@@ -144,14 +103,16 @@ 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;
 		}
 	}
 	
@@ -188,7 +149,6 @@ float m_spider(float req)
 		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;
@@ -199,9 +159,7 @@ float m_spider(float req)
 		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:
diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc
index fb24280bad..bad048dcc1 100644
--- a/qcsrc/common/monsters/sv_monsters.qc
+++ b/qcsrc/common/monsters/sv_monsters.qc
@@ -104,7 +104,7 @@ float monster_isvalidtarget (entity targ, entity ent)
 	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)
diff --git a/qcsrc/common/monsters/sv_monsters.qh b/qcsrc/common/monsters/sv_monsters.qh
index 3ac6c87d32..5bdb23b5a4 100644
--- a/qcsrc/common/monsters/sv_monsters.qh
+++ b/qcsrc/common/monsters/sv_monsters.qh
@@ -11,6 +11,8 @@ float monsters_killed;
 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;
diff --git a/qcsrc/common/notifications.qh b/qcsrc/common/notifications.qh
index 7bf58ac95e..26c711f37c 100644
--- a/qcsrc/common/notifications.qh
+++ b/qcsrc/common/notifications.qh
@@ -393,7 +393,6 @@ void Send_Notification_WOCOVA(
 	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"), "") \
@@ -731,7 +730,6 @@ void Send_Notification_WOCOVA(
 	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) \
diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc
index ea193f148a..8a29d14b4a 100644
--- a/qcsrc/server/cl_physics.qc
+++ b/qcsrc/server/cl_physics.qc
@@ -788,6 +788,12 @@ void SV_PlayerPhysics()
 	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))
diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc
index f3516c2741..02450ead17 100644
--- a/qcsrc/server/g_damage.qc
+++ b/qcsrc/server/g_damage.qc
@@ -749,7 +749,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
 			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;
-- 
2.39.5