Merge branch 'master' into Playerbot
This commit is contained in:
@@ -194,6 +194,7 @@ ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature),
|
||||
{
|
||||
_isHeroic = me->GetMap()->IsHeroic();
|
||||
_difficulty = Difficulty(me->GetMap()->GetSpawnMode());
|
||||
_invincible = false;
|
||||
}
|
||||
|
||||
void ScriptedAI::AttackStartNoMove(Unit* who)
|
||||
@@ -222,6 +223,12 @@ void ScriptedAI::UpdateAI(uint32 /*diff*/)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void ScriptedAI::DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/)
|
||||
{
|
||||
if (IsInvincible() && damage >= me->GetHealth())
|
||||
damage = me->GetHealth() - 1;
|
||||
}
|
||||
|
||||
void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle)
|
||||
{
|
||||
if (victim)
|
||||
@@ -732,8 +739,10 @@ void BossAI::UpdateAI(uint32 diff)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void BossAI::DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/)
|
||||
void BossAI::DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask)
|
||||
{
|
||||
ScriptedAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask);
|
||||
|
||||
if (_nextHealthCheck._valid)
|
||||
if (me->HealthBelowPctDamaged(_nextHealthCheck._healthPct, damage))
|
||||
{
|
||||
|
||||
@@ -198,7 +198,7 @@ struct ScriptedAI : public CreatureAI
|
||||
void AttackStartNoMove(Unit* target);
|
||||
|
||||
// Called at any Damage from any attacker (before damage apply)
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override {}
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override;
|
||||
|
||||
//Called at World update tick
|
||||
void UpdateAI(uint32 diff) override;
|
||||
@@ -438,9 +438,14 @@ struct ScriptedAI : public CreatureAI
|
||||
|
||||
Player* SelectTargetFromPlayerList(float maxdist, uint32 excludeAura = 0, bool mustBeInLOS = false) const;
|
||||
|
||||
// Allows dropping to 1 HP but prevents creature from dying.
|
||||
void SetInvincibility(bool apply) { _invincible = apply; };
|
||||
[[nodiscard]] bool IsInvincible() const { return _invincible; };
|
||||
|
||||
private:
|
||||
Difficulty _difficulty;
|
||||
bool _isHeroic;
|
||||
bool _invincible;
|
||||
std::unordered_set<uint32> _uniqueTimedEvents;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "SmartAI.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
// however, for some reasons removing it would cause a damn linking issue
|
||||
@@ -696,6 +697,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (isWithinLOSInMap && isWithinMeleeRange && isRangedAttack && isTargetRooted && canCastSpell && !me->IsVehicle())
|
||||
{
|
||||
failedSpellCast = true; // Mark spellcast as failed so we can retry it later
|
||||
|
||||
if (me->IsRooted()) // Rooted inhabit type, never move/reposition
|
||||
continue;
|
||||
|
||||
float minDistance = std::max(meleeRange, spellMinRange) - distanceToTarget + NOMINAL_MELEE_RANGE;
|
||||
CAST_AI(SmartAI, me->AI())->MoveAway(std::min(minDistance, spellMaxRange));
|
||||
continue;
|
||||
@@ -705,12 +710,20 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (distanceToTarget > spellMaxRange && isWithinLOSInMap)
|
||||
{
|
||||
failedSpellCast = true;
|
||||
|
||||
if (me->IsRooted()) // Rooted inhabit type, never move/reposition
|
||||
continue;
|
||||
|
||||
CAST_AI(SmartAI, me->AI())->SetCombatMove(true, std::max(spellMaxRange - NOMINAL_MELEE_RANGE, 0.0f));
|
||||
continue;
|
||||
}
|
||||
else if (distanceToTarget < spellMinRange || !(isWithinLOSInMap || isSpellIgnoreLOS))
|
||||
{
|
||||
failedSpellCast = true;
|
||||
|
||||
if (me->IsRooted()) // Rooted inhabit type, never move/reposition
|
||||
continue;
|
||||
|
||||
CAST_AI(SmartAI, me->AI())->SetCombatMove(true);
|
||||
continue;
|
||||
}
|
||||
@@ -3257,6 +3270,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_WORLD_SCRIPT:
|
||||
{
|
||||
sWorldState->HandleExternalEvent(static_cast<WorldStateEvent>(e.action.worldStateScript.eventId), e.action.worldStateScript.param);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
break;
|
||||
@@ -5061,7 +5079,7 @@ void SmartScript::GetScript()
|
||||
|
||||
if (CreatureTemplate const* cInfo = me->GetCreatureTemplate())
|
||||
{
|
||||
if (cInfo->HasFlagsExtra(CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI))
|
||||
if (cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI))
|
||||
{
|
||||
e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType);
|
||||
FillScript(e, me, nullptr);
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
#ifndef ACORE_SMARTSCRIPT_H
|
||||
#define ACORE_SMARTSCRIPT_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "SmartScriptMgr.h"
|
||||
#include "Spell.h"
|
||||
|
||||
@@ -777,6 +777,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
case SMART_ACTION_MOVEMENT_STOP: return NO_PARAMS;
|
||||
case SMART_ACTION_MOVEMENT_PAUSE: return sizeof(SmartAction::move);
|
||||
case SMART_ACTION_MOVEMENT_RESUME: return sizeof(SmartAction::move);
|
||||
case SMART_ACTION_WORLD_SCRIPT: return sizeof(SmartAction::worldStateScript);
|
||||
default:
|
||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||
@@ -1960,6 +1961,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
case SMART_ACTION_MOVEMENT_STOP:
|
||||
case SMART_ACTION_MOVEMENT_PAUSE:
|
||||
case SMART_ACTION_MOVEMENT_RESUME:
|
||||
case SMART_ACTION_WORLD_SCRIPT:
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "DBCStores.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Optional.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Unit.h"
|
||||
#include <limits>
|
||||
|
||||
typedef uint32 SAIBool;
|
||||
@@ -727,8 +726,9 @@ enum SMART_ACTION
|
||||
SMART_ACTION_MOVEMENT_STOP = 234, //
|
||||
SMART_ACTION_MOVEMENT_PAUSE = 235, // timer
|
||||
SMART_ACTION_MOVEMENT_RESUME = 236, // timerOverride
|
||||
SMART_ACTION_WORLD_SCRIPT = 237, // eventId, param
|
||||
|
||||
SMART_ACTION_AC_END = 237, // placeholder
|
||||
SMART_ACTION_AC_END = 238, // placeholder
|
||||
};
|
||||
|
||||
enum class SmartActionSummonCreatureFlags
|
||||
@@ -1472,6 +1472,12 @@ struct SmartAction
|
||||
{
|
||||
uint32 timer;
|
||||
} move;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 eventId;
|
||||
uint32 param;
|
||||
} worldStateScript;
|
||||
//! Note for any new future actions
|
||||
//! All parameters must have type uint32
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "Battlefield.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "World.h"
|
||||
|
||||
class Group;
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
#define __BATTLEGROUNDQUEUE_H
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "EventProcessor.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "SharedDefines.h"
|
||||
#include <array>
|
||||
|
||||
constexpr auto COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME = 10;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#ifndef _CHANNEL_H
|
||||
#define _CHANNEL_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include <string>
|
||||
|
||||
@@ -506,6 +506,9 @@ bool Acore::Impl::ChatCommands::ChatCommandNode::IsInvokerVisible(ChatHandler co
|
||||
if (!_invoker)
|
||||
return false;
|
||||
|
||||
if (!sScriptMgr->OnBeforeIsInvokerVisible(_name, _permission, who))
|
||||
return true;
|
||||
|
||||
if (who.IsConsole() && (_permission.AllowConsole == Acore::ChatCommands::Console::No))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "World.h"
|
||||
|
||||
using namespace Acore::Hyperlinks;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "Spell.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
// Checks if object meets the condition
|
||||
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
|
||||
@@ -570,6 +571,11 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
||||
condMeets = unit->IsCharmed();
|
||||
break;
|
||||
}
|
||||
case CONDITION_WORLD_SCRIPT:
|
||||
{
|
||||
condMeets = sWorldState->IsConditionFulfilled(static_cast<WorldStateCondition>(ConditionValue1), static_cast<WorldStateConditionState>(ConditionValue2));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
condMeets = false;
|
||||
break;
|
||||
@@ -770,6 +776,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
|
||||
case CONDITION_CHARMED:
|
||||
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
|
||||
break;
|
||||
case CONDITION_WORLD_SCRIPT:
|
||||
mask |= GRID_MAP_TYPE_MASK_ALL;
|
||||
break;
|
||||
default:
|
||||
ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
|
||||
break;
|
||||
|
||||
@@ -86,7 +86,9 @@ enum ConditionTypes
|
||||
CONDITION_AC_START = 100,
|
||||
CONDITION_QUEST_SATISFY_EXCLUSIVE = 101, // quest_id 0 0 true if satisfied exclusive group
|
||||
CONDITION_HAS_AURA_TYPE = 102, // aura_type 0 0 true if has aura type
|
||||
CONDITION_AC_END = 103 // placeholder
|
||||
CONDITION_WORLD_SCRIPT = 103, // conditionId state 0 true if WorldState::IsConditionFulfilled returns true
|
||||
|
||||
CONDITION_AC_END = 104 // placeholder
|
||||
};
|
||||
|
||||
/*! Documentation on implementing a new ConditionSourceType:
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#ifndef _LFGQUEUE_H
|
||||
#define _LFGQUEUE_H
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "LFG.h"
|
||||
|
||||
namespace lfg
|
||||
|
||||
@@ -22,10 +22,8 @@
|
||||
#include "CharmInfo.h"
|
||||
#include "Common.h"
|
||||
#include "CreatureData.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "LootMgr.h"
|
||||
#include "Unit.h"
|
||||
#include "World.h"
|
||||
#include <list>
|
||||
|
||||
class SpellInfo;
|
||||
|
||||
@@ -69,7 +69,7 @@ enum CreatureFlagsExtra : uint32
|
||||
CREATURE_FLAG_EXTRA_MODULE = 0x01000000,
|
||||
CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE = 0x02000000, // Prevent creatures from calling for assistance on initial aggro
|
||||
CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS = 0x04000000, // Prevents creature from responding to assistance calls
|
||||
CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI = 0x08000000, // Load both ENTRY and GUID specific SAI
|
||||
CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI = 0x08000000, // Load both ENTRY and GUID specific SAI
|
||||
CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)
|
||||
CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding
|
||||
CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Log.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "QueryResult.h"
|
||||
#include "WaypointMgr.h"
|
||||
|
||||
FormationMgr::~FormationMgr()
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define _FORMATIONS_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Unit.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "NPCHandler.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "QuestDef.h"
|
||||
#include <map>
|
||||
|
||||
class WorldSession;
|
||||
class ObjectGuid;
|
||||
|
||||
@@ -58,7 +58,7 @@ AC_API_EXPORT EnumText EnumUtils<CreatureFlagsExtra>::ToString(CreatureFlagsExtr
|
||||
case CREATURE_FLAG_EXTRA_MODULE: return { "CREATURE_FLAG_EXTRA_MODULE", "CREATURE_FLAG_EXTRA_MODULE", "" };
|
||||
case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return { "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "Prevent creatures from calling for assistance on initial aggro" };
|
||||
case CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS: return { "CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS", "CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS", "Prevents creature from responding to assistance calls" };
|
||||
case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return { "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "Load both ENTRY and GUID specific SAI" };
|
||||
case CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI: return { "CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI", "CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI", "Load both ENTRY and GUID specific SAI" };
|
||||
case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return { "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)" };
|
||||
case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return { "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "creature ignore pathfinding" };
|
||||
case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return { "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "creature is immune to knockback effects" };
|
||||
@@ -102,7 +102,7 @@ AC_API_EXPORT CreatureFlagsExtra EnumUtils<CreatureFlagsExtra>::FromIndex(std::s
|
||||
case 24: return CREATURE_FLAG_EXTRA_MODULE;
|
||||
case 25: return CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE;
|
||||
case 26: return CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS;
|
||||
case 27: return CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI;
|
||||
case 27: return CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI;
|
||||
case 28: return CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
|
||||
case 29: return CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING;
|
||||
case 30: return CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK;
|
||||
@@ -143,7 +143,7 @@ AC_API_EXPORT std::size_t EnumUtils<CreatureFlagsExtra>::ToIndex(CreatureFlagsEx
|
||||
case CREATURE_FLAG_EXTRA_MODULE: return 24;
|
||||
case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return 25;
|
||||
case CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS: return 26;
|
||||
case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return 27;
|
||||
case CREATURE_FLAG_EXTRA_DONT_OVERRIDE_ENTRY_SAI: return 27;
|
||||
case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return 28;
|
||||
case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return 29;
|
||||
case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return 30;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#define AZEROTHCORE_GAMEOBJECT_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "G3D/Quat.h"
|
||||
#include "GameObjectData.h"
|
||||
#include "LootMgr.h"
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
#define GAMEOBJECTDATA_H
|
||||
|
||||
#include "SharedDefines.h"
|
||||
#include "WorldPacket.h"
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define MAX_GAMEOBJECT_QUEST_ITEMS 6
|
||||
#define MAX_GO_STATE 3
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "QueryResult.h"
|
||||
#include "Util.h"
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "ByteBuffer.h"
|
||||
#include "Geometry.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Random.h"
|
||||
#include <G3D/g3dmath.h>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
#define CinematicMgr_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include "Object.h"
|
||||
#include "Position.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include <vector>
|
||||
|
||||
constexpr auto CINEMATIC_UPDATEDIFF = 500;
|
||||
constexpr auto CINEMATIC_LOOKAHEAD = 2000;
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldState.h"
|
||||
#include <cmath>
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
@@ -1722,6 +1723,7 @@ void Player::RemoveFromWorld()
|
||||
m_session->DoLootRelease(lguid);
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sWorldState->HandlePlayerLeaveZone(this, static_cast<WorldStateZoneId>(m_zoneUpdateId));
|
||||
}
|
||||
|
||||
// Remove items from world before self - player must be found in Item::RemoveFromObjectUpdate
|
||||
@@ -6930,7 +6932,7 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
|
||||
float maxDamage = proto->Damage[i].DamageMax;
|
||||
|
||||
// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
|
||||
if (ssv)
|
||||
if (ssv && i == 0) // scaling stats only for first damage
|
||||
{
|
||||
int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
|
||||
if (extraDPS)
|
||||
@@ -6945,6 +6947,8 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
|
||||
|
||||
if (apply)
|
||||
{
|
||||
sScriptMgr->OnApplyWeaponDamage(this, slot, proto, minDamage, maxDamage, i);
|
||||
|
||||
if (minDamage > 0.f)
|
||||
{
|
||||
SetBaseWeaponDamage(WeaponAttackType(attType), MINDAMAGE, minDamage, i);
|
||||
|
||||
@@ -1423,6 +1423,7 @@ public:
|
||||
void CompleteQuest(uint32 quest_id);
|
||||
void IncompleteQuest(uint32 quest_id);
|
||||
void RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, bool announce = true, bool isLFGReward = false);
|
||||
void SetRewardedQuest(uint32 quest_id);
|
||||
void FailQuest(uint32 quest_id);
|
||||
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
|
||||
bool SatisfyQuestLevel(Quest const* qInfo, bool msg) const;
|
||||
|
||||
@@ -819,8 +819,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
SetSeasonalQuestStatus(quest_id);
|
||||
|
||||
RemoveActiveQuest(quest_id, false);
|
||||
m_RewardedQuests.insert(quest_id);
|
||||
m_RewardedQuestsSave[quest_id] = true;
|
||||
SetRewardedQuest(quest_id);
|
||||
|
||||
if (announce)
|
||||
SendQuestReward(quest, XP);
|
||||
@@ -877,6 +876,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
sScriptMgr->OnPlayerCompleteQuest(this, quest);
|
||||
}
|
||||
|
||||
void Player::SetRewardedQuest(uint32 quest_id)
|
||||
{
|
||||
m_RewardedQuests.insert(quest_id);
|
||||
m_RewardedQuestsSave[quest_id] = true;
|
||||
}
|
||||
|
||||
void Player::FailQuest(uint32 questId)
|
||||
{
|
||||
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "Vehicle.h"
|
||||
#include "Weather.h"
|
||||
#include "WeatherMgr.h"
|
||||
#include "WorldState.h"
|
||||
#include "WorldStatePackets.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
@@ -1216,6 +1217,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||
{
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sOutdoorPvPMgr->HandlePlayerEnterZone(this, newZone);
|
||||
sWorldState->HandlePlayerLeaveZone(this, static_cast<WorldStateZoneId>(m_zoneUpdateId));
|
||||
sWorldState->HandlePlayerEnterZone(this, static_cast<WorldStateZoneId>(newZone));
|
||||
sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
|
||||
sBattlefieldMgr->HandlePlayerEnterZone(this, newZone);
|
||||
SendInitWorldStates(newZone,
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
#ifndef _CHARMINFO_H
|
||||
#define _CHARMINFO_H
|
||||
|
||||
#include "Object.h"
|
||||
#include "Define.h"
|
||||
#include "ObjectGuid.h"
|
||||
|
||||
#define MAX_SPELL_CHARM 4
|
||||
#define MAX_SPELL_VEHICLE 6
|
||||
|
||||
@@ -180,6 +180,7 @@ enum eScriptFlags
|
||||
// Playsound flags
|
||||
SF_PLAYSOUND_TARGET_PLAYER = 0x1,
|
||||
SF_PLAYSOUND_DISTANCE_SOUND = 0x2,
|
||||
SF_PLAYSOUND_DISTANCE_RADIUS = 0x4,
|
||||
|
||||
// Orientation flags
|
||||
SF_ORIENTATION_FACE_TARGET = 0x1,
|
||||
@@ -307,6 +308,7 @@ struct ScriptInfo
|
||||
{
|
||||
uint32 SoundID; // datalong
|
||||
uint32 Flags; // datalong2
|
||||
int32 Radius; // dataint
|
||||
} Playsound;
|
||||
|
||||
struct // SCRIPT_COMMAND_CREATE_ITEM (17)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "Grid.h"
|
||||
#include "GridReference.h"
|
||||
#include "Timer.h"
|
||||
#include "Util.h"
|
||||
|
||||
template
|
||||
<
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "Optional.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
@@ -59,6 +59,9 @@ void InstanceScript::OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
AddObject(creature);
|
||||
AddMinion(creature);
|
||||
|
||||
if (creature->IsSummon())
|
||||
SetSummoner(creature);
|
||||
}
|
||||
|
||||
void InstanceScript::OnCreatureRemove(Creature* creature)
|
||||
@@ -194,6 +197,15 @@ void InstanceScript::LoadObjectData(ObjectData const* data, ObjectInfoMap& objec
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceScript::LoadSummonData(ObjectData const* data)
|
||||
{
|
||||
while (data->entry)
|
||||
{
|
||||
_summonInfo[data->entry] = data->type;
|
||||
++data;
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceScript::UpdateMinionState(Creature* minion, EncounterState state)
|
||||
{
|
||||
switch (state)
|
||||
@@ -348,6 +360,16 @@ void InstanceScript::RemoveMinion(Creature* minion)
|
||||
AddMinion(minion, false);
|
||||
}
|
||||
|
||||
void InstanceScript::SetSummoner(Creature* creature)
|
||||
{
|
||||
auto const& summonData = _summonInfo.find(creature->GetEntry());
|
||||
|
||||
if (summonData != _summonInfo.end())
|
||||
if (Creature* summoner = GetCreature(summonData->second))
|
||||
if (summoner->IsAIEnabled)
|
||||
summoner->AI()->JustSummoned(creature);
|
||||
}
|
||||
|
||||
bool InstanceScript::SetBossState(uint32 id, EncounterState state)
|
||||
{
|
||||
if (id < bosses.size())
|
||||
@@ -393,7 +415,11 @@ void InstanceScript::StorePersistentData(uint32 index, uint32 data)
|
||||
return;
|
||||
}
|
||||
|
||||
persistentData[index] = data;
|
||||
if (persistentData[index] != data)
|
||||
{
|
||||
persistentData[index] = data;
|
||||
SaveToDB();
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceScript::DoForAllMinions(uint32 id, std::function<void(Creature*)> exec)
|
||||
|
||||
@@ -288,6 +288,11 @@ protected:
|
||||
void LoadDoorData(DoorData const* data);
|
||||
void LoadMinionData(MinionData const* data);
|
||||
void LoadObjectData(ObjectData const* creatureData, ObjectData const* gameObjectData);
|
||||
// Allows setting another creature as summoner for a creature.
|
||||
// This is used to handle summons that are not directly controlled by the summoner.
|
||||
// Summoner creature must be loaded in the instance data (LoadObjectData).
|
||||
void LoadSummonData(ObjectData const* data);
|
||||
void SetSummoner(Creature* creature);
|
||||
|
||||
void AddObject(Creature* obj, bool add = true);
|
||||
void RemoveObject(Creature* obj);
|
||||
@@ -324,6 +329,7 @@ private:
|
||||
MinionInfoMap minions;
|
||||
ObjectInfoMap _creatureInfo;
|
||||
ObjectInfoMap _gameObjectInfo;
|
||||
ObjectInfoMap _summonInfo;
|
||||
ObjectGuidMap _objectGuids;
|
||||
ObjectStateMap _objectStateMap;
|
||||
uint32 completedEncounters; // completed encounter mask, bit indexes are DungeonEncounter.dbc boss numbers, used for packets
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PreparedStatement.h"
|
||||
#include "QueryResult.h"
|
||||
|
||||
LootItemStorage::LootItemStorage()
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "MapInstanced.h"
|
||||
#include "Metric.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "MMapFactory.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectGridLoader.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "InstanceScript.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "QueryResult.h"
|
||||
#include "Transport.h"
|
||||
|
||||
TransportTemplate::~TransportTemplate()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef __DYNAMICVISIBILITY_H
|
||||
#define __DYNAMICVISIBILITY_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Define.h"
|
||||
|
||||
struct VisibilitySettingData
|
||||
{
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
#define ACORE_MOTIONMASTER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "PathGenerator.h"
|
||||
#include "Position.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Spline/MoveSpline.h"
|
||||
#include <optional>
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
#ifndef ACORE_FLEEINGMOVEMENTGENERATOR_H
|
||||
#define ACORE_FLEEINGMOVEMENTGENERATOR_H
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "Timer.h"
|
||||
|
||||
template<class T>
|
||||
class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovementGenerator<T> >
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "MMapFactory.h"
|
||||
#include "MMapMgr.h"
|
||||
#include "MapDefines.h"
|
||||
#include "MoveSplineInitArgs.h"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef ACORE_POINTMOVEMENTGENERATOR_H
|
||||
#define ACORE_POINTMOVEMENTGENERATOR_H
|
||||
|
||||
#include "FollowerReference.h"
|
||||
#include "Creature.h"
|
||||
#include "MovementGenerator.h"
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Spell.h"
|
||||
#include "Util.h"
|
||||
#include "World.h"
|
||||
|
||||
template<class T>
|
||||
RandomMovementGenerator<T>::~RandomMovementGenerator() { }
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
#include "PathGenerator.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#define RANDOM_POINTS_NUMBER 12
|
||||
#define RANDOM_LINKS_COUNT 7
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef ACORE_WAYPOINTMANAGER_H
|
||||
#define ACORE_WAYPOINTMANAGER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Define.h"
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Log.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "QueryResult.h"
|
||||
#include "Transport.h"
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
#ifndef __ACORE_REPUTATION_MGR_H
|
||||
#define __ACORE_REPUTATION_MGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnvFwd.h"
|
||||
#include "DBCStructure.h"
|
||||
#include "Language.h"
|
||||
#include "QueryResult.h"
|
||||
#include "SharedDefines.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
@@ -20,14 +20,12 @@
|
||||
#include "GridNotifiers.h"
|
||||
#include "Map.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MapRefMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Transport.h"
|
||||
#include "WaypointMgr.h"
|
||||
#include "World.h"
|
||||
|
||||
/// Put scripts in the execution queue
|
||||
void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
|
||||
@@ -730,8 +728,10 @@ void Map::ScriptsProcess()
|
||||
break;
|
||||
}
|
||||
|
||||
// Playsound.Flags bitmask: 0/2=without/with distance dependent
|
||||
if (step.script->Playsound.Flags & SF_PLAYSOUND_DISTANCE_SOUND)
|
||||
// Playsound.Flags bitmask: 0/2/4=without/with distance dependent/radius
|
||||
if (step.script->Playsound.Flags & SF_PLAYSOUND_DISTANCE_RADIUS)
|
||||
object->PlayRadiusSound(step.script->Playsound.SoundID, step.script->Playsound.Radius);
|
||||
else if (step.script->Playsound.Flags & SF_PLAYSOUND_DISTANCE_SOUND)
|
||||
object->PlayDistanceSound(step.script->Playsound.SoundID, player);
|
||||
else
|
||||
object->PlayDirectSound(step.script->Playsound.SoundID, player);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "AllCommandScript.h"
|
||||
#include "ChatCommand.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptMgrMacros.h"
|
||||
|
||||
@@ -29,6 +30,11 @@ bool ScriptMgr::OnTryExecuteCommand(ChatHandler& handler, std::string_view cmdSt
|
||||
CALL_ENABLED_BOOLEAN_HOOKS(AllCommandScript, ALLCOMMANDHOOK_ON_TRY_EXECUTE_COMMAND, !script->OnTryExecuteCommand(handler, cmdStr));
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnBeforeIsInvokerVisible(std::string name, Acore::Impl::ChatCommands::CommandPermissions permissions, ChatHandler const& who)
|
||||
{
|
||||
CALL_ENABLED_BOOLEAN_HOOKS(AllCommandScript, ALLCOMMANDHOOK_ON_BEFORE_IS_INVOKER_VISIBLE, !script->OnBeforeIsInvokerVisible(name, permissions, who));
|
||||
}
|
||||
|
||||
AllCommandScript::AllCommandScript(const char* name, std::vector<uint16> enabledHooks)
|
||||
: ScriptObject(name, ALLCOMMANDHOOK_END)
|
||||
{
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
#define SCRIPT_OBJECT_ALL_COMMAND_SCRIPT_H_
|
||||
|
||||
#include "ScriptObject.h"
|
||||
#include "ChatCommand.h"
|
||||
#include <vector>
|
||||
|
||||
enum AllCommandHook
|
||||
{
|
||||
ALLCOMMANDHOOK_ON_HANDLE_DEV_COMMAND,
|
||||
ALLCOMMANDHOOK_ON_TRY_EXECUTE_COMMAND,
|
||||
ALLCOMMANDHOOK_ON_BEFORE_IS_INVOKER_VISIBLE,
|
||||
ALLCOMMANDHOOK_END
|
||||
};
|
||||
|
||||
@@ -45,6 +47,8 @@ public:
|
||||
* @param cmdStr Contains information about the command name
|
||||
*/
|
||||
[[nodiscard]] virtual bool OnTryExecuteCommand(ChatHandler& /*handler*/, std::string_view /*cmdStr*/) { return true; }
|
||||
|
||||
[[nodiscard]] virtual bool OnBeforeIsInvokerVisible(std::string /*name*/, Acore::Impl::ChatCommands::CommandPermissions /*permissions*/, ChatHandler const& /*who*/) { return true; }
|
||||
};
|
||||
|
||||
// Compatibility for old scripts
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#ifndef SCRIPT_OBJECT_GLOBAL_SCRIPT_H_
|
||||
#define SCRIPT_OBJECT_GLOBAL_SCRIPT_H_
|
||||
|
||||
#include "DatabaseEnvFwd.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "ScriptObject.h"
|
||||
|
||||
@@ -652,6 +652,11 @@ void ScriptMgr::OnApplyEnchantmentItemModsBefore(Player* player, Item* item, Enc
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_APPLY_ENCHANTMENT_ITEM_MODS_BEFORE, script->OnApplyEnchantmentItemModsBefore(player, item, slot, apply, enchant_spell_id, enchant_amount));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnApplyWeaponDamage(Player* player, uint8 slot, ItemTemplate const* proto, float& minDamage, float& maxDamage, uint8 damageIndex)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_APPLY_WEAPON_DAMAGE, script->OnApplyWeaponDamage(player, slot, proto, minDamage, maxDamage, damageIndex));
|
||||
}
|
||||
|
||||
bool ScriptMgr::CanArmorDamageModifier(Player* player)
|
||||
{
|
||||
CALL_ENABLED_BOOLEAN_HOOKS(PlayerScript, PLAYERHOOK_CAN_ARMOR_DAMAGE_MODIFIER, !script->CanArmorDamageModifier(player));
|
||||
|
||||
@@ -150,6 +150,7 @@ enum PlayerHook
|
||||
PLAYERHOOK_ON_CUSTOM_SCALING_STAT_VALUE,
|
||||
PLAYERHOOK_ON_APPLY_ITEM_MODS_BEFORE,
|
||||
PLAYERHOOK_ON_APPLY_ENCHANTMENT_ITEM_MODS_BEFORE,
|
||||
PLAYERHOOK_ON_APPLY_WEAPON_DAMAGE,
|
||||
PLAYERHOOK_CAN_ARMOR_DAMAGE_MODIFIER,
|
||||
PLAYERHOOK_ON_GET_FERAL_AP_BONUS,
|
||||
PLAYERHOOK_CAN_APPLY_WEAPON_DEPENDENT_AURA_DAMAGE_MOD,
|
||||
@@ -548,6 +549,8 @@ public:
|
||||
|
||||
virtual void OnApplyEnchantmentItemModsBefore(Player* /*player*/, Item* /*item*/, EnchantmentSlot /*slot*/, bool /*apply*/, uint32 /*enchant_spell_id*/, uint32& /*enchant_amount*/) { }
|
||||
|
||||
virtual void OnApplyWeaponDamage(Player* /*player*/, uint8 /*slot*/, ItemTemplate const* /*proto*/, float& /*minDamage*/, float& /*maxDamage*/, uint8 /*damageIndex*/) { }
|
||||
|
||||
[[nodiscard]] virtual bool CanArmorDamageModifier(Player* /*player*/) { return true; }
|
||||
|
||||
virtual void OnGetFeralApBonus(Player* /*player*/, int32& /*feral_bonus*/, int32 /*dpsMod*/, ItemTemplate const* /*proto*/, ScalingStatValuesEntry const* /*ssv*/) { }
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "ScriptObject.h"
|
||||
#include <vector>
|
||||
#include <memory> // NOTE: this import is NEEDED (even though some IDEs report it as unused)
|
||||
|
||||
enum ServerHook
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ArenaTeam.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Battleground.h"
|
||||
#include "ChatCommand.h"
|
||||
#include "Common.h"
|
||||
#include "DBCStores.h"
|
||||
#include "DynamicObject.h"
|
||||
@@ -444,6 +445,7 @@ public: /* PlayerScript */
|
||||
void OnCustomScalingStatValue(Player* player, ItemTemplate const* proto, uint32& statType, int32& val, uint8 itemProtoStatNumber, uint32 ScalingStatValue, ScalingStatValuesEntry const* ssv);
|
||||
void OnApplyItemModsBefore(Player* player, uint8 slot, bool apply, uint8 itemProtoStatNumber, uint32 statType, int32& val);
|
||||
void OnApplyEnchantmentItemModsBefore(Player* player, Item* item, EnchantmentSlot slot, bool apply, uint32 enchant_spell_id, uint32& enchant_amount);
|
||||
void OnApplyWeaponDamage(Player* player, uint8 slot, ItemTemplate const* proto, float& minDamage, float& maxDamage, uint8 damageIndex);
|
||||
bool CanArmorDamageModifier(Player* player);
|
||||
void OnGetFeralApBonus(Player* player, int32& feral_bonus, int32 dpsMod, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv);
|
||||
bool CanApplyWeaponDependentAuraDamageMod(Player* player, Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
||||
@@ -704,6 +706,7 @@ public: /* CommandSC */
|
||||
|
||||
void OnHandleDevCommand(Player* player, bool& enable);
|
||||
bool OnTryExecuteCommand(ChatHandler& handler, std::string_view cmdStr);
|
||||
bool OnBeforeIsInvokerVisible(std::string name, Acore::Impl::ChatCommands::CommandPermissions permissions, ChatHandler const& who);
|
||||
|
||||
public: /* DatabaseScript */
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#ifndef _SCRIPT_OBJECT_H_
|
||||
#define _SCRIPT_OBJECT_H_
|
||||
|
||||
#include "DatabaseEnvFwd.h"
|
||||
#include "ScriptObjectFwd.h"
|
||||
#include <string>
|
||||
|
||||
//#include "Duration.h"
|
||||
//#include "LFG.h"
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSocket.h"
|
||||
#include "WorldState.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include "BanMgr.h"
|
||||
@@ -641,6 +642,7 @@ void WorldSession::LogoutPlayer(bool save)
|
||||
_player->RepopAtGraveyard();
|
||||
|
||||
sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
|
||||
sWorldState->HandlePlayerLeaveZone(_player, static_cast<WorldStateZoneId>(_player->GetZoneId()));
|
||||
|
||||
// pussywizard: remove from battleground queues on logout
|
||||
for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
|
||||
|
||||
@@ -18,11 +18,13 @@
|
||||
#ifndef __SPELL_H
|
||||
#define __SPELL_H
|
||||
|
||||
#include "ConditionMgr.h"
|
||||
#include "GridDefines.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "LootMgr.h"
|
||||
#include "PathGenerator.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class Unit;
|
||||
class Player;
|
||||
|
||||
@@ -1152,13 +1152,29 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex)
|
||||
|
||||
void Spell::CalculateJumpSpeeds(uint8 i, float dist, float& speedXY, float& speedZ)
|
||||
{
|
||||
if (m_spellInfo->Effects[i].MiscValue)
|
||||
speedZ = float(m_spellInfo->Effects[i].MiscValue) / 10;
|
||||
else if (m_spellInfo->Effects[i].MiscValueB)
|
||||
speedZ = float(m_spellInfo->Effects[i].MiscValueB) / 10;
|
||||
float runSpeed = m_caster->IsControlledByPlayer() ? playerBaseMoveSpeed[MOVE_RUN] : baseMoveSpeed[MOVE_RUN];
|
||||
if (Creature* creature = m_caster->ToCreature())
|
||||
runSpeed *= creature->GetCreatureTemplate()->speed_run;
|
||||
|
||||
float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
|
||||
if (multiplier <= 0.0f)
|
||||
multiplier = 1.0f;
|
||||
|
||||
speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
|
||||
|
||||
float duration = dist / speedXY;
|
||||
float durationSqr = duration * duration;
|
||||
float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
|
||||
float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
|
||||
float height;
|
||||
if (durationSqr < minHeight * 8 / Movement::gravity)
|
||||
height = minHeight;
|
||||
else if (durationSqr > maxHeight * 8 / Movement::gravity)
|
||||
height = maxHeight;
|
||||
else
|
||||
speedZ = 10.0f;
|
||||
speedXY = dist * 10.0f / speedZ;
|
||||
height = Movement::gravity * durationSqr / 8;
|
||||
|
||||
speedZ = std::sqrt(2 * Movement::gravity * height);
|
||||
}
|
||||
|
||||
void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/)
|
||||
@@ -1869,6 +1885,12 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
|
||||
if (!unitTarget->IsAlive())
|
||||
return;
|
||||
|
||||
if (unitTarget->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
{
|
||||
m_caster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
|
||||
return;
|
||||
|
||||
@@ -3663,6 +3685,12 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)
|
||||
if (!unitTarget || !unitTarget->IsAlive())
|
||||
return;
|
||||
|
||||
if (unitTarget->HasUnitState(UNIT_STATE_ISOLATED))
|
||||
{
|
||||
m_caster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id);
|
||||
return;
|
||||
}
|
||||
|
||||
int32 addhealth = 0;
|
||||
|
||||
// damage == 0 - heal for caster max health
|
||||
@@ -4743,8 +4771,8 @@ void Spell::EffectQuestComplete(SpellEffIndex effIndex)
|
||||
uint16 logSlot = player->FindQuestSlot(questId);
|
||||
if (logSlot < MAX_QUEST_LOG_SIZE)
|
||||
player->AreaExploredOrEventHappens(questId);
|
||||
else if (player->CanTakeQuest(quest, false)) // never rewarded before
|
||||
player->CompleteQuest(questId); // quest not in log - for internal use
|
||||
else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
|
||||
player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1389,18 +1389,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
|
||||
});
|
||||
|
||||
// A'dal's Song of Battle
|
||||
ApplySpellFix({ 39953 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
|
||||
spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
|
||||
spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_SRC_CASTER);
|
||||
spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
|
||||
spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
|
||||
spellInfo->Effects[EFFECT_2].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
|
||||
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(367); // 2 Hours
|
||||
});
|
||||
|
||||
ApplySpellFix({
|
||||
57607, // WintergraspCatapult - Spell Plague Barrel - EffectRadiusIndex
|
||||
57619, // WintergraspDemolisher - Spell Hourl Boulder - EffectRadiusIndex
|
||||
@@ -4856,6 +4844,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_SUPPRESS_CASTER_PROCS;
|
||||
});
|
||||
|
||||
// Claw Rage
|
||||
ApplySpellFix({ 43149 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].TriggerSpell = 0;
|
||||
});
|
||||
|
||||
// Black Qiraji Battle Tank
|
||||
ApplySpellFix({ 26655, 26656 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "Define.h"
|
||||
#include "Duration.h"
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
constexpr auto AVG_DIFF_COUNT = 500;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "DBCStores.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "QueryResult.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "World.h"
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#define _PLAYER_DUMP_H
|
||||
|
||||
#include "ObjectGuid.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
enum DumpTableType
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "WardenCheckMgr.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "QueryResult.h"
|
||||
#include "Util.h"
|
||||
#include "Warden.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "Player.h"
|
||||
#include "Weather.h"
|
||||
#include "WorldSession.h"
|
||||
#include <memory>
|
||||
|
||||
namespace WeatherMgr
|
||||
{
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
#include "WhoListCacheMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldState.h"
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <cmath>
|
||||
|
||||
@@ -2414,6 +2415,11 @@ void World::Update(uint32 diff)
|
||||
sOutdoorPvPMgr->Update(diff);
|
||||
}
|
||||
|
||||
{
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update worldstate"));
|
||||
sWorldState->Update(diff);
|
||||
}
|
||||
|
||||
{
|
||||
METRIC_TIMER("world_update_time", METRIC_TAG("type", "Update battlefields"));
|
||||
sBattlefieldMgr->Update(diff);
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#ifndef __WORLD_H
|
||||
#define __WORLD_H
|
||||
|
||||
#include "DatabaseEnvFwd.h"
|
||||
#include "IWorld.h"
|
||||
#include "LockedQueue.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "QueryResult.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Timer.h"
|
||||
#include <atomic>
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "MapMgr.h"
|
||||
#include "Player.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "WorldState.h"
|
||||
|
||||
WorldState* WorldState::instance()
|
||||
{
|
||||
static WorldState instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
WorldState::WorldState() : _isMagtheridonHeadSpawnedHorde(false), _isMagtheridonHeadSpawnedAlliance(false)
|
||||
{
|
||||
_transportStates[WORLD_STATE_CONDITION_THE_IRON_EAGLE] = WORLD_STATE_CONDITION_STATE_NONE;
|
||||
_transportStates[WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS] = WORLD_STATE_CONDITION_STATE_NONE;
|
||||
_transportStates[WORLD_STATE_CONDITION_THE_THUNDERCALLER] = WORLD_STATE_CONDITION_STATE_NONE;
|
||||
}
|
||||
|
||||
WorldState::~WorldState()
|
||||
{
|
||||
}
|
||||
|
||||
bool WorldState::IsConditionFulfilled(WorldStateCondition conditionId, WorldStateConditionState state) const
|
||||
{
|
||||
switch (conditionId)
|
||||
{
|
||||
case WORLD_STATE_CONDITION_TROLLBANES_COMMAND:
|
||||
return _isMagtheridonHeadSpawnedAlliance;
|
||||
case WORLD_STATE_CONDITION_NAZGRELS_FAVOR:
|
||||
return _isMagtheridonHeadSpawnedHorde;
|
||||
case WORLD_STATE_CONDITION_THE_IRON_EAGLE:
|
||||
case WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS:
|
||||
case WORLD_STATE_CONDITION_THE_THUNDERCALLER:
|
||||
return _transportStates.at(conditionId) == state;
|
||||
default:
|
||||
LOG_ERROR("scripts", "WorldState::IsConditionFulfilled: Unhandled WorldStateCondition {}", conditionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldState::HandleConditionStateChange(WorldStateCondition conditionId, WorldStateConditionState state)
|
||||
{
|
||||
_transportStates[conditionId] = state;
|
||||
}
|
||||
|
||||
void WorldState::HandleExternalEvent(WorldStateEvent eventId, uint32 param)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
switch (eventId)
|
||||
{
|
||||
case WORLD_STATE_CUSTOM_EVENT_ON_ADALS_SONG_OF_BATTLE:
|
||||
if (!_adalSongOfBattleTimer)
|
||||
{
|
||||
_adalSongOfBattleTimer = 120 * MINUTE * IN_MILLISECONDS;
|
||||
BuffAdalsSongOfBattle();
|
||||
}
|
||||
break;
|
||||
case WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_SPAWN:
|
||||
if (param == TEAM_ALLIANCE)
|
||||
{
|
||||
_isMagtheridonHeadSpawnedAlliance = true;
|
||||
BuffMagtheridonTeam(TEAM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isMagtheridonHeadSpawnedHorde = true;
|
||||
BuffMagtheridonTeam(TEAM_HORDE);
|
||||
}
|
||||
break;
|
||||
case WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_DESPAWN:
|
||||
if (param == TEAM_ALLIANCE)
|
||||
{
|
||||
_isMagtheridonHeadSpawnedAlliance = false;
|
||||
DispelMagtheridonTeam(TEAM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isMagtheridonHeadSpawnedHorde = false;
|
||||
DispelMagtheridonTeam(TEAM_HORDE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldState::Update(uint32 diff)
|
||||
{
|
||||
if (_adalSongOfBattleTimer)
|
||||
{
|
||||
if (_adalSongOfBattleTimer <= diff)
|
||||
{
|
||||
_adalSongOfBattleTimer = 0;
|
||||
DispelAdalsSongOfBattle();
|
||||
}
|
||||
else
|
||||
{
|
||||
_adalSongOfBattleTimer -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldState::HandlePlayerEnterZone(Player* player, WorldStateZoneId zoneId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
switch (zoneId)
|
||||
{
|
||||
case ZONEID_SHATTRATH:
|
||||
case ZONEID_BOTANICA:
|
||||
case ZONEID_MECHANAR:
|
||||
case ZONEID_ARCATRAZ:
|
||||
if (_adalSongOfBattleTimer)
|
||||
player->CastSpell(player, SPELL_ADAL_SONG_OF_BATTLE, true);
|
||||
break;
|
||||
case ZONEID_HELLFIRE_PENINSULA:
|
||||
case ZONEID_HELLFIRE_RAMPARTS:
|
||||
case ZONEID_HELLFIRE_CITADEL:
|
||||
case ZONEID_BLOOD_FURNACE:
|
||||
case ZONEID_SHATTERED_HALLS:
|
||||
case ZONEID_MAGTHERIDON_LAIR:
|
||||
if (_isMagtheridonHeadSpawnedAlliance && player->GetTeamId() == TEAM_ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TROLLBANES_COMMAND, true);
|
||||
else if (_isMagtheridonHeadSpawnedHorde && player->GetTeamId() == TEAM_HORDE)
|
||||
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
void WorldState::HandlePlayerLeaveZone(Player* player, WorldStateZoneId zoneId)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
switch (zoneId)
|
||||
{
|
||||
case ZONEID_SHATTRATH:
|
||||
case ZONEID_BOTANICA:
|
||||
case ZONEID_MECHANAR:
|
||||
case ZONEID_ARCATRAZ:
|
||||
if (!_adalSongOfBattleTimer)
|
||||
player->RemoveAurasDueToSpell(SPELL_ADAL_SONG_OF_BATTLE);
|
||||
break;
|
||||
case ZONEID_HELLFIRE_PENINSULA:
|
||||
case ZONEID_HELLFIRE_RAMPARTS:
|
||||
case ZONEID_HELLFIRE_CITADEL:
|
||||
case ZONEID_BLOOD_FURNACE:
|
||||
case ZONEID_SHATTERED_HALLS:
|
||||
case ZONEID_MAGTHERIDON_LAIR:
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
player->RemoveAurasDueToSpell(SPELL_TROLLBANES_COMMAND);
|
||||
else if (player->GetTeamId() == TEAM_HORDE)
|
||||
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
void WorldState::BuffMagtheridonTeam(TeamId team)
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TROLLBANES_COMMAND, true);
|
||||
else if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
||||
});
|
||||
break;
|
||||
case 540: // The Shattered Halls
|
||||
case 542: // The Blood Furnace
|
||||
case 543: // Ramparts
|
||||
case 544: // Magtheridon's Lair
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->CastSpell(player, SPELL_TROLLBANES_COMMAND, true);
|
||||
else if (player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->CastSpell(player, SPELL_NAZGRELS_FAVOR, true);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WorldState::DispelMagtheridonTeam(TeamId team)
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->RemoveAurasDueToSpell(SPELL_TROLLBANES_COMMAND);
|
||||
else if (player->GetZoneId() == ZONEID_HELLFIRE_PENINSULA && player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
||||
});
|
||||
break;
|
||||
case 540: // The Shattered Halls
|
||||
case 542: // The Blood Furnace
|
||||
case 543: // Ramparts
|
||||
case 544: // Magtheridon's Lair
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE && team == TEAM_ALLIANCE)
|
||||
player->RemoveAurasDueToSpell(SPELL_TROLLBANES_COMMAND);
|
||||
else if (player->GetTeamId() == TEAM_HORDE && team == TEAM_HORDE)
|
||||
player->RemoveAurasDueToSpell(SPELL_NAZGRELS_FAVOR);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WorldState::BuffAdalsSongOfBattle()
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_SHATTRATH)
|
||||
player->CastSpell(player, SPELL_ADAL_SONG_OF_BATTLE, true);
|
||||
});
|
||||
break;
|
||||
case 552: // Arcatraz
|
||||
case 553: // Botanica
|
||||
case 554: // Mechanar
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
player->CastSpell(player, SPELL_ADAL_SONG_OF_BATTLE, true);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WorldState::DispelAdalsSongOfBattle()
|
||||
{
|
||||
sMapMgr->DoForAllMaps([&](Map* map) -> void
|
||||
{
|
||||
switch (map->GetId())
|
||||
{
|
||||
case 530: // Outland
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
if (player->GetZoneId() == ZONEID_SHATTRATH)
|
||||
player->RemoveAurasDueToSpell(SPELL_ADAL_SONG_OF_BATTLE);
|
||||
});
|
||||
break;
|
||||
case 552: // Arcatraz
|
||||
case 553: // Botanica
|
||||
case 554: // Mechanar
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_ADAL_SONG_OF_BATTLE);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WORLD_STATE_H
|
||||
#define WORLD_STATE_H
|
||||
|
||||
#include "Player.h"
|
||||
#include <atomic>
|
||||
|
||||
enum WorldStateCondition
|
||||
{
|
||||
WORLD_STATE_CONDITION_TROLLBANES_COMMAND = 39911,
|
||||
WORLD_STATE_CONDITION_NAZGRELS_FAVOR = 39913,
|
||||
// Zeppelins
|
||||
WORLD_STATE_CONDITION_THE_THUNDERCALLER = 164871,
|
||||
WORLD_STATE_CONDITION_THE_IRON_EAGLE = 175080,
|
||||
WORLD_STATE_CONDITION_THE_PURPLE_PRINCESS = 176495,
|
||||
};
|
||||
|
||||
enum WorldStateConditionState
|
||||
{
|
||||
WORLD_STATE_CONDITION_STATE_NONE = 0,
|
||||
};
|
||||
|
||||
enum WorldStateEvent
|
||||
{
|
||||
WORLD_STATE_CUSTOM_EVENT_ON_ADALS_SONG_OF_BATTLE = 39953,
|
||||
WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_SPAWN = 184640,
|
||||
WORLD_STATE_CUSTOM_EVENT_ON_MAGTHERIDON_HEAD_DESPAWN = 184641,
|
||||
};
|
||||
|
||||
enum WorldStateZoneId
|
||||
{
|
||||
ZONEID_SHATTRATH = 3703,
|
||||
ZONEID_BOTANICA = 3847,
|
||||
ZONEID_ARCATRAZ = 3848,
|
||||
ZONEID_MECHANAR = 3849,
|
||||
|
||||
ZONEID_HELLFIRE_PENINSULA = 3483,
|
||||
ZONEID_HELLFIRE_RAMPARTS = 3562,
|
||||
ZONEID_HELLFIRE_CITADEL = 3563,
|
||||
ZONEID_BLOOD_FURNACE = 3713,
|
||||
ZONEID_SHATTERED_HALLS = 3714,
|
||||
ZONEID_MAGTHERIDON_LAIR = 3836,
|
||||
};
|
||||
|
||||
enum WorldStateSpells
|
||||
{
|
||||
SPELL_ADAL_SONG_OF_BATTLE = 39953,
|
||||
|
||||
SPELL_TROLLBANES_COMMAND = 39911,
|
||||
SPELL_NAZGRELS_FAVOR = 39913,
|
||||
};
|
||||
|
||||
// Intended for implementing server wide scripts, note: all behaviour must be safeguarded towards multithreading
|
||||
class WorldState
|
||||
{
|
||||
public:
|
||||
WorldState();
|
||||
virtual ~WorldState();
|
||||
static WorldState* instance();
|
||||
void HandlePlayerEnterZone(Player* player, WorldStateZoneId zoneId);
|
||||
void HandlePlayerLeaveZone(Player* player, WorldStateZoneId zoneId);
|
||||
bool IsConditionFulfilled(WorldStateCondition conditionId, WorldStateConditionState state = WORLD_STATE_CONDITION_STATE_NONE) const;
|
||||
void HandleConditionStateChange(WorldStateCondition conditionId, WorldStateConditionState state);
|
||||
void HandleExternalEvent(WorldStateEvent eventId, uint32 param);
|
||||
void Update(uint32 diff);
|
||||
private:
|
||||
void BuffAdalsSongOfBattle();
|
||||
void DispelAdalsSongOfBattle();
|
||||
uint32 _adalSongOfBattleTimer;
|
||||
void BuffMagtheridonTeam(TeamId team);
|
||||
void DispelMagtheridonTeam(TeamId team);
|
||||
bool _isMagtheridonHeadSpawnedHorde;
|
||||
bool _isMagtheridonHeadSpawnedAlliance;
|
||||
std::map<WorldStateCondition, std::atomic<WorldStateConditionState>> _transportStates; // atomic to avoid having to lock
|
||||
std::mutex _mutex; // all World State operations are threat unsafe
|
||||
};
|
||||
|
||||
#define sWorldState WorldState::instance()
|
||||
#endif
|
||||
Reference in New Issue
Block a user