Browse Source

disarm chest traps trigger on group

Fixes #49

Added group triggers to disarm chest traps.

Rule R_Loot, ChestTriggerRadiusGroup added (by default 10.0f).  Outside radius group members will not be impacted
Image 4 years ago
parent
commit
3234470441

+ 1 - 0
EQ2/source/WorldServer/Rules/Rules.cpp

@@ -288,6 +288,7 @@ RuleManager::RuleManager() {
 
 	RULE_INIT(R_Loot, LootRadius, "5.0");
 	RULE_INIT(R_Loot, AutoDisarmChest, "1");
+	RULE_INIT(R_Loot, ChestTriggerRadiusGroup, "10.0"); // radius at which chest will trigger against group members
 
 	RULE_INIT(R_Spells, NoInterruptBaseChance, "50");
 

+ 2 - 0
EQ2/source/WorldServer/Rules/Rules.h

@@ -148,6 +148,8 @@ enum RuleType {
 	/* LOOT */
 	LootRadius,
 	AutoDisarmChest, // if enabled disarm only works if you right click and disarm, clicking and opening chest won't attempt auto disarm
+	ChestTriggerRadiusGroup,
+	
 	/* SPELLS */
 	NoInterruptBaseChance,
 

+ 33 - 20
EQ2/source/WorldServer/client.cpp

@@ -4118,16 +4118,8 @@ void Client::OpenChest(Entity* entity, bool attemptDisarm)
 		{
 			if (disarmSkill->CheckDisarmSkill(entity->GetLevel(), chest_difficulty) < 1)
 			{
-				Spell* spell = master_spell_list.GetSpell(nextTrap.spell_id, nextTrap.spell_tier);
-				if (spell)
-				{
-					// Get the current zones spell process
-					SpellProcess* spellProcess = GetCurrentZone()->GetSpellProcess();
-
-					spellProcess->CastInstant(spell, entity, (Entity*)GetPlayer());
-				}
-
-				// need to confirm live fail to disarm message (seems now you either trigger or it gives no message?)
+				CastGroupOrSelf(entity, nextTrap.spell_id, nextTrap.spell_tier, 
+					rule_manager.GetGlobalRule(R_Loot, ChestTriggerRadiusGroup)->GetFloat());
 				Message(CHANNEL_COLOR_WHITE, "You trigger the trap on %s!", modelName.c_str());
 			}
 			else
@@ -4140,16 +4132,8 @@ void Client::OpenChest(Entity* entity, bool attemptDisarm)
 		}
 		else // no disarm skill, always fail
 		{
-			Spell* spell = master_spell_list.GetSpell(nextTrap.spell_id, nextTrap.spell_tier);
-
-			if (spell)
-			{
-				// Get the current zones spell process
-				SpellProcess* spellProcess = GetCurrentZone()->GetSpellProcess();
-
-				spellProcess->CastInstant(spell, entity, (Entity*)GetPlayer());
-			}
-
+			CastGroupOrSelf(entity, nextTrap.spell_id, nextTrap.spell_tier, 
+				rule_manager.GetGlobalRule(R_Loot, ChestTriggerRadiusGroup)->GetFloat());
 			Message(CHANNEL_COLOR_WHITE, "You trigger the trap on %s!", modelName.c_str());
 		}
 	}
@@ -4169,6 +4153,35 @@ void Client::OpenChest(Entity* entity, bool attemptDisarm)
 	GetCurrentZone()->SendStateCommand(entity, state);
 }
 
+void Client::CastGroupOrSelf(Entity* source, uint32 spellID, uint32 spellTier, float restrictiveRadius)
+{
+	Spell* spell = master_spell_list.GetSpell(spellID, spellTier);
+	SpellProcess* spellProcess = GetCurrentZone()->GetSpellProcess();
+	if (source == NULL)
+		source = (Entity*)GetPlayer();
+	if (spell)
+	{
+		GroupMemberInfo* gmi = GetPlayer()->GetGroupMemberInfo();
+		if (gmi && gmi->group_id)
+		{
+			deque<GroupMemberInfo*>* members = world.GetGroupManager()->GetGroupMembers(gmi->group_id);
+			for (int8 i = 0; i < members->size(); i++) {
+				Entity* member = members->at(i)->member;
+
+				if (!member->Alive() || (member->GetZone() != source->GetZone()))
+					continue;
+				// if we have a radius provided then check if the group member is outside the radius or not
+				if (restrictiveRadius > 0.0f && member->GetDistance(source) > restrictiveRadius)
+					continue;
+
+				spellProcess->CastInstant(spell, source, (Entity*)GetPlayer());
+			}
+		}
+		else
+			spellProcess->CastInstant(spell, source, (Entity*)GetPlayer());
+	}
+}
+
 Spawn* Client::GetBanker(){
 	return banker;
 }

+ 1 - 0
EQ2/source/WorldServer/client.h

@@ -245,6 +245,7 @@ public:
 	void	Loot(int32 total_coins, vector<Item*>* items, Entity* entity);
 	void	Loot(Entity* entity, bool attemptDisarm=true);
 	void	OpenChest(Entity* entity, bool attemptDisarm=true);
+	void	CastGroupOrSelf(Entity* source, uint32 spellID, uint32 spellTier=1, float restrictiveRadius=0.0f);
 	void	CheckPlayerQuestsKillUpdate(Spawn* spawn);
 	void	CheckPlayerQuestsChatUpdate(Spawn* spawn);
 	void	CheckPlayerQuestsItemUpdate(Item* item);