diff options
Diffstat (limited to 'src')
202 files changed, 3399 insertions, 2343 deletions
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index d55d2cf02b3..fc4d4dfcc9b 100755 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -196,7 +196,7 @@ const AuthHandler table[] = Patcher PatchesCache; // Constructor - set the N and g values for SRP6 -AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket), pPatch(NULL) +AuthSocket::AuthSocket(RealmSocket& socket) : pPatch(NULL), socket_(socket) { N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); @@ -409,7 +409,7 @@ bool AuthSocket::_HandleLogonChallenge() PreparedQueryResult banresult = LoginDatabase.Query(stmt); if (banresult) { - if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) + if ((*banresult)[0].GetUInt32() == (*banresult)[1].GetUInt32()) { pkt << uint8(WOW_FAIL_BANNED); sLog->outDebug(LOG_FILTER_AUTHSERVER, "'%s:%d' [AuthChallenge] Banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ()); diff --git a/src/server/collision/Management/IVMapManager.h b/src/server/collision/Management/IVMapManager.h index a645e88ef05..7cf296625f4 100755 --- a/src/server/collision/Management/IVMapManager.h +++ b/src/server/collision/Management/IVMapManager.h @@ -35,7 +35,7 @@ namespace VMAP { VMAP_LOAD_RESULT_ERROR, VMAP_LOAD_RESULT_OK, - VMAP_LOAD_RESULT_IGNORED, + VMAP_LOAD_RESULT_IGNORED }; #define VMAP_INVALID_HEIGHT -100000.0f // for check diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index f35e36d92fd..89412a69c33 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -125,7 +125,7 @@ namespace VMAP } StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath) - : iMapID(mapID), iTreeValues(0), iBasePath(basePath), iIsTiled(false) + : iMapID(mapID), iIsTiled(false), iTreeValues(0), iBasePath(basePath) { if (iBasePath.length() > 0 && iBasePath[iBasePath.length()-1] != '/' && iBasePath[iBasePath.length()-1] != '\\') { diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp index 8458ffdd5d3..434522d3515 100644 --- a/src/server/collision/Maps/TileAssembler.cpp +++ b/src/server/collision/Maps/TileAssembler.cpp @@ -54,7 +54,7 @@ namespace VMAP //================================================================= TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName) - : iSrcDir(pSrcDirName), iDestDir(pDestDirName), iCurrentUniqueNameId(0), iFilterMethod(NULL) + : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iFilterMethod(NULL), iCurrentUniqueNameId(0) { //mkdir(iDestDir); //init(); diff --git a/src/server/collision/Models/GameObjectModel.h b/src/server/collision/Models/GameObjectModel.h index 0bb6c0f47bc..78a0e876676 100644 --- a/src/server/collision/Models/GameObjectModel.h +++ b/src/server/collision/Models/GameObjectModel.h @@ -61,6 +61,8 @@ public: void disable() { phasemask = 0;} void enable(uint32 ph_mask) { phasemask = ph_mask;} + bool isEnabled() const {return phasemask != 0;} + bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const; static GameObjectModel* Create(const GameObject& go); diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h index 2745628ac7e..b0189ad8542 100755 --- a/src/server/collision/Models/ModelInstance.h +++ b/src/server/collision/Models/ModelInstance.h @@ -63,7 +63,7 @@ namespace VMAP class ModelInstance: public ModelSpawn { public: - ModelInstance(): iModel(0), iInvScale(0.0f) {} + ModelInstance(): iInvScale(0.0f), iModel(0) {} ModelInstance(const ModelSpawn &spawn, WorldModel* model); void setUnloaded() { iModel = 0; } bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const; diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index 7d7a27fce13..5ab5f99310a 100755 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -111,6 +111,11 @@ void CombatAI::UpdateAI(const uint32 diff) DoMeleeAttackIfReady(); } +void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs) +{ + events.RescheduleEvent(spellId, unTimeMs); +} + ///////////////// //CasterAI ///////////////// diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index ad98cec0779..fa31e57d780 100755 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -46,6 +46,7 @@ class CombatAI : public CreatureAI void EnterCombat(Unit* who); void JustDied(Unit* killer); void UpdateAI(const uint32 diff); + void SpellInterrupted(uint32 spellId, uint32 unTimeMs); static int Permissible(const Creature*); protected: EventMap events; diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 593f0d15e18..119cfd3d35e 100755 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -35,7 +35,7 @@ enum GeneralScriptTexts EMOTE_GENERIC_FRENZY = -1000002, EMOTE_GENERIC_ENRAGED = -1000003, EMOTE_GENERIC_BERSERK = -1000004, - EMOTE_GENERIC_BERSERK_RAID = -1000005, // RaidBossEmote version of the previous one + EMOTE_GENERIC_BERSERK_RAID = -1000005 // RaidBossEmote version of the previous one }; //Selection method used by SelectTarget @@ -45,7 +45,7 @@ enum SelectAggroTarget SELECT_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom SELECT_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top SELECT_TARGET_NEAREST, - SELECT_TARGET_FARTHEST, + SELECT_TARGET_FARTHEST }; // default predicate function to select target based on distance, player and/or aura criteria @@ -242,6 +242,10 @@ class UnitAI // Called when the unit heals virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) {} + /// Called when a spell is interrupted by Spell::EffectInterruptCast + /// Use to reschedule next planned cast of spell. + virtual void SpellInterrupted(uint32 /*spellId*/, uint32 /*unTimeMs*/) {} + void AttackStartCaster(Unit* victim, float dist); void DoAddAuraToAllHostilePlayers(uint32 spellid); diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 17cef3ec1a1..e5868117da8 100755 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -153,13 +153,20 @@ void CreatureAI::EnterEvadeMode() me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE); } else + { + // Required to prevent attacking creatures that are evading and cause them to reenter combat + // Does not apply to MoveFollow + me->AddUnitState(UNIT_STATE_EVADE); me->GetMotionMaster()->MoveTargetedHome(); + } } Reset(); if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons! me->GetVehicleKit()->Reset(true); + + me->SetLastDamagedTime(0); } /*void CreatureAI::AttackedBy(Unit* attacker) diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 68752b82e7f..d3ad27935ca 100755 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -45,7 +45,7 @@ enum SelectTargetType SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend SELECT_TARGET_AOE_FRIEND, //Only AoE Friend - SELECT_TARGET_ANY_FRIEND, //AoE or Single Friend + SELECT_TARGET_ANY_FRIEND //AoE or Single Friend }; //Spell Effects used by SelectSpell @@ -54,7 +54,7 @@ enum SelectEffect SELECT_EFFECT_DONTCARE = 0, //All spell effects allowed SELECT_EFFECT_DAMAGE, //Spell does damage SELECT_EFFECT_HEALING, //Spell does healing - SELECT_EFFECT_AURA, //Spell applies an aura + SELECT_EFFECT_AURA //Spell applies an aura }; enum SCEquip diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index d097adf38ec..981ac1f5f16 100755 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -505,14 +505,14 @@ enum AITarget AITARGET_ENEMY, AITARGET_ALLY, AITARGET_BUFF, - AITARGET_DEBUFF, + AITARGET_DEBUFF }; enum AICondition { AICOND_AGGRO, AICOND_COMBAT, - AICOND_DIE, + AICOND_DIE }; #define AI_DEFAULT_COOLDOWN 5000 diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index aa14bc1b56e..951a035628a 100755 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -1317,6 +1317,10 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger if (!me->IsInRange(target, spell->GetMinRange(false), spell->GetMaxRange(false))) return false; + //Spell is on cooldown + if (me->HasSpellCooldown(spell->Id)) + return false; + return true; } diff --git a/src/server/game/AI/EventAI/CreatureEventAI.h b/src/server/game/AI/EventAI/CreatureEventAI.h index b9e1ae32be4..da5f0b084cf 100755 --- a/src/server/game/AI/EventAI/CreatureEventAI.h +++ b/src/server/game/AI/EventAI/CreatureEventAI.h @@ -60,7 +60,7 @@ enum EventAI_Type EVENT_T_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max EVENT_T_RESET = 35, // Is it called after combat, when the creature respawn and spawn. -- TRINITY ONLY - EVENT_T_END, + EVENT_T_END }; enum EventAI_ActionType @@ -119,7 +119,7 @@ enum EventAI_ActionType ACTION_T_ATTACK_START_PULSE = 103, //Distance ACTION_T_SUMMON_GO = 104, //GameObjectID, DespawnTime in ms - ACTION_T_END = 105, + ACTION_T_END = 105 }; enum Target @@ -156,7 +156,7 @@ enum CastFlags CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself - CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell + CAST_AURA_NOT_PRESENT = 0x20 //Only casts the spell if the target does not have an aura from the spell }; enum EventFlags diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index ba0a94d2590..aa46d555b7d 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -41,8 +41,10 @@ class SummonList : public std::list<uint64> template <class Predicate> void DoAction(int32 info, Predicate& predicate, uint16 max = 0) { - Trinity::Containers::RandomResizeList<uint64, Predicate>(*this, predicate, max); - for (iterator i = begin(); i != end(); ) + // We need to use a copy of SummonList here, otherwise original SummonList would be modified + std::list<uint64> listCopy = *this; + Trinity::Containers::RandomResizeList<uint64, Predicate>(listCopy, predicate, max); + for (iterator i = listCopy.begin(); i != listCopy.end(); ) { Creature* summon = Unit::GetCreature(*me, *i++); if (summon && summon->IsAIEnabled) diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 0b8236908a0..7dd4053b82f 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -634,8 +634,11 @@ void SmartAI::SpellHitTarget(Unit* target, const SpellInfo* spellInfo) void SmartAI::DamageTaken(Unit* doneBy, uint32& damage) { GetScript()->ProcessEventsFor(SMART_EVENT_DAMAGED, doneBy, damage); - if ((me->GetHealth() - damage) <= mInvincibilityHpLevel) - damage = me->GetHealth() - mInvincibilityHpLevel; + if (mInvincibilityHpLevel && (damage >= me->GetHealth() - mInvincibilityHpLevel)) + { + damage = 0; + me->SetHealth(mInvincibilityHpLevel); + } } void SmartAI::HealReceived(Unit* doneBy, uint32& addhealth) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 79cef0c3b37..f81d6e86850 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -40,7 +40,7 @@ enum SmartEscortState enum SmartEscortVars { SMART_ESCORT_MAX_PLAYER_DIST = 50, - SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2, + SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2 }; class SmartAI : public CreatureAI diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 69ecb1ef581..32b9f8b5903 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1951,6 +1951,27 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u delete targets; break; } + case SMART_ACTION_SET_HOME_POS: + { + if (!me) + break; + + if (e.GetTargetType() == SMART_TARGET_SELF) + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + else if (e.GetTargetType() == SMART_TARGET_POSITION) + me->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); + else + sLog->outError(LOG_FILTER_SQL, "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is not using SMART_TARGET_SELF or SMART_TARGET_POSITION, skipping"); + + break; + } + case SMART_ACTION_SET_HEALTH_REGEN: + { + if (!me || me->GetTypeId() != TYPEID_UNIT) + break; + me->setRegeneratingHealth(e.action.setHealthRegen.regenHealth ? true : false); + break; + } default: sLog->outError(LOG_FILTER_SQL, "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index ef5c7511124..4e2c51e50c8 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -904,6 +904,8 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_SEND_GOSSIP_MENU: case SMART_ACTION_GO_SET_LOOT_STATE: case SMART_ACTION_SEND_TARGET_TO_TARGET: + case SMART_ACTION_SET_HOME_POS: + case SMART_ACTION_SET_HEALTH_REGEN: break; default: sLog->outError(LOG_FILTER_SQL, "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index f1747734a29..cccf5c2ce10 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -54,7 +54,7 @@ enum SMART_EVENT_PHASE SMART_EVENT_PHASE_6 = 6, SMART_EVENT_PHASE_MAX = 7, - SMART_EVENT_PHASE_COUNT = 6, + SMART_EVENT_PHASE_COUNT = 6 }; enum SMART_EVENT_PHASE_BITS @@ -66,7 +66,7 @@ enum SMART_EVENT_PHASE_BITS SMART_EVENT_PHASE_4_BIT = 8, SMART_EVENT_PHASE_5_BIT = 16, SMART_EVENT_PHASE_6_BIT = 32, - SMART_EVENT_PHASE_ALL = SMART_EVENT_PHASE_1_BIT + SMART_EVENT_PHASE_2_BIT + SMART_EVENT_PHASE_3_BIT + SMART_EVENT_PHASE_4_BIT + SMART_EVENT_PHASE_5_BIT + SMART_EVENT_PHASE_6_BIT, + SMART_EVENT_PHASE_ALL = SMART_EVENT_PHASE_1_BIT + SMART_EVENT_PHASE_2_BIT + SMART_EVENT_PHASE_3_BIT + SMART_EVENT_PHASE_4_BIT + SMART_EVENT_PHASE_5_BIT + SMART_EVENT_PHASE_6_BIT }; const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] = @@ -76,7 +76,7 @@ const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] = {SMART_EVENT_PHASE_3, SMART_EVENT_PHASE_3_BIT }, {SMART_EVENT_PHASE_4, SMART_EVENT_PHASE_4_BIT }, {SMART_EVENT_PHASE_5, SMART_EVENT_PHASE_5_BIT }, - {SMART_EVENT_PHASE_6, SMART_EVENT_PHASE_6_BIT }, + {SMART_EVENT_PHASE_6, SMART_EVENT_PHASE_6_BIT } }; enum SMART_EVENT @@ -156,7 +156,7 @@ enum SMART_EVENT SMART_EVENT_ACTION_DONE = 72, // eventId (SharedDefines.EventId) SMART_EVENT_ON_SPELLCLICK = 73, // clicker (unit) - SMART_EVENT_END = 74, + SMART_EVENT_END = 74 }; struct SmartEvent @@ -376,7 +376,7 @@ enum SMART_SCRIPT_RESPAWN_CONDITION SMART_SCRIPT_RESPAWN_CONDITION_NONE = 0, SMART_SCRIPT_RESPAWN_CONDITION_MAP = 1, SMART_SCRIPT_RESPAWN_CONDITION_AREA = 2, - SMART_SCRIPT_RESPAWN_CONDITION_END = 3, + SMART_SCRIPT_RESPAWN_CONDITION_END = 3 }; enum SMART_ACTION @@ -484,8 +484,10 @@ enum SMART_ACTION SMART_ACTION_SEND_GOSSIP_MENU = 98, // menuId, optionId SMART_ACTION_GO_SET_LOOT_STATE = 99, // state SMART_ACTION_SEND_TARGET_TO_TARGET = 100, // id + SMART_ACTION_SET_HOME_POS = 101, // none + SMART_ACTION_SET_HEALTH_REGEN = 102, // 0/1 - SMART_ACTION_END = 101, + SMART_ACTION_END = 103 }; struct SmartAction @@ -911,6 +913,11 @@ struct SmartAction uint32 angle; } setRangedMovement; + struct + { + uint32 regenHealth; + } setHealthRegen; + //! Note for any new future actions //! All parameters must have type uint32 @@ -934,7 +941,7 @@ enum SMARTAI_TEMPLATE SMARTAI_TEMPLATE_PASSIVE = 3, SMARTAI_TEMPLATE_CAGED_GO_PART = 4, //creatureID, give credit at point end?, SMARTAI_TEMPLATE_CAGED_NPC_PART = 5, //gameObjectID, despawntime, run?, dist, TextGroupID - SMARTAI_TEMPLATE_END = 6, + SMARTAI_TEMPLATE_END = 6 }; enum SMARTAI_TARGETS @@ -964,7 +971,7 @@ enum SMARTAI_TARGETS SMART_TARGET_ACTION_INVOKER_VEHICLE = 22, // Unit's vehicle who caused this Event to occur SMART_TARGET_OWNER_OR_SUMMONER = 23, // Unit's owner or summoner SMART_TARGET_THREAT_LIST = 24, // All units on creature's threat list - SMART_TARGET_END = 25, + SMART_TARGET_END = 25 }; struct SmartTarget @@ -1057,12 +1064,12 @@ struct SmartTarget enum eSmartAI { - SMART_EVENT_PARAM_COUNT = 4, - SMART_ACTION_PARAM_COUNT = 6, - SMART_SUMMON_COUNTER = 0xFFFFFF, + SMART_EVENT_PARAM_COUNT = 4, + SMART_ACTION_PARAM_COUNT = 6, + SMART_SUMMON_COUNTER = 0xFFFFFF, SMART_ESCORT_LAST_OOC_POINT = 0xFFFFFF, - SMART_RANDOM_POINT = 0xFFFFFE, - SMART_ESCORT_TARGETS = 0xFFFFFF + SMART_RANDOM_POINT = 0xFFFFFE, + SMART_ESCORT_TARGETS = 0xFFFFFF }; enum SmartScriptType @@ -1091,7 +1098,7 @@ enum SmartAITypeMaskId SMART_SCRIPT_TYPE_MASK_SPELL = 64, SMART_SCRIPT_TYPE_MASK_TRANSPORT = 128, SMART_SCRIPT_TYPE_MASK_INSTANCE = 256, - SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST = 512, + SMART_SCRIPT_TYPE_MASK_TIMED_ACTIONLIST = 512 }; const uint32 SmartAITypeMask[SMART_SCRIPT_TYPE_MAX][2] = @@ -1183,7 +1190,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] = {SMART_EVENT_GO_STATE_CHANGED, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GO_EVENT_INFORM, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_ACTION_DONE, SMART_SCRIPT_TYPE_MASK_CREATURE }, - {SMART_EVENT_ON_SPELLCLICK, SMART_SCRIPT_TYPE_MASK_CREATURE }, + {SMART_EVENT_ON_SPELLCLICK, SMART_SCRIPT_TYPE_MASK_CREATURE } }; enum SmartEventFlags @@ -1209,14 +1216,15 @@ enum SmartCastFlags //CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range //CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range //CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself - SMARTCAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell + SMARTCAST_AURA_NOT_PRESENT = 0x20 //Only casts the spell if the target does not have an aura from the spell }; // one line in DB is one event struct SmartScriptHolder { - SmartScriptHolder() : timer(0), active(false), runOnce(false), link(0), entryOrGuid(0), - event_id(0), enableTimed(false), source_type(SMART_SCRIPT_TYPE_CREATURE) {} + SmartScriptHolder() : entryOrGuid(0), source_type(SMART_SCRIPT_TYPE_CREATURE) + , event_id(0), link(0), timer(0), active(false), runOnce(false) + , enableTimed(false) {} int32 entryOrGuid; SmartScriptType source_type; diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index c69f3c0a6f3..aaaf4f4f603 100755 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -55,6 +55,6 @@ namespace AccountMgr bool IsGMAccount(uint32 gmlevel); bool IsAdminAccount(uint32 gmlevel); bool IsConsoleAccount(uint32 gmlevel); -}; +} #endif diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 506495469d3..93a3378c3c5 100755 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -128,12 +128,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) } return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE: - if (!classRace.class_id && !classRace.race_id) - { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.", - criteria->ID, criteria->requiredType, dataType); - return false; - } if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.", @@ -364,7 +358,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un return sScriptMgr->OnCriteriaCheck(this, const_cast<Player*>(source), const_cast<Unit*>(target)); case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY: if (source->GetMap()->IsRaid()) - if (source->GetMap()->Is25ManRaid() != (difficulty.difficulty & RAID_DIFFICULTY_MASK_25MAN)) + if (source->GetMap()->Is25ManRaid() != ((difficulty.difficulty & RAID_DIFFICULTY_MASK_25MAN) != 0)) return false; return source->GetMap()->GetSpawnMode() >= difficulty.difficulty; case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT: @@ -634,8 +628,7 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement)) if (uint32 titleId = reward->titleId[Player::TeamForRace(GetPlayer()->getRace()) == ALLIANCE ? 0 : 1]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) - if (!GetPlayer()->HasTitle(titleEntry)) - GetPlayer()->SetTitle(titleEntry); + GetPlayer()->SetTitle(titleEntry); } while (achievementResult->NextRow()); } @@ -723,7 +716,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); data.append(GetPlayer()->GetPackGUID()); data << uint32(achievement->ID); - data << uint32(secsToTimeBitFields(time(NULL))); + data.AppendPackedTime(time(NULL)); data << uint32(0); GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } @@ -741,7 +734,7 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C data << uint32(0); else data << uint32(timedCompleted ? 0 : 1); // this are some flags, 1 is for keeping the counter at 0 in client - data << uint32(secsToTimeBitFields(progress->date)); + data.AppendPackedTime(progress->date); data << uint32(timeElapsed); // time elapsed in seconds data << uint32(0); // unk GetPlayer()->SendDirectMessage(&data); @@ -2132,7 +2125,7 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const continue; *data << uint32(iter->first); - *data << uint32(secsToTimeBitFields(iter->second.date)); + data->AppendPackedTime(iter->second.date); } *data << int32(-1); @@ -2142,7 +2135,7 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const data->appendPackGUID(iter->second.counter); data->append(GetPlayer()->GetPackGUID()); *data << uint32(0); - *data << uint32(secsToTimeBitFields(iter->second.date)); + data->AppendPackedTime(iter->second.date); *data << uint32(0); *data << uint32(0); } diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index c7d838fcb44..3215b4196f7 100755 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -63,7 +63,7 @@ enum AchievementCriteriaDataType ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id - ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id + ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21 // class_id race_id }; #define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 22 // maximum value in AchievementCriteriaDataType enum diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 84b5513b659..940f1f8beb7 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -34,7 +34,7 @@ enum eAuctionHouse { - AH_MINIMUM_DEPOSIT = 100, + AH_MINIMUM_DEPOSIT = 100 }; AuctionHouseMgr::AuctionHouseMgr() @@ -145,7 +145,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& { bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template); // FIXME: for offline player need also - bidder->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); + bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); } MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, 0, 0)) @@ -179,8 +179,8 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa //FIXME: what do if owner offline if (owner) { - owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); - owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); + owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); + owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); //send auction owner notification, bidder must be current! owner->GetSession()->SendAuctionOwnerNotification(auction); } diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index ffc5e48290b..ae58f3504b4 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -60,6 +60,13 @@ Battlefield::Battlefield() Battlefield::~Battlefield() { + for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) + delete itr->second; + + for (GraveyardVect::const_iterator itr = m_GraveyardList.begin(); itr != m_GraveyardList.end(); ++itr) + delete *itr; + + m_capturePoints.clear(); } // Called when a player enters the zone @@ -444,8 +451,8 @@ WorldPacket Battlefield::BuildWarningAnnPacket(std::string msg) data << uint32(1); data << uint8(0); data << uint64(0); - data << uint32(strlen(msg.c_str()) + 1); - data << msg.c_str(); + data << uint32(msg.length() + 1); + data << msg; data << uint8(0); return data; @@ -456,7 +463,7 @@ void Battlefield::SendWarningToAllInZone(uint32 entry) if (Unit* unit = sObjectAccessor->FindUnit(StalkerGuid)) if (Creature* stalker = unit->ToCreature()) // FIXME: replaced CHAT_TYPE_END with CHAT_MSG_BG_SYSTEM_NEUTRAL to fix compile, it's a guessed change :/ - sCreatureTextMgr->SendChat(stalker, (uint8) entry, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_ADDON, TEXT_RANGE_ZONE); + sCreatureTextMgr->SendChat(stalker, (uint8) entry, 0, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_ADDON, TEXT_RANGE_ZONE); } /*void Battlefield::SendWarningToAllInWar(int32 entry,...) @@ -669,8 +676,8 @@ BfGraveyard::BfGraveyard(Battlefield* battlefield) m_Bf = battlefield; m_GraveyardId = 0; m_ControlTeam = TEAM_NEUTRAL; - m_SpiritGuide[0] = NULL; - m_SpiritGuide[1] = NULL; + m_SpiritGuide[0] = 0; + m_SpiritGuide[1] = 0; m_ResurrectQueue.clear(); } diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 07daf33d431..480aafbeb42 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -29,13 +29,12 @@ enum BattlefieldTypes { - BATTLEFIELD_WG, // Wintergrasp - BATTLEFIELD_TB, // Tol Barad (cataclysm) + BATTLEFIELD_WG // Wintergrasp }; enum BattlefieldIDs { - BATTLEFIELD_BATTLEID_WG = 1, // Wintergrasp battle + BATTLEFIELD_BATTLEID_WG = 1 // Wintergrasp battle }; enum BattlefieldObjectiveStates @@ -46,7 +45,7 @@ enum BattlefieldObjectiveStates BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE, BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE, BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE, - BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE, + BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE }; enum BattlefieldSounds diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 09783176094..2270bcf7927 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -30,13 +30,16 @@ enum WGVehicles NPC_WG_SEIGE_ENGINE_ALLIANCE = 28312, NPC_WG_SEIGE_ENGINE_HORDE = 32627, NPC_WG_DEMOLISHER = 28094, - NPC_WG_CATAPULT = 27881, + NPC_WG_CATAPULT = 27881 }; BattlefieldWG::~BattlefieldWG() { for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) delete *itr; + + for (GameObjectBuilding::const_iterator itr = BuildingsInZone.begin(); itr != BuildingsInZone.end(); ++itr) + delete *itr; } bool BattlefieldWG::SetupBattlefield() @@ -456,7 +459,7 @@ void BattlefieldWG::DoCompleteOrIncrementAchievement(uint32 achievement, Player* { case ACHIEVEMENTS_WIN_WG_100: { - // player->GetAchievementMgr().UpdateAchievementCriteria(); + // player->UpdateAchievementCriteria(); } default: { diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 734154020d9..11510e1ea98 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -47,7 +47,7 @@ typedef std::set<Group*> GroupSet; enum WintergrastData { BATTLEFIELD_WG_ZONEID = 4197, // Wintergrasp - BATTLEFIELD_WG_MAPID = 571, // Northrend + BATTLEFIELD_WG_MAPID = 571 // Northrend }; enum WintergraspSpells @@ -91,7 +91,7 @@ enum WintergraspSpells SPELL_ALLIANCE_CONTROLS_FACTORY_PHASE_SHIFT = 56617, // ADDS PHASE 32 SPELL_HORDE_CONTROL_PHASE_SHIFT = 55773, // ADDS PHASE 64 - SPELL_ALLIANCE_CONTROL_PHASE_SHIFT = 55774, // ADDS PHASE 128 + SPELL_ALLIANCE_CONTROL_PHASE_SHIFT = 55774 // ADDS PHASE 128 }; enum WintergraspData @@ -104,7 +104,7 @@ enum WintergraspData BATTLEFIELD_WG_DATA_MAX_VEHICLE_H, BATTLEFIELD_WG_DATA_VEHICLE_A, BATTLEFIELD_WG_DATA_VEHICLE_H, - BATTLEFIELD_WG_DATA_MAX, + BATTLEFIELD_WG_DATA_MAX }; enum WintergraspAchievements @@ -124,7 +124,7 @@ enum WintergraspAchievements ACHIEVEMENTS_STONE_KEEPER_1000 = 2089, // todo ACHIEVEMENTS_WG_RANGER = 2199, // todo ACHIEVEMENTS_DESTRUCTION_DERBY_H = 2476, // todo - ACHIEVEMENTS_WG_MASTER_H = 2776, // todo + ACHIEVEMENTS_WG_MASTER_H = 2776 // todo }; enum WintergraspWorldStates @@ -136,7 +136,7 @@ enum WintergraspWorldStates BATTLEFIELD_WG_WORLD_STATE_ACTIVE = 3801, BATTLEFIELD_WG_WORLD_STATE_DEFENDER = 3802, BATTLEFIELD_WG_WORLD_STATE_ATTACKER = 3803, - BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE = 3710, + BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE = 3710 }; enum WintergraspAreaIds @@ -147,7 +147,7 @@ enum WintergraspAreaIds AREA_WESTPARK_WORKSHOP = 4611, AREA_EASTPARK_WORKSHOP = 4612, AREA_WINTERGRASP = 4197, - AREA_THE_CHILLED_QUAGMIRE = 4589, + AREA_THE_CHILLED_QUAGMIRE = 4589 }; /*######################### @@ -174,7 +174,7 @@ enum WGGraveyardId BATTLEFIELD_WG_GY_KEEP, BATTLEFIELD_WG_GY_HORDE, BATTLEFIELD_WG_GY_ALLIANCE, - BATTLEFIELD_WG_GRAVEYARD_MAX, + BATTLEFIELD_WG_GRAVEYARD_MAX }; enum WGGossipText @@ -185,7 +185,7 @@ enum WGGossipText BATTLEFIELD_WG_GOSSIPTEXT_GY_SW = -1850503, BATTLEFIELD_WG_GOSSIPTEXT_GY_KEEP = -1850500, BATTLEFIELD_WG_GOSSIPTEXT_GY_HORDE = -1850505, - BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE = -1850506, + BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE = -1850506 }; enum WintergraspNpcs @@ -222,7 +222,7 @@ enum WintergraspNpcs NPC_WINTERGRASP_SIEGE_ENGINE_HORDE = 32627, NPC_WINTERGRASP_CATAPULT = 27881, NPC_WINTERGRASP_DEMOLISHER = 28094, - NPC_WINTERGRASP_TOWER_CANNON = 28366, + NPC_WINTERGRASP_TOWER_CANNON = 28366 }; struct BfWGCoordGY @@ -456,7 +456,7 @@ enum WintergraspGameObjectBuildingType BATTLEFIELD_WG_OBJECTTYPE_WALL, BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST, BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER, - BATTLEFIELD_WG_OBJECTTYPE_TOWER, + BATTLEFIELD_WG_OBJECTTYPE_TOWER }; enum WintergraspGameObjectState @@ -470,7 +470,7 @@ enum WintergraspGameObjectState BATTLEFIELD_WG_OBJECTSTATE_HORDE_DESTROY, BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT, BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE, - BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY, + BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY }; enum WintergraspWorkshopIds @@ -480,7 +480,7 @@ enum WintergraspWorkshopIds BATTLEFIELD_WG_WORKSHOP_SE, BATTLEFIELD_WG_WORKSHOP_SW, BATTLEFIELD_WG_WORKSHOP_KEEP_WEST, - BATTLEFIELD_WG_WORKSHOP_KEEP_EAST, + BATTLEFIELD_WG_WORKSHOP_KEEP_EAST }; enum WintergraspWorldstates @@ -497,7 +497,7 @@ enum WintergraspTeamControl { BATTLEFIELD_WG_TEAM_ALLIANCE, BATTLEFIELD_WG_TEAM_HORDE, - BATTLEFIELD_WG_TEAM_NEUTRAL, + BATTLEFIELD_WG_TEAM_NEUTRAL }; // TODO: Handle this with creature_text ? @@ -525,7 +525,7 @@ enum WintergraspText BATTLEFIELD_WG_TEXT_TOWER_NAME_E = 12070, BATTLEFIELD_WG_TEXT_TOWER_NAME_W = 12071, BATTLEFIELD_WG_TEXT_DEFEND_KEEP = 12068, - BATTLEFIELD_WG_TEXT_WIN_KEEP = 12072, + BATTLEFIELD_WG_TEXT_WIN_KEEP = 12072 }; enum WintergraspGameObject @@ -549,8 +549,7 @@ enum WintergraspGameObject GO_WINTERGRASP_FORTRESS_GATE = 190375, GO_WINTERGRASP_VAULT_GATE = 191810, - GO_WINTERGRASP_KEEP_COLLISION_WALL = 194323, - + GO_WINTERGRASP_KEEP_COLLISION_WALL = 194323 }; struct WintergraspObjectPositionData @@ -1133,9 +1132,9 @@ const WGWorkshopData WorkshopsData[WG_MAX_WORKSHOP] = // SW {BATTLEFIELD_WG_WORKSHOP_SW, WORLDSTATE_WORKSHOP_SW, BATTLEFIELD_WG_TEXT_WORKSHOP_NAME_SW}, // KEEP WEST - It can't be taken, so it doesn't have a textid - {BATTLEFIELD_WG_WORKSHOP_KEEP_WEST, WORLDSTATE_WORKSHOP_K_W, NULL}, + {BATTLEFIELD_WG_WORKSHOP_KEEP_WEST, WORLDSTATE_WORKSHOP_K_W, 0}, // KEEP EAST - It can't be taken, so it doesn't have a textid - {BATTLEFIELD_WG_WORKSHOP_KEEP_EAST, WORLDSTATE_WORKSHOP_K_E, NULL} + {BATTLEFIELD_WG_WORKSHOP_KEEP_EAST, WORLDSTATE_WORKSHOP_K_E, 0} }; // ******************************************************************** diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index eb5f3459edf..647f55c4ffa 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -851,7 +851,7 @@ void Battleground::EndBattleground(uint32 winner) { // update achievement BEFORE personal rating update uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot()); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change); } @@ -860,7 +860,7 @@ void Battleground::EndBattleground(uint32 winner) loser_arena_team->MemberLost(player, winner_matchmaker_rating, loser_matchmaker_change); // Arena lost => reset the win_rated_arena having the "no_lose" condition - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); } } @@ -880,7 +880,7 @@ void Battleground::EndBattleground(uint32 winner) player->SetRandomWinner(true); } - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1); } else { @@ -899,7 +899,7 @@ void Battleground::EndBattleground(uint32 winner) BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType()); player->GetSession()->SendPacket(&data); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team) @@ -1177,17 +1177,17 @@ void Battleground::AddPlayer(Player* player) player->CastSpell(player, SPELL_PREPARATION, true); // reduces all mana cost of spells. } - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); - player->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true); // setup BG group membership PlayerAddedToBGCheckIfBGIsRunning(player); @@ -1923,7 +1923,7 @@ void Battleground::StartTimedAchievement(AchievementCriteriaTimedTypes type, uin { for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) if (Player* player = ObjectAccessor::FindPlayer(itr->first)) - player->GetAchievementMgr().StartTimedAchievement(type, entry); + player->StartTimedAchievement(type, entry); } void Battleground::SetBracket(PvPDifficultyEntry const* bracketEntry) @@ -1937,3 +1937,11 @@ void Battleground::RewardXPAtKill(Player* killer, Player* victim) if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) && killer && victim) killer->RewardPlayerAndGroupAtKill(victim, true); } + +void Battleground::HandleAreaTrigger(Player* player, uint32 trigger) +{ + sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger %u in Battleground %u. Player coords (x: %f, y: %f, z: %f)", + trigger, player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + if (player->isGameMaster()) + player->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", trigger); +} diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 01dfbb23033..fc292aa5bc1 100755 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -38,7 +38,7 @@ enum BattlegroundSounds SOUND_HORDE_WINS = 8454, SOUND_ALLIANCE_WINS = 8455, SOUND_BG_START = 3439, - SOUND_BG_START_L70ETC = 11803, + SOUND_BG_START_L70ETC = 11803 }; enum BattlegroundQuests @@ -79,7 +79,7 @@ enum BattlegroundMarksCount enum BattlegroundCreatures { BG_CREATURE_ENTRY_A_SPIRITGUIDE = 13116, // alliance - BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117, // horde + BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117 // horde }; enum BattlegroundSpells @@ -99,7 +99,7 @@ enum BattlegroundSpells SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2) SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds - SPELL_THE_LAST_STANDING = 26549, // Arena achievement related + SPELL_THE_LAST_STANDING = 26549 // Arena achievement related }; enum BattlegroundTimeIntervals @@ -112,7 +112,7 @@ enum BattlegroundTimeIntervals MAX_OFFLINE_TIME = 300, // secs RESPAWN_ONE_DAY = 86400, // secs RESPAWN_IMMEDIATELY = 0, // secs - BUFF_RESPAWN_TIME = 180, // secs + BUFF_RESPAWN_TIME = 180 // secs }; enum BattlegroundStartTimeIntervals @@ -121,7 +121,7 @@ enum BattlegroundStartTimeIntervals BG_START_DELAY_1M = 60000, // ms (1 minute) BG_START_DELAY_30S = 30000, // ms (30 seconds) BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena - BG_START_DELAY_NONE = 0, // ms + BG_START_DELAY_NONE = 0 // ms }; enum BattlegroundBuffObjects @@ -137,8 +137,8 @@ enum BattlegroundRandomRewards BG_REWARD_WINNER_ARENA_FIRST = 25, BG_REWARD_WINNER_HONOR_LAST = 15, BG_REWARD_WINNER_ARENA_LAST = 0, - BG_REWARD_LOSER_HONOR_FIRST = 5, - BG_REWARD_LOSER_HONOR_LAST = 5 + BG_REWARD_LOSER_HONOR_FIRST = 5, + BG_REWARD_LOSER_HONOR_LAST = 5 }; const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY }; @@ -209,7 +209,7 @@ enum ScoreType SCORE_SECONDARY_OBJECTIVES = 17, //SOTA SCORE_DESTROYED_DEMOLISHER = 18, - SCORE_DESTROYED_WALL = 19, + SCORE_DESTROYED_WALL = 19 }; enum ArenaType @@ -275,7 +275,7 @@ enum GroupJoinBattlegroundResult ERR_BATTLEGROUND_JOIN_FAILED = -12, // Join as a group failed (uint64 guid doesn't exist in client cache) ERR_LFG_CANT_USE_BATTLEGROUND = -13, // You cannot queue for a battleground or arena while using the dungeon system. ERR_IN_RANDOM_BG = -14, // Can't do that while in a Random Battleground queue. - ERR_IN_NON_RANDOM_BG = -15, // Can't queue for Random Battleground while in another Battleground queue. + ERR_IN_NON_RANDOM_BG = -15 // Can't queue for Random Battleground while in another Battleground queue. }; class BattlegroundScore @@ -507,7 +507,7 @@ class Battleground // Triggers handle // must be implemented in BG subclass - virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {} + virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/); // must be implemented in BG subclass if need AND call base class generic code virtual void HandleKillPlayer(Player* player, Player* killer); virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 85d41977d13..f36b4d49a35 100755 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -309,7 +309,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) { //we must check premade and normal team's queue - because when players from premade are joining bg, //they leave groupinfo so we can't use its players size to find out index - for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_QUEUE_NORMAL_ALLIANCE) + for (uint32 j = index; j < BG_QUEUE_GROUP_TYPES_COUNT; j += BG_TEAMS_COUNT) { for (group_itr_tmp = m_QueuedGroups[bracket_id_tmp][j].begin(); group_itr_tmp != m_QueuedGroups[bracket_id_tmp][j].end(); ++group_itr_tmp) { diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 8b2543f20ff..dfd7af583a5 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -210,24 +210,24 @@ void BattlegroundAB::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /* } -void BattlegroundAB::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundAB::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - switch (Trigger) + switch (trigger) { case 3948: // Arathi Basin Alliance Exit. - if (Source->GetTeam() != ALLIANCE) - Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal"); + if (player->GetTeam() != ALLIANCE) + player->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal"); else - Source->LeaveBattleground(); + player->LeaveBattleground(); break; case 3949: // Arathi Basin Horde Exit. - if (Source->GetTeam() != HORDE) - Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal"); + if (player->GetTeam() != HORDE) + player->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal"); else - Source->LeaveBattleground(); + player->LeaveBattleground(); break; case 3866: // Stables case 3869: // Gold Mine @@ -238,8 +238,7 @@ void BattlegroundAB::HandleAreaTrigger(Player* Source, uint32 Trigger) case 4021: // Unk2 //break; default: - //sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - //Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } } @@ -371,9 +370,10 @@ void BattlegroundAB::_NodeOccupied(uint8 node, Team team) if (node >= BG_AB_DYNAMIC_NODES_COUNT)//only dynamic nodes, no start points return; - Creature* trigger = GetBGCreature(node+7);//0-6 spirit guides + + Creature* trigger = BgCreatures[node+7] ? GetBGCreature(node+7) : NULL;//0-6 spirit guides if (!trigger) - trigger = AddCreature(WORLD_TRIGGER, node+7, team, BG_AB_NodePositions[node][0], BG_AB_NodePositions[node][1], BG_AB_NodePositions[node][2], BG_AB_NodePositions[node][3]); + trigger = AddCreature(WORLD_TRIGGER, node+7, team, BG_AB_NodePositions[node][0], BG_AB_NodePositions[node][1], BG_AB_NodePositions[node][2], BG_AB_NodePositions[node][3]); //add bonus honor aura trigger creature when node is accupied //cast bonus aura (+50% honor in 25yards) @@ -681,11 +681,11 @@ void BattlegroundAB::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_BASES_ASSAULTED: ((BattlegroundABScore*)itr->second)->BasesAssaulted += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_ASSAULT_BASE); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_ASSAULT_BASE); break; case SCORE_BASES_DEFENDED: ((BattlegroundABScore*)itr->second)->BasesDefended += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_DEFEND_BASE); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_DEFEND_BASE); break; default: Battleground::UpdatePlayerScore(Source, type, value, doAddHonor); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index 2cac5df73a9..870b3965522 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -102,7 +102,7 @@ enum BG_AB_ObjectType BG_AB_OBJECT_SPEEDBUFF_GOLD_MINE = 54, BG_AB_OBJECT_REGENBUFF_GOLD_MINE = 55, BG_AB_OBJECT_BERSERKBUFF_GOLD_MINE = 56, - BG_AB_OBJECT_MAX = 57, + BG_AB_OBJECT_MAX = 57 }; /* Object id templates from DB */ @@ -123,7 +123,7 @@ enum BG_AB_ObjectTypes enum BG_AB_Timers { - BG_AB_FLAG_CAPTURING_TIME = 60000, + BG_AB_FLAG_CAPTURING_TIME = 60000 }; enum BG_AB_Score @@ -146,7 +146,7 @@ enum BG_AB_BattlegroundNodes BG_AB_SPIRIT_ALIANCE = 5, BG_AB_SPIRIT_HORDE = 6, - BG_AB_ALL_NODES_COUNT = 7, // all nodes (dynamic and static) + BG_AB_ALL_NODES_COUNT = 7 // all nodes (dynamic and static) }; enum BG_AB_NodeStatus diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index 96fa899a746..aeebfb945f9 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -489,27 +489,25 @@ void BattlegroundAV::RemovePlayer(Player* player, uint64 /*guid*/, uint32 /*team player->RemoveAurasDueToSpell(AV_BUFF_H_CAPTAIN); } -void BattlegroundAV::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundAV::HandleAreaTrigger(Player* player, uint32 trigger) { - // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - uint32 SpellId = 0; - switch (Trigger) + switch (trigger) { case 95: case 2608: - if (Source->GetTeam() != ALLIANCE) - Source->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal"); + if (player->GetTeam() != ALLIANCE) + player->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal"); else - Source->LeaveBattleground(); + player->LeaveBattleground(); break; case 2606: - if (Source->GetTeam() != HORDE) - Source->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal"); + if (player->GetTeam() != HORDE) + player->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal"); else - Source->LeaveBattleground(); + player->LeaveBattleground(); break; case 3326: case 3327: @@ -520,13 +518,9 @@ void BattlegroundAV::HandleAreaTrigger(Player* Source, uint32 Trigger) //Source->Unmount(); break; default: - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); -// Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } - - if (SpellId) - Source->CastSpell(Source, SpellId, true); } void BattlegroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor) @@ -540,19 +534,19 @@ void BattlegroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_GRAVEYARDS_ASSAULTED: ((BattlegroundAVScore*)itr->second)->GraveyardsAssaulted += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_GRAVEYARD); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_GRAVEYARD); break; case SCORE_GRAVEYARDS_DEFENDED: ((BattlegroundAVScore*)itr->second)->GraveyardsDefended += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_GRAVEYARD); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_GRAVEYARD); break; case SCORE_TOWERS_ASSAULTED: ((BattlegroundAVScore*)itr->second)->TowersAssaulted += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_TOWER); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_TOWER); break; case SCORE_TOWERS_DEFENDED: ((BattlegroundAVScore*)itr->second)->TowersDefended += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_TOWER); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_TOWER); break; case SCORE_MINES_CAPTURED: ((BattlegroundAVScore*)itr->second)->MinesCaptured += value; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index f073b69a779..b71b3476fcc 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -95,7 +95,7 @@ horde: AV_SOUND_BOTH_TOWER_DEFEND = 8192, AV_SOUND_ALLIANCE_CAPTAIN = 8232, //gets called when someone attacks them and at the beginning after 3min+rand(x)*10sec (maybe buff) - AV_SOUND_HORDE_CAPTAIN = 8333, + AV_SOUND_HORDE_CAPTAIN = 8333 }; @@ -1359,7 +1359,7 @@ enum BG_AV_WorldStates //Neutral //Snowfall Grave */ - AV_SNOWFALL_N = 1966, //over aa + AV_SNOWFALL_N = 1966 //over aa /* AV_SNOWFALL_A_C = 1341, //over hc AV_SNOWFALL_A_A = 1343, //over ha diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp index 78cf6b9863f..4b34422f31b 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp @@ -105,30 +105,20 @@ bool BattlegroundBE::HandlePlayerUnderMap(Player* player) return true; } -void BattlegroundBE::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger) { - // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; - //uint64 buff_guid = 0; - switch (Trigger) + switch (trigger) { case 4538: // buff trigger? - //buff_guid = BgObjects[BG_BE_OBJECT_BUFF_1]; - break; case 4539: // buff trigger? - //buff_guid = BgObjects[BG_BE_OBJECT_BUFF_2]; break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } - - //if (buff_guid) - // HandleTriggerBuff(buff_guid, Source); } void BattlegroundBE::FillInitialWorldStates(WorldPacket &data) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp index 20eba2a7f67..be947458964 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp @@ -181,18 +181,18 @@ void BattlegroundDS::HandleKillPlayer(Player* player, Player* killer) CheckArenaWinConditions(); } -void BattlegroundDS::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - switch (Trigger) + switch (trigger) { case 5347: case 5348: // Remove effects of Demonic Circle Summon - if (Source->HasAura(48018)) - Source->RemoveAurasDueToSpell(48018); + if (player->HasAura(48018)) + player->RemoveAurasDueToSpell(48018); // Someone has get back into the pipes and the knockback has already been performed, // so we reset the knockback count for kicking the player again into the arena. @@ -200,8 +200,7 @@ void BattlegroundDS::HandleAreaTrigger(Player* Source, uint32 Trigger) setPipeKnockBackCount(0); break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h index aaf08ba1313..d9e60079bf6 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h @@ -52,14 +52,14 @@ enum BattlegroundDSCreatureTypes enum BattlegroundDSCreatures { - BG_DS_NPC_TYPE_WATER_SPOUT = 28567, + BG_DS_NPC_TYPE_WATER_SPOUT = 28567 }; enum BattlegroundDSSpells { BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not need to be casted) - BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall + BG_DS_SPELL_WATER_SPOUT = 58873 // Knockback effect of the central waterfall }; enum BattlegroundDSData @@ -76,7 +76,7 @@ enum BattlegroundDSData BG_DS_WATERFALL_STATUS_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking BG_DS_WATERFALL_STATUS_ON = 2, // LoS and Movement blocking active - BG_DS_WATERFALL_STATUS_OFF = 3, + BG_DS_WATERFALL_STATUS_OFF = 3 }; class BattlegroundDSScore : public BattlegroundScore diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 9bab15d9b5e..bad56a95cfb 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -368,35 +368,35 @@ void BattlegroundEY::RemovePlayer(Player* player, uint64 guid, uint32 /*team*/) } } -void BattlegroundEY::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundEY::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if (!Source->isAlive()) //hack code, must be removed later + if (!player->isAlive()) //hack code, must be removed later return; - switch (Trigger) + switch (trigger) { case TR_BLOOD_ELF_POINT: - if (m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == Source->GetTeam()) - if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) - EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_BLOOD_ELF); + if (m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[BLOOD_ELF] == player->GetTeam()) + if (m_FlagState && GetFlagPickerGUID() == player->GetGUID()) + EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_BLOOD_ELF); break; case TR_FEL_REAVER_POINT: - if (m_PointState[FEL_REAVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REAVER] == Source->GetTeam()) - if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) - EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_FEL_REAVER); + if (m_PointState[FEL_REAVER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[FEL_REAVER] == player->GetTeam()) + if (m_FlagState && GetFlagPickerGUID() == player->GetGUID()) + EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_FEL_REAVER); break; case TR_MAGE_TOWER_POINT: - if (m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == Source->GetTeam()) - if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) - EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_MAGE_TOWER); + if (m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[MAGE_TOWER] == player->GetTeam()) + if (m_FlagState && GetFlagPickerGUID() == player->GetGUID()) + EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_MAGE_TOWER); break; case TR_DRAENEI_RUINS_POINT: - if (m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == Source->GetTeam()) - if (m_FlagState && GetFlagPickerGUID() == Source->GetGUID()) - EventPlayerCapturedFlag(Source, BG_EY_OBJECT_FLAG_DRAENEI_RUINS); + if (m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL && m_PointOwnedByTeam[DRAENEI_RUINS] == player->GetTeam()) + if (m_FlagState && GetFlagPickerGUID() == player->GetGUID()) + EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_DRAENEI_RUINS); break; case 4512: case 4515: @@ -411,8 +411,7 @@ void BattlegroundEY::HandleAreaTrigger(Player* Source, uint32 Trigger) case 5866: break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } } @@ -816,7 +815,7 @@ void BattlegroundEY::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_FLAG_CAPTURES: // flags captured ((BattlegroundEYScore*)itr->second)->FlagCaptures += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG); break; default: Battleground::UpdatePlayerScore(Source, type, value, doAddHonor); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index 534a40484ce..c7ee4c62504 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -26,7 +26,7 @@ class Battleground; enum BG_EY_Misc { BG_EY_FLAG_RESPAWN_TIME = (8*IN_MILLISECONDS), - BG_EY_FPOINTS_TICK_TIME = (2*IN_MILLISECONDS), + BG_EY_FPOINTS_TICK_TIME = (2*IN_MILLISECONDS) }; enum BG_EY_WorldStates diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index 90f39a61e12..20f44acc14f 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -178,7 +178,7 @@ enum gameobjectsIC GO_HORDE_BANNER_GRAVEYARD_H_CONT = 195394, GO_HORDE_GUNSHIP = 195276, - GO_ALLIANCE_GUNSHIP = 195121, + GO_ALLIANCE_GUNSHIP = 195121 }; #define MAX_REINFORCEMENTS 300 @@ -336,7 +336,7 @@ enum BG_IC_GOs BG_IC_GO_TELEPORTER_EFFECTS_H_3, BG_IC_GO_TELEPORTER_EFFECTS_H_4, BG_IC_GO_TELEPORTER_EFFECTS_H_5, - BG_IC_GO_TELEPORTER_EFFECTS_H_6, + BG_IC_GO_TELEPORTER_EFFECTS_H_6 }; enum BG_IC_NPCs @@ -411,7 +411,7 @@ enum BG_IC_NPCs BG_IC_NPC_SPIRIT_GUIDE_4, BG_IC_NPC_SPIRIT_GUIDE_5, BG_IC_NPC_SPIRIT_GUIDE_6, - BG_IC_NPC_SPIRIT_GUIDE_7, + BG_IC_NPC_SPIRIT_GUIDE_7 }; enum BannersTypes @@ -751,7 +751,7 @@ enum ICDoorList BG_IC_A_FRONT, BG_IC_A_WEST, BG_IC_A_EAST, - BG_IC_MAXDOOR, + BG_IC_MAXDOOR }; enum ICNodePointType diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp index f39b1ba5540..6c45d4a8873 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp @@ -102,26 +102,20 @@ bool BattlegroundNA::HandlePlayerUnderMap(Player* player) return true; } -void BattlegroundNA::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; - //uint64 buff_guid = 0; - switch (Trigger) + switch (trigger) { case 4536: // buff trigger? case 4537: // buff trigger? break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } - - //if (buff_guid) - // HandleTriggerBuff(buff_guid, Source); } void BattlegroundNA::FillInitialWorldStates(WorldPacket &data) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp index 7fa9980a77c..3dd4fb32da4 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp @@ -102,27 +102,20 @@ bool BattlegroundRL::HandlePlayerUnderMap(Player* player) return true; } -void BattlegroundRL::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger) { - // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; - //uint64 buff_guid = 0; - switch (Trigger) + switch (trigger) { case 4696: // buff trigger? case 4697: // buff trigger? break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } - - //if (buff_guid) - // HandleTriggerBuff(buff_guid, Source); } void BattlegroundRL::FillInitialWorldStates(WorldPacket &data) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp index 769df5445c7..2cc48648022 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp @@ -148,12 +148,12 @@ bool BattlegroundRV::HandlePlayerUnderMap(Player* player) return true; } -void BattlegroundRV::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - switch (Trigger) + switch (trigger) { case 5224: case 5226: @@ -162,8 +162,7 @@ void BattlegroundRV::HandleAreaTrigger(Player* Source, uint32 Trigger) case 5474: break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } } @@ -247,4 +246,4 @@ void BattlegroundRV::TogglePillarCollision() } SetPillarCollision(!apply); -}
\ No newline at end of file +} diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h index 8c5746931e3..d8ac082ec19 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h @@ -46,7 +46,7 @@ enum BattlegroundRVObjectTypes BG_RV_OBJECT_ELEVATOR_1, BG_RV_OBJECT_ELEVATOR_2, - BG_RV_OBJECT_MAX, + BG_RV_OBJECT_MAX }; enum BattlegroundRVObjects @@ -73,7 +73,7 @@ enum BattlegroundRVObjects BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning - BG_RV_OBJECT_TYPE_PILAR_4 = 194587, // ivory + BG_RV_OBJECT_TYPE_PILAR_4 = 194587 // ivory }; enum BattlegroundRVData @@ -88,7 +88,7 @@ enum BattlegroundRVData BG_RV_FIRST_TIMER = 20133, BG_RV_WORLD_STATE_A = 0xe10, BG_RV_WORLD_STATE_H = 0xe11, - BG_RV_WORLD_STATE = 0xe1a, + BG_RV_WORLD_STATE = 0xe1a }; class BattlegroundRVScore : public BattlegroundScore diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index fd11cb2c5ea..78653a993a0 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -104,7 +104,7 @@ enum BG_SA_WorldStates BG_SA_LEFT_GY_HORDE = 3633, BG_SA_CENTER_GY_HORDE = 3634, BG_SA_BONUS_TIMER = 0xdf3, - BG_SA_ENABLE_TIMER = 3564, + BG_SA_ENABLE_TIMER = 3564 }; enum npc @@ -112,7 +112,7 @@ enum npc NPC_ANTI_PERSONNAL_CANNON = 27894, NPC_DEMOLISHER_SA = 28781, NPC_RIGGER_SPARKLIGHT = 29260, - NPC_GORGRIL_RIGSPARK = 29262, + NPC_GORGRIL_RIGSPARK = 29262 }; enum BG_SA_NPCs @@ -146,7 +146,7 @@ enum BG_SA_Boat BG_SA_BOAT_ONE_A = 193182, BG_SA_BOAT_TWO_H = 193183, BG_SA_BOAT_ONE_H = 193184, - BG_SA_BOAT_TWO_A = 193185, + BG_SA_BOAT_TWO_A = 193185 }; uint32 const BG_SA_NpcEntries[BG_SA_MAXNPC] = diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 8df6f93a082..a50553d2fa3 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -453,7 +453,7 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target UpdateFlagState(HORDE, BG_WS_FLAG_STATE_ON_PLAYER); UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 1); Source->CastSpell(Source, BG_WS_SPELL_SILVERWING_FLAG, true); - Source->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, BG_WS_SPELL_SILVERWING_FLAG_PICKED); + Source->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, BG_WS_SPELL_SILVERWING_FLAG_PICKED); if (_flagState[1] == BG_WS_FLAG_STATE_ON_PLAYER) _bothFlagsKept = true; } @@ -472,7 +472,7 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target UpdateFlagState(ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER); UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 1); Source->CastSpell(Source, BG_WS_SPELL_WARSONG_FLAG, true); - Source->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, BG_WS_SPELL_WARSONG_FLAG_PICKED); + Source->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, BG_WS_SPELL_WARSONG_FLAG_PICKED); if (_flagState[0] == BG_WS_FLAG_STATE_ON_PLAYER) _bothFlagsKept = true; } @@ -595,15 +595,14 @@ void BattlegroundWS::UpdateTeamScore(uint32 team) UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team)); } -void BattlegroundWS::HandleAreaTrigger(Player* Source, uint32 Trigger) +void BattlegroundWS::HandleAreaTrigger(Player* player, uint32 trigger) { - // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; //uint32 SpellId = 0; //uint64 buff_guid = 0; - switch (Trigger) + switch (trigger) { case 3686: // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in Battleground::Update(). //buff_guid = BgObjects[BG_WS_OBJECT_SPEEDBUFF_1]; @@ -625,13 +624,13 @@ void BattlegroundWS::HandleAreaTrigger(Player* Source, uint32 Trigger) break; case 3646: // Alliance Flag spawn if (_flagState[BG_TEAM_HORDE] && !_flagState[BG_TEAM_ALLIANCE]) - if (GetFlagPickerGUID(BG_TEAM_HORDE) == Source->GetGUID()) - EventPlayerCapturedFlag(Source); + if (GetFlagPickerGUID(BG_TEAM_HORDE) == player->GetGUID()) + EventPlayerCapturedFlag(player); break; case 3647: // Horde Flag spawn if (_flagState[BG_TEAM_ALLIANCE] && !_flagState[BG_TEAM_HORDE]) - if (GetFlagPickerGUID(BG_TEAM_ALLIANCE) == Source->GetGUID()) - EventPlayerCapturedFlag(Source); + if (GetFlagPickerGUID(BG_TEAM_ALLIANCE) == player->GetGUID()) + EventPlayerCapturedFlag(player); break; case 3649: // unk1 case 3688: // unk2 @@ -639,8 +638,7 @@ void BattlegroundWS::HandleAreaTrigger(Player* Source, uint32 Trigger) case 4629: // unk4 break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger); - Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); + Battleground::HandleAreaTrigger(player, trigger); break; } @@ -731,7 +729,6 @@ void BattlegroundWS::Reset() _bothFlagsKept = false; _flagDebuffState = 0; _flagSpellForceTimer = 0; - _lastFlagCaptureTeam = 0; _flagsDropTimer[BG_TEAM_ALLIANCE] = 0; _flagsDropTimer[BG_TEAM_HORDE] = 0; _flagsTimer[BG_TEAM_ALLIANCE] = 0; @@ -773,11 +770,11 @@ void BattlegroundWS::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_FLAG_CAPTURES: // flags captured ((BattlegroundWGScore*)itr->second)->FlagCaptures += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG); break; case SCORE_FLAG_RETURNS: // flags returned ((BattlegroundWGScore*)itr->second)->FlagReturns += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG); break; default: Battleground::UpdatePlayerScore(Source, type, value, doAddHonor); diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 9564dbb381e..04bb4ae2916 100755 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -68,7 +68,7 @@ enum ChatNotify CHAT_NOT_IN_AREA_NOTICE = 0x20, //+ "[%s] You are not in the correct area for this channel."; -- The user is trying to send a chat to a zone specific channel, and they're not physically in that zone. CHAT_NOT_IN_LFG_NOTICE = 0x21, //+ "[%s] You must be queued in looking for group before joining this channel."; -- The user must be in the looking for group system to join LFG chat channels. CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s."; - CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s."; + CHAT_VOICE_OFF_NOTICE = 0x23 //+ "[%s] Channel voice disabled by %s."; }; enum ChannelFlags @@ -101,7 +101,7 @@ enum ChannelDBCFlags CHANNEL_DBC_FLAG_DEFENSE = 0x10000, // LocalDefense, WorldDefense CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment CHANNEL_DBC_FLAG_LFG = 0x40000, // LFG - CHANNEL_DBC_FLAG_UNK1 = 0x80000, // General + CHANNEL_DBC_FLAG_UNK1 = 0x80000 // General }; enum ChannelMemberFlags @@ -112,7 +112,7 @@ enum ChannelMemberFlags MEMBER_FLAG_VOICED = 0x04, MEMBER_FLAG_MUTED = 0x08, MEMBER_FLAG_CUSTOM = 0x10, - MEMBER_FLAG_MIC_MUTED = 0x20, + MEMBER_FLAG_MIC_MUTED = 0x20 // 0x40 // 0x80 }; diff --git a/src/server/game/Combat/UnitEvents.h b/src/server/game/Combat/UnitEvents.h index 07d8b20af52..8d57ef6c59c 100755 --- a/src/server/game/Combat/UnitEvents.h +++ b/src/server/game/Combat/UnitEvents.h @@ -49,7 +49,7 @@ enum UNIT_EVENT_TYPE UEV_THREAT_SET_NEXT_TARGET = 1<<5, // A new victim (target) was set. Could be NULL - UEV_THREAT_VICTIM_CHANGED = 1<<6, + UEV_THREAT_VICTIM_CHANGED = 1<<6 // Future use //UEV_UNIT_KILLED = 1<<7, diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index e24547f1a31..7dc4b57d188 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -83,7 +83,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) case CONDITION_ACHIEVEMENT: { if (Player* player = object->ToPlayer()) - condMeets = player->GetAchievementMgr().HasAchieved(ConditionValue1); + condMeets = player->HasAchieved(ConditionValue1); break; } case CONDITION_TEAM: @@ -223,6 +223,9 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) case RELATION_PASSENGER_OF: condMeets = unit->IsOnVehicle(toUnit); break; + case RELATION_CREATED_BY: + condMeets = unit->GetCreatorGUID() == toUnit->GetGUID(); + break; } } } @@ -279,6 +282,11 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = player->HasTitle(ConditionValue1); break; } + case CONDITION_SPAWNMASK: + { + condMeets = ((1 << object->GetMap()->GetSpawnMode()) & ConditionValue1); + break; + } default: condMeets = false; break; @@ -430,6 +438,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition() case CONDITION_TITLE: mask |= GRID_MAP_TYPE_MASK_PLAYER; break; + case CONDITION_SPAWNMASK: + mask |= GRID_MAP_TYPE_MASK_ALL; + break; default: ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!"); break; @@ -1842,9 +1853,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) } break; } - case CONDITION_UNUSED_19: - sLog->outError(LOG_FILTER_SQL, "Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring"); - return false; + case CONDITION_SPAWNMASK: + { + if (cond->ConditionValue1 > SPAWNMASK_RAID_ALL) + { + sLog->outError(LOG_FILTER_SQL, "SpawnMask condition has non existing SpawnMask in value1 (%u), skipped", cond->ConditionValue1); + return false; + } + break; + } case CONDITION_UNUSED_20: sLog->outError(LOG_FILTER_SQL, "Found ConditionTypeOrReference = CONDITION_UNUSED_20 in `conditions` table - ignoring"); return false; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 130a23a0cb0..57af0562dcd 100755 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -49,7 +49,7 @@ enum ConditionTypes CONDITION_RACE = 16, // race 0 0 true if player's race is equal to race CONDITION_ACHIEVEMENT = 17, // achievement_id 0 0 true if achievement is complete CONDITION_TITLE = 18, // title id 0 0 true if player has title - CONDITION_UNUSED_19 = 19, // + CONDITION_SPAWNMASK = 19, // spawnMask 0 0 true if in spawnMask CONDITION_UNUSED_20 = 20, // CONDITION_UNUSED_21 = 21, // CONDITION_MAPID = 22, // map_id 0 0 true if in map_id @@ -144,12 +144,13 @@ enum RelationType RELATION_IN_RAID_OR_PARTY, RELATION_OWNED_BY, RELATION_PASSENGER_OF, + RELATION_CREATED_BY, RELATION_MAX }; enum { - MAX_CONDITION_TARGETS = 3, + MAX_CONDITION_TARGETS = 3 }; struct ConditionSourceInfo diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index 0f9310ace3b..b1bb43315bd 100755 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -31,7 +31,7 @@ enum DisableType DISABLE_TYPE_BATTLEGROUND = 3, DISABLE_TYPE_ACHIEVEMENT_CRITERIA = 4, DISABLE_TYPE_OUTDOORPVP = 5, - DISABLE_TYPE_VMAP = 6, + DISABLE_TYPE_VMAP = 6 }; enum SpellDisableTypes @@ -43,7 +43,7 @@ enum SpellDisableTypes SPELL_DISABLE_MAP = 0x10, SPELL_DISABLE_AREA = 0x20, MAX_SPELL_DISABLE_TYPE = ( SPELL_DISABLE_PLAYER | SPELL_DISABLE_CREATURE | SPELL_DISABLE_PET | - SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA), + SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA) }; enum VmapDisableTypes @@ -51,7 +51,7 @@ enum VmapDisableTypes VMAP_DISABLE_AREAFLAG = 0x1, VMAP_DISABLE_HEIGHT = 0x2, VMAP_DISABLE_LOS = 0x4, - VMAP_DISABLE_LIQUIDSTATUS = 0x8, + VMAP_DISABLE_LIQUIDSTATUS = 0x8 }; namespace DisableMgr diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index e73480cb4de..12ec7206141 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -53,7 +53,7 @@ enum AchievementFaction { ACHIEVEMENT_FACTION_HORDE = 0, ACHIEVEMENT_FACTION_ALLIANCE = 1, - ACHIEVEMENT_FACTION_ANY = -1, + ACHIEVEMENT_FACTION_ANY = -1 }; enum AchievementFlags @@ -67,7 +67,7 @@ enum AchievementFlags ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // - ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // + ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200 // }; #define MAX_CRITERIA_REQUIREMENTS 2 @@ -81,7 +81,7 @@ enum AchievementCriteriaCondition ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing" ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT = 9, // requires the player not to be hit by specific spell ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group - ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk + ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13 // unk }; enum AchievementCriteriaFlags @@ -91,7 +91,7 @@ enum AchievementCriteriaFlags ACHIEVEMENT_CRITERIA_FLAG_UNK3 = 0x00000004, // BG related?? ACHIEVEMENT_CRITERIA_FLAG_UNK4 = 0x00000008, // ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used - ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money + ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020 // Displays counter as money }; enum AchievementCriteriaTimedTypes @@ -103,7 +103,7 @@ enum AchievementCriteriaTimedTypes ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent ACHIEVEMENT_TIMED_TYPE_ITEM = 9, // Timer is started by using item with entry in timerStartEvent - ACHIEVEMENT_TIMED_TYPE_MAX, + ACHIEVEMENT_TIMED_TYPE_MAX }; enum AchievementCriteriaTypes @@ -223,12 +223,12 @@ enum AchievementCriteriaTypes // 122 // 123 // 0..123 => 124 criteria types total - ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 124, + ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 124 }; enum AchievementCategory { - CATEGORY_CHILDRENS_WEEK = 163, + CATEGORY_CHILDRENS_WEEK = 163 }; enum AreaFlags @@ -275,7 +275,7 @@ enum Difficulty RAID_DIFFICULTY_10MAN_NORMAL = 0, RAID_DIFFICULTY_25MAN_NORMAL = 1, RAID_DIFFICULTY_10MAN_HEROIC = 2, - RAID_DIFFICULTY_25MAN_HEROIC = 3, + RAID_DIFFICULTY_25MAN_HEROIC = 3 }; #define RAID_DIFFICULTY_MASK_25MAN 1 // since 25man difficulties are 1 and 3, we can check them like that @@ -300,14 +300,14 @@ enum SpawnMask SPAWNMASK_RAID_25MAN_HEROIC = (1 << RAID_DIFFICULTY_25MAN_HEROIC), SPAWNMASK_RAID_HEROIC_ALL = (SPAWNMASK_RAID_10MAN_HEROIC | SPAWNMASK_RAID_25MAN_HEROIC), - SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL), + SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL) }; enum FactionTemplateFlags { FACTION_TEMPLATE_FLAG_PVP = 0x00000800, // flagged for PvP FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats - FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT= 0x00002000, + FACTION_TEMPLATE_FLAG_HOSTILE_BY_DEFAULT= 0x00002000 }; enum FactionMasks @@ -350,7 +350,7 @@ enum ItemEnchantmentType enum ItemLimitCategoryMode { ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank - ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1, // limit applied to amount equipped items (including used gems) + ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1 // limit applied to amount equipped items (including used gems) }; enum TotemCategoryType @@ -411,7 +411,7 @@ enum SummonPropFlags SUMMON_PROP_FLAG_UNK13 = 0x00001000, // Lightwell, Jeeves, Gnomish Alarm-o-bot, Build vehicles(wintergrasp) SUMMON_PROP_FLAG_UNK14 = 0x00002000, // Guides, player follows SUMMON_PROP_FLAG_UNK15 = 0x00004000, // Force of Nature, Shadowfiend, Feral Spirit, Summon Water Elemental - SUMMON_PROP_FLAG_UNK16 = 0x00008000, // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related? + SUMMON_PROP_FLAG_UNK16 = 0x00008000 // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related? }; enum VehicleSeatFlags @@ -436,7 +436,7 @@ enum VehicleSeatFlags VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_EXIT = 0x10000000, VEHICLE_SEAT_FLAG_CAN_CAST = 0x20000000, // Lua_UnitHasVehicleUI VEHICLE_SEAT_FLAG_UNK2 = 0x40000000, // checked in conjunction with 0x800 in CastSpell2 - VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION = 0x80000000, + VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION = 0x80000000 }; enum VehicleSeatFlagsB @@ -449,7 +449,7 @@ enum VehicleSeatFlagsB VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100, VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000, VEHICLE_SEAT_FLAG_B_CAN_SWITCH = 0x04000000, - VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000 + VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000 // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000 }; #endif diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index fdec06f6f48..ef949f43f49 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1092,7 +1092,7 @@ struct ItemEntry uint32 ID; // 0 uint32 Class; // 1 uint32 SubClass; // 2 some items have strange subclasses - int32 Unk0; // 3 + int32 SoundOverrideSubclass; // 3 int32 Material; // 4 uint32 DisplayId; // 5 uint32 InventoryType; // 6 diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index bb6c1dfdcc1..618032e5f97 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -440,7 +440,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player) locktype = LFG_LOCKSTATUS_TOO_HIGH_LEVEL; else if (locktype == LFG_LOCKSTATUS_OK && ar) { - if (ar->achievement && !player->GetAchievementMgr().HasAchieved(ar->achievement)) + if (ar->achievement && !player->HasAchieved(ar->achievement)) locktype = LFG_LOCKSTATUS_RAID_LOCKED; // FIXME: Check the correct lock value else if (player->GetTeam() == ALLIANCE && ar->quest_A && !player->GetQuestRewardStatus(ar->quest_A)) locktype = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED; @@ -1899,7 +1899,7 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) // Update achievements if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); if (!reward) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index f21818deb64..e341b21706f 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -29,7 +29,7 @@ class Player; enum LFGenum { - LFG_TIME_ROLECHECK = 2*MINUTE, + LFG_TIME_ROLECHECK = 40*IN_MILLISECONDS, LFG_TIME_BOOT = 2*MINUTE, LFG_TIME_PROPOSAL = 2*MINUTE, LFG_TANKS_NEEDED = 1, diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index afa4b62d8b0..b92c3048b45 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2231,6 +2231,38 @@ bool Creature::HasSpellCooldown(uint32 spell_id) const return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id); } +void Creature::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) +{ + time_t curTime = time(NULL); + for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + { + if (m_spells[i] == 0) + continue; + + uint32 unSpellId = m_spells[i]; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId); + if (!spellInfo) + { + ASSERT(spellInfo); + continue; + } + + // Not send cooldown for this spells + if (spellInfo->Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE) + continue; + + if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE) + continue; + + if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs) + { + _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS); + if (UnitAI* ai = GetAI()) + ai->SpellInterrupted(unSpellId, unTimeMs); + } + } +} + bool Creature::HasSpell(uint32 spellID) const { uint8 i; @@ -2448,7 +2480,7 @@ void Creature::SetPosition(float x, float y, float z, float o) GetMap()->CreatureRelocation(ToCreature(), x, y, z, o); if (IsVehicle()) - GetVehicleKit()->RelocatePassengers(x, y, z, o); + GetVehicleKit()->RelocatePassengers(); } bool Creature::IsDungeonBoss() const diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 4dd080f8b15..b9fb5c8831c 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -54,7 +54,7 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // Creature is subject to all diminishing returns as player are - CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB) + CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000 // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB) }; #define CREATURE_FLAG_EXTRA_DB_ALLOWED (CREATURE_FLAG_EXTRA_INSTANCE_BIND | CREATURE_FLAG_EXTRA_CIVILIAN | \ @@ -412,15 +412,15 @@ typedef std::map<uint32, time_t> CreatureSpellCooldowns; enum CreatureCellMoveState { - CREATURE_CELL_MOVE_NONE, //not in move list - CREATURE_CELL_MOVE_ACTIVE, //in move list - CREATURE_CELL_MOVE_INACTIVE, //in move list but should not move + CREATURE_CELL_MOVE_NONE, // not in move list + CREATURE_CELL_MOVE_ACTIVE, // in move list + CREATURE_CELL_MOVE_INACTIVE // in move list but should not move }; class MapCreature { - friend class Map; //map for moving creatures - friend class ObjectGridLoader; //grid loader for loading creatures + friend class Map; // map for moving creatures + friend class ObjectGridLoader; // grid loader for loading creatures protected: MapCreature() : _moveState(CREATURE_CELL_MOVE_NONE) {} @@ -540,6 +540,13 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void AddCreatureSpellCooldown(uint32 spellid); bool HasSpellCooldown(uint32 spell_id) const; bool HasCategoryCooldown(uint32 spell_id) const; + uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const + { + CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spellId); + time_t t = time(NULL); + return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0); + } + virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); bool HasSpell(uint32 spellID) const; @@ -661,6 +668,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature bool hasInvolvedQuest(uint32 quest_id) const; bool isRegeneratingHealth() { return m_regenHealth; } + void setRegeneratingHealth(bool regenHealth) { m_regenHealth = regenHealth; } virtual uint8 GetPetAutoSpellSize() const { return MAX_SPELL_CHARM; } virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const { diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index 7e68f6acd38..68da99ac668 100755 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -29,7 +29,7 @@ enum DynamicObjectType { DYNAMIC_OBJECT_PORTAL = 0x0, // unused DYNAMIC_OBJECT_AREA_SPELL = 0x1, - DYNAMIC_OBJECT_FARSIGHT_FOCUS = 0x2, + DYNAMIC_OBJECT_FARSIGHT_FOCUS = 0x2 }; class DynamicObject : public WorldObject, public GridObject<DynamicObject> diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 751107ac011..c28ff21bfa5 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -133,13 +133,13 @@ void GameObject::AddToWorld() m_zoneScript->OnGameObjectCreate(this); sObjectAccessor->AddObject(this); - bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false); + // The state can be changed after GameObject::Create but before GameObject::AddToWorld - bool toggledState = GetGOData() ? GetGOData()->go_state != GO_STATE_READY : false; + bool toggledState = GetGoType() == GAMEOBJECT_TYPE_CHEST ? getLootState() == GO_READY : GetGoState() == GO_STATE_READY; if (m_model) GetMap()->InsertGameObjectModel(*m_model); - EnableCollision(startOpen ^ toggledState); + EnableCollision(toggledState); WorldObject::AddToWorld(); } } @@ -1707,6 +1707,11 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const float dy = y - GetPositionY(); float dz = z - GetPositionZ(); float dist = sqrt(dx*dx + dy*dy); + //! Check if the distance between the 2 objects is 0, can happen if both objects are on the same position. + //! The code below this check wont crash if dist is 0 because 0/0 in float operations is valid, and returns infinite + if (G3D::fuzzyEq(dist, 0.0f)) + return true; + float sinB = dx / dist; float cosB = dy / dist; dx = dist * (cosA * cosB + sinA * sinB); @@ -1926,17 +1931,12 @@ void GameObject::SetLootState(LootState state, Unit* unit) sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); if (m_model) { - // startOpen determines whether we are going to add or remove the LoS on activation - bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false); - + bool collision = false; // Use the current go state - if (GetGoState() != GO_STATE_READY) - startOpen = !startOpen; + if ((GetGoState() != GO_STATE_READY && (state == GO_ACTIVATED || state == GO_JUST_DEACTIVATED)) || state == GO_READY) + collision = !collision; - if (state == GO_ACTIVATED || state == GO_JUST_DEACTIVATED) - EnableCollision(startOpen); - else if (state == GO_READY) - EnableCollision(!startOpen); + EnableCollision(collision); } } @@ -1950,12 +1950,11 @@ void GameObject::SetGoState(GOState state) return; // startOpen determines whether we are going to add or remove the LoS on activation - bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false); - - if (state != GO_STATE_READY) - startOpen = !startOpen; + bool collision = false; + if (state == GO_STATE_READY) + collision = !collision; - EnableCollision(startOpen); + EnableCollision(collision); } } @@ -1968,7 +1967,8 @@ void GameObject::SetDisplayId(uint32 displayid) void GameObject::SetPhaseMask(uint32 newPhaseMask, bool update) { WorldObject::SetPhaseMask(newPhaseMask, update); - EnableCollision(true); + if (m_model && m_model->isEnabled()) + EnableCollision(true); } void GameObject::EnableCollision(bool enable) diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 5088a30157c..f2f41d6a8b9 100755 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -181,7 +181,7 @@ enum ItemFieldFlags ITEM_FLAG_UNK25 = 0x40000000, // ? ITEM_FLAG_UNK26 = 0x80000000, // ? - ITEM_FLAG_MAIL_TEXT_MASK = ITEM_FLAG_READABLE | ITEM_FLAG_UNK13 | ITEM_FLAG_UNK14, + ITEM_FLAG_MAIL_TEXT_MASK = ITEM_FLAG_READABLE | ITEM_FLAG_UNK13 | ITEM_FLAG_UNK14 }; enum ItemFlagsExtra @@ -196,7 +196,7 @@ enum ItemFlagsCustom { ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline ITEM_FLAGS_CU_IGNORE_QUEST_STATUS = 0x0002, // No quest status will be checked when this item drops - ITEM_FLAGS_CU_FOLLOW_LOOT_RULES = 0x0004, // Item will always follow group/master/need before greed looting rules + ITEM_FLAGS_CU_FOLLOW_LOOT_RULES = 0x0004 // Item will always follow group/master/need before greed looting rules }; enum BAG_FAMILY_MASK @@ -588,7 +588,7 @@ struct ItemTemplate uint32 ItemId; uint32 Class; // id from ItemClass.dbc uint32 SubClass; // id from ItemSubClass.dbc - int32 Unk0; + int32 SoundOverrideSubclass; // < 0: id from ItemSubClass.dbc, used to override weapon sound from actual SubClass std::string Name1; uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc uint32 Quality; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index fe5d32b9b95..cbdae9de0bf 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2537,6 +2537,15 @@ GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range) const return go; } +GameObject* WorldObject::FindNearestGameObjectOfType(GameobjectTypes type, float range) const +{ + GameObject* go = NULL; + Trinity::NearestGameObjectTypeInObjectRangeCheck checker(*this, type, range); + Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectTypeInObjectRangeCheck> searcher(this, go, checker); + VisitNearbyGridObject(range, searcher); + return go; +} + void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameobjectList, uint32 entry, float maxSearchRange) const { CellCoord pair(Trinity::ComputeCellCoord(this->GetPositionX(), this->GetPositionY())); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index ab9ea2daea9..410903f6619 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -799,6 +799,7 @@ class WorldObject : public Object, public WorldLocation Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; GameObject* FindNearestGameObject(uint32 entry, float range) const; + GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const; void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList, uint32 uiEntry, float fMaxSearchRange) const; void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, uint32 uiEntry, float fMaxSearchRange) const; diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index c227d081d8b..a3c8901880f 100755 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -44,7 +44,7 @@ enum HighGuid HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100 HIGHGUID_CORPSE = 0xF101, // blizz F100 HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) - HIGHGUID_GROUP = 0x1F50, + HIGHGUID_GROUP = 0x1F50 }; #define IS_EMPTY_GUID(Guid) (Guid == 0) diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h index 71b3f0cd4aa..2cd303d5fc5 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h +++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h @@ -32,7 +32,7 @@ enum UpdatefieldFlags UF_FLAG_SPECIAL_INFO = 0x020, UF_FLAG_PARTY_MEMBER = 0x040, UF_FLAG_UNUSED2 = 0x080, - UF_FLAG_DYNAMIC = 0x100, + UF_FLAG_DYNAMIC = 0x100 }; extern uint32 ItemUpdateFieldFlags[CONTAINER_END]; diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 825bda98ae6..7e4aa9aaab8 100755 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -28,7 +28,7 @@ enum EObjectFields OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE - OBJECT_END = 0x0006, + OBJECT_END = 0x0006 }; enum EItemFields @@ -71,7 +71,7 @@ enum EItemFields ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: PUBLIC ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE - ITEM_END = OBJECT_END + 0x003A, + ITEM_END = OBJECT_END + 0x003A }; enum EContainerFields @@ -79,7 +79,7 @@ enum EContainerFields CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC - CONTAINER_END = ITEM_END + 0x004A, + CONTAINER_END = ITEM_END + 0x004A }; enum EUnitFields @@ -333,9 +333,9 @@ enum EUnitFields PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x015C, // Size: 64, Type: LONG, Flags: PRIVATE PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x019C, // Size: 64, Type: LONG, Flags: PRIVATE PLAYER_FARSIGHT = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01E4, // Size: 2, Type: LONG, Flags: PRIVATE PLAYER_XP = UNIT_END + 0x01E6, // Size: 1, Type: INT, Flags: PRIVATE PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E7, // Size: 1, Type: INT, Flags: PRIVATE @@ -390,7 +390,7 @@ enum EUnitFields PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0492, // Size: 6, Type: INT, Flags: PRIVATE PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0498, // Size: 1, Type: INT, Flags: PRIVATE PLAYER_PET_SPELL_POWER = UNIT_END + 0x0499, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_END = UNIT_END + 0x049A, + PLAYER_END = UNIT_END + 0x049A }; enum EGameObjectFields @@ -403,7 +403,7 @@ enum EGameObjectFields GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC - GAMEOBJECT_END = OBJECT_END + 0x000C, + GAMEOBJECT_END = OBJECT_END + 0x000C }; enum EDynamicObjectFields @@ -413,7 +413,7 @@ enum EDynamicObjectFields DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC - DYNAMICOBJECT_END = OBJECT_END + 0x0006, + DYNAMICOBJECT_END = OBJECT_END + 0x0006 }; enum ECorpseFields @@ -428,6 +428,6 @@ enum ECorpseFields CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE - CORPSE_END = OBJECT_END + 0x001E, + CORPSE_END = OBJECT_END + 0x001E }; #endif diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 17b214857db..ead018ac620 100755 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -2033,3 +2033,40 @@ void Pet::SynchronizeLevelWithOwner() break; } } + +void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) +{ + WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8); + data << uint64(GetGUID()); + data << uint8(0x0); // flags (0x1, 0x2) + time_t curTime = time(NULL); + for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if (itr->second.state == PETSPELL_REMOVED) + continue; + uint32 unSpellId = itr->first; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId); + if (!spellInfo) + { + ASSERT(spellInfo); + continue; + } + + // Not send cooldown for this spells + if (spellInfo->Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE) + continue; + + if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE) + continue; + + if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs) + { + data << uint32(unSpellId); + data << uint32(unTimeMs); // in m.secs + _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS); + } + } + + if (Player* owner = GetOwner()) + owner->GetSession()->SendPacket(&data); +}
\ No newline at end of file diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 3475817816d..6e080263862 100755 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -27,7 +27,7 @@ enum PetType { SUMMON_PET = 0, HUNTER_PET = 1, - MAX_PET_TYPE = 4, + MAX_PET_TYPE = 4 }; #define MAX_PET_STABLES 4 @@ -61,7 +61,7 @@ enum PetSpellType { PETSPELL_NORMAL = 0, PETSPELL_FAMILY = 1, - PETSPELL_TALENT = 2, + PETSPELL_TALENT = 2 }; struct PetSpell @@ -200,6 +200,7 @@ class Pet : public Guardian bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true); bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true); void CleanupActionBar(); + virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); PetSpellMap m_spells; AutoSpellList m_autospells; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 65f6588f80e..c498350c78c 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1305,7 +1305,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) GetSession()->SendPacket(&data2); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); } return final_damage; @@ -1593,7 +1593,7 @@ void Player::Update(uint32 p_time) } } - GetAchievementMgr().UpdateTimedAchievements(p_time); + m_achievementMgr.UpdateTimedAchievements(p_time); if (HasUnitState(UNIT_STATE_MELEE_ATTACKING) && !HasUnitState(UNIT_STATE_CASTING)) { @@ -1844,12 +1844,12 @@ void Player::setDeathState(DeathState s) // passive spell if (!ressSpellId) ressSpellId = GetResurrectionSpellId(); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); - GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); - GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); - GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); + ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); + ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); + ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); } Unit::setDeathState(s); @@ -3076,7 +3076,7 @@ void Player::GiveLevel(uint8 level) CharacterDatabase.CommitTransaction(trans); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); // Refer-A-Friend if (GetSession()->GetRecruiterId()) @@ -3866,11 +3866,11 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent // not ranked skills for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx) { - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE, _spell_idx->second->skillId); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE, _spell_idx->second->skillId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId); } // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell @@ -4461,8 +4461,8 @@ bool Player::resetTalents(bool no_cost) if (!no_cost) { ModifyMoney(-(int32)cost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1); m_resetTalentsCost = cost; m_resetTalentsTime = time(NULL); @@ -6079,7 +6079,7 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step) if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; UpdateSkillEnchantments(skill_id, value, new_value); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id); return true; } @@ -6222,7 +6222,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) } } UpdateSkillEnchantments(SkillId, SkillValue, new_value); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId); sLog->outDebug(LOG_FILTER_PLAYER_SKILLS, "Player::UpdateSkillPro Chance=%3.1f%% taken", Chance / 10.0f); return true; } @@ -6412,8 +6412,8 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) // if skill value is going up, update enchantments after setting the new value if (newVal > currVal) UpdateSkillEnchantments(id, currVal, newVal); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); } else //remove { @@ -6453,8 +6453,8 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step)); SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(newVal, maxVal)); UpdateSkillEnchantments(id, currVal, newVal); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); // insert new entry or update if not deleted old entry yet if (itr != mSkillStatus.end()) @@ -6822,7 +6822,7 @@ void Player::CheckAreaExploreAndOutdoor() { SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId()); if (!areaEntry) @@ -7620,10 +7620,10 @@ void Player::DuelComplete(DuelCompleteType type) } break; case DUEL_WON: - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1); if (duel->opponent) { - duel->opponent->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1); + duel->opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1); //Credit for quest Death's Challenge if (getClass() == CLASS_DEATH_KNIGHT && duel->opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE) @@ -7913,6 +7913,9 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -val, apply); m_spellPenetrationItemMod += apply ? val : -val; break; + case ITEM_MOD_BLOCK_VALUE: + HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(val), apply); + break; // deprecated item mods case ITEM_MOD_SPELL_HEALING_DONE: case ITEM_MOD_SPELL_DAMAGE_DONE: @@ -11528,7 +11531,11 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool if (eslot == EQUIPMENT_SLOT_OFFHAND) { - if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) + // Do not allow polearm to be equipped in the offhand (rare case for the only 1h polearm 41750) + if (type == INVTYPE_WEAPON && pProto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM) + return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT; + + else if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) { if (!CanDualWield()) return EQUIP_ERR_CANT_DUAL_WIELD; @@ -12068,8 +12075,8 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update if (pItem) { ItemAddedQuestCheck(item, count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, item, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, item, 1); if (randomPropertyId) pItem->SetItemRandomProperties(randomPropertyId); pItem = StoreItem(dest, pItem, update); @@ -12239,7 +12246,7 @@ Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update) if (Item* pItem = Item::CreateItem(item, 1, this)) { ItemAddedQuestCheck(item, 1); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1); return EquipItem(pos, pItem, update); } @@ -12349,8 +12356,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) } // only for full equip instead adding to stack - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); return pItem; } @@ -12371,8 +12378,8 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem) pItem->SendUpdateToPlayer(this); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); } } @@ -12518,7 +12525,7 @@ void Player::MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool { // update quest counters ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); // store item Item* pLastItem = StoreItem(dest, pItem, update); @@ -14723,13 +14730,14 @@ bool Player::CanSeeStartQuest(Quest const* quest) bool Player::CanTakeQuest(Quest const* quest, bool msg) { - return SatisfyQuestStatus(quest, msg) && SatisfyQuestExclusiveGroup(quest, msg) + return !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) + && SatisfyQuestStatus(quest, msg) && SatisfyQuestExclusiveGroup(quest, msg) && SatisfyQuestClass(quest, msg) && SatisfyQuestRace(quest, msg) && SatisfyQuestLevel(quest, msg) && SatisfyQuestSkill(quest, msg) && SatisfyQuestReputation(quest, msg) && SatisfyQuestPreviousQuest(quest, msg) && SatisfyQuestTimed(quest, msg) && SatisfyQuestNextChain(quest, msg) && SatisfyQuestPrevChain(quest, msg) && SatisfyQuestDay(quest, msg) && SatisfyQuestWeek(quest, msg) - && SatisfyQuestSeasonal(quest,msg) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) + && SatisfyQuestSeasonal(quest,msg) && SatisfyQuestConditions(quest, msg); } @@ -14984,7 +14992,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) m_QuestStatusSave[quest_id] = true; - GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id); + StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id); //starting initial quest script if (questGiver && quest->GetQuestStartScript() != 0) @@ -15121,7 +15129,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, ModifyMoney(moneyRew); if (moneyRew > 0) - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, uint32(moneyRew)); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, uint32(moneyRew)); } // honor reward @@ -15158,8 +15166,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, SetDailyQuestStatus(quest_id); if (quest->IsDaily()) { - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id); } } else if (quest->IsWeekly()) @@ -15187,9 +15195,9 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, CastSpell(this, quest->GetRewSpell(), true); if (quest->GetZoneOrSort() > 0) - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); uint32 zone = 0; uint32 area = 0; @@ -15968,8 +15976,8 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid) real_entry = killed->GetEntry(); } - GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL); + StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL); for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) { @@ -18478,7 +18486,7 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report leader = ObjectAccessor::FindPlayer(leaderGuid); if (ar->achievement) - if (!leader || !leader->GetAchievementMgr().HasAchieved(ar->achievement)) + if (!leader || !leader->HasAchieved(ar->achievement)) missingAchievement = ar->achievement; Difficulty target_difficulty = GetDifficulty(mapEntry->IsRaid()); @@ -20736,8 +20744,8 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc //Checks and preparations done, DO FLIGHT ModifyMoney(-(int32)totalcost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1); // prevent stealth flight //RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK); @@ -22090,7 +22098,7 @@ void Player::SendInitialPacketsBeforeAddToMap() SendEquipmentSetList(); data.Initialize(SMSG_LOGIN_SETTIMESPEED, 4 + 4 + 4); - data << uint32(secsToTimeBitFields(sWorld->GetGameTime())); + data.AppendPackedTime(sWorld->GetGameTime()); data << float(0.01666667f); // game speed data << uint32(0); // added in 3.1.2 GetSession()->SendPacket(&data); @@ -22727,7 +22735,7 @@ void Player::SummonIfPossible(bool agree) m_summon_expire = 0; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation()); } @@ -23901,9 +23909,9 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) --loot->unlootedCount; SendNewItem(newitem, uint32(item->count), false, false, true); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); } else SendEquipError(msg, NULL, NULL, item->itemid); @@ -24169,7 +24177,7 @@ void Player::HandleFall(MovementInfo const& movementInfo) // recheck alive, might have died of EnvironmentalDamage, avoid cases when player die in fact like Spirit of Redemption case if (isAlive() && final_damage < original_health) - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100)); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100)); } //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction @@ -24179,14 +24187,44 @@ void Player::HandleFall(MovementInfo const& movementInfo) RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // No fly zone - Parachute } +void Player::ResetAchievements() +{ + m_achievementMgr.Reset(); +} + +void Player::SendRespondInspectAchievements(Player* player) const +{ + m_achievementMgr.SendRespondInspectAchievements(player); +} + +bool Player::HasAchieved(uint32 achievementId) const +{ + return m_achievementMgr.HasAchieved(achievementId); +} + +void Player::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost/* = 0*/) +{ + m_achievementMgr.StartTimedAchievement(type, entry, timeLost); +} + +void Player::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) +{ + m_achievementMgr.RemoveTimedAchievement(type, entry); +} + +void Player::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/) +{ + m_achievementMgr.ResetAchievementCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); +} + void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) { - GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit); + m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, unit); } void Player::CompletedAchievement(AchievementEntry const* entry) { - GetAchievementMgr().CompletedAchievement(entry); + m_achievementMgr.CompletedAchievement(entry); } void Player::LearnTalent(uint32 talentId, uint32 talentRank) @@ -24502,11 +24540,11 @@ bool Player::canSeeSpellClickOn(Creature const* c) const ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(c->GetEntry(), itr->second.spellId); ConditionSourceInfo info = ConditionSourceInfo(const_cast<Player*>(this), const_cast<Creature*>(c)); - if (!sConditionMgr->IsObjectMeetToConditions(info, conds)) - return false; + if (sConditionMgr->IsObjectMeetToConditions(info, conds)) + return true; } - return true; + return false; } void Player::BuildPlayerTalentsInfoData(WorldPacket* data) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 71915f42784..0decacd6258 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -299,7 +299,7 @@ struct Areas enum RuneCooldowns { RUNE_BASE_COOLDOWN = 10000, - RUNE_MISS_COOLDOWN = 1500, // cooldown applied on runes when the spell misses + RUNE_MISS_COOLDOWN = 1500 // cooldown applied on runes when the spell misses }; enum RuneType @@ -399,7 +399,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK28 = 0x10000000, PLAYER_FLAGS_UNK29 = 0x20000000, PLAYER_FLAGS_UNK30 = 0x40000000, - PLAYER_FLAGS_UNK31 = 0x80000000, + PLAYER_FLAGS_UNK31 = 0x80000000 }; // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1) @@ -672,7 +672,7 @@ enum TradeSlots TRADE_SLOT_COUNT = 7, TRADE_SLOT_TRADED_COUNT = 6, TRADE_SLOT_NONTRADED = 6, - TRADE_SLOT_INVALID = -1, + TRADE_SLOT_INVALID = -1 }; enum TransferAbortReason @@ -692,7 +692,7 @@ enum TransferAbortReason TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1 TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2 TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. - TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time. + TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10 // Map can't be entered at this time. }; enum InstanceResetWarningType @@ -739,7 +739,7 @@ enum TeleportToOptions TELE_TO_NOT_LEAVE_TRANSPORT = 0x02, TELE_TO_NOT_LEAVE_COMBAT = 0x04, TELE_TO_NOT_UNSUMMON_PET = 0x08, - TELE_TO_SPELL = 0x10, + TELE_TO_SPELL = 0x10 }; /// Type of environmental damages @@ -761,7 +761,7 @@ enum PlayerChatTag CHAT_TAG_DND = 0x02, CHAT_TAG_GM = 0x04, CHAT_TAG_COM = 0x08, // Commentator - CHAT_TAG_DEV = 0x10, + CHAT_TAG_DEV = 0x10 }; enum PlayedTimeIndex @@ -807,7 +807,7 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOADQUESTSTATUSREW = 29, PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES = 30, PLAYER_LOGIN_QUERY_LOADSEASONALQUESTSTATUS = 31, - MAX_PLAYER_LOGIN_QUERY, + MAX_PLAYER_LOGIN_QUERY }; enum PlayerDelayedOperations @@ -2472,9 +2472,14 @@ class Player : public Unit, public GridObject<Player> void AddRunePower(uint8 index); void InitRunes(); - AchievementMgr& GetAchievementMgr() { return m_achievementMgr; } - AchievementMgr const& GetAchievementMgr() const { return m_achievementMgr; } + void SendRespondInspectAchievements(Player* player) const; + bool HasAchieved(uint32 achievementId) const; + void ResetAchievements(); + void CheckAllAchievementCriteria(); + void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false); void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); + void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0); + void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); void CompletedAchievement(AchievementEntry const* entry); bool HasTitle(uint32 bitIndex); diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp index a9a0484a4ea..d5d1bd99277 100755 --- a/src/server/game/Entities/Totem/Totem.cpp +++ b/src/server/game/Entities/Totem/Totem.cpp @@ -98,6 +98,12 @@ void Totem::InitSummon() void Totem::UnSummon(uint32 msTime) { + if (msTime) + { + m_Events.AddEvent(new ForcedUnsummonDelayEvent(*this), m_Events.CalculateTime(msTime)); + return; + } + CombatStop(); RemoveAurasDueToSpell(GetSpell(), GetGUID()); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 88d3108dbe2..558fdd72a95 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -704,17 +704,15 @@ void Transport::UpdateNPCPositions() } } -//! This method transforms supplied transport offsets into global coordinates void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o) { float inx = x, iny = y, inz = z, ino = o; o = GetOrientation() + ino; - x = GetPositionX() + (inx * cos(GetOrientation()) + iny * sin(GetOrientation() + M_PI)); - y = GetPositionY() + (iny * cos(GetOrientation()) + inx * sin(GetOrientation())); + x = GetPositionX() + inx * cos(GetOrientation()) - iny * sin(GetOrientation()); + y = GetPositionY() + iny * cos(GetOrientation()) + inx * sin(GetOrientation()); z = GetPositionZ() + inz; } -//! This method transforms supplied global coordinates into local offsets void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o) { o -= GetOrientation(); @@ -722,6 +720,6 @@ void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o) y -= GetPositionY(); // y = searchedY * cos(o) + searchedX * sin(o) x -= GetPositionX(); // x = searchedX * cos(o) + searchedY * sin(o + pi) float inx = x, iny = y; - y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) - sin(GetOrientation() + M_PI) * tan(GetOrientation())); - x = (inx - iny * sin(GetOrientation() + M_PI) / cos(GetOrientation())) / (cos(GetOrientation()) - tan(GetOrientation()) * sin(GetOrientation() + M_PI)); + y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) + sin(GetOrientation()) * tan(GetOrientation())); + x = (inx + iny * tan(GetOrientation())) / (cos(GetOrientation()) + sin(GetOrientation()) * tan(GetOrientation())); } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 4b0c42c9071..8fd12b50695 100755 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -20,12 +20,13 @@ #define TRANSPORTS_H #include "GameObject.h" +#include "VehicleDefines.h" #include <map> #include <set> #include <string> -class Transport : public GameObject +class Transport : public GameObject, public TransportBase { public: Transport(uint32 period, uint32 script); @@ -47,8 +48,13 @@ class Transport : public GameObject uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0); void UpdatePosition(MovementInfo* mi); void UpdateNPCPositions(); + + /// This method transforms supplied transport offsets into global coordinates void CalculatePassengerPosition(float& x, float& y, float& z, float& o); + + /// This method transforms supplied global coordinates into local offsets void CalculatePassengerOffset(float& x, float& y, float& z, float& o); + void BuildStartMovePacket(Map const* targetMap); void BuildStopMovePacket(Map const* targetMap); uint32 GetScriptId() const { return ScriptId; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5118b5810b6..b5729ba516f 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -154,12 +154,26 @@ _hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo) #ifdef _MSC_VER #pragma warning(disable:4355) #endif -Unit::Unit(bool isWorldObject): WorldObject(isWorldObject), -m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false), -m_ControlledByPlayer(false), movespline(new Movement::MoveSpline()), i_AI(NULL), -i_disabledAI(NULL), m_procDeep(0), m_removedAurasCount(0), i_motionMaster(this), -m_ThreatManager(this), m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), -m_HostileRefManager(this), m_TempSpeed(0.0f), m_AutoRepeatFirstCast(false) +Unit::Unit(bool isWorldObject): WorldObject(isWorldObject) + , m_movedPlayer(NULL) + , m_lastSanctuaryTime(0) + , m_TempSpeed(0.0f) + , IsAIEnabled(false) + , NeedChangeAI(false) + , m_ControlledByPlayer(false) + , movespline(new Movement::MoveSpline()) + , i_AI(NULL) + , i_disabledAI(NULL) + , m_AutoRepeatFirstCast(false) + , m_procDeep(0) + , m_removedAurasCount(0) + , i_motionMaster(this) + , m_ThreatManager(this) + , m_vehicle(NULL) + , m_vehicleKit(NULL) + , m_unitTypeMask(UNIT_MASK_NONE) + , m_HostileRefManager(this) + , _lastDamagedTime(0) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -254,8 +268,8 @@ m_HostileRefManager(this), m_TempSpeed(0.0f), m_AutoRepeatFirstCast(false) m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); _focusSpell = NULL; - _targetLocked = false; _lastLiquid = NULL; + _isWalkingBeforeCharm = false; } //////////////////////////////////////////////////////////// @@ -380,9 +394,7 @@ void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed) void Unit::UpdateSplineMovement(uint32 t_diff) { - enum{ - POSITION_UPDATE_DELAY = 400, - }; + uint32 const positionUpdateDelay = 400; if (movespline->Finalized()) return; @@ -396,7 +408,7 @@ void Unit::UpdateSplineMovement(uint32 t_diff) m_movesplineTimer.Update(t_diff); if (m_movesplineTimer.Passed() || arrived) { - m_movesplineTimer.Reset(POSITION_UPDATE_DELAY); + m_movesplineTimer.Reset(positionUpdateDelay); Movement::Location loc = movespline->ComputePosition(); if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) @@ -406,17 +418,14 @@ void Unit::UpdateSplineMovement(uint32 t_diff) pos.m_positionY = loc.y; pos.m_positionZ = loc.z; pos.m_orientation = loc.orientation; - if (Unit* vehicle = GetVehicleBase()) - { - loc.x += vehicle->GetPositionX(); - loc.y += vehicle->GetPositionY(); - loc.z += vehicle->GetPositionZMinusOffset(); - loc.orientation = vehicle->GetOrientation(); - } - else if (Transport* trans = GetTransport()) - trans->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation); + + if (TransportBase* transport = GetDirectTransport()) + transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation); } + if (HasUnitState(UNIT_STATE_CANNOT_TURN)) + loc.orientation = GetOrientation(); + UpdatePosition(loc.x, loc.y, loc.z, loc.orientation); } } @@ -542,12 +551,11 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam GetAI()->DamageDealt(victim, damage, damagetype); if (victim->GetTypeId() == TYPEID_PLAYER) + { if (victim->ToPlayer()->GetCommandStatus(CHEAT_GOD)) return 0; - // Signal to pets that their owner was attacked - if (victim->GetTypeId() == TYPEID_PLAYER) - { + // Signal to pets that their owner was attacked Pet* pet = victim->ToPlayer()->GetPet(); if (pet && pet->isAlive()) @@ -700,7 +708,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam // call before auras are removed if (Player* killer = GetCharmerOrOwnerPlayerOrPlayerItself()) - killer->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim); + killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim); } Kill(victim, durabilityLoss); @@ -863,17 +871,24 @@ void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 values.AddSpellMod(SPELLVALUE_BASE_POINT1, *bp1); if (bp2) values.AddSpellMod(SPELLVALUE_BASE_POINT2, *bp2); - CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster); + CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) { CustomSpellValues values; values.AddSpellMod(mod, value); - CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster); + CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } -void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) +void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) +{ + CustomSpellValues values; + values.AddSpellMod(mod, value); + CastCustomSpell(spellId, values, target, triggerFlags, castItem, triggeredByAura, originalCaster); +} + +void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) @@ -884,7 +899,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* SpellCastTargets targets; targets.SetUnitTarget(victim); - CastSpell(targets, spellInfo, &value, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); + CastSpell(targets, spellInfo, &value, triggerFlags, castItem, triggeredByAura, originalCaster); } void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) @@ -4299,11 +4314,16 @@ uint32 Unit::GetDoTsByCaster(uint64 casterGUID) const int32 Unit::GetTotalAuraModifier(AuraType auratype) const { + std::map<SpellGroup, int32> SameEffectSpellGroup; int32 modifier = 0; AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) - modifier += (*i)->GetAmount(); + if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) + modifier += (*i)->GetAmount(); + + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) + modifier += itr->second; return modifier; } @@ -4347,14 +4367,19 @@ int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const { + std::map<SpellGroup, int32> SameEffectSpellGroup; int32 modifier = 0; AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); + for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) - { - if ((*i)->GetMiscValue()& misc_mask) - modifier += (*i)->GetAmount(); - } + if ((*i)->GetMiscValue() & misc_mask) + if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) + modifier += (*i)->GetAmount(); + + for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr) + modifier += itr->second; + return modifier; } @@ -6424,30 +6449,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere basepoints0 = CalculatePctN(int32(damage), triggerAmount); break; } - // King of the Jungle - else if (dummySpell->SpellIconID == 2850) - { - // Effect 0 - mod damage while having Enrage - if (effIndex == 0) - { - if (!(procSpell->SpellFamilyFlags[0] & 0x00080000) || procSpell->SpellIconID != 961) - return false; - triggered_spell_id = 51185; - basepoints0 = triggerAmount; - target = this; - break; - } - // Effect 1 - Tiger's Fury restore energy - else if (effIndex == 1) - { - if (!(procSpell->SpellFamilyFlags[2] & 0x00000800) || procSpell->SpellIconID != 1181) - return false; - triggered_spell_id = 51178; - basepoints0 = triggerAmount; - target = this; - break; - } - } break; } case SPELLFAMILY_ROGUE: @@ -6629,24 +6630,33 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Light's Beacon - Beacon of Light if (dummySpell->Id == 53651) { - // Get target of beacon of light - if (Unit* beaconTarget = triggeredByAura->GetBase()->GetCaster()) + if (this->GetTypeId() != TYPEID_PLAYER) + return false; + // Check Party/Raid Group + if (Group *group = this->ToPlayer()->GetGroup()) { - // do not proc when target of beacon of light is healed - if (beaconTarget == this) - return false; - // check if it was heal by paladin which casted this beacon of light - if (beaconTarget->GetAura(53563, victim->GetGUID())) + for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { - if (beaconTarget->IsWithinLOSInMap(victim)) + Player* Member = itr->getSource(); + + // check if it was heal by paladin which casted this beacon of light + if (Aura const * aura = Member->GetAura(53563, victim->GetGUID())) { - basepoints0 = damage; - victim->CastCustomSpell(beaconTarget, 53654, &basepoints0, NULL, NULL, true); + Unit* beaconTarget = Member; + + // do not proc when target of beacon of light is healed + if (beaconTarget == this) + return false; + + basepoints0 = int32(damage); + triggered_spell_id = 53652; + victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, NULL, NULL, true, 0, triggeredByAura); return true; } } } - return false; + else + return false; } // Judgements of the Wise if (dummySpell->SpellIconID == 3017) @@ -6666,34 +6676,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere CastCustomSpell(target, triggered_spell_id, &basepoints0, &basepoints0, NULL, true, castItem, triggeredByAura); return true; } - // Sacred Shield - if (dummySpell->SpellFamilyFlags[1] & 0x80000) - { - if (procFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) - { - if (procSpell->SpellFamilyName == SPELLFAMILY_PALADIN && (procSpell->SpellFamilyFlags[0] & 0x40000000)) - { - basepoints0 = damage / 12; - - if (basepoints0) - CastCustomSpell(this, 66922, &basepoints0, NULL, NULL, true, 0, triggeredByAura, victim->GetGUID()); - - return true; - } - else - return false; - } - else if (damage > 0) - triggered_spell_id = 58597; - - // Item - Paladin T8 Holy 4P Bonus - if (Unit* caster = triggeredByAura->GetCaster()) - if (AuraEffect const* aurEff = caster->GetAuraEffect(64895, 0)) - cooldown = aurEff->GetAmount(); - - target = this; - break; - } // Righteous Vengeance if (dummySpell->SpellIconID == 3025) { @@ -6714,6 +6696,23 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } switch (dummySpell->Id) { + // Sacred Shield + case 53601: + { + if (procFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) + return false; + + if (damage > 0) + triggered_spell_id = 58597; + + // Item - Paladin T8 Holy 4P Bonus + if (Unit* caster = triggeredByAura->GetCaster()) + if (AuraEffect const* aurEff = caster->GetAuraEffect(64895, 0)) + cooldown = aurEff->GetAmount(); + + target = this; + break; + } // Heart of the Crusader case 20335: // rank 1 triggered_spell_id = 21183; @@ -6727,10 +6726,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Judgement of Light case 20185: { - // 2% of base mana - basepoints0 = int32(victim->CountPctFromMaxHealth(2)); - victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura); - return true; + if (!victim) + return false; + + // 2% of maximum health + basepoints0 = int32(victim->CountPctFromMaxHealth(2)); + victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura); + return true; } // Judgement of Wisdom case 20186: @@ -9978,7 +9980,8 @@ void Unit::SetCharm(Unit* charm, bool apply) if (!charm->AddUInt64Value(UNIT_FIELD_CHARMEDBY, GetGUID())) sLog->outFatal(LOG_FILTER_UNITS, "Unit %u is being charmed, but it already has a charmer " UI64FMTD "", charm->GetEntry(), charm->GetCharmerGUID()); - if (charm->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) + _isWalkingBeforeCharm = charm->IsWalking(); + if (_isWalkingBeforeCharm) { charm->SetWalk(false); charm->SendMovementFlagUpdate(); @@ -10016,6 +10019,12 @@ void Unit::SetCharm(Unit* charm, bool apply) charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0); } + if (charm->IsWalking() != _isWalkingBeforeCharm) + { + charm->SetWalk(_isWalkingBeforeCharm); + charm->SendMovementFlagUpdate(true); // send packet to self, to update movement state on player. + } + if (charm->GetTypeId() == TYPEID_PLAYER || !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION) || charm->GetOwnerGUID() != GetGUID()) @@ -10048,15 +10057,15 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth) // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria) if (gain) - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth); } if (Player* player = victim->ToPlayer()) { - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth); } return gain; @@ -10290,6 +10299,10 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (!spellProto || !victim || damagetype == DIRECT_DAMAGE) return pdamage; + // Some spells don't benefit from done mods + if (spellProto->AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS) + return pdamage; + // small exception for Deep Wounds, can't find any general rule // should ignore ALL damage mods, they already calculated in trigger spell if (spellProto->Id == 12721) // Deep Wounds @@ -10691,13 +10704,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); } - // Some spells don't benefit from done mods - if (spellProto->AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS) - { - DoneTotal = 0; - DoneTotalMod = 1.0f; - } - float tmpDamage = (int32(pdamage) + DoneTotal) * DoneTotalMod; // apply spellmod to Done damage (flat and pct) if (Player* modOwner = GetSpellModOwner()) @@ -11081,9 +11087,12 @@ uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage crit_bonus -= damage; - // adds additional damage to crit_bonus (from talents) - if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); + if (damage > uint32(crit_bonus)) + { + // adds additional damage to critBonus (from talents) + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); + } crit_bonus += damage; @@ -11248,16 +11257,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); } - // Gift of the Naaru - if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329) - { - int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK))); - if (apBonus > DoneAdvertisedBenefit) - DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick - else - DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick - } - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { switch (spellProto->Effects[i].ApplyAuraName) @@ -12266,19 +12265,21 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo if (GetReactionTo(target) == REP_NEUTRAL && target->GetReactionTo(this) == REP_NEUTRAL) { - if ( - !(target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER) && - !(target->GetTypeId() == TYPEID_UNIT && GetTypeId() == TYPEID_UNIT) - ) + if (!(target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER) && + !(target->GetTypeId() == TYPEID_UNIT && GetTypeId() == TYPEID_UNIT)) { Player const* player = target->GetTypeId() == TYPEID_PLAYER ? target->ToPlayer() : ToPlayer(); Unit const* creature = target->GetTypeId() == TYPEID_UNIT ? target : this; if (FactionTemplateEntry const* factionTemplate = creature->getFactionTemplateEntry()) - if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction)) - if (FactionState const* repState = player->GetReputationMgr().GetState(factionEntry)) - if (!(repState->Flags & FACTION_FLAG_AT_WAR)) - return false; + { + if (!(player->GetReputationMgr().GetForcedRankIfAny(factionTemplate))) + if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction)) + if (FactionState const* repState = player->GetReputationMgr().GetState(factionEntry)) + if (!(repState->Flags & FACTION_FLAG_AT_WAR)) + return false; + + } } } @@ -12416,6 +12417,10 @@ int32 Unit::ModifyHealth(int32 dVal) if (dVal == 0) return 0; + // Part of Evade mechanics. Only track health lost, not gained. + if (dVal < 0 && GetTypeId() != TYPEID_PLAYER && !isPet()) + SetLastDamagedTime(time(NULL)); + int32 curHealth = (int32)GetHealth(); int32 val = dVal + curHealth; @@ -13042,6 +13047,14 @@ Unit* Creature::SelectVictim() return target; } + // Case where mob is being kited. + // Mob may not be in range to attack or may have dropped target. In any case, + // don't evade if damage received within the last 10 seconds + // Does not apply to world bosses to prevent kiting to cities + if (!isWorldBoss() && !GetInstanceId()) + if (time(NULL) - GetLastDamagedTime() <= MAX_AGGRO_RESET_TIME) + return target; + // last case when creature must not go to evade mode: // it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list // for example at owner command to pet attack some far away creature @@ -13218,13 +13231,13 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in } break; case SPELLFAMILY_PALADIN: - if (spellProto->SpellFamilyFlags[0] & 0x00000002) + if ((spellProto->SpellFamilyFlags[0] & 0x00000002) && spellProto->SpellIconID == 298) { // Glyph of Blessing of Might if (AuraEffect* aurEff = GetAuraEffect(57958, 0)) duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS; } - else if (spellProto->SpellFamilyFlags[0] & 0x00010000) + else if ((spellProto->SpellFamilyFlags[0] & 0x00010000) && spellProto->SpellIconID == 306) { // Glyph of Blessing of Wisdom if (AuraEffect* aurEff = GetAuraEffect(57979, 0)) @@ -14346,10 +14359,17 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u continue; ProcTriggeredData triggerData(itr->second->GetBase()); // Defensive procs are active on absorbs (so absorption effects are not a hindrance) - bool active = (damage > 0) || (procExtra & (PROC_EX_ABSORB|PROC_EX_BLOCK) && isVictim); + bool active = damage || (procExtra & PROC_EX_BLOCK && isVictim); if (isVictim) procExtra &= ~PROC_EX_INTERNAL_REQ_FAMILY; + SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo(); + + // only auras that has triggered spell should proc from fully absorbed damage + if (procExtra & PROC_EX_ABSORB && isVictim) + if (damage || spellProto->Effects[EFFECT_0].TriggerSpell || spellProto->Effects[EFFECT_1].TriggerSpell || spellProto->Effects[EFFECT_2].TriggerSpell) + active = true; + if (!IsTriggeredAtSpellProcEvent(target, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, active, triggerData.spellProcEvent)) continue; @@ -14761,11 +14781,11 @@ void Unit::StopMoving() init.Launch(); } -void Unit::SendMovementFlagUpdate() +void Unit::SendMovementFlagUpdate(bool self /* = false */) { WorldPacket data; BuildHeartBeatMsg(&data); - SendMessageToSet(&data, false); + SendMessageToSet(&data, self); } bool Unit::IsSitState() const @@ -15554,7 +15574,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) // update get killing blow achievements, must be done before setDeathState to be able to require auras on target // and before Spirit of Redemption as it also removes auras if (player) - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim); // if talent known but not triggered (check priest class for speedup check) bool spiritOfRedemption = false; @@ -15710,9 +15730,9 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (victim->GetTypeId() == TYPEID_PLAYER) { if (GetTypeId() == TYPEID_UNIT) - victim->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); + victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); else if (GetTypeId() == TYPEID_PLAYER && victim != this) - victim->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam()); + victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam()); } // Hook for OnPVPKill Event @@ -16142,7 +16162,8 @@ void Unit::RemoveCharmedBy(Unit* charmer) if (Creature* creature = ToCreature()) { - creature->AI()->OnCharmed(false); + if (creature->AI()) + creature->AI()->OnCharmed(false); if (type != CHARM_TYPE_VEHICLE) // Vehicles' AI is never modified { @@ -16281,6 +16302,13 @@ uint64 Unit::GetTransGUID() const return 0; } +TransportBase* Unit::GetDirectTransport() const +{ + if (Vehicle* veh = GetVehicle()) + return veh; + return GetTransport(); +} + bool Unit::IsInPartyWith(Unit const* unit) const { if (this == unit) @@ -16957,19 +16985,20 @@ void Unit::JumpTo(WorldObject* obj, float speedZ) bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) { + bool result = false; uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry(); SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry); for (SpellClickInfoContainer::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) { //! First check simple relations from clicker to clickee if (!itr->second.IsFitToRequirements(clicker, this)) - return false; + continue; //! Check database conditions ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(spellClickEntry, itr->second.spellId); ConditionSourceInfo info = ConditionSourceInfo(clicker, this); if (!sConditionMgr->IsObjectMeetToConditions(info, conds)) - return false; + continue; Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this; Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this; @@ -16995,11 +17024,11 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) if (!valid) { sLog->outError(LOG_FILTER_SQL, "Spell %u specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId); - return false; + continue; } if (IsInMap(caster)) - caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, false, NULL, NULL, origCasterGUID); + caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID); else // This can happen during Player::_LoadAuras { int32 bp0 = seatId; @@ -17009,22 +17038,27 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) else { if (IsInMap(caster)) - caster->CastSpell(target, spellEntry, false, NULL, NULL, origCasterGUID); + caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID); else Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID); } + + result = true; } - Creature* creature = ToCreature(); - if (creature && creature->IsAIEnabled) - creature->AI()->OnSpellClick(clicker); + if (result) + { + Creature* creature = ToCreature(); + if (creature && creature->IsAIEnabled) + creature->AI()->OnSpellClick(clicker); + } - return true; + return result; } void Unit::EnterVehicle(Unit* base, int8 seatId) { - CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId+1, base, false); + CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId+1, base, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE); } void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp) @@ -17042,6 +17076,7 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a sLog->outDebug(LOG_FILTER_VEHICLES, "EnterVehicle: %u leave vehicle %u seat %d and enter %d.", GetEntry(), m_vehicle->GetBase()->GetEntry(), GetTransSeat(), seatId); ChangeSeat(seatId); } + return; } else @@ -17077,6 +17112,7 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a ASSERT(!m_vehicle); m_vehicle = vehicle; + if (!m_vehicle->AddPassenger(this, seatId)) { m_vehicle = NULL; @@ -17129,9 +17165,11 @@ void Unit::_ExitVehicle(Position const* exitPosition) m_vehicle->RemovePassenger(this); + Player* player = ToPlayer(); + // If player is on mouted duel and exits the mount should immediatly lose the duel - if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->duel && ToPlayer()->duel->isMounted) - ToPlayer()->DuelComplete(DUEL_FLED); + if (player && player->duel && player->duel->isMounted) + player->DuelComplete(DUEL_FLED); // This should be done before dismiss, because there may be some aura removal Vehicle* vehicle = m_vehicle; @@ -17148,8 +17186,8 @@ void Unit::_ExitVehicle(Position const* exitPosition) AddUnitState(UNIT_STATE_MOVE); - if (GetTypeId() == TYPEID_PLAYER) - ToPlayer()->SetFallInformation(0, GetPositionZ()); + if (player) + player->SetFallInformation(0, GetPositionZ()); else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT)) { WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); @@ -17165,7 +17203,7 @@ void Unit::_ExitVehicle(Position const* exitPosition) //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above) - if (Player* player = ToPlayer()) + if (player) player->ResummonPetTemporaryUnSummonedIfAny(); if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION)) @@ -17294,7 +17332,7 @@ void Unit::UpdateOrientation(float orientation) { SetOrientation(orientation); if (IsVehicle()) - GetVehicleKit()->RelocatePassengers(GetPositionX(), GetPositionY(), GetPositionZ(), orientation); + GetVehicleKit()->RelocatePassengers(); } //! Only server-side height update, does not broadcast to client @@ -17302,7 +17340,7 @@ void Unit::UpdateHeight(float newZ) { Relocate(GetPositionX(), GetPositionY(), newZ); if (IsVehicle()) - GetVehicleKit()->RelocatePassengers(GetPositionX(), GetPositionY(), newZ, GetOrientation()); + GetVehicleKit()->RelocatePassengers(); } void Unit::SendThreatListUpdate() @@ -17700,3 +17738,31 @@ void Unit::SendMovementCanFlyChange() BuildMovementPacket(&data); SendMessageToSet(&data, false); } + +void Unit::FocusTarget(Spell const* focusSpell, uint64 target) +{ + // already focused + if (_focusSpell) + return; + + _focusSpell = focusSpell; + SetUInt64Value(UNIT_FIELD_TARGET, target); + if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) + AddUnitState(UNIT_STATE_ROTATING); +} + +void Unit::ReleaseFocus(Spell const* focusSpell) +{ + // focused to something else + if (focusSpell != _focusSpell) + return; + + _focusSpell = NULL; + if (Unit* victim = getVictim()) + SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); + else + SetUInt64Value(UNIT_FIELD_TARGET, 0); + + if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST) + ClearUnitState(UNIT_STATE_ROTATING); +} diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 2ec3ffec8ef..5a639de574c 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -46,7 +46,7 @@ enum SpellInterruptFlags SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back SPELL_INTERRUPT_FLAG_UNK3 = 0x04, // any info? SPELL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt - SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage + SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10 // _complete_ interrupt on direct damage //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph" }; @@ -86,7 +86,7 @@ enum SpellAuraInterruptFlags AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground - AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE), + AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE) }; enum SpellModOp @@ -133,7 +133,7 @@ enum SpellValueMod SPELLVALUE_BASE_POINT2, SPELLVALUE_RADIUS_MOD, SPELLVALUE_MAX_TARGETS, - SPELLVALUE_AURA_STACK, + SPELLVALUE_AURA_STACK }; typedef std::pair<SpellValueMod, int32> CustomSpellValueMod; @@ -253,7 +253,7 @@ enum UnitPVPStateFlags enum UnitRename { UNIT_CAN_BE_RENAMED = 0x01, - UNIT_CAN_BE_ABANDONED = 0x02, + UNIT_CAN_BE_ABANDONED = 0x02 }; #define CREATURE_MAX_SPELLS 8 @@ -262,6 +262,8 @@ enum UnitRename #define MAX_SPELL_POSSESS 8 #define MAX_SPELL_CONTROL_BAR 10 +#define MAX_AGGRO_RESET_TIME 10 // in seconds + enum Swing { NOSWING = 0, @@ -339,6 +341,7 @@ class UnitAI; class Totem; class Transport; class Vehicle; +class TransportBase; typedef std::list<Unit*> UnitList; typedef std::list< std::pair<Aura*, uint8> > DispelChargesList; @@ -402,7 +405,7 @@ enum TriggerCastFlags TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements TRIGGERED_DISALLOW_PROC_EVENTS = 0x00020000, //! Disallows proc events from triggered spell (default) TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions - TRIGGERED_FULL_MASK = 0xFFFFFFFF, + TRIGGERED_FULL_MASK = 0xFFFFFFFF }; enum UnitMods @@ -461,11 +464,11 @@ enum BaseModType enum DeathState { - ALIVE = 0, - JUST_DIED = 1, - CORPSE = 2, - DEAD = 3, - JUST_RESPAWNED = 4, + ALIVE = 0, + JUST_DIED = 1, + CORPSE = 2, + DEAD = 3, + JUST_RESPAWNED = 4 }; enum UnitState @@ -635,7 +638,7 @@ enum UnitFlags2 UNIT_FLAG2_DISABLE_TURN = 0x00008000, UNIT_FLAG2_UNK2 = 0x00010000, UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death - UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL + UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000 // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL }; /// Non Player Character flags @@ -667,7 +670,7 @@ enum NPCFlags UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) - UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set + UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000 // players with mounts that have vehicle data should have it set }; enum MovementFlags @@ -719,7 +722,7 @@ enum MovementFlags //! TODO if needed: add more flags to this masks that are exclusive to players MOVEMENTFLAG_MASK_PLAYER_ONLY = - MOVEMENTFLAG_FLYING, + MOVEMENTFLAG_FLYING }; enum MovementFlags2 { @@ -739,7 +742,7 @@ enum MovementFlags2 MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000, MOVEMENTFLAG2_UNK14 = 0x00002000, MOVEMENTFLAG2_UNK15 = 0x00004000, - MOVEMENTFLAG2_UNK16 = 0x00008000, + MOVEMENTFLAG2_UNK16 = 0x00008000 }; enum UnitTypeMask @@ -754,7 +757,7 @@ enum UnitTypeMask UNIT_MASK_PUPPET = 0x00000040, UNIT_MASK_HUNTER_PET = 0x00000080, UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100, - UNIT_MASK_ACCESSORY = 0x00000200, + UNIT_MASK_ACCESSORY = 0x00000200 }; namespace Movement{ @@ -768,7 +771,7 @@ enum DiminishingLevels DIMINISHING_LEVEL_3 = 2, DIMINISHING_LEVEL_IMMUNE = 3, DIMINISHING_LEVEL_4 = 3, - DIMINISHING_LEVEL_TAUNT_IMMUNE = 4, + DIMINISHING_LEVEL_TAUNT_IMMUNE = 4 }; struct DiminishingReturn @@ -1079,7 +1082,7 @@ enum CharmType CHARM_TYPE_CHARM, CHARM_TYPE_POSSESS, CHARM_TYPE_VEHICLE, - CHARM_TYPE_CONVERT, + CHARM_TYPE_CONVERT }; typedef UnitActionBarEntry CharmSpellInfo; @@ -1089,7 +1092,7 @@ enum ActionBarIndex ACTION_BAR_INDEX_START = 0, ACTION_BAR_INDEX_PET_SPELL_START = 3, ACTION_BAR_INDEX_PET_SPELL_END = 7, - ACTION_BAR_INDEX_END = 10, + ACTION_BAR_INDEX_END = 10 }; #define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) @@ -1189,7 +1192,7 @@ enum PlayerTotemType SUMMON_TYPE_TOTEM_FIRE = 63, SUMMON_TYPE_TOTEM_EARTH = 81, SUMMON_TYPE_TOTEM_WATER = 82, - SUMMON_TYPE_TOTEM_AIR = 83, + SUMMON_TYPE_TOTEM_AIR = 83 }; // delay time next attack to prevent client attack animation problems @@ -1568,13 +1571,14 @@ class Unit : public WorldObject void CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* Victim = NULL, bool triggered = true, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim = NULL, bool triggered = true, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(Unit* victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim = NULL, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* victim = NULL, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); Aura* AddAura(uint32 spellId, Unit* target); Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target); void SetAuraStack(uint32 spellId, Unit* target, uint32 stack); @@ -1606,7 +1610,7 @@ class Unit : public WorldObject void MonsterMoveWithSpeed(float x, float y, float z, float speed); //void SetFacing(float ori, WorldObject* obj = NULL); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); - void SendMovementFlagUpdate(); + void SendMovementFlagUpdate(bool self = false); /*! These methods send the same packet to the client in apply and unapply case. The client-side interpretation of this packet depends on the presence of relevant movementflags @@ -2168,6 +2172,8 @@ class Unit : public WorldObject uint32 GetTransTime() const { return m_movementInfo.t_time; } int8 GetTransSeat() const { return m_movementInfo.t_seat; } uint64 GetTransGUID() const; + /// Returns the transport this unit is on directly (if on vehicle and transport, return vehicle) + TransportBase* GetDirectTransport() const; bool m_ControlledByPlayer; @@ -2203,38 +2209,21 @@ class Unit : public WorldObject void SetTarget(uint64 guid) { - if (!_targetLocked) + if (!_focusSpell) SetUInt64Value(UNIT_FIELD_TARGET, guid); } - void FocusTarget(Spell const* focusSpell, uint64 target) - { - // already focused - if (_focusSpell) - return; - - _focusSpell = focusSpell; - _targetLocked = true; - SetUInt64Value(UNIT_FIELD_TARGET, target); - } - - void ReleaseFocus(Spell const* focusSpell) - { - // focused to something else - if (focusSpell != _focusSpell) - return; - - _focusSpell = NULL; - _targetLocked = false; - if (Unit* victim = getVictim()) - SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); - else - SetUInt64Value(UNIT_FIELD_TARGET, 0); - } + // Handling caster facing during spellcast + void FocusTarget(Spell const* focusSpell, uint64 target); + void ReleaseFocus(Spell const* focusSpell); // Movement info Movement::MoveSpline * movespline; + // Part of Evade mechanics + time_t GetLastDamagedTime() const { return _lastDamagedTime; } + void SetLastDamagedTime(time_t val) { _lastDamagedTime = val; } + protected: explicit Unit (bool isWorldObject); @@ -2354,8 +2343,10 @@ class Unit : public WorldObject bool m_cleanupDone; // lock made to not add stuff after cleanup before delete bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world - Spell const* _focusSpell; - bool _targetLocked; // locks the target during spell cast for proper facing + Spell const* _focusSpell; ///> Locks the target during spell cast for proper facing + bool _isWalkingBeforeCharm; // Are we walking before we were charmed? + + time_t _lastDamagedTime; // Part of Evade mechanics }; namespace Trinity diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 710821f2f24..ef4ed1a7f81 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -437,23 +437,23 @@ void Vehicle::RemovePassenger(Unit* unit) } //! Must be called after m_base::Relocate -void Vehicle::RelocatePassengers(float x, float y, float z, float ang) +void Vehicle::RelocatePassengers() { ASSERT(_me->GetMap()); - // not sure that absolute position calculation is correct, it must depend on vehicle orientation and pitch angle + // not sure that absolute position calculation is correct, it must depend on vehicle pitch angle for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) + { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger)) { ASSERT(passenger->IsInWorld()); - float px = x + passenger->m_movementInfo.t_pos.m_positionX; - float py = y + passenger->m_movementInfo.t_pos.m_positionY; - float pz = z + passenger->m_movementInfo.t_pos.m_positionZ; - float po = ang + passenger->m_movementInfo.t_pos.m_orientation; - + float px, py, pz, po; + passenger->m_movementInfo.t_pos.GetPosition(px, py, pz, po); + CalculatePassengerPosition(px, py, pz, po); passenger->UpdatePosition(px, py, pz, po); } + } } void Vehicle::Dismiss() @@ -512,3 +512,23 @@ uint8 Vehicle::GetAvailableSeatCount() const return ret; } + +void Vehicle::CalculatePassengerPosition(float& x, float& y, float& z, float& o) +{ + float inx = x, iny = y, inz = z, ino = o; + o = GetBase()->GetOrientation() + ino; + x = GetBase()->GetPositionX() + inx * cos(GetBase()->GetOrientation()) - iny * sin(GetBase()->GetOrientation()); + y = GetBase()->GetPositionY() + iny * cos(GetBase()->GetOrientation()) + inx * sin(GetBase()->GetOrientation()); + z = GetBase()->GetPositionZ() + inz; +} + +void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o) +{ + o -= GetBase()->GetOrientation(); + z -= GetBase()->GetPositionZ(); + y -= GetBase()->GetPositionY(); // y = searchedY * cos(o) + searchedX * sin(o) + x -= GetBase()->GetPositionX(); // x = searchedX * cos(o) + searchedY * sin(o + pi) + float inx = x, iny = y; + y = (iny - inx * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation())); + x = (inx + iny * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation())); +} diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 95fc2364256..4ad8663a17a 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -27,7 +27,7 @@ class Unit; typedef std::set<uint64> GuidSet; -class Vehicle +class Vehicle : public TransportBase { public: explicit Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry); @@ -52,7 +52,7 @@ class Vehicle bool AddPassenger(Unit* passenger, int8 seatId = -1); void EjectPassenger(Unit* passenger, Unit* controller); void RemovePassenger(Unit* passenger); - void RelocatePassengers(float x, float y, float z, float ang); + void RelocatePassengers(); void RemoveAllPassengers(); void Dismiss(); void TeleportVehicle(float x, float y, float z, float ang); @@ -66,6 +66,12 @@ class Vehicle SeatMap::iterator GetSeatIteratorForPassenger(Unit* passenger); void InitMovementInfoForBase(); + /// This method transforms supplied transport offsets into global coordinates + void CalculatePassengerPosition(float& x, float& y, float& z, float& o); + + /// This method transforms supplied global coordinates into local offsets + void CalculatePassengerOffset(float& x, float& y, float& z, float& o); + Unit* _me; VehicleEntry const* _vehicleInfo; GuidSet vehiclePlayers; diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index df34a61d444..cb8a6628b80 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -44,7 +44,7 @@ enum VehicleFlags VEHICLE_FLAG_FULLSPEEDPITCHING = 0x00000020, // Sets MOVEFLAG2_FULLSPEEDPITCHING VEHICLE_FLAG_CUSTOM_PITCH = 0x00000040, // If set use pitchMin and pitchMax from DBC, otherwise pitchMin = -pi/2, pitchMax = pi/2 VEHICLE_FLAG_ADJUST_AIM_ANGLE = 0x00000400, // Lua_IsVehicleAimAngleAdjustable - VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800, // Lua_IsVehicleAimPowerAdjustable + VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800 // Lua_IsVehicleAimPowerAdjustable }; enum VehicleSpells @@ -75,4 +75,14 @@ typedef std::vector<VehicleAccessory> VehicleAccessoryList; typedef std::map<uint32, VehicleAccessoryList> VehicleAccessoryContainer; typedef std::map<int8, VehicleSeat> SeatMap; +class TransportBase +{ + public: + /// This method transforms supplied transport offsets into global coordinates + virtual void CalculatePassengerPosition(float& x, float& y, float& z, float& o) = 0; + + /// This method transforms supplied global coordinates into local offsets + virtual void CalculatePassengerOffset(float& x, float& y, float& z, float& o) = 0; +}; + #endif diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index bead65bbfdd..2116738fac3 100755 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -205,7 +205,7 @@ void GameEventMgr::LoadFromDB() { { uint32 oldMSTime = getMSTime(); - // 1 2 3 4 5 6 7 8 + // 0 1 2 3 4 5 6 7 QueryResult result = WorldDatabase.Query("SELECT eventEntry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, length, holiday, description, world_event FROM game_event"); if (!result) { @@ -366,7 +366,7 @@ void GameEventMgr::LoadFromDB() { uint32 oldMSTime = getMSTime(); - // 1 2 + // 0 1 QueryResult result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.eventEntry FROM creature" " JOIN game_event_creature ON creature.guid = game_event_creature.guid"); @@ -860,7 +860,7 @@ void GameEventMgr::LoadFromDB() if (!result) { - sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 battleground holidays in game events. DB table `game_event_condition` is empty."); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 battleground holidays in game events. DB table `game_event_battleground_holiday` is empty."); } else { diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index d9b5890bfe5..dbc2c7ead10 100755 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -28,12 +28,12 @@ enum GameEventState { - GAMEEVENT_NORMAL = 0, // standard game events - GAMEEVENT_WORLD_INACTIVE = 1, // not yet started - GAMEEVENT_WORLD_CONDITIONS = 2, // condition matching phase - GAMEEVENT_WORLD_NEXTPHASE = 3, // conditions are met, now 'length' timer to start next event - GAMEEVENT_WORLD_FINISHED = 4, // next events are started, unapply this one - GAMEEVENT_INTERNAL = 5, // never handled in update + GAMEEVENT_NORMAL = 0, // standard game events + GAMEEVENT_WORLD_INACTIVE = 1, // not yet started + GAMEEVENT_WORLD_CONDITIONS = 2, // condition matching phase + GAMEEVENT_WORLD_NEXTPHASE = 3, // conditions are met, now 'length' timer to start next event + GAMEEVENT_WORLD_FINISHED = 4, // next events are started, unapply this one + GAMEEVENT_INTERNAL = 5 // never handled in update }; struct GameEventFinishCondition diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 3d58d5f4ce9..7d94e0ad209 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2001,8 +2001,8 @@ void ObjectMgr::LoadItemTemplates() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 9 10 11 12 - QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, unk0, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, " + // 0 1 2 3 4 5 6 7 8 9 10 11 12 + QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, " // 13 14 15 16 17 18 19 20 "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, " // 21 22 23 24 25 26 27 28 @@ -2055,7 +2055,7 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.ItemId = entry; itemTemplate.Class = uint32(fields[1].GetUInt8()); itemTemplate.SubClass = uint32(fields[2].GetUInt8()); - itemTemplate.Unk0 = fields[3].GetInt32(); + itemTemplate.SoundOverrideSubclass = int32(fields[3].GetInt8()); itemTemplate.Name1 = fields[4].GetString(); itemTemplate.DisplayInfoID = fields[5].GetUInt32(); itemTemplate.Quality = uint32(fields[6].GetUInt8()); @@ -2171,11 +2171,11 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.Class = dbcitem->Class; } - if (itemTemplate.Unk0 != dbcitem->Unk0) + if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclass) { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct Unk0 (%i), must be %i .", entry, itemTemplate.Unk0, dbcitem->Unk0); + sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct SoundOverrideSubclass (%i), must be %i .", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclass); if (enforceDBCAttributes) - itemTemplate.Unk0 = dbcitem->Unk0; + itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclass; } if (itemTemplate.Material != dbcitem->Material) { @@ -5606,8 +5606,8 @@ WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveYard(uint32 team) { enum DefaultGraveyard { - HORDE_GRAVEYARD = 10, // Crossroads - ALLIANCE_GRAVEYARD = 4, // Westfall + HORDE_GRAVEYARD = 10, // Crossroads + ALLIANCE_GRAVEYARD = 4 // Westfall }; if (team == HORDE) @@ -7301,6 +7301,11 @@ uint8 ObjectMgr::CheckPlayerName(const std::string& name, bool create) if (!isValidString(wname, strictMask, false, create)) return CHAR_NAME_MIXED_LANGUAGES; + wstrToLower(wname); + for (size_t i = 2; i < wname.size(); ++i) + if (wname[i] == wname[i-1] && wname[i] == wname[i-2]) + return CHAR_NAME_THREE_CONSECUTIVE; + return CHAR_NAME_SUCCESS; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index da0d37cf27a..a6d1dc6c386 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -128,7 +128,7 @@ enum eScriptFlags SF_PLAYSOUND_DISTANCE_SOUND = 0x2, // Orientation flags - SF_ORIENTATION_FACE_TARGET = 0x1, + SF_ORIENTATION_FACE_TARGET = 0x1 }; struct ScriptInfo @@ -536,7 +536,7 @@ enum SkillRangeType SKILL_RANGE_LEVEL, // 1..max skill for level SKILL_RANGE_MONO, // 1..1, grey monolite bar SKILL_RANGE_RANK, // 1..skill for known rank - SKILL_RANGE_NONE, // 0..0 always + SKILL_RANGE_NONE // 0..0 always }; SkillRangeType GetSkillRangeType(SkillLineEntry const* pSkill, bool racial); @@ -561,7 +561,7 @@ LanguageDesc const* GetLanguageDescByID(uint32 lang); enum EncounterCreditType { ENCOUNTER_CREDIT_KILL_CREATURE = 0, - ENCOUNTER_CREDIT_CAST_SPELL = 1, + ENCOUNTER_CREDIT_CAST_SPELL = 1 }; struct DungeonEncounter @@ -1285,7 +1285,7 @@ class ObjectMgr CREATURE_TO_CREATURE, CREATURE_TO_GO, // Creature is dependant on GO GO_TO_GO, - GO_TO_CREATURE, // GO is dependant on creature + GO_TO_CREATURE // GO is dependant on creature }; }; diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h index 6bf558a4d5e..0ef885703be 100755 --- a/src/server/game/Grids/NGrid.h +++ b/src/server/game/Grids/NGrid.h @@ -79,7 +79,12 @@ class NGrid public: typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridType; NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true) - : i_gridId(id), i_x(x), i_y(y), i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false), i_GridInfo(GridInfo(expiry, unload)) + : i_gridId(id) + , i_GridInfo(GridInfo(expiry, unload)) + , i_x(x) + , i_y(y) + , i_cellstate(GRID_STATE_INVALID) + , i_GridObjectDataLoaded(false) { } diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 072db578220..db4dc819557 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -694,6 +694,30 @@ namespace Trinity NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&); }; + // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO with a certain type) + class NearestGameObjectTypeInObjectRangeCheck + { + public: + NearestGameObjectTypeInObjectRangeCheck(WorldObject const& obj, GameobjectTypes type, float range) : i_obj(obj), i_type(type), i_range(range) {} + bool operator()(GameObject* go) + { + if (go->GetGoType() == i_type && i_obj.IsWithinDistInMap(go, i_range)) + { + i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check + return true; + } + return false; + } + float GetLastRange() const { return i_range; } + private: + WorldObject const& i_obj; + GameobjectTypes i_type; + float i_range; + + // prevent clone this object + NearestGameObjectTypeInObjectRangeCheck(NearestGameObjectTypeInObjectRangeCheck const&); + }; + class GameObjectWithDbGUIDCheck { public: diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index fda04effbf5..19ea3ff8174 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1326,7 +1326,7 @@ void Group::CountTheRoll(Rolls::iterator rollI) if (player && player->GetSession()) { - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul); ItemPosCountVec dest; LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]); @@ -1376,7 +1376,7 @@ void Group::CountTheRoll(Rolls::iterator rollI) if (player && player->GetSession()) { - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul); LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]); diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index de622a16301..a00b7e1ef3a 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -66,20 +66,20 @@ enum GroupMemberOnlineStatus MEMBER_STATUS_PVP_FFA = 0x0010, // Lua_UnitIsPVPFreeForAll MEMBER_STATUS_UNK3 = 0x0020, // used in calls from Lua_GetPlayerMapPosition/Lua_GetBattlefieldFlagPosition MEMBER_STATUS_AFK = 0x0040, // Lua_UnitIsAFK - MEMBER_STATUS_DND = 0x0080, // Lua_UnitIsDND + MEMBER_STATUS_DND = 0x0080 // Lua_UnitIsDND }; enum GroupMemberFlags { MEMBER_FLAG_ASSISTANT = 0x01, MEMBER_FLAG_MAINTANK = 0x02, - MEMBER_FLAG_MAINASSIST = 0x04, + MEMBER_FLAG_MAINASSIST = 0x04 }; enum GroupMemberAssignment { GROUP_ASSIGN_MAINTANK = 0, - GROUP_ASSIGN_MAINASSIST = 1, + GROUP_ASSIGN_MAINASSIST = 1 }; enum GroupType @@ -89,7 +89,7 @@ enum GroupType GROUPTYPE_RAID = 0x02, GROUPTYPE_BGRAID = GROUPTYPE_BG | GROUPTYPE_RAID, // mask GROUPTYPE_UNK1 = 0x04, - GROUPTYPE_LFG = 0x08, + GROUPTYPE_LFG = 0x08 // 0x10, leave/change group?, I saw this flag when leaving group and after leaving BG while in group }; @@ -117,7 +117,7 @@ enum GroupUpdateFlags GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras... GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint32 vehicle_seat_id (index from VehicleSeat.dbc) GROUP_UPDATE_PET = 0x0007FC00, // all pet flags - GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags + GROUP_UPDATE_FULL = 0x0007FFFF // all known flags }; #define GROUP_UPDATE_FLAGS_COUNT 20 diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4df77f874f3..332c0924b61 100755 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1717,7 +1717,7 @@ void Guild::SendInfo(WorldSession* session) const { WorldPacket data(SMSG_GUILD_INFO, m_name.size() + 4 + 4 + 4); data << m_name; - data << secsToTimeBitFields(m_createdDate); // 3.x (prev. year + month + day) + data.AppendPackedTime(m_createdDate); // 3.x (prev. year + month + day) data << uint32(m_members.size()); // Number of members data << m_accountsNumber; // Number of accounts diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index e18e62e51b7..dd1fb7cc6b6 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -37,7 +37,7 @@ enum GuildMisc GUILD_RANK_NONE = 0xFF, GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF, GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF, - GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF, + GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF }; enum GuildDefaultRanks @@ -47,7 +47,7 @@ enum GuildDefaultRanks GR_OFFICER = 1, GR_VETERAN = 2, GR_MEMBER = 3, - GR_INITIATE = 4, + GR_INITIATE = 4 // When promoting member server does: rank-- // When demoting member server does: rank++ }; @@ -141,7 +141,7 @@ enum PetitionTurns { PETITION_TURN_OK = 0, PETITION_TURN_ALREADY_IN_GUILD = 2, - PETITION_TURN_NEED_MORE_SIGNATURES = 4, + PETITION_TURN_NEED_MORE_SIGNATURES = 4 }; enum PetitionSigns @@ -150,7 +150,7 @@ enum PetitionSigns PETITION_SIGN_ALREADY_SIGNED = 1, PETITION_SIGN_ALREADY_IN_GUILD = 2, PETITION_SIGN_CANT_SIGN_OWN = 3, - PETITION_SIGN_NOT_SERVER = 4, + PETITION_SIGN_NOT_SERVER = 4 }; enum GuildBankRights @@ -160,7 +160,7 @@ enum GuildBankRights GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, - GUILD_BANK_RIGHT_FULL = 0xFF, + GUILD_BANK_RIGHT_FULL = 0xFF }; enum GuildBankEventLogTypes @@ -173,7 +173,7 @@ enum GuildBankEventLogTypes GUILD_BANK_LOG_REPAIR_MONEY = 6, GUILD_BANK_LOG_MOVE_ITEM2 = 7, GUILD_BANK_LOG_UNK1 = 8, - GUILD_BANK_LOG_UNK2 = 9, + GUILD_BANK_LOG_UNK2 = 9 }; enum GuildEventLogTypes @@ -183,7 +183,7 @@ enum GuildEventLogTypes GUILD_EVENT_LOG_PROMOTE_PLAYER = 3, GUILD_EVENT_LOG_DEMOTE_PLAYER = 4, GUILD_EVENT_LOG_UNINVITE_PLAYER = 5, - GUILD_EVENT_LOG_LEAVE_GUILD = 6, + GUILD_EVENT_LOG_LEAVE_GUILD = 6 }; enum GuildEmblemError diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 2ebcbce0661..74d4f4102cf 100755 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -277,7 +277,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); return; } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size @@ -347,7 +347,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); return; } } @@ -438,7 +438,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) auction->bidder = player->GetGUIDLow(); auction->bid = price; - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_AUCTION_BID); stmt->setUInt32(0, auction->bidder); @@ -461,7 +461,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) } auction->bidder = player->GetGUIDLow(); auction->bid = auction->buyout; - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); //- Mails must be under transaction control too to prevent data loss sAuctionMgr->SendAuctionSalePendingMail(auction, trans); diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 475c1c42fca..3bae430ad2c 100755 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -244,7 +244,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data) sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } -void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recv_data*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message"); @@ -252,39 +252,44 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recv_ if (!bg) // can't be received if player not in battleground return; - uint32 count = 0; - Player* aplr = NULL; - Player* hplr = NULL; + uint32 flagCarrierCount = 0; + Player* allianceFlagCarrier = NULL; + Player* hordeFlagCarrier = NULL; if (uint64 guid = bg->GetFlagPickerGUID(BG_TEAM_ALLIANCE)) { - aplr = ObjectAccessor::FindPlayer(guid); - if (aplr) - ++count; + allianceFlagCarrier = ObjectAccessor::FindPlayer(guid); + if (allianceFlagCarrier) + ++flagCarrierCount; } if (uint64 guid = bg->GetFlagPickerGUID(BG_TEAM_HORDE)) { - hplr = ObjectAccessor::FindPlayer(guid); - if (hplr) - ++count; + hordeFlagCarrier = ObjectAccessor::FindPlayer(guid); + if (hordeFlagCarrier) + ++flagCarrierCount; } - WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * count); - data << 0; - data << count; - if (aplr) + WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * flagCarrierCount); + // Used to send several player positions (found used in AV) + data << 0; // CGBattlefieldInfo__m_numPlayerPositions + /* + for (CGBattlefieldInfo__m_numPlayerPositions) + data << guid << posx << posy; + */ + data << flagCarrierCount; + if (allianceFlagCarrier) { - data << uint64(aplr->GetGUID()); - data << float(aplr->GetPositionX()); - data << float(aplr->GetPositionY()); + data << uint64(allianceFlagCarrier->GetGUID()); + data << float(allianceFlagCarrier->GetPositionX()); + data << float(allianceFlagCarrier->GetPositionY()); } - if (hplr) + if (hordeFlagCarrier) { - data << uint64(hplr->GetGUID()); - data << float(hplr->GetPositionX()); - data << float(hplr->GetPositionY()); + data << uint64(hordeFlagCarrier->GetGUID()); + data << float(hordeFlagCarrier->GetPositionX()); + data << float(hordeFlagCarrier->GetPositionY()); } SendPacket(&data); @@ -457,6 +462,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data) sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); break; case 0: // leave queue + if (bg->isArena() && bg->GetStatus() > STATUS_WAIT_QUEUE) + return; + // if player leaves rated arena match before match start, it is counted as he played but he lost if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID) { diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index e83f0f55a44..d1209eead22 100755 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -90,9 +90,9 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(*it)) { data << uint64(*it); - data << calendarEvent->GetTitle().c_str(); + data << calendarEvent->GetTitle(); data << uint32(calendarEvent->GetType()); - data << uint32(calendarEvent->GetTime()); + data.AppendPackedTime(calendarEvent->GetTime()); data << uint32(calendarEvent->GetFlags()); data << uint32(calendarEvent->GetDungeonId()); data.appendPackGUID(calendarEvent->GetCreatorGUID()); @@ -111,7 +111,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) } data << uint32(cur_time); // server time - data << uint32(secsToTimeBitFields(cur_time)); // server time + data.AppendPackedTime(cur_time); // server time uint32 counter = 0; size_t p_counter = data.wpos(); @@ -240,7 +240,10 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) uint8 rank; recvData >> title >> description >> type >> repeatable >> maxInvites; - recvData >> dungeonId >> eventPackedTime >> unkPackedTime >> flags; + recvData >> dungeonId; + recvData.ReadPackedTime(eventPackedTime); + recvData.ReadPackedTime(unkPackedTime); + recvData >> flags; if (!(flags & CALENDAR_FLAG_WITHOUT_INVITES)) { @@ -317,7 +320,9 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData) recvData >> eventId >> inviteId >> title >> description >> type; recvData >> repeatable >> maxInvites >> dungeonId; - recvData >> eventPackedTime >> timeZoneTime >> flags; + recvData.ReadPackedTime(eventPackedTime); + recvData.ReadPackedTime(timeZoneTime); + recvData >> flags; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_UPDATE_EVENT [" UI64FMTD "] EventId [" UI64FMTD "], InviteId [" UI64FMTD "] Title %s, Description %s, type %u " @@ -372,7 +377,8 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData) uint64 inviteId; uint32 time; - recvData >> eventId >> inviteId >> time; + recvData >> eventId >> inviteId; + recvData.ReadPackedTime(time); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_COPY_EVENT [" UI64FMTD "], EventId [" UI64FMTD "] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, time); @@ -425,7 +431,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) return; } - if (_player->GetTeam() != team) + if (_player->GetTeam() != team && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR)) { SendCalendarCommandResult(CALENDAR_ERROR_NOT_ALLIED); return; @@ -607,15 +613,15 @@ void WorldSession::SendCalendarEvent(CalendarEvent const& calendarEvent, Calenda data << uint8(sendEventType); data.appendPackGUID(calendarEvent.GetCreatorGUID()); data << uint64(eventId); - data << calendarEvent.GetTitle().c_str(); - data << calendarEvent.GetDescription().c_str(); + data << calendarEvent.GetTitle(); + data << calendarEvent.GetDescription(); data << uint8(calendarEvent.GetType()); data << uint8(calendarEvent.GetRepeatable()); data << uint32(calendarEvent.GetMaxInvites()); data << int32(calendarEvent.GetDungeonId()); data << uint32(calendarEvent.GetFlags()); - data << uint32(calendarEvent.GetTime()); - data << uint32(calendarEvent.GetTimeZoneTime()); + data.AppendPackedTime(calendarEvent.GetTime()); + data.AppendPackedTime(calendarEvent.GetTimeZoneTime()); data << uint32(calendarEvent.GetGuildId()); CalendarInviteIdList const& invites = calendarEvent.GetInviteIdList(); @@ -635,7 +641,7 @@ void WorldSession::SendCalendarEvent(CalendarEvent const& calendarEvent, Calenda data << uint8(calendarEvent.GetGuildId() != 0); data << uint64(invite->GetInviteId()); data << uint32(invite->GetStatusTime()); - data << invite->GetText().c_str(); + data << invite->GetText(); } else { @@ -692,7 +698,7 @@ void WorldSession::SendCalendarEventInviteAlert(CalendarEvent const& calendarEve WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_ALERT); data << uint64(eventId); data << calendarEvent.GetTitle().c_str(); - data << uint32(calendarEvent.GetTime()); + data.AppendPackedTime(calendarEvent.GetTime()); data << uint32(calendarEvent.GetFlags()); data << uint32(calendarEvent.GetType()); data << uint32(calendarEvent.GetDungeonId()); @@ -717,9 +723,9 @@ void WorldSession::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEve calendarEvent.GetTitle().size() + calendarEvent.GetDescription().size() + 1 + 4 + 4); data << uint8(sendEventType); data << uint64(eventId); - data << uint32(calendarEvent.GetTime()); + data.AppendPackedTime(calendarEvent.GetTime()); data << uint32(calendarEvent.GetFlags()); - data << uint32(calendarEvent.GetTime()); + data.AppendPackedTime(calendarEvent.GetTime()); data << uint8(calendarEvent.GetType()); data << uint32(calendarEvent.GetDungeonId()); data << calendarEvent.GetTitle().c_str(); @@ -734,7 +740,7 @@ void WorldSession::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEv { uint64 guid = _player->GetGUID(); uint64 eventId = calendarEvent.GetEventId(); - uint32 eventTime = (calendarEvent.GetTime()); + uint32 eventTime = calendarEvent.GetTime(); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_REMOVED_ALERT [" UI64FMTD "] EventId [" UI64FMTD "] Time %u", guid, eventId, eventTime); @@ -742,7 +748,7 @@ void WorldSession::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEv WorldPacket data(SMSG_CALENDAR_EVENT_REMOVED_ALERT, 1 + 8 + 1); data << uint8(1); // FIXME: If true does not SignalEvent(EVENT_CALENDAR_ACTION_PENDING) data << uint64(eventId); - data << uint32(eventTime); + data.AppendPackedTime(eventTime); SendPacket(&data); } @@ -752,11 +758,11 @@ void WorldSession::SendCalendarEventStatus(CalendarEvent const& calendarEvent, C uint64 eventId = calendarEvent.GetEventId(); uint64 inviteId = invite.GetInviteId(); uint64 invitee = invite.GetInvitee(); - uint32 eventTime = (calendarEvent.GetTime()); + uint32 eventTime = calendarEvent.GetTime(); uint32 flags = calendarEvent.GetFlags(); uint8 status = invite.GetStatus(); uint8 rank = invite.GetRank(); - uint32 statusTime = secsToTimeBitFields(invite.GetStatusTime()); + uint32 statusTime = invite.GetStatusTime(); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_STATUS [" UI64FMTD "] EventId [" @@ -768,11 +774,11 @@ void WorldSession::SendCalendarEventStatus(CalendarEvent const& calendarEvent, C WorldPacket data(SMSG_CALENDAR_EVENT_STATUS, 8 + 8 + 4 + 4 + 1 + 1 + 4); data.appendPackGUID(invitee); data << uint64(eventId); - data << uint32(eventTime); + data.AppendPackedTime(eventTime); data << uint32(flags); data << uint8(status); data << uint8(rank); - data << uint32(statusTime); + data.AppendPackedTime(statusTime); SendPacket(&data); } @@ -801,7 +807,7 @@ void WorldSession::SendCalendarEventInviteRemoveAlert(CalendarEvent const& calen { uint64 guid = _player->GetGUID(); uint64 eventId = calendarEvent.GetEventId(); - uint32 eventTime = (calendarEvent.GetTime()); + uint32 eventTime = calendarEvent.GetTime(); uint32 flags = calendarEvent.GetFlags(); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT [" @@ -810,7 +816,7 @@ void WorldSession::SendCalendarEventInviteRemoveAlert(CalendarEvent const& calen WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1); data << uint64(eventId); - data << uint32(eventTime); + data.AppendPackedTime(eventTime); data << uint32(flags); data << uint8(status); SendPacket(&data); @@ -877,7 +883,7 @@ void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add) if (add) { data.SetOpcode(SMSG_CALENDAR_RAID_LOCKOUT_ADDED); - data << uint32(secsToTimeBitFields(currTime)); + data.AppendPackedTime(currTime); } data << uint32(save->GetMapId()); @@ -899,7 +905,7 @@ void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save) time_t cur_time = time_t(time(NULL)); WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8); - data << secsToTimeBitFields(cur_time); + data.AppendPackedTime(cur_time); data << uint32(save->GetMapId()); data << uint32(save->GetDifficulty()); data << uint32(0); // Amount of seconds that has changed to the reset time diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index c294dd9b772..39cf0d6b3cf 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1308,12 +1308,29 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender())) return; - uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor); + GameObject* go = _player->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_BARBER_CHAIR, 5.0f); + if (!go) + { + WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); + data << uint32(2); + SendPacket(&data); + return; + } + + if (_player->getStandState() != UNIT_STAND_STATE_SIT_LOW_CHAIR + go->GetGOInfo()->barberChair.chairheight) + { + WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); + data << uint32(2); + SendPacket(&data); + return; + } + + uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor); // 0 - ok // 1, 3 - not enough money // 2 - you have to seat on barber chair - if (!_player->HasEnoughMoney(Cost)) + if (!_player->HasEnoughMoney(cost)) { WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); data << uint32(1); // no money @@ -1327,8 +1344,8 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) SendPacket(&data); } - _player->ModifyMoney(-int32(Cost)); // it isn't free - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost); + _player->ModifyMoney(-int32(cost)); // it isn't free + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, cost); _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id)); _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color)); @@ -1336,7 +1353,7 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) if (bs_skinColor) _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id)); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); _player->SetStandState(0); // stand up } diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 880f2df86f7..711d7af4dc3 100755 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -577,7 +577,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data) TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker); cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); //Send scripted event call if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI()) diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index c11a1cfc2aa..43655750aff 100755 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -450,10 +450,10 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData) switch (rollType) { case ROLL_NEED: - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1); break; case ROLL_GREED: - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); break; } } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 260220bb8d5..614e0064132 100755 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -306,7 +306,7 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPacket & recv_data) data << pProto->ItemId; data << pProto->Class; data << pProto->SubClass; - data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache? + data << pProto->SoundOverrideSubclass; data << Name; data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); @@ -586,7 +586,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket & recv_data) uint32 money = pProto->SellPrice * count; _player->ModifyMoney(money); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money); } else _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0); @@ -634,7 +634,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data) _player->ModifyMoney(-(int32)price); _player->RemoveItemFromBuyBackSlot(slot, false); _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount()); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); _player->StoreItem(dest, pItem, true); } else @@ -908,7 +908,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket) data << uint32(ERR_BANKSLOT_OK); SendPacket(&data); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT); } void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket) diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 8259d0c4e9b..73c8457eb66 100755 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -179,7 +179,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(goldPerPlayer); - (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); + (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); @@ -190,7 +190,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) else { player->ModifyMoney(loot->gold); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); @@ -498,9 +498,9 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket & recv_data) // not move item from loot to target inventory Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters); target->SendNewItem(newitem, uint32(item.count), false, false, true); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); // mark as looted item.count=0; diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index ae04444a118..c6b5377fe36 100755 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -246,7 +246,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-int32(reqmoney)); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; @@ -500,6 +500,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data) player->RemoveMItem(it->GetGUIDLow()); uint32 count = it->GetCount(); // save counts before store and possible merge with deleting + it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary player->MoveItemToInventory(dest, it, true); player->SaveInventoryAndGoldToDB(trans); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 80caee7d896..1da44882ea9 100755 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1662,7 +1662,7 @@ void WorldSession::HandleQueryInspectAchievements(WorldPacket & recv_data) if (!player) return; - player->GetAchievementMgr().SendRespondInspectAchievements(_player); + player->SendRespondInspectAchievements(_player); } void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recv_data*/) @@ -1741,7 +1741,7 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/) if (_player->isInFlight()) return; - if(Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + if (/*Battlefield* bf = */sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) { // bf->PlayerAskToLeave(_player); FIXME return; diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index f0c3093aa25..085e3c49157 100755 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -44,7 +44,7 @@ enum StableResultCode STABLE_SUCCESS_STABLE = 0x08, // stable success STABLE_SUCCESS_UNSTABLE = 0x09, // unstable/swap success STABLE_SUCCESS_BUY_SLOT = 0x0A, // buy slot success - STABLE_ERR_EXOTIC = 0x0C, // "you are unable to control exotic creatures" + STABLE_ERR_EXOTIC = 0x0C // "you are unable to control exotic creatures" }; void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket & recv_data) diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index db18f2a01c9..b16459a48b0 100755 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -433,14 +433,14 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data) _player->TakeQuestSourceItem(questId, true); // remove quest src item from player _player->RemoveActiveQuest(questId); - _player->GetAchievementMgr().RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId); + _player->RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId); sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u abandoned quest %u", _player->GetGUIDLow(), questId); } _player->SetQuestSlot(slot, 0); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1); } } diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index f9731ba85db..8872816f87d 100755 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -84,9 +84,13 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket & recv_data) unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect" } -void WorldSession::HandleUnlearnSkillOpcode(WorldPacket & recv_data) +void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recvData) { - uint32 skill_id; - recv_data >> skill_id; - GetPlayer()->SetSkill(skill_id, 0, 0, 0); + uint32 skillId; + recvData >> skillId; + + if (!IsPrimaryProfessionSkill(skillId)) + return; + + GetPlayer()->SetSkill(skillId, 0, 0, 0); } diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index b9e5523fd23..afaa38527bb 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -305,7 +305,7 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) go->AI()->GossipHello(_player); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); } void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index be9ee67b341..f8df5862df0 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -339,7 +339,7 @@ void InstanceScript::DoStartTimedAchievement(AchievementCriteriaTimedTypes type, if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* player = i->getSource()) - player->GetAchievementMgr().StartTimedAchievement(type, entry); + player->StartTimedAchievement(type, entry); } // Stop timed achievement for all players in instance @@ -350,7 +350,7 @@ void InstanceScript::DoStopTimedAchievement(AchievementCriteriaTimedTypes type, if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* player = i->getSource()) - player->GetAchievementMgr().RemoveTimedAchievement(type, entry); + player->RemoveTimedAchievement(type, entry); } // Remove Auras due to Spell on all players in instance diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index ba6d327e631..f1766833aee 100755 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -49,7 +49,7 @@ enum EncounterFrameType ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 4, ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 5, ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 6, - ENCOUNTER_FRAME_UNK7 = 7, // Seems to have something to do with sorting the encounter units + ENCOUNTER_FRAME_UNK7 = 7 // Seems to have something to do with sorting the encounter units }; enum EncounterState @@ -59,7 +59,7 @@ enum EncounterState FAIL = 2, DONE = 3, SPECIAL = 4, - TO_BE_DECIDED = 5, + TO_BE_DECIDED = 5 }; enum DoorType @@ -67,7 +67,7 @@ enum DoorType DOOR_TYPE_ROOM = 0, // Door can open if encounter is not in progress DOOR_TYPE_PASSAGE = 1, // Door can open if encounter is done DOOR_TYPE_SPAWN_HOLE = 2, // Door can open if encounter is in progress, typically used for spawning places - MAX_DOOR_TYPES, + MAX_DOOR_TYPES }; enum BoundaryType @@ -84,7 +84,7 @@ enum BoundaryType BOUNDARY_MAX_X = BOUNDARY_N, BOUNDARY_MIN_X = BOUNDARY_S, BOUNDARY_MAX_Y = BOUNDARY_W, - BOUNDARY_MIN_Y = BOUNDARY_E, + BOUNDARY_MIN_Y = BOUNDARY_E }; typedef std::map<BoundaryType, float> BossBoundaryMap; diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 72636a5d2aa..fca8d78a3de 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -524,7 +524,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player) // increase once if one looter only, looter-times if free for all if (item.freeforall || !item.is_blocked) ++unlootedCount; - if (!player->GetGroup() || (player->GetGroup()->GetLootMethod() != GROUP_LOOT || player->GetGroup()->GetLootMethod() != ROUND_ROBIN)) + if (!player->GetGroup() || (player->GetGroup()->GetLootMethod() != GROUP_LOOT && player->GetGroup()->GetLootMethod() != ROUND_ROBIN)) item.is_blocked = true; if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS) diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 1af5bd1ea62..45fc5c7983c 100755 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -69,7 +69,7 @@ enum PermissionTypes MASTER_PERMISSION = 2, ROUND_ROBIN_PERMISSION = 3, OWNER_PERMISSION = 4, - NONE_PERMISSION = 5, + NONE_PERMISSION = 5 }; enum LootType @@ -94,7 +94,7 @@ enum LootSlotType LOOT_SLOT_TYPE_ROLL_ONGOING = 1, // roll is ongoing. player cannot loot. LOOT_SLOT_TYPE_MASTER = 2, // item can only be distributed by group loot master. LOOT_SLOT_TYPE_LOCKED = 3, // item is shown in red. player cannot loot. - LOOT_SLOT_TYPE_OWNER = 4, // ignore binding confirmation and etc, for single player looting + LOOT_SLOT_TYPE_OWNER = 4 // ignore binding confirmation and etc, for single player looting }; class Player; diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h index 8efb33bda9a..10095268ead 100755 --- a/src/server/game/Mails/Mail.h +++ b/src/server/game/Mails/Mail.h @@ -36,7 +36,7 @@ enum MailMessageType MAIL_AUCTION = 2, MAIL_CREATURE = 3, // client send CMSG_CREATURE_QUERY on this mailmessagetype MAIL_GAMEOBJECT = 4, // client send CMSG_GAMEOBJECT_QUERY on this mailmessagetype - MAIL_ITEM = 5, // client send CMSG_ITEM_QUERY on this mailmessagetype + MAIL_ITEM = 5 // client send CMSG_ITEM_QUERY on this mailmessagetype }; enum MailCheckMask @@ -46,7 +46,7 @@ enum MailCheckMask MAIL_CHECK_MASK_RETURNED = 0x02, /// This mail was returned. Do not allow returning mail back again. MAIL_CHECK_MASK_COPIED = 0x04, /// This mail was copied. Do not allow making a copy of items in mail. MAIL_CHECK_MASK_COD_PAYMENT = 0x08, - MAIL_CHECK_MASK_HAS_BODY = 0x10, /// This mail has body text. + MAIL_CHECK_MASK_HAS_BODY = 0x10 /// This mail has body text. }; // gathered from Stationery.dbc @@ -58,7 +58,7 @@ enum MailStationery MAIL_STATIONERY_AUCTION = 62, MAIL_STATIONERY_VAL = 64, // Valentine MAIL_STATIONERY_CHR = 65, // Christmas - MAIL_STATIONERY_ORP = 67, // Orphan + MAIL_STATIONERY_ORP = 67 // Orphan }; enum MailState @@ -74,7 +74,7 @@ enum MailShowFlags MAIL_SHOW_DELETE = 0x0002, // forced show delete button instead return button MAIL_SHOW_AUCTION = 0x0004, // from old comment MAIL_SHOW_UNK2 = 0x0008, // unknown, COD will be shown even without that flag - MAIL_SHOW_RETURN = 0x0010, + MAIL_SHOW_RETURN = 0x0010 }; class MailSender diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c06c7414e6e..aee516f6f1d 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -711,7 +711,7 @@ void Map::PlayerRelocation(Player* player, float x, float y, float z, float orie player->Relocate(x, y, z, orientation); if (player->IsVehicle()) - player->GetVehicleKit()->RelocatePassengers(x, y, z, orientation); + player->GetVehicleKit()->RelocatePassengers(); if (old_cell.DiffGrid(new_cell) || old_cell.DiffCell(new_cell)) { @@ -757,7 +757,7 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa { creature->Relocate(x, y, z, ang); if (creature->IsVehicle()) - creature->GetVehicleKit()->RelocatePassengers(x, y, z, ang); + creature->GetVehicleKit()->RelocatePassengers(); creature->UpdateObjectVisibility(false); RemoveCreatureFromMoveList(creature); } @@ -1223,8 +1223,8 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/) } if (!(header.flags & MAP_LIQUID_NO_HEIGHT)) { - _liquidMap = new float[_liquidWidth*_liquidHeight]; - if (fread(_liquidMap, sizeof(float), _liquidWidth*_liquidHeight, in) != _liquidWidth*_liquidHeight) + _liquidMap = new float[uint32(_liquidWidth) * uint32(_liquidHeight)]; + if (fread(_liquidMap, sizeof(float), _liquidWidth*_liquidHeight, in) != (uint32(_liquidWidth) * uint32(_liquidHeight))) return false; } return true; diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index a766108dbb0..5893bbd6564 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -86,7 +86,8 @@ enum TrinityStrings LANG_CONNECTED_PLAYERS = 60, LANG_ACCOUNT_ADDON = 61, LANG_IMPROPER_VALUE = 62, - // Room for more level 0 63-99 not used + LANG_CANT_DO_NOW = 63, + // Room for more level 0 64-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, @@ -337,7 +338,13 @@ enum TrinityStrings LANG_TITLE_REMOVE_RES = 354, LANG_TITLE_CURRENT_RES = 355, LANG_CURRENT_TITLE_RESET = 356, - // Room for more level 2 357-399 not used + LANG_COMMAND_CHEAT_STATUS = 357, + LANG_COMMAND_CHEAT_GOD = 358, + LANG_COMMAND_CHEAT_CT = 359, + LANG_COMMAND_CHEAT_CD = 360, + LANG_COMMAND_CHEAT_POWER = 361, + LANG_COMMAND_CHEAT_WW = 362, + // Room for more level 2 363-399 not used // level 3 chat LANG_SCRIPTS_RELOADED = 400, @@ -1069,7 +1076,7 @@ enum TrinityStrings // Use for custom patches 11000-11999 LANG_AUTO_BROADCAST = 11000, - LANG_INVALID_REALMID = 11001, + LANG_INVALID_REALMID = 11001 // NOT RESERVED IDS 12000-1999999999 // `db_script_string` table index 2000000000-2000009999 (MIN_DB_SCRIPT_STRING_ID-MAX_DB_SCRIPT_STRING_ID) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index f74d6c44be7..4f6ad917423 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -26,7 +26,7 @@ enum SpellEffIndex { EFFECT_0 = 0, EFFECT_1 = 1, - EFFECT_2 = 2, + EFFECT_2 = 2 }; // used in script definitions @@ -124,7 +124,7 @@ enum UnitClass UNIT_CLASS_WARRIOR = 1, UNIT_CLASS_PALADIN = 2, UNIT_CLASS_ROGUE = 4, - UNIT_CLASS_MAGE = 8, + UNIT_CLASS_MAGE = 8 }; #define CLASSMASK_ALL_CREATURES ((1<<(UNIT_CLASS_WARRIOR-1)) | (1<<(UNIT_CLASS_PALADIN-1)) | (1<<(UNIT_CLASS_ROGUE-1)) | (1<<(UNIT_CLASS_MAGE-1))) @@ -245,7 +245,7 @@ enum ItemQualities enum SpellCategory { SPELL_CATEGORY_FOOD = 11, - SPELL_CATEGORY_DRINK = 59, + SPELL_CATEGORY_DRINK = 59 }; const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = @@ -465,7 +465,7 @@ enum SpellAttr5 SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK = 0x00010000, // 16 this allows spells with EquippedItemClass to affect spells from other items if the required item is equipped SPELL_ATTR5_USABLE_WHILE_FEARED = 0x00020000, // 17 usable while feared SPELL_ATTR5_USABLE_WHILE_CONFUSED = 0x00040000, // 18 usable while confused - SPELL_ATTR5_UNK19 = 0x00080000, // 19 + SPELL_ATTR5_DONT_TURN_DURING_CAST = 0x00080000, // 19 Blocks caster's turning when casting (client does not automatically turn caster's model to face UNIT_FIELD_TARGET) SPELL_ATTR5_UNK20 = 0x00100000, // 20 SPELL_ATTR5_UNK21 = 0x00200000, // 21 SPELL_ATTR5_UNK22 = 0x00400000, // 22 @@ -572,7 +572,7 @@ enum SpellClickCastFlags { NPC_CLICK_CAST_CASTER_CLICKER = 0x01, NPC_CLICK_CAST_TARGET_CLICKER = 0x02, - NPC_CLICK_CAST_ORIG_CASTER_OWNER = 0x04, + NPC_CLICK_CAST_ORIG_CASTER_OWNER = 0x04 }; enum SheathTypes @@ -642,7 +642,7 @@ enum TeamId { TEAM_ALLIANCE = 0, TEAM_HORDE, - TEAM_NEUTRAL, + TEAM_NEUTRAL }; enum Team @@ -654,7 +654,7 @@ enum Team //TEAM_HORDE_FORCES = 892, //TEAM_SANCTUARY = 936, //TEAM_OUTLAND = 980, - TEAM_OTHER = 0, // if ReputationListId > 0 && Flags != FACTION_FLAG_TEAM_HEADER + TEAM_OTHER = 0 // if ReputationListId > 0 && Flags != FACTION_FLAG_TEAM_HEADER }; enum SpellEffects @@ -1121,7 +1121,7 @@ enum SpellCustomErrors SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_RECRUITS = 96, // You already have the max number of recruits. SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_VOLUNTEERS = 97, // You already have the max number of volunteers. SPELL_CUSTOM_ERROR_FROSTMOURNE_RENDERED_RESSURECT = 98, // Frostmourne has rendered you unable to ressurect. - SPELL_CUSTOM_ERROR_CANT_MOUNT_WITH_SHAPESHIFT = 99, // You can't mount while affected by that shapeshift. + SPELL_CUSTOM_ERROR_CANT_MOUNT_WITH_SHAPESHIFT = 99 // You can't mount while affected by that shapeshift. }; enum StealthType @@ -1192,7 +1192,7 @@ enum AuraStateType //AURA_STATE_UNKNOWN20 = 20, // c | only (45317 Suicide) //AURA_STATE_UNKNOWN21 = 21, // | not used AURA_STATE_UNKNOWN22 = 22, // C t| varius spells (63884, 50240) - AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C | + AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23 // C | }; #define PER_CASTER_AURA_STATE_MASK (\ @@ -1485,7 +1485,7 @@ enum GameObjectFlags GO_FLAG_NODESPAWN = 0x00000020, // never despawn, typically for doors, they just change state GO_FLAG_TRIGGERED = 0x00000040, // typically, summoned objects. Triggered by spell or other events GO_FLAG_DAMAGED = 0x00000200, - GO_FLAG_DESTROYED = 0x00000400, + GO_FLAG_DESTROYED = 0x00000400 }; enum GameObjectDynamicLowFlags @@ -1493,7 +1493,7 @@ enum GameObjectDynamicLowFlags GO_DYNFLAG_LO_ACTIVATE = 0x01, // enables interaction with GO GO_DYNFLAG_LO_ANIMATE = 0x02, // possibly more distinct animation of GO GO_DYNFLAG_LO_NO_INTERACT = 0x04, // appears to disable interaction (not fully verified) - GO_DYNFLAG_LO_SPARKLE = 0x08, // makes GO sparkle + GO_DYNFLAG_LO_SPARKLE = 0x08 // makes GO sparkle }; enum GameObjectDestructibleState @@ -1501,7 +1501,7 @@ enum GameObjectDestructibleState GO_DESTRUCTIBLE_INTACT = 0, GO_DESTRUCTIBLE_DAMAGED = 1, GO_DESTRUCTIBLE_DESTROYED = 2, - GO_DESTRUCTIBLE_REBUILDING = 3, + GO_DESTRUCTIBLE_REBUILDING = 3 }; // EmotesText.dbc @@ -1758,7 +1758,7 @@ enum TextEmotes TEXT_EMOTE_LOOK = 449, TEXT_EMOTE_OBJECT = 450, TEXT_EMOTE_SWEAT = 451, - TEXT_EMOTE_YW = 453, + TEXT_EMOTE_YW = 453 }; // Emotes.dbc @@ -2595,7 +2595,7 @@ enum CreatureTypeFlags CREATURE_TYPEFLAGS_UNK28 = 0x10000000, CREATURE_TYPEFLAGS_UNK29 = 0x20000000, CREATURE_TYPEFLAGS_UNK30 = 0x40000000, - CREATURE_TYPEFLAGS_UNK31 = 0x80000000, + CREATURE_TYPEFLAGS_UNK31 = 0x80000000 }; enum CreatureEliteType @@ -2700,7 +2700,7 @@ enum QuestSort QUEST_SORT_JEWELCRAFTING = 373, QUEST_SORT_NOBLEGARDEN = 374, QUEST_SORT_PILGRIMS_BOUNTY = 375, - QUEST_SORT_LOVE_IS_IN_THE_AIR = 376, + QUEST_SORT_LOVE_IS_IN_THE_AIR = 376 }; inline uint8 ClassByQuestSort(int32 QuestSort) @@ -3085,7 +3085,7 @@ enum AiReaction AI_REACTION_FRIENDLY = 1, // (NOT used in client packet handler) AI_REACTION_HOSTILE = 2, // sent on every attack, triggers aggro sound (used in client packet handler) AI_REACTION_AFRAID = 3, // seen for polymorph (when AI not in control of self?) (NOT used in client packet handler) - AI_REACTION_DESTROY = 4, // used on object destroy (NOT used in client packet handler) + AI_REACTION_DESTROY = 4 // used on object destroy (NOT used in client packet handler) }; // Diminishing Returns Types @@ -3119,7 +3119,7 @@ enum DiminishingGroup DIMINISHING_SLEEP = 17, DIMINISHING_TAUNT = 18, DIMINISHING_LIMITONLY = 19, - DIMINISHING_DRAGONS_BREATH = 20, + DIMINISHING_DRAGONS_BREATH = 20 }; enum SummonCategory @@ -3129,7 +3129,7 @@ enum SummonCategory SUMMON_CATEGORY_PET = 2, SUMMON_CATEGORY_PUPPET = 3, SUMMON_CATEGORY_VEHICLE = 4, - SUMMON_CATEGORY_UNK = 5, // as of patch 3.3.5a only Bone Spike in Icecrown Citadel + SUMMON_CATEGORY_UNK = 5 // as of patch 3.3.5a only Bone Spike in Icecrown Citadel // uses this category }; @@ -3146,12 +3146,12 @@ enum SummonType SUMMON_TYPE_WILD3 = 8, SUMMON_TYPE_VEHICLE = 9, SUMMON_TYPE_VEHICLE2 = 10, - SUMMON_TYPE_OBJECT = 11, + SUMMON_TYPE_OBJECT = 11 }; enum EventId { - EVENT_CHARGE = 1003, + EVENT_CHARGE = 1003 }; enum ResponseCodes @@ -3335,7 +3335,7 @@ enum MailResponseResult MAIL_ERR_MAIL_AND_CHAT_SUSPENDED = 17, MAIL_ERR_TOO_MANY_ATTACHMENTS = 18, MAIL_ERR_MAIL_ATTACHMENT_INVALID = 19, - MAIL_ERR_ITEM_HAS_EXPIRED = 21, + MAIL_ERR_ITEM_HAS_EXPIRED = 21 }; enum SpellFamilyNames @@ -3401,7 +3401,7 @@ enum RemoveMethod { GROUP_REMOVEMETHOD_DEFAULT = 0, GROUP_REMOVEMETHOD_KICK = 1, - GROUP_REMOVEMETHOD_LEAVE = 2, + GROUP_REMOVEMETHOD_LEAVE = 2 }; enum ActivateTaxiReply @@ -3428,7 +3428,7 @@ enum CalendarFlags CALENDAR_FLAG_ALL_ALLOWED = 0x001, CALENDAR_FLAG_INVITES_LOCKED = 0x010, CALENDAR_FLAG_WITHOUT_INVITES = 0x040, - CALENDAR_FLAG_GUILD_ONLY = 0x400, + CALENDAR_FLAG_GUILD_ONLY = 0x400 }; enum CalendarActionData @@ -3442,21 +3442,21 @@ enum CalendarActionData CALENDAR_ACTION_MODIFY_EVENT_INVITE, CALENDAR_ACTION_MODIFY_MODERATOR_EVENT_INVITE, CALENDAR_ACTION_REMOVE_EVENT_INVITE, - CALENDAR_ACTION_SIGNUP_TO_EVENT, + CALENDAR_ACTION_SIGNUP_TO_EVENT }; enum CalendarModerationRank { CALENDAR_RANK_PLAYER, CALENDAR_RANK_MODERATOR, - CALENDAR_RANK_OWNER, + CALENDAR_RANK_OWNER }; enum CalendarSendEventType { CALENDAR_SENDTYPE_GET, CALENDAR_SENDTYPE_ADD, - CALENDAR_SENDTYPE_COPY, + CALENDAR_SENDTYPE_COPY }; enum CalendarEventType @@ -3465,7 +3465,7 @@ enum CalendarEventType CALENDAR_TYPE_DUNGEON, CALENDAR_TYPE_PVP, CALENDAR_TYPE_MEETING, - CALENDAR_TYPE_OTHER, + CALENDAR_TYPE_OTHER }; enum CalendarInviteStatus @@ -3479,7 +3479,7 @@ enum CalendarInviteStatus CALENDAR_STATUS_CONFIRMED, CALENDAR_STATUS_NO_OWNER, CALENDAR_STATUS_8, - CALENDAR_STATUS_9, + CALENDAR_STATUS_9 }; enum CalendarError diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 727f626cdea..8d7fdee7ad2 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -51,7 +51,7 @@ enum MovementGeneratorType FOLLOW_MOTION_TYPE = 14, ROTATE_MOTION_TYPE = 15, EFFECT_MOTION_TYPE = 16, - NULL_MOTION_TYPE = 17, + NULL_MOTION_TYPE = 17 }; enum MovementSlot @@ -59,7 +59,7 @@ enum MovementSlot MOTION_SLOT_IDLE, MOTION_SLOT_ACTIVE, MOTION_SLOT_CONTROLLED, - MAX_MOTION_SLOT, + MAX_MOTION_SLOT }; enum MMCleanFlag @@ -72,7 +72,7 @@ enum MMCleanFlag enum RotateDirection { ROTATE_DIRECTION_LEFT, - ROTATE_DIRECTION_RIGHT, + ROTATE_DIRECTION_RIGHT }; // assume it is 25 yard per 0.6 second diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 7e130a2c143..56818e95a2b 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -140,7 +140,12 @@ bool FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float angle = i_cur_angle + static_cast<float>(M_PI); distance /= 2; break; + default: + angle = 0.0f; + distance = 0.0f; + break; } + temp_x = x + distance * cos(angle); temp_y = y + distance * sin(angle); Trinity::NormalizeMapCoord(temp_x); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index fdff5a92564..2cd3d745750 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -89,6 +89,7 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner) Movement::MoveSplineInit init(owner); init.MoveTo(x,y,z); + init.SetFacing(i_target.getTarget()); init.SetWalk(((D*)this)->EnableWalking()); init.Launch(); } diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 61bd3900b9d..699d054be4b 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -107,7 +107,7 @@ struct FallInitializer }; enum{ - minimal_duration = 1, + minimal_duration = 1 }; struct CommonInitializer @@ -167,6 +167,7 @@ void MoveSpline::Initialize(const MoveSplineInitArgs& args) point_Idx_offset = args.path_Idx_offset; initialOrientation = args.initialOrientation; + onTransport = false; time_passed = 0; vertical_acceleration = 0.f; effect_start_time = 0; @@ -217,7 +218,7 @@ bool MoveSplineInitArgs::_checkPathBounds() const if (!(flags & MoveSplineFlag::Mask_CatmullRom) && path.size() > 2) { enum{ - MAX_OFFSET = (1 << 11) / 2, + MAX_OFFSET = (1 << 11) / 2 }; Vector3 middle = (path.front()+path.back()) / 2; Vector3 offset; diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index d4b19b21634..945adf6d9f8 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -45,7 +45,7 @@ namespace Movement Result_None = 0x01, Result_Arrived = 0x02, Result_NextCycle = 0x04, - Result_NextSegment = 0x08, + Result_NextSegment = 0x08 }; friend class PacketBuilder; protected: @@ -119,6 +119,7 @@ namespace Movement const Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx+1) : Vector3();} int32 currentPathIdx() const; + bool onTransport; std::string ToString() const; }; } diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index cfc2fdee450..a7262182391 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -70,7 +70,7 @@ namespace Movement // CatmullRom interpolation mode used Mask_CatmullRom = Flying | Catmullrom, // Unused, not suported flags - Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13, + Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13 }; inline uint32& raw() { return (uint32&)*this;} diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index c539dd3cc39..fec629c3329 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -74,7 +74,8 @@ namespace Movement // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals - if (!move_spline.Finalized()) + // Don't compute for transport movement if the unit is in a motion between two transports + if (!move_spline.Finalized() && move_spline.onTransport == transport) real_position = move_spline.ComputePosition(); // should i do the things that user should do? - no. @@ -84,6 +85,7 @@ namespace Movement // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; + move_spline.onTransport = transport; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) @@ -158,17 +160,9 @@ namespace Movement { if (_transformForTransport) { - if (Unit* vehicle = _owner.GetVehicleBase()) - { - input.x -= vehicle->GetPositionX(); - input.y -= vehicle->GetPositionY(); - input.z -= vehicle->GetPositionZMinusOffset(); - } - else if (Transport* transport = _owner.GetTransport()) - { - float unused = 0.0f; + float unused = 0.0f; + if (TransportBase* transport = _owner.GetDirectTransport()) transport->CalculatePassengerOffset(input.x, input.y, input.z, unused); - } } return input; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index ef847809ac8..cae9f1321d2 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -30,7 +30,7 @@ namespace Movement ToGround = 0, // 460 = ToGround, index of AnimationData.dbc FlyToFly = 1, // 461 = FlyToFly? ToFly = 2, // 458 = ToFly - FlyToGround = 3, // 463 = FlyToGround + FlyToGround = 3 // 463 = FlyToGround }; // Transforms coordinates from global to transport offsets diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index 627cdcf3e3b..63e61b84579 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -53,7 +53,7 @@ protected: // lesser value saves more performance in cost of lover precision // minimal value is 1 // client's value is 20, blizzs use 2-3 steps to compute length - STEPS_PER_SEGMENT = 3, + STEPS_PER_SEGMENT = 3 }; static_assert(STEPS_PER_SEGMENT > 0, "shouldn't be lesser than 1"); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 5a4d5734929..9919a47642e 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -30,7 +30,7 @@ #include "CellImpl.h" OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp) : -m_capturePointGUID(0), m_capturePoint(NULL), m_minValue(0.0f), m_maxValue(0.0f), m_maxSpeed(0), +m_capturePointGUID(0), m_capturePoint(NULL), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), m_value(0), m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL), m_State(OBJECTIVESTATE_NEUTRAL), m_neutralValuePct(0), m_PvP(pvp) { diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index 6ea13d353c5..e896fa2acf6 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -31,7 +31,7 @@ enum OutdoorPvPTypes OUTDOOR_PVP_TF = 3, OUTDOOR_PVP_ZM = 4, OUTDOOR_PVP_SI = 5, - OUTDOOR_PVP_EP = 6, + OUTDOOR_PVP_EP = 6 }; #define MAX_OUTDOORPVP_TYPES 7 @@ -44,7 +44,7 @@ enum ObjectiveStates OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE, OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE, OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE, - OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE, + OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE }; #define OTHER_TEAM(a) (a == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE) diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 6155e33d35e..5a8891d888c 100755 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -90,7 +90,7 @@ enum __QuestTradeSkill QUEST_TRSKILL_MINING = 11, QUEST_TRSKILL_FISHING = 12, QUEST_TRSKILL_SKINNING = 13, - QUEST_TRSKILL_JEWELCRAFTING = 14, + QUEST_TRSKILL_JEWELCRAFTING = 14 }; enum QuestStatus @@ -158,7 +158,7 @@ enum __QuestFlags QUEST_TRINITY_FLAGS_SPEAKTO = 0x08000000, // Internal flag computed only QUEST_TRINITY_FLAGS_KILL_OR_CAST = 0x10000000, // Internal flag computed only QUEST_TRINITY_FLAGS_TIMED = 0x20000000, // Internal flag computed only - QUEST_TRINITY_FLAGS_PLAYER_KILL = 0x40000000, // Internal flag computed only + QUEST_TRINITY_FLAGS_PLAYER_KILL = 0x40000000 // Internal flag computed only }; struct QuestLocale diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 05b224fb024..7ef59916099 100755 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -388,11 +388,11 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in UpdateRankCounters(old_rank, new_rank); _player->ReputationChanged(factionEntry); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID); return true; } diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index bd993a24193..625ee88a853 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1356,7 +1356,7 @@ enum SessionStatus STATUS_TRANSFER, // Player transferring to another map (_player != NULL, m_GUID == _player->GetGUID(), !inWorld()) STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player != NULL or _player == NULL && m_playerRecentlyLogout && m_playerLogout, m_GUID store last _player guid) STATUS_NEVER, // Opcode not accepted from client (deprecated or server side only) - STATUS_UNHANDLED, // Opcode not handled yet + STATUS_UNHANDLED // Opcode not handled yet }; enum PacketProcessing diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 0aa14eb78a8..bc9e6ac4298 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -68,7 +68,7 @@ enum AccountDataType GLOBAL_MACROS_CACHE = 4, // 0x10 g PER_CHARACTER_MACROS_CACHE = 5, // 0x20 p PER_CHARACTER_LAYOUT_CACHE = 6, // 0x40 p - PER_CHARACTER_CHAT_CACHE = 7, // 0x80 p + PER_CHARACTER_CHAT_CACHE = 7 // 0x80 p }; #define NUM_ACCOUNT_DATA_TYPES 8 @@ -132,7 +132,7 @@ enum BFLeaveReason //BF_LEAVE_REASON_UNK1 = 0x00000002, (not used) //BF_LEAVE_REASON_UNK2 = 0x00000004, (not used) BF_LEAVE_REASON_EXITED = 0x00000008, - BF_LEAVE_REASON_LOW_LEVEL = 0x00000010, + BF_LEAVE_REASON_LOW_LEVEL = 0x00000010 }; enum ChatRestrictionType diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index ddb230d6773..6902dd60c80 100755 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -47,14 +47,14 @@ enum AuraEffectHandleModes AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_SEND_FOR_CLIENT | AURA_EFFECT_HANDLE_REAL), // any case handler need to send packet AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAL), // any case handler applies effect depending on amount AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK), - AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK = (AURA_EFFECT_HANDLE_REAPPLY | AURA_EFFECT_HANDLE_REAL), + AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK = (AURA_EFFECT_HANDLE_REAPPLY | AURA_EFFECT_HANDLE_REAL) }; //m_schoolAbsorb enum DAMAGE_ABSORB_TYPE { ALL_DAMAGE_ABSORB = -2, - ONLY_MAGIC_ABSORB = -1, + ONLY_MAGIC_ABSORB = -1 }; enum AuraType @@ -382,6 +382,7 @@ enum AuraType enum AuraObjectType { UNIT_AURA_TYPE, - DYNOBJ_AURA_TYPE, + DYNOBJ_AURA_TYPE }; + #endif diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index bca26bd7391..29dcde9d616 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5042,7 +5042,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool } case 43681: // Inactive { - if (!target || target->GetTypeId() != TYPEID_PLAYER || aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + if (target->GetTypeId() != TYPEID_PLAYER || aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) return; if (target->GetMap()->IsBattleground()) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 9ee05b9a2a4..1c129c4d57c 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -425,7 +425,7 @@ void Aura::_UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * auraA if (itr == m_applications.end()) { sLog->outError(LOG_FILTER_SPELLS_AURAS, "Aura::_UnapplyForTarget, target:%u, caster:%u, spell:%u was not found in owners application map!", - target->GetGUIDLow(), caster->GetGUIDLow(), auraApp->GetBase()->GetSpellInfo()->Id); + target->GetGUIDLow(), caster ? caster->GetGUIDLow() : 0, auraApp->GetBase()->GetSpellInfo()->Id); ASSERT(false); } @@ -766,7 +766,7 @@ void Aura::SetCharges(uint8 charges) uint8 Aura::CalcMaxCharges(Unit* caster) const { - uint8 maxProcCharges = m_spellInfo->ProcCharges; + uint32 maxProcCharges = m_spellInfo->ProcCharges; if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId())) maxProcCharges = procEntry->charges; @@ -1414,10 +1414,16 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b if (caster->GetTypeId() == TYPEID_PLAYER) { if (caster->ToPlayer()->HasSpellCooldown(aura->GetId())) - break; - // and add if needed - caster->ToPlayer()->AddSpellCooldown(aura->GetId(), 0, uint32(time(NULL) + 12)); + { + // This additional check is needed to add a minimal delay before cooldown in in effect + // to allow all bubbles broken by a single damage source proc mana return + if (caster->ToPlayer()->GetSpellCooldownDelay(aura->GetId()) <= 11) + break; + } + else // and add if needed + caster->ToPlayer()->AddSpellCooldown(aura->GetId(), 0, uint32(time(NULL) + 12)); } + // effect on caster if (AuraEffect const* aurEff = aura->GetEffect(0)) { @@ -1631,6 +1637,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b } if (GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_AURA) { + if (!caster) + break; + // Improved devotion aura if (caster->HasAura(20140) || caster->HasAura(20138) || caster->HasAura(20139)) { @@ -2062,6 +2071,7 @@ void Aura::LoadScripts() { std::list<AuraScript*>::iterator bitr = itr; ++itr; + delete (*bitr); m_loadedScripts.erase(bitr); continue; } @@ -2324,7 +2334,7 @@ UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne LoadScripts(); _InitEffects(effMask, caster, baseAmount); GetUnitOwner()->_AddAura(this, caster); -}; +} void UnitAura::_ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 95345ed8b93..6b51f240b28 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -583,7 +583,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme && !m_spellInfo->IsPassive() && !m_spellInfo->IsPositive(); CleanupTargetList(); - CleanupEffectExecuteData(); + memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*)); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) m_destTargets[i] = SpellDestination(*m_caster); @@ -916,7 +916,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa { case TARGET_UNIT_CHANNEL_TARGET: { - WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()); + WorldObject* target = ObjectAccessor::GetUnit(*m_caster, m_originalCaster->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)); CallScriptObjectTargetSelectHandlers(target, effIndex); // unit target may be no longer avalible - teleported out of map for example if (target && target->ToUnit()) @@ -928,7 +928,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa case TARGET_DEST_CHANNEL_TARGET: if (channeledSpell->m_targets.HasDst()) m_targets.SetDst(channeledSpell->m_targets); - else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID())) + else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, m_originalCaster->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT))) { CallScriptObjectTargetSelectHandlers(target, effIndex); if (target) @@ -2525,7 +2525,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) } } - if (missInfo != SPELL_MISS_EVADE && m_caster && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) + if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) { m_caster->CombatStart(unit, !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO)); @@ -2601,17 +2601,17 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA PrepareScriptHitHandlers(); CallScriptBeforeHitHandlers(); - if (unit->GetTypeId() == TYPEID_PLAYER) + if (Player* player = unit->ToPlayer()) { - unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id); - unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster); - unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); + player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); } - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (Player* player = m_caster->ToPlayer()) { - m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id); - m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); + player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); } if (m_caster != unit) @@ -3025,7 +3025,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered if (m_caster->GetTypeId() == TYPEID_PLAYER) { m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); - + // Set casttime to 0 if .cheat casttime is enabled. if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_CASTTIME)) m_casttime = 0; @@ -3069,10 +3069,9 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered SendSpellStart(); // set target for proper facing - if (m_casttime && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) - if (uint64 target = m_targets.GetUnitTargetGUID()) - if (m_caster->GetGUID() != target && m_caster->GetTypeId() == TYPEID_UNIT) - m_caster->FocusTarget(this, target); + if ((m_casttime || m_spellInfo->IsChanneled()) && !(_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING)) + if (m_caster->GetGUID() != m_targets.GetObjectTargetGUID() && m_caster->GetTypeId() == TYPEID_UNIT) + m_caster->FocusTarget(this, m_targets.GetObjectTargetGUID()); if (!(_triggeredCastFlags & TRIGGERED_IGNORE_GCD)) TriggerGlobalCooldown(); @@ -3254,15 +3253,15 @@ void Spell::cast(bool skipCheck) // set to real guid to be sent later to the client m_targets.UpdateTradeSlotItem(); - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (Player* player = m_caster->ToPlayer()) { if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM) && m_CastItem) { - m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry()); - m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); + player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry()); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); } - m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); } if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)) @@ -3323,7 +3322,7 @@ void Spell::cast(bool skipCheck) if (m_caster->GetTypeId() == TYPEID_PLAYER) { m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); - + //Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled. if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true); @@ -4083,41 +4082,47 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) *data << uint32(ammoInventoryType); } +/// Writes miss and hit targets for a SMSG_SPELL_GO packet void Spell::WriteSpellGoTargets(WorldPacket* data) { // This function also fill data for channeled spells: // m_needAliveTargetMask req for stop channelig if one target die - uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO - uint32 miss = 0; for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { if ((*ihit).effectMask == 0) // No effect apply - all immuned add state - { // possibly SPELL_MISS_IMMUNE2 for this?? ihit->missCondition = SPELL_MISS_IMMUNE2; - ++miss; - } - else if ((*ihit).missCondition == SPELL_MISS_NONE) - ++hit; - else - ++miss; } - *data << (uint8)hit; - for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + // Hit and miss target counts are both uint8, that limits us to 255 targets for each + // sending more than 255 targets crashes the client (since count sent would be wrong) + // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need + // target conditions but we still need to limit the number of targets sent and keeping + // correct count for both hit and miss). + + uint32 hit = 0; + size_t hitPos = data->wpos(); + *data << (uint8)0; // placeholder + for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit <= 255; ++ihit) { if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits { *data << uint64(ihit->targetGUID); m_channelTargetEffectMask |=ihit->effectMask; + ++hit; } } - for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit) + for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit <= 255; ++ighit) + { *data << uint64(ighit->targetGUID); // Always hits + ++hit; + } - *data << (uint8)miss; - for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + uint32 miss = 0; + size_t missPos = data->wpos(); + *data << (uint8)0; // placeholder + for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss <= 255; ++ihit) { if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss { @@ -4125,11 +4130,15 @@ void Spell::WriteSpellGoTargets(WorldPacket* data) *data << uint8(ihit->missCondition); if (ihit->missCondition == SPELL_MISS_REFLECT) *data << uint8(ihit->reflectResult); + ++miss; } } // Reset m_needAliveTargetMask for non channeled spell if (!m_spellInfo->IsChanneled()) m_channelTargetEffectMask = 0; + + data->put<uint8>(hitPos, (uint8)hit); + data->put<uint8>(missPos, (uint8)miss); } void Spell::SendLogExecute() @@ -4268,6 +4277,9 @@ void Spell::SendChannelUpdate(uint32 time) void Spell::SendChannelStart(uint32 duration) { uint64 channelTarget = m_targets.GetObjectTargetGUID(); + if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget()) + if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY + channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID; WorldPacket data(MSG_CHANNEL_START, (8+4+4)); data.append(m_caster->GetPackGUID()); @@ -5135,6 +5147,10 @@ SpellCastResult Spell::CheckCast(bool strict) } if (m_caster->HasUnitState(UNIT_STATE_ROOT)) return SPELL_FAILED_ROOTED; + if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (Unit* target = m_targets.GetUnitTarget()) + if (!target->isAlive()) + return SPELL_FAILED_BAD_TARGETS; break; } case SPELL_EFFECT_SKINNING: @@ -6915,12 +6931,6 @@ void Spell::InitEffectExecuteData(uint8 effIndex) } } -void Spell::CleanupEffectExecuteData() -{ - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - m_effectExecuteData[i] = NULL; -} - void Spell::CheckEffectExecuteData() { for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -6936,6 +6946,7 @@ void Spell::LoadScripts() { std::list<SpellScript*>::iterator bitr = itr; ++itr; + delete (*bitr); m_loadedScripts.erase(bitr); continue; } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 1376b0fbd40..d2bdf4b8970 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -69,14 +69,14 @@ enum SpellCastFlags CAST_FLAG_UNKNOWN_29 = 0x10000000, CAST_FLAG_UNKNOWN_30 = 0x20000000, CAST_FLAG_UNKNOWN_31 = 0x40000000, - CAST_FLAG_UNKNOWN_32 = 0x80000000, + CAST_FLAG_UNKNOWN_32 = 0x80000000 }; enum SpellRangeFlag { SPELL_RANGE_DEFAULT = 0, SPELL_RANGE_MELEE = 1, //melee - SPELL_RANGE_RANGED = 2, //hunter range and ranged weapon + SPELL_RANGE_RANGED = 2 //hunter range and ranged weapon }; struct SpellDestination @@ -203,7 +203,7 @@ enum SpellEffectHandleMode SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_HANDLE_HIT, - SPELL_EFFECT_HANDLE_HIT_TARGET, + SPELL_EFFECT_HANDLE_HIT_TARGET }; class Spell @@ -616,7 +616,6 @@ class Spell // spell execution log void InitEffectExecuteData(uint8 effIndex); - void CleanupEffectExecuteData(); void CheckEffectExecuteData(); // Scripting system diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3637bb18049..dcbd1888b03 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1153,6 +1153,14 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) if (unitTarget->getLevel() > uiMaxSafeLevel) { unitTarget->AddAura(60444, unitTarget); //Apply Lost! Aura + + // ALLIANCE from 60323 to 60330 - HORDE from 60328 to 60335 + uint32 spellId = 60323; + if (m_caster->ToPlayer()->GetTeam() == HORDE) + spellId += 5; + + spellId += urand(0, 7); + m_caster->CastSpell(m_caster, spellId, true); return; } break; @@ -1724,8 +1732,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) pItem->SetUInt32Value(ITEM_FIELD_CREATOR, player->GetGUIDLow()); // send info to the client - if (pItem) - player->SendNewItem(pItem, num_to_add, true, bgType == 0); + player->SendNewItem(pItem, num_to_add, true, bgType == 0); // we succeeded in creating at least one item, so a levelup is possible if (bgType == 0) @@ -2079,7 +2086,8 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) bg->EventPlayerClickedOnFlag(player, gameObjTarget); return; } - }else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP && gameObjTarget->GetOwner()) + } + else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP && gameObjTarget->GetOwner()) { gameObjTarget->SetLootState(GO_JUST_DEACTIVATED); return; @@ -2116,7 +2124,7 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) if (gameObjTarget) SendLoot(guid, LOOT_SKINNING); - else + else if (itemTarget) itemTarget->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); // not allow use skill grow at item base open @@ -4141,6 +4149,8 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) return; } case 59317: // Teleporting + { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -4152,20 +4162,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) unitTarget->CastSpell(unitTarget, 59314, true); return; - // random spell learn instead placeholder - case 60893: // Northrend Alchemy Research - case 61177: // Northrend Inscription Research - case 61288: // Minor Inscription Research - case 61756: // Northrend Inscription Research (FAST QA VERSION) - case 64323: // Book of Glyph Mastery - { - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - // learn random explicit discovery recipe (if any) - if (uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, m_caster->ToPlayer())) - m_caster->ToPlayer()->learnSpell(discoveredSpell, false); - return; } case 62482: // Grab Crate { diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 7b3f9a1bef9..0531549cbd3 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -361,7 +361,7 @@ bool SpellEffectInfo::IsAura() const bool SpellEffectInfo::IsAura(AuraType aura) const { - return IsAura() && ApplyAuraName == aura; + return IsAura() && ApplyAuraName == uint32(aura); } bool SpellEffectInfo::IsTargetingArea() const @@ -1020,7 +1020,7 @@ bool SpellInfo::IsPassiveStackableWithRanks() const bool SpellInfo::IsMultiSlotAura() const { - return IsPassive() || Id == 44413; + return IsPassive() || Id == 40075 || Id == 44413; // No other way to make 40075 have more than 1 copy of aura } bool SpellInfo::IsDeathPersistent() const @@ -1127,10 +1127,6 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const bool SpellInfo::CanDispelAura(SpellInfo const* aura) const { - // These auras (like ressurection sickness) can't be dispelled - if (aura->Attributes & SPELL_ATTR0_NEGATIVE_1) - return false; - // These spells (like Mass Dispel) can dispell all auras if (Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) return true; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 54430cd7116..2d53c7d8ace 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -67,7 +67,7 @@ enum SpellCastTargetFlags | TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_DEAD | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER, TARGET_FLAG_GAMEOBJECT_MASK = TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM, TARGET_FLAG_CORPSE_MASK = TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY, - TARGET_FLAG_ITEM_MASK = TARGET_FLAG_TRADE_ITEM | TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM, + TARGET_FLAG_ITEM_MASK = TARGET_FLAG_TRADE_ITEM | TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM }; enum SpellTargetSelectionCategories @@ -77,7 +77,7 @@ enum SpellTargetSelectionCategories TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_CONE, - TARGET_SELECT_CATEGORY_AREA, + TARGET_SELECT_CATEGORY_AREA }; enum SpellTargetReferenceTypes @@ -87,7 +87,7 @@ enum SpellTargetReferenceTypes TARGET_REFERENCE_TYPE_TARGET, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, - TARGET_REFERENCE_TYPE_DEST, + TARGET_REFERENCE_TYPE_DEST }; enum SpellTargetObjectTypes @@ -103,7 +103,7 @@ enum SpellTargetObjectTypes TARGET_OBJECT_TYPE_CORPSE, // only for effect target type TARGET_OBJECT_TYPE_CORPSE_ENEMY, - TARGET_OBJECT_TYPE_CORPSE_ALLY, + TARGET_OBJECT_TYPE_CORPSE_ALLY }; enum SpellTargetCheckTypes @@ -115,7 +115,7 @@ enum SpellTargetCheckTypes TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, - TARGET_CHECK_PASSENGER, + TARGET_CHECK_PASSENGER }; enum SpellTargetDirectionTypes @@ -130,14 +130,14 @@ enum SpellTargetDirectionTypes TARGET_DIR_BACK_LEFT, TARGET_DIR_FRONT_LEFT, TARGET_DIR_RANDOM, - TARGET_DIR_ENTRY, + TARGET_DIR_ENTRY }; enum SpellEffectImplicitTargetTypes { EFFECT_IMPLICIT_TARGET_NONE = 0, EFFECT_IMPLICIT_TARGET_EXPLICIT, - EFFECT_IMPLICIT_TARGET_CASTER, + EFFECT_IMPLICIT_TARGET_CASTER }; // Spell clasification @@ -165,7 +165,7 @@ enum SpellSpecificType SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE = 25, SPELL_SPECIFIC_WARRIOR_ENRAGE = 26, SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27, - SPELL_SPECIFIC_HAND = 28, + SPELL_SPECIFIC_HAND = 28 }; enum SpellCustomAttributes @@ -187,7 +187,7 @@ enum SpellCustomAttributes SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER = 0x00010000, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET = 0x00020000, - SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2, + SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2 }; uint32 GetTargetFlagMask(SpellTargetObjectTypes objType); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index e17e71f8869..c692a3d6991 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -74,6 +74,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto, // Pet charge effects (Infernal Awakening, Demon Charge) if (spellproto->SpellVisual[0] == 2816 && spellproto->SpellIconID == 15) return DIMINISHING_CONTROLLED_STUN; + // Frost Tomb + else if (spellproto->Id == 48400) + return DIMINISHING_NONE; // Gnaw else if (spellproto->Id == 47481) return DIMINISHING_CONTROLLED_STUN; @@ -1135,7 +1138,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 case 68719: // Oil Refinery - Isle of Conquest. case 68720: // Quarry - Isle of Conquest. { - if (player->GetBattlegroundTypeId() != BATTLEGROUND_IC || !player->GetBattleground()) + if (!player || player->GetBattlegroundTypeId() != BATTLEGROUND_IC || !player->GetBattleground()) return false; uint8 nodeType = spellId == 68719 ? NODE_TYPE_REFINERY : NODE_TYPE_QUARRY; @@ -2772,6 +2775,10 @@ void SpellMgr::LoadSpellCustomAttr() switch (spellInfo->Id) { + case 60256: + //Crashes client on pressing ESC (Maybe because of ReqSpellFocus and GameObject) + spellInfo->AttributesEx4 &= ~SPELL_ATTR4_TRIGGERED; + break; case 1776: // Gouge case 1777: case 8629: @@ -2982,6 +2989,16 @@ void SpellMgr::LoadDbcDataCorrections() switch (spellInfo->Id) { + case 42730: + spellInfo->EffectTriggerSpell[EFFECT_1] = 42739; + break; + case 59735: + spellInfo->EffectTriggerSpell[EFFECT_1] = 59736; + break; + case 52611: // Summon Skeletons + case 52612: // Summon Skeletons + spellInfo->EffectMiscValueB[0] = 64; + break; case 40244: // Simon Game Visual case 40245: // Simon Game Visual case 40246: // Simon Game Visual @@ -3422,6 +3439,9 @@ void SpellMgr::LoadDbcDataCorrections() case 71159: // Awaken Plagued Zombies spellInfo->DurationIndex = 21; break; + case 70530: // Volatile Ooze Beam Protection (Professor Putricide) + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AURA; // for an unknown reason this was SPELL_EFFECT_APPLY_AREA_AURA_RAID + break; // THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS IS NOT IMPLEMENTED case 71604: // Mutated Strength (Professor Putricide) case 72673: // Mutated Strength (Professor Putricide) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 9c5619ef5f6..9423ebf2893 100755 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -38,8 +38,8 @@ enum SpellCategories SPELLCATEGORY_HEALTH_MANA_POTIONS = 4, SPELLCATEGORY_DEVOUR_MAGIC = 12, SPELLCATEGORY_JUDGEMENT = 1210, // Judgement (seal trigger) - SPELLCATEGORY_FOOD = 11, - SPELLCATEGORY_DRINK = 59, + SPELLCATEGORY_FOOD = 11, + SPELLCATEGORY_DRINK = 59 }; //SpellFamilyFlags @@ -85,7 +85,7 @@ enum SpellFamilyFlag SPELLFAMILYFLAG_DK_DEATH_COIL = 0x00002000, // TODO: Figure out a more accurate name for the following familyflag(s) - SPELLFAMILYFLAG_SHAMAN_TOTEM_EFFECTS = 0x04000000, // Seems to be linked to most totems and some totem effects + SPELLFAMILYFLAG_SHAMAN_TOTEM_EFFECTS = 0x04000000 // Seems to be linked to most totems and some totem effects }; @@ -96,7 +96,7 @@ enum SpellLinkedType SPELL_LINK_CAST = 0, // +: cast; -: remove SPELL_LINK_HIT = 1 * 200000, SPELL_LINK_AURA = 2 * 200000, // +: aura; -: immune - SPELL_LINK_REMOVE = 0, + SPELL_LINK_REMOVE = 0 }; @@ -177,7 +177,7 @@ enum ProcFlags | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_DAMAGE, - REQ_SPELL_PHASE_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK & DONE_HIT_PROC_FLAG_MASK, + REQ_SPELL_PHASE_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK & DONE_HIT_PROC_FLAG_MASK }; #define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_DONE_MELEE_AUTO_ATTACK | \ @@ -261,12 +261,12 @@ enum ProcFlagsHit PROC_HIT_REFLECT = 0x0000800, PROC_HIT_INTERRUPT = 0x0001000, // (not used atm) PROC_HIT_FULL_BLOCK = 0x0002000, - PROC_HIT_MASK_ALL = 0x2FFF, + PROC_HIT_MASK_ALL = 0x2FFF }; enum ProcAttributes { - PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000010, + PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000010 }; struct SpellProcEventEntry @@ -322,12 +322,12 @@ typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap; enum SpellGroup { - SPELL_GROUP_NONE = 0, - SPELL_GROUP_ELIXIR_BATTLE = 1, - SPELL_GROUP_ELIXIR_GUARDIAN = 2, - SPELL_GROUP_ELIXIR_UNSTABLE = 3, + SPELL_GROUP_NONE = 0, + SPELL_GROUP_ELIXIR_BATTLE = 1, + SPELL_GROUP_ELIXIR_GUARDIAN = 2, + SPELL_GROUP_ELIXIR_UNSTABLE = 3, SPELL_GROUP_ELIXIR_SHATTRATH = 4, - SPELL_GROUP_CORE_RANGE_MAX = 5, + SPELL_GROUP_CORE_RANGE_MAX = 5 }; #define SPELL_GROUP_DB_RANGE_MIN 1000 @@ -342,11 +342,12 @@ typedef std::pair<SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_ enum SpellGroupStackRule { - SPELL_GROUP_STACK_RULE_DEFAULT = 0, - SPELL_GROUP_STACK_RULE_EXCLUSIVE = 1, + SPELL_GROUP_STACK_RULE_DEFAULT = 0, + SPELL_GROUP_STACK_RULE_EXCLUSIVE = 1, SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER = 2, - SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT = 3, + SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT = 3 }; + #define SPELL_GROUP_STACK_RULE_MAX 4 typedef std::map<SpellGroup, SpellGroupStackRule> SpellGroupStackMap; diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 376e7f18edc..460a4e20d7f 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -47,7 +47,7 @@ enum SpellScriptState SPELL_SCRIPT_STATE_NONE = 0, SPELL_SCRIPT_STATE_REGISTRATION, SPELL_SCRIPT_STATE_LOADING, - SPELL_SCRIPT_STATE_UNLOADING, + SPELL_SCRIPT_STATE_UNLOADING }; #define SPELL_SCRIPT_STATE_END SPELL_SCRIPT_STATE_UNLOADING + 1 @@ -136,7 +136,7 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_CHECK_CAST, SPELL_SCRIPT_HOOK_BEFORE_CAST, SPELL_SCRIPT_HOOK_ON_CAST, - SPELL_SCRIPT_HOOK_AFTER_CAST, + SPELL_SCRIPT_HOOK_AFTER_CAST }; #define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT_HIT @@ -425,7 +425,7 @@ enum AuraScriptHookType AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD, AURA_SCRIPT_HOOK_CHECK_AREA_TARGET, AURA_SCRIPT_HOOK_DISPEL, - AURA_SCRIPT_HOOK_AFTER_DISPEL, + AURA_SCRIPT_HOOK_AFTER_DISPEL /*AURA_SCRIPT_HOOK_APPLY, AURA_SCRIPT_HOOK_REMOVE, */ }; diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index be8b4063d84..ecf315c059c 100755 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -29,13 +29,13 @@ class ChatHandler; enum GMTicketSystemStatus { GMTICKET_QUEUE_STATUS_DISABLED = 0, - GMTICKET_QUEUE_STATUS_ENABLED = 1, + GMTICKET_QUEUE_STATUS_ENABLED = 1 }; enum GMTicketStatus { GMTICKET_STATUS_HASTEXT = 0x06, - GMTICKET_STATUS_DEFAULT = 0x0A, + GMTICKET_STATUS_DEFAULT = 0x0A }; enum GMTicketResponse @@ -45,7 +45,7 @@ enum GMTicketResponse GMTICKET_RESPONSE_CREATE_ERROR = 3, GMTICKET_RESPONSE_UPDATE_SUCCESS = 4, GMTICKET_RESPONSE_UPDATE_ERROR = 5, - GMTICKET_RESPONSE_TICKET_DELETED = 9, + GMTICKET_RESPONSE_TICKET_DELETED = 9 }; // from Blizzard LUA: @@ -58,14 +58,14 @@ enum GMTicketEscalationStatus TICKET_UNASSIGNED = 0, TICKET_ASSIGNED = 1, TICKET_IN_ESCALATION_QUEUE = 2, - TICKET_ESCALATED_ASSIGNED = 3, + TICKET_ESCALATED_ASSIGNED = 3 }; // from blizzard lua enum GMTicketOpenedByGMStatus { GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED = 0, // ticket has never been opened by a gm - GMTICKET_OPENEDBYGM_STATUS_OPENED = 1, // ticket has been opened by a gm + GMTICKET_OPENEDBYGM_STATUS_OPENED = 1 // ticket has been opened by a gm }; enum LagReportType diff --git a/src/server/game/Tools/PlayerDump.h b/src/server/game/Tools/PlayerDump.h index b5655328507..6662d91fb31 100755 --- a/src/server/game/Tools/PlayerDump.h +++ b/src/server/game/Tools/PlayerDump.h @@ -48,7 +48,7 @@ enum DumpTableType DTT_ITEM_GIFT, // <- item guids // character_gifts DTT_PET, // -> pet guids collection // character_pet - DTT_PET_TABLE, // <- pet guids // pet_aura, pet_spell, pet_spell_cooldown + DTT_PET_TABLE // <- pet guids // pet_aura, pet_spell, pet_spell_cooldown }; enum DumpReturn diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index d16890b31b9..7a8f0f52315 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -54,7 +54,7 @@ enum WardenCheckType DRIVER_CHECK = 0x71, // 113: uint Seed + byte[20] SHA1 + byte driverNameIndex (check to ensure driver isn't loaded) TIMING_CHECK = 0x57, // 87: empty (check to ensure GetTickCount() isn't detoured) PROC_CHECK = 0x7E, // 126: uint Seed + byte[20] SHA1 + byte moluleNameIndex + byte procNameIndex + uint Offset + byte Len (check to ensure proc isn't detoured) - MODULE_CHECK = 0xD9, // 217: uint Seed + byte[20] SHA1 (check to ensure module isn't injected) + MODULE_CHECK = 0xD9 // 217: uint Seed + byte[20] SHA1 (check to ensure module isn't injected) }; #if defined(__GNUC__) diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h index dadd1151a53..59bff95d7ea 100755 --- a/src/server/game/Weather/Weather.h +++ b/src/server/game/Weather/Weather.h @@ -57,7 +57,7 @@ enum WeatherState WEATHER_STATE_HEAVY_SANDSTORM = 42, WEATHER_STATE_THUNDERS = 86, WEATHER_STATE_BLACKRAIN = 90, - WEATHER_STATE_BLACKSNOW = 106, + WEATHER_STATE_BLACKSNOW = 106 }; /// Weather for one zone diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index ea74b6d06dd..1d1fb45b74e 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -655,6 +655,7 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_REALM_ZONE] = ConfigMgr::GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT); m_bool_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = ConfigMgr::GetBoolDefault("AllowTwoSide.Accounts", true); + m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR]= ConfigMgr::GetBoolDefault("AllowTwoSide.Interaction.Calendar", false); m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT] = ConfigMgr::GetBoolDefault("AllowTwoSide.Interaction.Chat", false); m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = ConfigMgr::GetBoolDefault("AllowTwoSide.Interaction.Channel", false); m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = ConfigMgr::GetBoolDefault("AllowTwoSide.Interaction.Group", false); @@ -1193,6 +1194,11 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_AUTOBROADCAST] = ConfigMgr::GetBoolDefault("AutoBroadcast.On", false); m_int_configs[CONFIG_AUTOBROADCAST_CENTER] = ConfigMgr::GetIntDefault("AutoBroadcast.Center", 0); m_int_configs[CONFIG_AUTOBROADCAST_INTERVAL] = ConfigMgr::GetIntDefault("AutoBroadcast.Timer", 60000); + if (reload) + { + m_timers[WUPDATE_AUTOBROADCAST].SetInterval(m_int_configs[CONFIG_AUTOBROADCAST_INTERVAL]); + m_timers[WUPDATE_AUTOBROADCAST].Reset(); + } // MySQL ping time interval m_int_configs[CONFIG_DB_PING_INTERVAL] = ConfigMgr::GetIntDefault("MaxPingTime", 30); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index a6cdd4742f6..90bb82f1c2e 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -55,14 +55,14 @@ enum ServerMessageType enum ShutdownMask { SHUTDOWN_MASK_RESTART = 1, - SHUTDOWN_MASK_IDLE = 2, + SHUTDOWN_MASK_IDLE = 2 }; enum ShutdownExitCode { SHUTDOWN_EXIT_CODE = 0, ERROR_EXIT_CODE = 1, - RESTART_EXIT_CODE = 2, + RESTART_EXIT_CODE = 2 }; /// Timers for different object refresh rates @@ -91,6 +91,7 @@ enum WorldBoolConfigs CONFIG_GRID_UNLOAD, CONFIG_STATS_SAVE_ONLY_ON_LOGOUT, CONFIG_ALLOW_TWO_SIDE_ACCOUNTS, + CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL, CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP, @@ -408,18 +409,18 @@ enum BillingPlanFlags SESSION_USAGE = 0x10, SESSION_TIME_MIXTURE = 0x20, SESSION_RESTRICTED = 0x40, - SESSION_ENABLE_CAIS = 0x80, + SESSION_ENABLE_CAIS = 0x80 }; /// Type of server, this is values from second column of Cfg_Configs.dbc enum RealmType { - REALM_TYPE_NORMAL = 0, - REALM_TYPE_PVP = 1, - REALM_TYPE_NORMAL2 = 4, - REALM_TYPE_RP = 6, - REALM_TYPE_RPPVP = 8, - REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries + REALM_TYPE_NORMAL = 0, + REALM_TYPE_PVP = 1, + REALM_TYPE_NORMAL2 = 4, + REALM_TYPE_RP = 6, + REALM_TYPE_RPPVP = 8, + REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries // replaced by REALM_PVP in realm list }; diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp index ade1b9fae02..4f503fdbb76 100644 --- a/src/server/scripts/Commands/cs_cheat.cpp +++ b/src/server/scripts/Commands/cs_cheat.cpp @@ -41,6 +41,7 @@ public: { "cooldown", SEC_GAMEMASTER, false, &HandleCoolDownCheatCommand, "", NULL }, { "power", SEC_GAMEMASTER, false, &HandlePowerCheatCommand, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterWalkCheatCommand, "", NULL }, + { "status", SEC_GAMEMASTER, false, &HandleCheatStatusCommand, "", NULL }, { "taxi", SEC_GAMEMASTER, false, &HandleTaxiCheatCommand, "", NULL }, { "explore", SEC_GAMEMASTER, false, &HandleExploreCheatCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } @@ -159,6 +160,22 @@ public: return false; } + static bool HandleCheatStatusCommand(ChatHandler* handler, const char* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + const char* enabled = "enabled"; + const char* disabled = "disabled"; + + handler->SendSysMessage(LANG_COMMAND_CHEAT_STATUS); + handler->PSendSysMessage(LANG_COMMAND_CHEAT_GOD, player->GetCommandStatus(CHEAT_GOD) ? enabled : disabled); + handler->PSendSysMessage(LANG_COMMAND_CHEAT_CD, player->GetCommandStatus(CHEAT_COOLDOWN) ? enabled : disabled); + handler->PSendSysMessage(LANG_COMMAND_CHEAT_CT, player->GetCommandStatus(CHEAT_CASTTIME) ? enabled : disabled); + handler->PSendSysMessage(LANG_COMMAND_CHEAT_POWER, player->GetCommandStatus(CHEAT_POWER) ? enabled : disabled); + handler->PSendSysMessage(LANG_COMMAND_CHEAT_WW, player->GetCommandStatus(CHEAT_WATERWALK) ? enabled : disabled); + return true; + } + static bool HandleWaterWalkCheatCommand(ChatHandler* handler, const char* args) { if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index fa4b0ce3957..2c9623b23a6 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -14,7 +14,7 @@ * 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 "Chat.h" #include "ScriptMgr.h" #include "AccountMgr.h" @@ -29,12 +29,12 @@ #include "TargetedMovementGenerator.h" #include "WeatherMgr.h" #include "ace/INET_Addr.h" -
+ class misc_commandscript : public CommandScript { public: misc_commandscript() : CommandScript("misc_commandscript") { } -
+ ChatCommand* GetCommands() const { static ChatCommand groupCommandTable[] = @@ -81,7 +81,7 @@ public: { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, - { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, + { "unstuck", SEC_PLAYER, true, &HandleUnstuckCommand, "", NULL }, { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, @@ -117,7 +117,7 @@ public: }; return commandTable; } -
+ static bool HandleDevCommand(ChatHandler* handler, char const* args) { if (!*args) @@ -128,28 +128,28 @@ public: handler->GetSession()->SendNotification(LANG_DEV_OFF); return true; } -
+ std::string argstr = (char*)args; -
+ if (argstr == "on") { handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); handler->GetSession()->SendNotification(LANG_DEV_ON); return true; } -
+ if (argstr == "off") { handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); handler->GetSession()->SendNotification(LANG_DEV_OFF); return true; } -
+ handler->SendSysMessage(LANG_USE_BOL); handler->SetSentErrorMessage(true); return false; } -
+ static bool HandleGPSCommand(ChatHandler* handler, char const* args) { WorldObject* object = NULL; @@ -158,7 +158,7 @@ public: uint64 guid = handler->extractGuidFromLink((char*)args); if (guid) object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); -
+ if (!object) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -169,7 +169,7 @@ public: else { object = handler->getSelectedUnit(); -
+ if (!object) { handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); @@ -177,35 +177,35 @@ public: return false; } } -
+ CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); Cell cell(cellCoord); -
+ uint32 zoneId, areaId; object->GetZoneAndAreaId(zoneId, areaId); -
+ MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); -
+ float zoneX = object->GetPositionX(); float zoneY = object->GetPositionY(); -
+ Map2ZoneCoordinates(zoneX, zoneY, zoneId); -
+ Map const* map = object->GetMap(); float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); -
+ GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); -
+ // 63? WHY? int gridX = 63 - gridCoord.x_coord; int gridY = 63 - gridCoord.y_coord; -
+ uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; -
+ if (haveVMap) { if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) @@ -215,7 +215,7 @@ public: } else handler->PSendSysMessage("no VMAP available for area info"); -
+ handler->PSendSysMessage(LANG_MAP_POSITION, object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"), zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), @@ -224,16 +224,16 @@ public: object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); -
+ LiquidData liquidStatus; ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); -
+ if (status) handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); -
+ return true; } -
+ static bool HandleAuraCommand(ChatHandler* handler, char const* args) { Unit* target = handler->getSelectedUnit(); @@ -243,16 +243,16 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellId = handler->extractSpellIdFromLink((char*)args); -
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target); -
+ return true; } -
+ static bool HandleUnAuraCommand(ChatHandler* handler, char const* args) { Unit* target = handler->getSelectedUnit(); @@ -262,21 +262,21 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ std::string argstr = args; if (argstr == "all") { target->RemoveAllAuras(); return true; } -
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellId = handler->extractSpellIdFromLink((char*)args); if (!spellId) return false; -
+ target->RemoveAurasDueToSpell(spellId); -
+ return true; } // Teleport to Player @@ -287,7 +287,7 @@ public: std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; -
+ Player* _player = handler->GetSession()->GetPlayer(); if (target == _player || targetGuid == _player->GetGUID()) { @@ -295,15 +295,15 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (target) { // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ std::string chrNameLink = handler->playerLink(targetName); -
+ Map* map = target->GetMap(); if (map->IsBattlegroundOrArena()) { @@ -317,7 +317,7 @@ public: // if both players are in different bgs else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff -
+ // all's well, set bg id // when porting out from the bg, it will be reset to 0 _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); @@ -350,7 +350,7 @@ public: return false; } } -
+ // if the player or the player's group is bound to another instance // the player will not be bound to another one InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(map->IsRaid())); @@ -363,15 +363,15 @@ public: if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) _player->BindToInstance(save, !save->CanReset()); } -
+ if (map->IsRaid()) _player->SetRaidDifficulty(target->GetRaidDifficulty()); else _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); } -
+ handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); -
+ // stop flight if need if (_player->isInFlight()) { @@ -381,11 +381,11 @@ public: // save only in non-flight case else _player->SaveRecallPosition(); -
+ // to point to see at target with same orientation float x, y, z; target->GetContactPoint(_player, x, y, z); -
+ _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); _player->SetPhaseMask(target->GetPhaseMask(), true); } @@ -394,18 +394,18 @@ public: // check offline security if (handler->HasLowerSecurity(NULL, targetGuid)) return false; -
+ std::string nameLink = handler->playerLink(targetName); -
+ handler->PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); -
+ // to point where player stay (if loaded) float x, y, z, o; uint32 map; bool in_flight; if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, targetGuid)) return false; -
+ // stop flight if need if (_player->isInFlight()) { @@ -415,10 +415,10 @@ public: // save only in non-flight case else _player->SaveRecallPosition(); -
+ _player->TeleportTo(map, x, y, z, _player->GetOrientation()); } -
+ return true; } // Summon Player @@ -429,7 +429,7 @@ public: std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; -
+ Player* _player = handler->GetSession()->GetPlayer(); if (target == _player || targetGuid == _player->GetGUID()) { @@ -437,23 +437,23 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (target) { std::string nameLink = handler->playerLink(targetName); // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ if (target->IsBeingTeleported()) { handler->PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); handler->SetSentErrorMessage(true); return false; } -
+ Map* map = handler->GetSession()->GetPlayer()->GetMap(); -
+ if (map->IsBattlegroundOrArena()) { // only allow if gm mode is on @@ -466,7 +466,7 @@ public: // if both players are in different bgs else if (target->GetBattlegroundId() && handler->GetSession()->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff -
+ // all's well, set bg id // when porting out from the bg, it will be reset to 0 target->SetBattlegroundId(handler->GetSession()->GetPlayer()->GetBattlegroundId(), handler->GetSession()->GetPlayer()->GetBattlegroundTypeId()); @@ -477,10 +477,10 @@ public: else if (map->IsDungeon()) { Map* map = target->GetMap(); -
+ if (map->Instanceable() && map->GetInstanceId() != map->GetInstanceId()) target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true); -
+ // we are in instance, and can summon only player in our group with us as lead if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() || (target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || @@ -492,11 +492,11 @@ public: return false; } } -
+ handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); if (handler->needReportToTarget(target)) ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, handler->playerLink(_player->GetName()).c_str()); -
+ // stop flight if need if (target->isInFlight()) { @@ -506,7 +506,7 @@ public: // save only in non-flight case else target->SaveRecallPosition(); -
+ // before GM float x, y, z; handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); @@ -518,11 +518,11 @@ public: // check offline security if (handler->HasLowerSecurity(NULL, targetGuid)) return false; -
+ std::string nameLink = handler->playerLink(targetName); -
+ handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE)); -
+ // in point where GM stay Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(), handler->GetSession()->GetPlayer()->GetPositionX(), @@ -532,7 +532,7 @@ public: handler->GetSession()->GetPlayer()->GetZoneId(), targetGuid); } -
+ return true; } // Summon group of player @@ -541,25 +541,25 @@ public: Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; -
+ // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ Group* group = target->GetGroup(); -
+ std::string nameLink = handler->GetNameLink(target); -
+ if (!group) { handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); handler->SetSentErrorMessage(true); return false; } -
+ Map* gmMap = handler->GetSession()->GetPlayer()->GetMap(); bool toInstance = gmMap->Instanceable(); -
+ // we are in instance, and can summon only player in our group with us as lead if (toInstance && ( !handler->GetSession()->GetPlayer()->GetGroup() || (group->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || @@ -570,31 +570,31 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->getSource(); -
+ if (!player || player == handler->GetSession()->GetPlayer() || !player->GetSession()) continue; -
+ // check online security if (handler->HasLowerSecurity(player, 0)) return false; -
+ std::string plNameLink = handler->GetNameLink(player); -
+ if (player->IsBeingTeleported() == true) { handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); handler->SetSentErrorMessage(true); return false; } -
+ if (toInstance) { Map* playerMap = player->GetMap(); -
+ if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) { // cannot summon from instance to instance @@ -603,11 +603,11 @@ public: return false; } } -
+ handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); if (handler->needReportToTarget(player)) ChatHandler(player).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); -
+ // stop flight if need if (player->isInFlight()) { @@ -617,39 +617,39 @@ public: // save only in non-flight case else player->SaveRecallPosition(); -
+ // before GM float x, y, z; handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); } -
+ return true; } -
+ static bool HandleCommandsCommand(ChatHandler* handler, char const* /*args*/) { handler->ShowHelpForCommand(handler->getCommandTable(), ""); return true; } -
+ static bool HandleDieCommand(ChatHandler* handler, char const* /*args*/) { Unit* target = handler->getSelectedUnit(); -
+ if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) { handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); handler->SetSentErrorMessage(true); return false; } -
+ if (target->GetTypeId() == TYPEID_PLAYER) { if (handler->HasLowerSecurity((Player*)target, 0, false)) return false; } -
+ if (target->isAlive()) { if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE)) @@ -657,17 +657,17 @@ public: else handler->GetSession()->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } -
+ return true; } -
+ static bool HandleReviveCommand(ChatHandler* handler, char const* args) { Player* target; uint64 targetGuid; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) return false; -
+ if (target) { target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); @@ -677,14 +677,14 @@ public: else // will resurrected at login without corpse sObjectAccessor->ConvertCorpseForPlayer(targetGuid); -
+ return true; } -
+ static bool HandleDismountCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); -
+ // If player is not mounted, so go out :) if (!player->IsMounted()) { @@ -692,34 +692,34 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (player->isInFlight()) { handler->SendSysMessage(LANG_YOU_IN_FLIGHT); handler->SetSentErrorMessage(true); return false; } -
+ player->Dismount(); player->RemoveAurasByType(SPELL_AURA_MOUNTED); return true; } -
+ static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/) { uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); -
+ if (guid == 0) { handler->SendSysMessage(LANG_NO_SELECTION); handler->SetSentErrorMessage(true); return false; } -
+ handler->PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); return true; } -
+ static bool HandleHelpCommand(ChatHandler* handler, char const* args) { char const* cmd = strtok((char*)args, " "); @@ -733,7 +733,7 @@ public: if (!handler->ShowHelpForCommand(handler->getCommandTable(), cmd)) handler->SendSysMessage(LANG_NO_HELP_CMD); } -
+ return true; } // move item to other slot @@ -741,35 +741,35 @@ public: { if (!*args) return false; -
+ char const* param1 = strtok((char*)args, " "); if (!param1) return false; -
+ char const* param2 = strtok(NULL, " "); if (!param2) return false; -
+ uint8 srcSlot = uint8(atoi(param1)); uint8 dstSlot = uint8(atoi(param2)); -
+ if (srcSlot == dstSlot) return true; -
+ if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcSlot, true)) return false; -
+ if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, dstSlot, false)) return false; -
+ uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcSlot); uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstSlot); -
+ handler->GetSession()->GetPlayer()->SwapItem(src, dst); -
+ return true; } -
+ static bool HandleCooldownCommand(ChatHandler* handler, char const* args) { Player* target = handler->getSelectedPlayer(); @@ -779,9 +779,9 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ std::string nameLink = handler->GetNameLink(target); -
+ if (!*args) { target->RemoveAllSpellCooldown(); @@ -793,30 +793,30 @@ public: uint32 spellIid = handler->extractSpellIdFromLink((char*)args); if (!spellIid) return false; -
+ if (!sSpellMgr->GetSpellInfo(spellIid)) { handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); handler->SetSentErrorMessage(true); return false; } -
+ target->RemoveSpellCooldown(spellIid, true); handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); } return true; } -
+ static bool HandleGetDistanceCommand(ChatHandler* handler, char const* args) { WorldObject* obj = NULL; -
+ if (*args) { uint64 guid = handler->extractGuidFromLink((char*)args); if (guid) obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); -
+ if (!obj) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -827,7 +827,7 @@ public: else { obj = handler->getSelectedUnit(); -
+ if (!obj) { handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); @@ -835,7 +835,7 @@ public: return false; } } -
+ handler->PSendSysMessage(LANG_DISTANCE, handler->GetSession()->GetPlayer()->GetDistance(obj), handler->GetSession()->GetPlayer()->GetDistance2d(obj), handler->GetSession()->GetPlayer()->GetExactDist(obj), handler->GetSession()->GetPlayer()->GetExactDist2d(obj)); return true; } @@ -845,33 +845,33 @@ public: Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; -
+ // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ if (target->IsBeingTeleported()) { handler->PSendSysMessage(LANG_IS_TELEPORTED, handler->GetNameLink(target).c_str()); handler->SetSentErrorMessage(true); return false; } -
+ // stop flight if need if (target->isInFlight()) { target->GetMotionMaster()->MovementExpired(); target->CleanupAfterTaxiFlight(); } -
+ target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); return true; } -
+ static bool HandleSaveCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); -
+ // save GM account without delay and output message if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) { @@ -882,15 +882,15 @@ public: handler->SendSysMessage(LANG_PLAYER_SAVED); return true; } -
+ // save if the player has last been saved over 20 seconds ago uint32 saveInterval = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE); if (saveInterval == 0 || (saveInterval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= saveInterval - 20 * IN_MILLISECONDS)) player->SaveToDB(); -
+ return true; } -
+ // Save all players in the world static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/) { @@ -898,7 +898,7 @@ public: handler->SendSysMessage(LANG_PLAYERS_SAVED); return true; } -
+ // kick player static bool HandleKickPlayerCommand(ChatHandler* handler, char const* args) { @@ -906,73 +906,106 @@ public: std::string playerName; if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) return false; -
+ if (handler->GetSession() && target == handler->GetSession()->GetPlayer()) { handler->SendSysMessage(LANG_COMMAND_KICKSELF); handler->SetSentErrorMessage(true); return false; } -
+ // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); else handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); -
+ target->GetSession()->KickPlayer(); -
+ return true; } -
- static bool HandleStartCommand(ChatHandler* handler, char const* /*args*/) + + static bool HandleUnstuckCommand(ChatHandler* handler, char const* args) { - Player* player = handler->GetSession()->GetPlayer(); -
- if (player->isInFlight()) + //No args required for players + if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) { - handler->SendSysMessage(LANG_YOU_IN_FLIGHT); - handler->SetSentErrorMessage(true); - return false; + Player* player = handler->GetSession()->GetPlayer(); + if (player->isInFlight() || player->isInCombat()) + { + handler->SendSysMessage(LANG_CANT_DO_NOW); + handler->SetSentErrorMessage(true); + return false; + } + + //7355: "Stuck" + player->CastSpell(player, 7355, false); + return true; } -
- if (player->isInCombat()) + + if (!*args) + return false; + + char* player_str = strtok((char*)args, " "); + if (!player_str) + return false; + + std::string location_str = "inn"; + if (char const* loc = strtok(NULL, " ")) + location_str = loc; + + Player* player = NULL; + if (!handler->extractPlayerTarget(player_str, &player)) + return false; + + if (player->isInFlight() || player->isInCombat()) { - handler->SendSysMessage(LANG_YOU_IN_COMBAT); + handler->SendSysMessage(LANG_CANT_DO_NOW); handler->SetSentErrorMessage(true); return false; } -
- if (player->isDead() || player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + + if (location_str == "inn") + { + player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, player->GetOrientation()); + return true; + } + + if (location_str == "graveyard") { - // if player is dead and stuck, send ghost to graveyard player->RepopAtGraveyard(); return true; } -
- // cast spell Stuck - player->CastSpell(player, 7355, false); - return true; + + if (location_str == "startzone") + { + player->TeleportTo(player->GetStartPosition()); + return true; + } + + //Not a supported argument + return false; + } -
+ static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ char* px = strtok((char*)args, " "); if (!px) return false; -
+ uint32 graveyardId = uint32(atoi(px)); -
+ uint32 team; -
+ char* px2 = strtok(NULL, " "); -
+ if (!px2) team = 0; else if (strncmp(px2, "horde", 6) == 0) @@ -981,20 +1014,20 @@ public: team = ALLIANCE; else return false; -
+ WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(graveyardId); -
+ if (!graveyard) { handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, graveyardId); handler->SetSentErrorMessage(true); return false; } -
+ Player* player = handler->GetSession()->GetPlayer(); -
+ uint32 zoneId = player->GetZoneId(); -
+ AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); if (!areaEntry || areaEntry->zone !=0) { @@ -1002,21 +1035,21 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (sObjectMgr->AddGraveYardLink(graveyardId, zoneId, team)) handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, graveyardId, zoneId); else handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, graveyardId, zoneId); -
+ return true; } -
+ static bool HandleNearGraveCommand(ChatHandler* handler, char const* args) { uint32 team; -
+ size_t argStr = strlen(args); -
+ if (!*args) team = 0; else if (strncmp((char*)args, "horde", argStr) == 0) @@ -1025,17 +1058,17 @@ public: team = ALLIANCE; else return false; -
+ Player* player = handler->GetSession()->GetPlayer(); uint32 zone_id = player->GetZoneId(); -
+ WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); -
+ if (graveyard) { uint32 graveyardId = graveyard->ID; -
+ GraveYardData const* data = sObjectMgr->FindGraveYardData(graveyardId, zone_id); if (!data) { @@ -1043,45 +1076,45 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ team = data->team; -
+ std::string team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); -
+ if (team == 0) team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); else if (team == HORDE) team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); else if (team == ALLIANCE) team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); -
+ handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, graveyardId, team_name.c_str(), zone_id); } else { std::string team_name; -
+ if (team == 0) team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); else if (team == HORDE) team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); else if (team == ALLIANCE) team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); -
+ if (team == ~uint32(0)) handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); else handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); } -
+ return true; } -
+ static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ Player* playerTarget = handler->getSelectedPlayer(); if (!playerTarget) { @@ -1089,30 +1122,30 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ int32 area = GetAreaFlagByAreaID(atoi((char*)args)); int32 offset = area / 32; uint32 val = uint32((1 << (area % 32))); -
+ if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } -
+ uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); -
+ handler->SendSysMessage(LANG_EXPLORE_AREA); return true; } -
+ static bool HandleHideAreaCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ Player* playerTarget = handler->getSelectedPlayer(); if (!playerTarget) { @@ -1120,45 +1153,45 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ int32 area = GetAreaFlagByAreaID(atoi((char*)args)); int32 offset = area / 32; uint32 val = uint32((1 << (area % 32))); -
+ if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } -
+ uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); -
+ handler->SendSysMessage(LANG_UNEXPLORE_AREA); return true; } -
+ static bool HandleAddItemCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ uint32 itemId = 0; -
+ if (args[0] == '[') // [name] manual form { char const* itemNameStr = strtok((char*)args, "]"); -
+ if (itemNameStr && itemNameStr[0]) { std::string itemName = itemNameStr+1; WorldDatabase.EscapeString(itemName); -
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); stmt->setString(0, itemName); PreparedQueryResult result = WorldDatabase.Query(stmt); -
+ if (!result) { handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); @@ -1177,24 +1210,24 @@ public: return false; itemId = uint32(atol(id)); } -
+ char const* ccount = strtok(NULL, " "); -
+ int32 count = 1; -
+ if (ccount) count = strtol(ccount, NULL, 10); -
+ if (count == 0) count = 1; -
+ Player* player = handler->GetSession()->GetPlayer(); Player* playerTarget = handler->getSelectedPlayer(); if (!playerTarget) playerTarget = player; -
+ sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEM), itemId, count); -
+ ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); if (!itemTemplate) { @@ -1202,7 +1235,7 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ // Subtract if (count < 0) { @@ -1210,55 +1243,55 @@ public: handler->PSendSysMessage(LANG_REMOVEITEM, itemId, -count, handler->GetNameLink(playerTarget).c_str()); return true; } -
+ // Adding items uint32 noSpaceForCount = 0; -
+ // check space and find places ItemPosCountVec dest; InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); if (msg != EQUIP_ERR_OK) // convert to possible store amount count -= noSpaceForCount; -
+ if (count == 0 || dest.empty()) // can't add any { handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); handler->SetSentErrorMessage(true); return false; } -
+ Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); -
+ // remove binding (let GM give it to another player later) if (player == playerTarget) for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) if (Item* item1 = player->GetItemByPos(itr->pos)) item1->SetBinding(false); -
+ if (count > 0 && item) { player->SendNewItem(item, count, false, true); if (player != playerTarget) playerTarget->SendNewItem(item, count, true, false); } -
+ if (noSpaceForCount > 0) handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); -
+ return true; } -
+ static bool HandleAddItemSetCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ char const* id = handler->extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r if (!id) return false; -
+ uint32 itemSetId = atol(id); -
+ // prevent generation all items with itemset field value '0' if (itemSetId == 0) { @@ -1266,14 +1299,14 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ Player* player = handler->GetSession()->GetPlayer(); Player* playerTarget = handler->getSelectedPlayer(); if (!playerTarget) playerTarget = player; -
+ sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEMSET), itemSetId); -
+ bool found = false; ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) @@ -1286,11 +1319,11 @@ public: if (msg == EQUIP_ERR_OK) { Item* item = playerTarget->StoreNewItem(dest, itr->second.ItemId, true); -
+ // remove binding (let GM give it to another player later) if (player == playerTarget) item->SetBinding(false); -
+ player->SendNewItem(item, 1, false, true); if (player != playerTarget) playerTarget->SendNewItem(item, 1, true, false); @@ -1302,28 +1335,28 @@ public: } } } -
+ if (!found) { handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); handler->SetSentErrorMessage(true); return false; } -
+ return true; } -
+ static bool HandleBankCommand(ChatHandler* handler, char const* /*args*/) { handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); return true; } -
+ static bool HandleChangeWeather(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ // Weather is OFF if (!sWorld->getBoolConfig(CONFIG_WEATHER)) { @@ -1331,22 +1364,22 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ // *Change the weather of a cell char const* px = strtok((char*)args, " "); char const* py = strtok(NULL, " "); -
+ if (!px || !py) return false; -
+ uint32 type = uint32(atoi(px)); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand float grade = float(atof(py)); //0 to 1, sending -1 is instand good weather -
+ Player* player = handler->GetSession()->GetPlayer(); uint32 zoneid = player->GetZoneId(); -
+ Weather* weather = WeatherMgr::FindWeather(zoneid); -
+ if (!weather) weather = WeatherMgr::AddWeather(zoneid); if (!weather) @@ -1355,12 +1388,12 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ weather->SetWeather(WeatherType(type), grade); -
+ return true; } -
+ static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) { @@ -1371,25 +1404,25 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ // each skills that have max skill value dependent from level seted to current level max skill value SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); return true; } -
+ static bool HandleSetSkillCommand(ChatHandler* handler, char const* args) { // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r char const* skillStr = handler->extractKeyFromLink((char*)args, "Hskill"); if (!skillStr) return false; -
+ char const* levelStr = strtok(NULL, " "); if (!levelStr) return false; -
+ char const* maxPureSkill = strtok(NULL, " "); -
+ int32 skill = atoi(skillStr); if (skill <= 0) { @@ -1397,9 +1430,9 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ int32 level = uint32(atol(levelStr)); -
+ Player* target = handler->getSelectedPlayer(); if (!target) { @@ -1407,7 +1440,7 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill); if (!skillLine) { @@ -1415,24 +1448,24 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ std::string tNameLink = handler->GetNameLink(target); -
+ if (!target->GetSkillValue(skill)) { handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]); handler->SetSentErrorMessage(true); return false; } -
+ uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill); -
+ if (level <= 0 || level > max || max <= 0) return false; -
+ target->SetSkill(skill, target->GetSkillStep(skill), level, max); handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max); -
+ return true; } // show info of player @@ -1441,9 +1474,9 @@ public: Player* target; uint64 targetGuid; std::string targetName; -
+ uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); -
+ if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) { target = sObjectMgr->GetPlayerByLowGUID(parseGUID); @@ -1451,7 +1484,7 @@ public: } else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; -
+ uint32 accId = 0; uint32 money = 0; uint32 totalPlayerTime = 0; @@ -1464,14 +1497,14 @@ public: uint32 mapId; uint32 areaId; uint32 phase = 0; -
+ // get additional information from Player object if (target) { // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); totalPlayerTime = target->GetTotalPlayedTime(); @@ -1490,14 +1523,14 @@ public: // check offline security if (handler->HasLowerSecurity(NULL, targetGuid)) return false; -
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); stmt->setUInt32(0, GUID_LOPART(targetGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); -
+ if (!result) return false; -
+ Field* fields = result->Fetch(); totalPlayerTime = fields[0].GetUInt32(); level = fields[1].GetUInt8(); @@ -1508,18 +1541,18 @@ public: mapId = fields[6].GetUInt16(); areaId = fields[7].GetUInt16(); } -
+ std::string userName = handler->GetTrinityString(LANG_ERROR); std::string eMail = handler->GetTrinityString(LANG_ERROR); std::string lastIp = handler->GetTrinityString(LANG_ERROR); uint32 security = 0; std::string lastLogin = handler->GetTrinityString(LANG_ERROR); -
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); stmt->setInt32(0, int32(realmID)); stmt->setUInt32(1, accId); PreparedQueryResult result = LoginDatabase.Query(stmt); -
+ if (result) { Field* fields = result->Fetch(); @@ -1527,26 +1560,26 @@ public: security = fields[1].GetUInt8(); eMail = fields[2].GetString(); muteTime = fields[5].GetUInt64(); -
+ if (eMail.empty()) eMail = "-"; -
+ if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security)) { lastIp = fields[3].GetString(); lastLogin = fields[4].GetString(); -
+ uint32 ip = inet_addr(lastIp.c_str()); #if TRINITY_ENDIAN == BIGENDIAN EndianConvertReverse(ip); #endif -
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); -
+ stmt->setUInt32(0, ip); -
+ PreparedQueryResult result2 = WorldDatabase.Query(stmt); -
+ if (result2) { Field* fields2 = result2->Fetch(); @@ -1561,14 +1594,14 @@ public: lastLogin = "-"; } } -
+ std::string nameLink = handler->playerLink(targetName); -
+ handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency); -
+ std::string bannedby = "unknown"; std::string banreason = ""; -
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); stmt->setUInt32(0, accId); PreparedQueryResult result2 = LoginDatabase.Query(stmt); @@ -1578,7 +1611,7 @@ public: stmt->setUInt32(0, GUID_LOPART(targetGuid)); result2 = CharacterDatabase.Query(stmt); } -
+ if (result2) { Field* fields = result2->Fetch(); @@ -1586,13 +1619,13 @@ public: bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } -
+ if (muteTime > 0) handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); -
+ if (banTime >= 0) handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); -
+ std::string raceStr, ClassStr; switch (race) { @@ -1627,7 +1660,7 @@ public: raceStr = "Draenei"; break; } -
+ switch (Class) { case CLASS_WARRIOR: @@ -1661,30 +1694,30 @@ public: ClassStr = "Druid"; break; } -
+ std::string timeStr = secsToTimeString(totalPlayerTime, true, true); uint32 gold = money /GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp); -
+ // Add map, zone, subzone and phase to output int locale = handler->GetSessionDbcLocale(); std::string areaName = "<unknown>"; std::string zoneName = ""; -
+ MapEntry const* map = sMapStore.LookupEntry(mapId); -
+ AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); if (area) { areaName = area->area_name[locale]; -
+ AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) zoneName = zone->area_name[locale]; } -
+ if (target) { if (!zoneName.empty()) @@ -1694,14 +1727,14 @@ public: } else handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); -
+ return true; } -
+ static bool HandleRespawnCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); -
+ // accept only explicitly selected target (not implicitly self targeting case) Unit* target = handler->getSelectedUnit(); if (player->GetSelection() && target) @@ -1712,22 +1745,22 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (target->isDead()) target->ToCreature()->Respawn(); return true; } -
+ CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); Cell cell(p); cell.SetNoCreate(); -
+ Trinity::RespawnDo u_do; Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(player, u_do); -
+ TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker); cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); -
+ return true; } // mute player for some times @@ -1738,33 +1771,33 @@ public: handler->extractOptFirstArg((char*)args, &nameStr, &delayStr); if (!delayStr) return false; -
+ char const* muteReason = strtok(NULL, "\r"); std::string muteReasonStr = "No reason"; if (muteReason != NULL) muteReasonStr = muteReason; -
+ Player* target; uint64 targetGuid; std::string targetName; if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) return false; -
+ uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); -
+ // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); -
+ uint32 notSpeakTime = uint32(atoi(delayStr)); -
+ // must have strong lesser security level if (handler->HasLowerSecurity (target, targetGuid, true)) return false; -
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); -
+ if (target) { // Target is online, mute will be in effect right away. @@ -1779,16 +1812,16 @@ public: int32 muteTime = -int32(notSpeakTime * MINUTE); stmt->setInt64(0, muteTime); } -
+ stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); -
+ handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); -
+ return true; } -
+ // unmute player static bool HandleUnmuteCommand(ChatHandler* handler, char const* args) { @@ -1797,18 +1830,18 @@ public: std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; -
+ uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); -
+ // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); -
+ // must have strong lesser security level if (handler->HasLowerSecurity (target, targetGuid, true)) return false; -
+ if (target) { if (target->CanSpeak()) @@ -1817,25 +1850,25 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ target->GetSession()->m_muteTime = 0; } -
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); -
+ if (target) ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); -
+ std::string nameLink = handler->playerLink(targetName); -
+ handler->PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); -
+ return true; } -
+ static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) { @@ -1846,13 +1879,13 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ handler->PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); -
+ MotionMaster* motionMaster = unit->GetMotionMaster(); float x, y, z; motionMaster->GetDestination(x, y, z); -
+ for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) { MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); @@ -1861,7 +1894,7 @@ public: handler->SendSysMessage("Empty"); continue; } -
+ switch (movementGenerator->GetMovementGeneratorType()) { case IDLE_MOTION_TYPE: @@ -1886,7 +1919,7 @@ public: target = static_cast<ChaseMovementGenerator<Player> const*>(movementGenerator)->GetTarget(); else target = static_cast<ChaseMovementGenerator<Creature> const*>(movementGenerator)->GetTarget(); -
+ if (!target) handler->SendSysMessage(LANG_MOVEGENS_CHASE_NULL); else if (target->GetTypeId() == TYPEID_PLAYER) @@ -1902,7 +1935,7 @@ public: target = static_cast<FollowMovementGenerator<Player> const*>(movementGenerator)->GetTarget(); else target = static_cast<FollowMovementGenerator<Creature> const*>(movementGenerator)->GetTarget(); -
+ if (!target) handler->SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); else if (target->GetTypeId() == TYPEID_PLAYER) @@ -1953,7 +1986,7 @@ public: char const* newFlagStr = strtok((char*)args, " "); if (!newFlagStr) return false; -
+ Creature* caster = handler->getSelectedCreature(); if (!caster) { @@ -1961,19 +1994,19 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ Player* player = handler->GetSession()->GetPlayer(); -
+ caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); -
+ return true; } -
+ static bool HandleDamageCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ Unit* target = handler->getSelectedUnit(); if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) { @@ -1981,28 +2014,28 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (target->GetTypeId() == TYPEID_PLAYER) { if (handler->HasLowerSecurity((Player*)target, 0, false)) return false; } -
+ if (!target->isAlive()) return true; -
+ char* damageStr = strtok((char*)args, " "); if (!damageStr) return false; -
+ int32 damage_int = atoi((char*)damageStr); if (damage_int <= 0) return true; -
+ uint32 damage = damage_int; -
+ char* schoolStr = strtok((char*)NULL, " "); -
+ // flat melee damage without resistence/etc reduction if (!schoolStr) { @@ -2011,52 +2044,52 @@ public: handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); return true; } -
+ uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL; if (school >= MAX_SPELL_SCHOOL) return false; -
+ SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); -
+ if (Unit::IsDamageReducedByArmor(schoolmask)) damage = handler->GetSession()->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK); -
+ char* spellStr = strtok((char*)NULL, " "); -
+ // melee damage by specific school if (!spellStr) { uint32 absorb = 0; uint32 resist = 0; -
+ handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); -
+ if (damage <= absorb + resist) return true; -
+ damage -= absorb + resist; -
+ handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb); handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); return true; } -
+ // non-melee damage -
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellid = handler->extractSpellIdFromLink((char*)args); if (!spellid || !sSpellMgr->GetSpellInfo(spellid)) return false; -
+ handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); return true; } -
+ static bool HandleCombatStopCommand(ChatHandler* handler, char const* args) { Player* target = NULL; -
+ if (args && strlen(args) > 0) { target = sObjectAccessor->FindPlayerByName(args); @@ -2067,48 +2100,48 @@ public: return false; } } -
+ if (!target) { if (!handler->extractPlayerTarget((char*)args, &target)) return false; } -
+ // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ target->CombatStop(); target->getHostileRefManager().deleteReferences(); return true; } -
+ static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) { sArenaTeamMgr->DistributeArenaPoints(); return true; } -
+ static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) { Player* target; if (!handler->extractPlayerTarget((char*)args, &target)) return false; -
+ // check online security if (handler->HasLowerSecurity(target, 0)) return false; -
+ // Repair items target->DurabilityRepairAll(false, 0, false); -
+ handler->PSendSysMessage(LANG_YOU_REPAIR_ITEMS, handler->GetNameLink(target).c_str()); if (handler->needReportToTarget(target)) ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, handler->GetNameLink().c_str()); -
+ return true; } -
+ // Send mail by command static bool HandleSendMailCommand(ChatHandler* handler, char const* args) { @@ -2118,37 +2151,37 @@ public: std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; -
+ char* tail1 = strtok(NULL, ""); if (!tail1) return false; -
+ char const* msgSubject = handler->extractQuotedArg(tail1); if (!msgSubject) return false; -
+ char* tail2 = strtok(NULL, ""); if (!tail2) return false; -
+ char const* msgText = handler->extractQuotedArg(tail2); if (!msgText) return false; -
+ // msgSubject, msgText isn't NUL after prev. check std::string subject = msgSubject; std::string text = msgText; -
+ // from console show not existed sender MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); -
+ //- TODO: Fix poor design SQLTransaction trans = CharacterDatabase.BeginTransaction(); MailDraft(subject, text) .SendMailTo(trans, MailReceiver(target, GUID_LOPART(targetGuid)), sender); -
+ CharacterDatabase.CommitTransaction(trans); -
+ std::string nameLink = handler->playerLink(targetName); handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; @@ -2162,49 +2195,49 @@ public: std::string receiverName; if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) return false; -
+ char* tail1 = strtok(NULL, ""); if (!tail1) return false; -
+ char const* msgSubject = handler->extractQuotedArg(tail1); if (!msgSubject) return false; -
+ char* tail2 = strtok(NULL, ""); if (!tail2) return false; -
+ char const* msgText = handler->extractQuotedArg(tail2); if (!msgText) return false; -
+ // msgSubject, msgText isn't NUL after prev. check std::string subject = msgSubject; std::string text = msgText; -
+ // extract items typedef std::pair<uint32, uint32> ItemPair; typedef std::list< ItemPair > ItemPairs; ItemPairs items; -
+ // get all tail string char* tail = strtok(NULL, ""); -
+ // get from tail next item str while (char* itemStr = strtok(tail, " ")) { // and get new tail tail = strtok(NULL, ""); -
+ // parse item str char const* itemIdStr = strtok(itemStr, ":"); char const* itemCountStr = strtok(NULL, " "); -
+ uint32 itemId = atoi(itemIdStr); if (!itemId) return false; -
+ ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(itemId); if (!item_proto) { @@ -2212,7 +2245,7 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1; if (itemCount < 1 || (item_proto->MaxCount > 0 && itemCount > uint32(item_proto->MaxCount))) { @@ -2220,15 +2253,15 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ while (itemCount > item_proto->GetMaxStackSize()) { items.push_back(ItemPair(itemId, item_proto->GetMaxStackSize())); itemCount -= item_proto->GetMaxStackSize(); } -
+ items.push_back(ItemPair(itemId, itemCount)); -
+ if (items.size() > MAX_MAIL_ITEMS) { handler->PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); @@ -2236,15 +2269,15 @@ public: return false; } } -
+ // from console show not existed sender MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); -
+ // fill mail MailDraft draft(subject, text); -
+ SQLTransaction trans = CharacterDatabase.BeginTransaction(); -
+ for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) { if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) @@ -2253,10 +2286,10 @@ public: draft.AddItem(item); } } -
+ draft.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); CharacterDatabase.CommitTransaction(trans); -
+ std::string nameLink = handler->playerLink(receiverName); handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; @@ -2265,49 +2298,49 @@ public: static bool HandleSendMoneyCommand(ChatHandler* handler, char const* args) { /// format: name "subject text" "mail text" money -
+ Player* receiver; uint64 receiverGuid; std::string receiverName; if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) return false; -
+ char* tail1 = strtok(NULL, ""); if (!tail1) return false; -
+ char* msgSubject = handler->extractQuotedArg(tail1); if (!msgSubject) return false; -
+ char* tail2 = strtok(NULL, ""); if (!tail2) return false; -
+ char* msgText = handler->extractQuotedArg(tail2); if (!msgText) return false; -
+ char* moneyStr = strtok(NULL, ""); int32 money = moneyStr ? atoi(moneyStr) : 0; if (money <= 0) return false; -
+ // msgSubject, msgText isn't NUL after prev. check std::string subject = msgSubject; std::string text = msgText; -
+ // from console show not existed sender MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); -
+ SQLTransaction trans = CharacterDatabase.BeginTransaction(); -
+ MailDraft(subject, text) .AddMoney(money) .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); -
+ CharacterDatabase.CommitTransaction(trans); -
+ std::string nameLink = handler->playerLink(receiverName); handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; @@ -2319,11 +2352,11 @@ public: Player* player; if (!handler->extractPlayerTarget((char*)args, &player)) return false; -
+ char* msgStr = strtok(NULL, ""); if (!msgStr) return false; -
+ ///- Check that he is not logging out. if (player->GetSession()->isLogingOut()) { @@ -2331,31 +2364,31 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ /// - Send the message // Use SendAreaTriggerMessage for fastest delivery. player->GetSession()->SendAreaTriggerMessage("%s", msgStr); player->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); -
+ // Confirmation message std::string nameLink = handler->GetNameLink(player); handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr); -
+ return true; } -
+ static bool HandleCreatePetCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); Creature* creatureTarget = handler->getSelectedCreature(); -
+ if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) { handler->PSendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } -
+ CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); // Creatures with family 0 crashes the server if (!creatrueTemplate->family) @@ -2364,14 +2397,14 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ if (player->GetPetGUID()) { handler->PSendSysMessage("You already have a pet"); handler->SetSentErrorMessage(true); return false; } -
+ // Everything looks OK, create new pet Pet* pet = new Pet(player, HUNTER_PET); if (!pet->CreateBaseAtCreature(creatureTarget)) @@ -2380,14 +2413,14 @@ public: handler->PSendSysMessage("Error 1"); return false; } -
+ creatureTarget->setDeathState(JUST_DIED); creatureTarget->RemoveCorpse(); creatureTarget->SetHealth(0); // just for nice GM-mode view -
+ pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); -
+ if (!pet->InitStatsForLevel(creatureTarget->getLevel())) { sLog->outError(LOG_FILTER_GENERAL, "InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); @@ -2395,47 +2428,47 @@ public: delete pet; return false; } -
+ // prepare visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); -
+ pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); // this enables pet details window (Shift+P) pet->InitPetCreateSpells(); pet->SetFullHealth(); -
+ pet->GetMap()->AddToMap(pet->ToCreature()); -
+ // visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); -
+ player->SetMinion(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); -
+ return true; } -
+ static bool HandlePetLearnCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ Player* player = handler->GetSession()->GetPlayer(); Pet* pet = player->GetPet(); -
+ if (!pet) { handler->PSendSysMessage("You have no pet"); handler->SetSentErrorMessage(true); return false; } -
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args); -
+ if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) return false; -
+ // Check if pet already has it if (pet->HasSpell(spellId)) { @@ -2443,7 +2476,7 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ // Check if spell is valid SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) @@ -2452,18 +2485,18 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ pet->learnSpell(spellId); -
+ handler->PSendSysMessage("Pet has learned spell %u", spellId); return true; } -
+ static bool HandlePetUnlearnCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ Player* player = handler->GetSession()->GetPlayer(); Pet* pet = player->GetPet(); if (!pet) @@ -2472,17 +2505,17 @@ public: handler->SetSentErrorMessage(true); return false; } -
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args); -
+ if (pet->HasSpell(spellId)) pet->removeSpell(spellId, false); else handler->PSendSysMessage("Pet doesn't have that spell"); -
+ return true; } -
+ static bool HandleFreezeCommand(ChatHandler* handler, char const* args) { std::string name; @@ -2503,31 +2536,31 @@ public: normalizePlayerName(name); player = sObjectAccessor->FindPlayerByName(name.c_str()); } -
+ if (!player) { handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); return true; } -
+ if (player == handler->GetSession()->GetPlayer()) { handler->SendSysMessage(LANG_COMMAND_FREEZE_ERROR); return true; } -
+ // effect if (player && (player != handler->GetSession()->GetPlayer())) { handler->PSendSysMessage(LANG_COMMAND_FREEZE, name.c_str()); -
+ // stop combat + make player unattackable + duel stop + stop some spells player->setFaction(35); player->CombatStop(); if (player->IsNonMeleeSpellCasted(true)) player->InterruptNonMeleeSpells(true); player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); -
+ // if player class = hunter || warlock remove pet if alive if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) { @@ -2539,23 +2572,23 @@ public: player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); } } -
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454)) Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player); -
+ // save player player->SaveToDB(); } -
+ return true; } -
+ static bool HandleUnFreezeCommand(ChatHandler* handler, char const*args) { std::string name; Player* player; char* targetName = strtok((char*)args, " "); // Get entered name -
+ if (targetName) { name = targetName; @@ -2568,18 +2601,18 @@ public: if (player) name = player->GetName(); } -
+ if (player) { handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); -
+ // Reset player faction + allow combat + allow duels player->setFactionForRace(player->getRace()); player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); -
+ // Remove Freeze spell (allowing movement and spells) player->RemoveAurasDueToSpell(9454); -
+ // Save player player->SaveToDB(); } @@ -2591,21 +2624,21 @@ public: PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_BY_NAME); stmt->setString(0, name); PreparedQueryResult result = CharacterDatabase.Query(stmt); -
+ if (!result) { handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); return true; } -
+ // If player found: delete his freeze aura Field* fields = result->Fetch(); uint32 lowGuid = fields[0].GetUInt32(); -
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); stmt->setUInt32(0, lowGuid); CharacterDatabase.Execute(stmt); -
+ handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); return true; } @@ -2615,10 +2648,10 @@ public: return true; } } -
+ return true; } -
+ static bool HandleListFreezeCommand(ChatHandler* handler, char const* /*args*/) { // Get names from DB @@ -2629,10 +2662,10 @@ public: handler->SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); return true; } -
+ // Header of the names handler->PSendSysMessage(LANG_COMMAND_LIST_FREEZE); -
+ // Output of the results do { @@ -2641,120 +2674,120 @@ public: handler->PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, player.c_str()); } while (result->NextRow()); -
+ return true; } -
+ static bool HandleGroupLeaderCommand(ChatHandler* handler, char const* args) { Player* player = NULL; Group* group = NULL; uint64 guid = 0; char* nameStr = strtok((char*)args, " "); -
+ if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) if (group && group->GetLeaderGUID() != guid) { group->ChangeLeader(guid); group->SendUpdate(); } -
+ return true; } -
+ static bool HandleGroupDisbandCommand(ChatHandler* handler, char const* args) { Player* player = NULL; Group* group = NULL; uint64 guid = 0; char* nameStr = strtok((char*)args, " "); -
+ if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) if (group) group->Disband(); -
+ return true; } -
+ static bool HandleGroupRemoveCommand(ChatHandler* handler, char const* args) { Player* player = NULL; Group* group = NULL; uint64 guid = 0; char* nameStr = strtok((char*)args, " "); -
+ if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid, true)) if (group) group->RemoveMember(guid); -
+ return true; } -
+ static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) { if (!*args) return false; -
+ uint32 soundId = atoi((char*)args); -
+ if (!sSoundEntriesStore.LookupEntry(soundId)) { handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); handler->SetSentErrorMessage(true); return false; } -
+ WorldPacket data(SMSG_PLAY_SOUND, 4); data << uint32(soundId) << handler->GetSession()->GetPlayer()->GetGUID(); sWorld->SendGlobalMessage(&data); -
+ handler->PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); return true; } -
+ static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/) { Unit* unit = handler->getSelectedUnit(); if (!unit) return false; -
+ handler->GetSession()->GetPlayer()->CastSpell(unit, 530, true); return true; } -
+ static bool HandleUnPossessCommand(ChatHandler* handler, char const* /*args*/) { Unit* unit = handler->getSelectedUnit(); if (!unit) unit = handler->GetSession()->GetPlayer(); -
+ unit->RemoveCharmAuras(); -
+ return true; } -
+ static bool HandleBindSightCommand(ChatHandler* handler, char const* /*args*/) { Unit* unit = handler->getSelectedUnit(); if (!unit) return false; -
+ handler->GetSession()->GetPlayer()->CastSpell(unit, 6277, true); return true; } -
+ static bool HandleUnbindSightCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); -
+ if (player->isPossessing()) return false; -
+ player->StopCastingBindSight(); return true; } }; -
+ void AddSC_misc_commandscript() { new misc_commandscript(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 3bb29f8abfe..7d2a4304054 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -467,56 +467,57 @@ public: cInfo->rangeattacktime = fields[29].GetUInt32(); cInfo->unit_class = fields[30].GetUInt8(); cInfo->unit_flags = fields[31].GetUInt32(); - cInfo->dynamicflags = fields[32].GetUInt32(); - cInfo->family = fields[33].GetUInt8(); - cInfo->trainer_type = fields[34].GetUInt8(); - cInfo->trainer_spell = fields[35].GetUInt32(); - cInfo->trainer_class = fields[36].GetUInt8(); - cInfo->trainer_race = fields[37].GetUInt8(); - cInfo->minrangedmg = fields[38].GetFloat(); - cInfo->maxrangedmg = fields[39].GetFloat(); - cInfo->rangedattackpower = fields[40].GetUInt16(); - cInfo->type = fields[41].GetUInt8(); - cInfo->type_flags = fields[42].GetUInt32(); - cInfo->lootid = fields[43].GetUInt32(); - cInfo->pickpocketLootId = fields[44].GetUInt32(); - cInfo->SkinLootId = fields[45].GetUInt32(); + cInfo->unit_flags2 = fields[32].GetUInt32(); + cInfo->dynamicflags = fields[33].GetUInt32(); + cInfo->family = fields[34].GetUInt8(); + cInfo->trainer_type = fields[35].GetUInt8(); + cInfo->trainer_spell = fields[36].GetUInt32(); + cInfo->trainer_class = fields[37].GetUInt8(); + cInfo->trainer_race = fields[38].GetUInt8(); + cInfo->minrangedmg = fields[39].GetFloat(); + cInfo->maxrangedmg = fields[40].GetFloat(); + cInfo->rangedattackpower = fields[41].GetUInt16(); + cInfo->type = fields[42].GetUInt8(); + cInfo->type_flags = fields[43].GetUInt32(); + cInfo->lootid = fields[44].GetUInt32(); + cInfo->pickpocketLootId = fields[45].GetUInt32(); + cInfo->SkinLootId = fields[46].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - cInfo->resistance[i] = fields[46 + i -1].GetUInt16(); - - cInfo->spells[0] = fields[52].GetUInt32(); - cInfo->spells[1] = fields[53].GetUInt32(); - cInfo->spells[2] = fields[54].GetUInt32(); - cInfo->spells[3] = fields[55].GetUInt32(); - cInfo->spells[4] = fields[56].GetUInt32(); - cInfo->spells[5] = fields[57].GetUInt32(); - cInfo->spells[6] = fields[58].GetUInt32(); - cInfo->spells[7] = fields[59].GetUInt32(); - cInfo->PetSpellDataId = fields[60].GetUInt32(); - cInfo->VehicleId = fields[61].GetUInt32(); - cInfo->mingold = fields[62].GetUInt32(); - cInfo->maxgold = fields[63].GetUInt32(); - cInfo->AIName = fields[64].GetString(); - cInfo->MovementType = fields[65].GetUInt8(); - cInfo->InhabitType = fields[66].GetUInt8(); - cInfo->HoverHeight = fields[67].GetFloat(); - cInfo->ModHealth = fields[68].GetFloat(); - cInfo->ModMana = fields[69].GetFloat(); - cInfo->ModArmor = fields[70].GetFloat(); - cInfo->RacialLeader = fields[71].GetBool(); - cInfo->questItems[0] = fields[72].GetUInt32(); - cInfo->questItems[1] = fields[73].GetUInt32(); - cInfo->questItems[2] = fields[74].GetUInt32(); - cInfo->questItems[3] = fields[75].GetUInt32(); - cInfo->questItems[4] = fields[76].GetUInt32(); - cInfo->questItems[5] = fields[77].GetUInt32(); - cInfo->movementId = fields[78].GetUInt32(); - cInfo->RegenHealth = fields[79].GetBool(); - cInfo->equipmentId = fields[80].GetUInt32(); - cInfo->MechanicImmuneMask = fields[81].GetUInt32(); - cInfo->flags_extra = fields[82].GetUInt32(); - cInfo->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString()); + cInfo->resistance[i] = fields[47 + i -1].GetUInt16(); + + cInfo->spells[0] = fields[53].GetUInt32(); + cInfo->spells[1] = fields[54].GetUInt32(); + cInfo->spells[2] = fields[55].GetUInt32(); + cInfo->spells[3] = fields[56].GetUInt32(); + cInfo->spells[4] = fields[57].GetUInt32(); + cInfo->spells[5] = fields[58].GetUInt32(); + cInfo->spells[6] = fields[59].GetUInt32(); + cInfo->spells[7] = fields[60].GetUInt32(); + cInfo->PetSpellDataId = fields[61].GetUInt32(); + cInfo->VehicleId = fields[62].GetUInt32(); + cInfo->mingold = fields[63].GetUInt32(); + cInfo->maxgold = fields[64].GetUInt32(); + cInfo->AIName = fields[65].GetString(); + cInfo->MovementType = fields[66].GetUInt8(); + cInfo->InhabitType = fields[67].GetUInt8(); + cInfo->HoverHeight = fields[68].GetFloat(); + cInfo->ModHealth = fields[69].GetFloat(); + cInfo->ModMana = fields[70].GetFloat(); + cInfo->ModArmor = fields[71].GetFloat(); + cInfo->RacialLeader = fields[72].GetBool(); + cInfo->questItems[0] = fields[73].GetUInt32(); + cInfo->questItems[1] = fields[74].GetUInt32(); + cInfo->questItems[2] = fields[75].GetUInt32(); + cInfo->questItems[3] = fields[76].GetUInt32(); + cInfo->questItems[4] = fields[77].GetUInt32(); + cInfo->questItems[5] = fields[78].GetUInt32(); + cInfo->movementId = fields[79].GetUInt32(); + cInfo->RegenHealth = fields[80].GetBool(); + cInfo->equipmentId = fields[81].GetUInt32(); + cInfo->MechanicImmuneMask = fields[82].GetUInt32(); + cInfo->flags_extra = fields[83].GetUInt32(); + cInfo->ScriptID = sObjectMgr->GetScriptId(fields[84].GetCString()); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index 82fb409faa7..76a4eb5d943 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -60,7 +60,7 @@ public: return false; if (target) - target->GetAchievementMgr().Reset(); + target->ResetAchievements(); else AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid)); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index d5add0f0bb7..f4195620dda 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -233,7 +233,7 @@ public: SWPainTimer = 20000; AmplifyDamageTimer = 5000; Cleave_Timer = 8000; - InfernalTimer = 45000; + InfernalTimer = 40000; InfernalCleanupTimer = 47000; AxesTargetSwitchTimer = urand(7500, 20000); SunderArmorTimer = urand(5000, 10000); diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp index 84e9957a60c..fa99078cedb 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp @@ -77,7 +77,7 @@ class boss_golemagg : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - if (HealthBelowPct(10) || me->HasAura(SPELL_ENRAGE)) + if (!HealthBelowPct(10) || me->HasAura(SPELL_ENRAGE)) return; DoCast(me, SPELL_ENRAGE, true); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp index 46fb62eae7f..0aad2857a45 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp @@ -283,6 +283,12 @@ public: DoScriptText(SAY_WH_KILL, me); } + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (!_bCanResurrectCheck && damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } + void UpdateAI(const uint32 diff) { if (!UpdateVictim()) diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp index 248932ecbb6..6a9dd77433a 100644 --- a/src/server/scripts/Kalimdor/ashenvale.cpp +++ b/src/server/scripts/Kalimdor/ashenvale.cpp @@ -447,7 +447,7 @@ class npc_muglash : public CreatureScript DoScriptText(SAY_MUG_START1, creature); creature->setFaction(113); - pEscortAI->Start(true, true, player->GetGUID()); + pEscortAI->Start(true, false, player->GetGUID()); } } return true; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index 89fdcc7f725..564df34462b 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -85,8 +85,10 @@ enum BossSpells SPELL_SPIDER_FRENZY = 66128, SPELL_EXPOSE_WEAKNESS = 67720, //Passive - Triggered SPELL_SHADOW_STRIKE = 66134, - SPELL_SUBMERGE_EFFECT = 53421, - SPELL_EMERGE_EFFECT = 66947, + SPELL_SUBMERGE_EFFECT = 68394, + SPELL_EMERGE_EFFECT = 65982, + SPELL_AWAKENED = 66311, + SPELL_PERSISTENT_DIRT = 68048, SUMMON_SCARAB = NPC_SCARAB, SUMMON_FROSTSPHERE = NPC_FROST_SPHERE, @@ -96,6 +98,7 @@ enum BossSpells SPELL_FROST_SPHERE = 67539, SPELL_PERMAFROST = 66193, SPELL_PERMAFROST_VISUAL = 65882, + SPELL_PERMAFROST_MODEL = 66185, //Spike SPELL_SUMMON_SPIKE = 66169, @@ -117,12 +120,12 @@ enum SummonActions const Position SphereSpawn[6] = { - { 786.6439f, 108.2498f, 155.6701f, 0 }, - { 806.8429f, 150.5902f, 155.6701f, 0 }, - { 759.1386f, 163.9654f, 155.6701f, 0 }, - { 744.3701f, 119.5211f, 155.6701f, 0 }, - { 710.0211f, 120.8152f, 155.6701f, 0 }, - { 706.6383f, 161.5266f, 155.6701f, 0 }, + {779.8038f, 150.6580f, 158.1426f, 0}, + {736.0243f, 113.4201f, 158.0226f, 0}, + {712.5712f, 160.9948f, 158.4368f, 0}, + {701.4271f, 126.4740f, 158.0205f, 0}, + {747.9202f, 155.0920f, 158.0613f, 0}, + {769.6285f, 121.1024f, 158.0504f, 0}, }; enum MovementPoints @@ -219,7 +222,10 @@ public: //Summon Scarab Swarms neutral at random places for (int i=0; i < 10; i++) if (Creature* temp = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ())) + { temp->setFaction(31); + temp->GetMotionMaster()->MoveRandom(10); + } } void JustDied(Unit* /*killer*/) @@ -447,10 +453,9 @@ public: m_uiDeterminationTimer = urand(5*IN_MILLISECONDS, 60*IN_MILLISECONDS); DoCast(me, SPELL_ACID_MANDIBLE); me->SetInCombatWithZone(); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - me->AddThreat(target, 20000.0f); - if (!me->isInCombat()) - me->DisappearAndDie(); + if (me->isInCombat()) + if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ANUBARAK))) + Anubarak->AI()->JustSummoned(me); } void DoAction(const int32 actionId) @@ -511,14 +516,16 @@ public: void Reset() { - me->SetCorpseDelay(0); + me->SetCorpseDelay(10); m_uiSpiderFrenzyTimer = urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS); m_uiSubmergeTimer = 30*IN_MILLISECONDS; DoCast(me, SPELL_EXPOSE_WEAKNESS); DoCast(me, SPELL_SPIDER_FRENZY); + DoCast(me, SPELL_AWAKENED); me->SetInCombatWithZone(); - if (!me->isInCombat()) - me->DisappearAndDie(); + if (me->isInCombat()) + if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ANUBARAK))) + Anubarak->AI()->JustSummoned(me); } void DoAction(const int32 actionId) @@ -526,8 +533,9 @@ public: switch (actionId) { case ACTION_SHADOW_STRIKE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHADOW_STRIKE); + if (!me->HasAura(SPELL_AWAKENED)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHADOW_STRIKE); break; } } @@ -537,22 +545,25 @@ public: if (!UpdateVictim()) return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + if ((m_uiSubmergeTimer <= uiDiff) && HealthBelowPct(80)) { if (me->HasAura(SPELL_SUBMERGE_EFFECT)) { me->RemoveAurasDueToSpell(SPELL_SUBMERGE_EFFECT); DoCast(me, SPELL_EMERGE_EFFECT); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); - me->CombatStart(me->SelectNearestTarget()); + DoCast(me, SPELL_AWAKENED); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } else { if (!me->HasAura(SPELL_PERMAFROST_HELPER)) { DoCast(me, SPELL_SUBMERGE_EFFECT); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE); - me->CombatStop(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_PERSISTENT_DIRT, true); } } m_uiSubmergeTimer = 20*IN_MILLISECONDS; @@ -577,16 +588,10 @@ class mob_frost_sphere : public CreatureScript void Reset() { - _isFalling = false; me->SetReactState(REACT_PASSIVE); - //! Confirmed sniff 3.3.5.a - me->SetDisableGravity(true); - me->SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); - //! end + DoCast(SPELL_FROST_SPHERE); me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - me->SetSpeed(MOVE_RUN, 0.5f, false); me->GetMotionMaster()->MoveRandom(20.0f); - DoCast(SPELL_FROST_SPHERE); } void DamageTaken(Unit* /*who*/, uint32& damage) @@ -594,9 +599,20 @@ class mob_frost_sphere : public CreatureScript if (me->GetHealth() <= damage) { damage = 0; - if (!_isFalling) + float floorZ = me->GetMap()->GetHeight(me->GetPhaseMask(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + if (fabs(me->GetPositionZ() - floorZ) < 0.1f) { - _isFalling = true; + // we are close to the ground + me->GetMotionMaster()->MoveIdle(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE); + DoCast(SPELL_PERMAFROST_MODEL); + DoCast(SPELL_PERMAFROST); + me->SetObjectScale(2.0f); + } + else + { + // we are in air me->GetMotionMaster()->MoveIdle(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //At hit the ground @@ -615,16 +631,13 @@ class mob_frost_sphere : public CreatureScript { case POINT_FALL_GROUND: me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE); - me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); + DoCast(SPELL_PERMAFROST_MODEL); DoCast(SPELL_PERMAFROST_VISUAL); DoCast(SPELL_PERMAFROST); me->SetObjectScale(2.0f); break; } } - - private: - bool _isFalling; }; CreatureAI* GetAI(Creature* creature) const diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index 10f7150351e..87e7801566e 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -329,6 +329,8 @@ public: // used to despawn corpse immediately me->DespawnOrUnsummon(); } + + void UpdateAI(uint32 const /*diff*/) {} }; }; @@ -438,6 +440,8 @@ public: // used to despawn corpse immediately me->DespawnOrUnsummon(); } + + void UpdateAI(uint32 const /*diff*/) {} }; }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 9767126371b..af6104008ff 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -332,7 +332,8 @@ class instance_trial_of_the_crusader : public InstanceMapScript } if (tributeChest) if (Creature* tirion = instance->GetCreature(TirionGUID)) - if (GameObject* chest = tirion->SummonGameObject(tributeChest, 805.62f, 134.87f, 142.16f, 3.27f, 0, 0, 0, 0, 90000000)) + // need proper location.this one is guessed based on videos + if (GameObject* chest = tirion->SummonGameObject(tributeChest, 643.814f, 136.027f, 141.295f, 0, 0, 0, 0, 0, 90000000)) chest->SetRespawnTime(chest->GetRespawnDelay()); break; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index 37d08484f0b..0476b2cbacb 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -25,7 +25,6 @@ EndScriptData */ //Known Bugs: // - Need better implementation of Gossip and correct gossip text and option -// - Misses Dalaran Teleport at the end. #include "ScriptMgr.h" #include "ScriptedCreature.h" @@ -121,11 +120,8 @@ class npc_announcer_toc10 : public CreatureScript { npc_announcer_toc10AI(Creature* creature) : ScriptedAI(creature) { - instance = creature->GetInstanceScript(); } - InstanceScript* instance; - void Reset() { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); @@ -219,7 +215,7 @@ class npc_announcer_toc10 : public CreatureScript return true; if (GameObject* floor = GameObject::GetGameObject(*player, instanceScript->GetData64(GO_ARGENT_COLISEUM_FLOOR))) - floor->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); + floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); creature->CastSpell(creature, 69016, false); @@ -275,7 +271,7 @@ class boss_lich_king_toc : public CreatureScript void MovementInform(uint32 uiType, uint32 uiId) { - if (uiType != POINT_MOTION_TYPE) + if (uiType != POINT_MOTION_TYPE || !instance) return; switch (uiId) { @@ -337,22 +333,20 @@ class boss_lich_king_toc : public CreatureScript break; case 5080: if (GameObject* go = instance->instance->GetGameObject(instance->GetData64(GO_ARGENT_COLISEUM_FLOOR))) - go->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); + go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); me->CastSpell(me, 69016, false); - if (instance) - { - instance->SetData(TYPE_LICH_KING, DONE); - Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_ANUBARAK)); - if (!temp || !temp->isAlive()) - temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + instance->SetData(TYPE_LICH_KING, DONE); + Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_ANUBARAK)); + if (!temp || !temp->isAlive()) + temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); - instance->SetData(TYPE_EVENT, 0); - } + instance->SetData(TYPE_EVENT, 0); me->DespawnOrUnsummon(); m_uiUpdateTimer = 20000; break; } } else m_uiUpdateTimer -= uiDiff; + instance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer); } }; @@ -797,7 +791,9 @@ class npc_tirion_toc : public CreatureScript instance->SetData(TYPE_EVENT, 0); break; case 6000: - me->NearTeleportTo(AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 4.0f); + me->SummonCreature(NPC_TIRION_FORDRING, EndSpawnLoc[0].GetPositionX(), EndSpawnLoc[0].GetPositionY(), EndSpawnLoc[0].GetPositionZ()); + me->SummonCreature(NPC_ARGENT_MAGE, EndSpawnLoc[1].GetPositionX(), EndSpawnLoc[1].GetPositionY(), EndSpawnLoc[1].GetPositionZ()); + me->SummonGameObject(GO_PORTAL_TO_DALARAN, EndSpawnLoc[2].GetPositionX(), EndSpawnLoc[2].GetPositionY(), EndSpawnLoc[2].GetPositionZ(), 5, 0, 0, 0, 0, 0); m_uiUpdateTimer = 20000; instance->SetData(TYPE_EVENT, 6005); break; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h index ba230551b24..58cbd727963 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h @@ -129,6 +129,13 @@ const Position AnubarakLoc[]= {740.184509f, 193.443390f, 142.117584f, 0}, // 4 - Nerub Spawn }; +const Position EndSpawnLoc[]= +{ + {648.9167f, 131.0208f, 141.6161f, 0}, // 0 - Highlord Tirion Fordring + {649.1614f, 142.0399f, 141.3057f ,0}, // 1 - Argent Mage + {644.6250f, 149.2743f, 140.6015f ,0}, // 2 - Portal to Dalaran +}; + enum euiWorldStates { UPDATE_STATE_UI_SHOW = 4390, @@ -163,6 +170,7 @@ enum eCreature NPC_BARRENT = 34816, NPC_TIRION = 34996, NPC_TIRION_FORDRING = 36095, + NPC_ARGENT_MAGE = 36097, NPC_FIZZLEBANG = 35458, NPC_GARROSH = 34995, NPC_VARIAN = 34990, @@ -245,6 +253,7 @@ enum eGameObject GO_MAIN_GATE_DOOR = 195647, GO_EAST_PORTCULLIS = 195648, GO_WEB_DOOR = 195485, + GO_PORTAL_TO_DALARAN = 195682, }; enum eAchievementData diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index 57d99908bfb..0d6e779c006 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -228,13 +228,13 @@ class boss_ick : public CreatureScript case EVENT_TOXIC_WASTE: if (Creature* krick = GetKrick()) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - krick->CastSpell(target, SPELL_TOXIC_WASTE, false); + krick->CastSpell(target, SPELL_TOXIC_WASTE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE); events.ScheduleEvent(EVENT_TOXIC_WASTE, urand(7000, 10000)); break; case EVENT_SHADOW_BOLT: if (Creature* krick = GetKrick()) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - krick->CastSpell(target, SPELL_SHADOW_BOLT, false); + krick->CastSpell(target, SPELL_SHADOW_BOLT, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE); events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000); return; case EVENT_MIGHTY_KICK: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index a9ba0baa86f..7f6448382ba 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -23,6 +23,7 @@ #include "Spell.h" #include "icecrown_citadel.h" #include "Vehicle.h" +#include "GridNotifiers.h" enum ScriptTexts { @@ -185,12 +186,15 @@ class AbominationDespawner if (Vehicle* veh = summon->GetVehicleKit()) veh->RemoveAllPassengers(); // also despawns the vehicle + // Found unit is Mutated Abomination, remove it return true; } + // Found unit is not Mutated Abomintaion, leave it return false; } + // No unit found, remove from SummonList return true; } @@ -198,6 +202,19 @@ class AbominationDespawner Unit* _owner; }; +struct RotfaceHeightCheck +{ + RotfaceHeightCheck(Creature* rotface) : _rotface(rotface) { } + + bool operator()(Creature* stalker) const + { + return stalker->GetPositionZ() < _rotface->GetPositionZ() + 5.0f; + } + +private: + Creature* _rotface; +}; + class boss_professor_putricide : public CreatureScript { public: @@ -246,7 +263,7 @@ class boss_professor_putricide : public CreatureScript events.Reset(); events.ScheduleEvent(EVENT_BERSERK, 600000); events.ScheduleEvent(EVENT_SLIME_PUDDLE, 10000); - events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, urand(25000, 30000)); + events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, urand(30000, 35000)); if (IsHeroic()) events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 20000); @@ -295,18 +312,16 @@ class boss_professor_putricide : public CreatureScript // no possible aura seen in sniff adding the aurastate summon->ModifyAuraState(AURA_STATE_UNKNOWN22, true); summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true); - summon->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, summon, false); summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); summon->SetReactState(REACT_PASSIVE); - return; + break; case NPC_VOLATILE_OOZE: // no possible aura seen in sniff adding the aurastate summon->ModifyAuraState(AURA_STATE_UNKNOWN19, true); summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true); - summon->CastSpell(summon, SPELL_VOLATILE_OOZE_ADHESIVE, false); summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); summon->SetReactState(REACT_PASSIVE); - return; + break; case NPC_CHOKING_GAS_BOMB: summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true); summon->CastSpell(summon, SPELL_CHOKING_GAS_EXPLOSION_TRIGGER, true); @@ -428,7 +443,8 @@ class boss_professor_putricide : public CreatureScript if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) { std::list<Creature*> list; - GetCreatureListWithEntryInGrid(list, rotface, NPC_PUDDLE_STALKER, 36.0f); + GetCreatureListWithEntryInGrid(list, rotface, NPC_PUDDLE_STALKER, 50.0f); + list.remove_if(RotfaceHeightCheck(rotface)); if (list.size() > 4) { list.sort(Trinity::ObjectDistanceOrderPred(rotface)); @@ -510,7 +526,6 @@ class boss_professor_putricide : public CreatureScript SetPhase(PHASE_COMBAT_3); events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 25000); events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT); - summons.remove_if(AbominationDespawner(me)); break; default: break; @@ -643,7 +658,7 @@ class boss_professor_putricide : public CreatureScript case EVENT_UNBOUND_PLAGUE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) { - me->CastCustomSpell(SPELL_UNBOUND_PLAGUE, SPELLVALUE_BASE_POINT0, 775, target); + DoCast(target, SPELL_UNBOUND_PLAGUE); DoCast(target, SPELL_UNBOUND_PLAGUE_SEARCHER); } events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 90000); @@ -668,6 +683,7 @@ class boss_professor_putricide : public CreatureScript me->SetFacingToObject(face); me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); Talk(SAY_TRANSFORM_2); + summons.remove_if(AbominationDespawner(me)); events.ScheduleEvent(EVENT_RESUME_ATTACK, 8500, 0, PHASE_COMBAT_3); break; default: @@ -702,57 +718,78 @@ class boss_professor_putricide : public CreatureScript } }; -class npc_volatile_ooze : public CreatureScript +class npc_putricide_oozeAI : public ScriptedAI { public: - npc_volatile_ooze() : CreatureScript("npc_volatile_ooze") { } + npc_putricide_oozeAI(Creature* creature, uint32 hitTargetSpellId) : ScriptedAI(creature), + _newTargetSelectTimer(0), _hitTargetSpellId(hitTargetSpellId) + { + } - struct npc_putricide_oozeAI : public ScriptedAI + void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) { - npc_putricide_oozeAI(Creature* creature) : ScriptedAI(creature) - { - _newTargetSelectTimer = 0; - } + if (!_newTargetSelectTimer && spell->Id == sSpellMgr->GetSpellIdForDifficulty(_hitTargetSpellId, me)) + _newTargetSelectTimer = 1000; + } - void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) - { - if (!_newTargetSelectTimer && spell->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_OOZE_ERUPTION, me)) - _newTargetSelectTimer = 1000; - } + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + if (spell->Id == SPELL_TEAR_GAS_CREATURE) + _newTargetSelectTimer = 1000; + } - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim() && !_newTargetSelectTimer) + return; + + if (!_newTargetSelectTimer && !me->IsNonMeleeSpellCasted(false, false, true, false, true)) + _newTargetSelectTimer = 1000; + + DoMeleeAttackIfReady(); + + if (!_newTargetSelectTimer) + return; + + if (me->HasAura(SPELL_TEAR_GAS_CREATURE)) + return; + + if (_newTargetSelectTimer <= diff) { - if (spell->Id == SPELL_TEAR_GAS_CREATURE) - _newTargetSelectTimer = 1000; + _newTargetSelectTimer = 0; + CastMainSpell(); } + else + _newTargetSelectTimer -= diff; + } - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim() && !_newTargetSelectTimer) - return; + virtual void CastMainSpell() = 0; - if (!_newTargetSelectTimer) - return; + private: + uint32 _hitTargetSpellId; + uint32 _newTargetSelectTimer; +}; - if (me->HasAura(SPELL_TEAR_GAS_CREATURE)) - return; +class npc_volatile_ooze : public CreatureScript +{ + public: + npc_volatile_ooze() : CreatureScript("npc_volatile_ooze") { } - if (_newTargetSelectTimer <= diff) - { - _newTargetSelectTimer = 0; - me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false); - } - else - _newTargetSelectTimer -= diff; + struct npc_volatile_oozeAI : public npc_putricide_oozeAI + { + npc_volatile_oozeAI(Creature* creature) : npc_putricide_oozeAI(creature, SPELL_OOZE_ERUPTION) + { } - private: - uint32 _newTargetSelectTimer; + void CastMainSpell() + { + me->CastSpell(me, SPELL_VOLATILE_OOZE_ADHESIVE, false); + } }; CreatureAI* GetAI(Creature* creature) const { - return GetIcecrownCitadelAI<npc_putricide_oozeAI>(creature); + return GetIcecrownCitadelAI<npc_volatile_oozeAI>(creature); } }; @@ -761,45 +798,16 @@ class npc_gas_cloud : public CreatureScript public: npc_gas_cloud() : CreatureScript("npc_gas_cloud") { } - struct npc_gas_cloudAI : public ScriptedAI + struct npc_gas_cloudAI : public npc_putricide_oozeAI { - npc_gas_cloudAI(Creature* creature) : ScriptedAI(creature) + npc_gas_cloudAI(Creature* creature) : npc_putricide_oozeAI(creature, SPELL_EXPUNGED_GAS) { _newTargetSelectTimer = 0; } - void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) - { - if (!_newTargetSelectTimer && spell->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_EXPUNGED_GAS, me)) - _newTargetSelectTimer = 1000; - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + void CastMainSpell() { - if (spell->Id == SPELL_TEAR_GAS_CREATURE) - _newTargetSelectTimer = 1000; - } - - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim() && !_newTargetSelectTimer) - return; - - DoMeleeAttackIfReady(); - - if (!_newTargetSelectTimer) - return; - - if (me->HasAura(SPELL_TEAR_GAS_CREATURE)) - return; - - if (_newTargetSelectTimer <= diff) - { - _newTargetSelectTimer = 0; - me->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, me, false); - } - else - _newTargetSelectTimer -= diff; + me->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, me, false); } private: @@ -900,23 +908,12 @@ class spell_putricide_ooze_channel : public SpellScriptLoader GetCaster()->AddThreat(GetHitUnit(), 500000000.0f); // value seen in sniff } - // temporary, until SelectTarget are not called on empty lists - void CheckTarget() - { - if (_target) - return; - - FinishCast(SPELL_FAILED_NO_VALID_TARGETS); - GetCaster()->ToCreature()->DespawnOrUnsummon(1); // despawn next update - } - void Register() { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack); - OnCast += SpellCastFn(spell_putricide_ooze_channel_SpellScript::CheckTarget); } WorldObject* _target; @@ -1125,6 +1122,22 @@ class spell_putricide_unbound_plague : public SpellScriptLoader return true; } + void FilterTargets(std::list<WorldObject*>& targets) + { + if (AuraEffect const* eff = GetCaster()->GetAuraEffect(SPELL_UNBOUND_PLAGUE_SEARCHER, EFFECT_0)) + { + if (eff->GetTickNumber() < 2) + { + targets.clear(); + return; + } + } + + + targets.remove_if(Trinity::UnitAuraCheck(true, sSpellMgr->GetSpellIdForDifficulty(SPELL_UNBOUND_PLAGUE, GetCaster()))); + Trinity::Containers::RandomResizeList(targets, 1); + } + void HandleScript(SpellEffIndex /*effIndex*/) { if (!GetHitUnit()) @@ -1159,6 +1172,7 @@ class spell_putricide_unbound_plague : public SpellScriptLoader void Register() { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_unbound_plague_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); OnEffectHitTarget += SpellEffectFn(spell_putricide_unbound_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index a8657925131..ba1a0614cdf 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -2112,7 +2112,7 @@ class spell_the_lich_king_necrotic_plague : public SpellScriptLoader CustomSpellValues values; //values.AddSpellMod(SPELLVALUE_AURA_STACK, 2); values.AddSpellMod(SPELLVALUE_MAX_TARGETS, 1); - GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID()); + GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, TRIGGERED_FULL_MASK, NULL, NULL, GetCasterGUID()); if (Unit* caster = GetCaster()) caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true); } @@ -2204,7 +2204,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader CustomSpellValues values; values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount()); - GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID()); + GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, TRIGGERED_FULL_MASK, NULL, NULL, GetCasterGUID()); if (Unit* caster = GetCaster()) caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true); } @@ -2223,7 +2223,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader CustomSpellValues values; values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount()); values.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1) - GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID()); + GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, TRIGGERED_FULL_MASK, NULL, NULL, GetCasterGUID()); if (Unit* caster = GetCaster()) caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true); diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp index 708ed600933..76237fe1890 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp @@ -113,6 +113,13 @@ enum EmeraldDrake SPELL_EMERALD_DREAM_FUNNEL = 50344 //(60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels. }; +enum EregosData +{ + DATA_RUBY_VOID = 0, // http://www.wowhead.com/achievement=2044 + DATA_EMERALD_VOID = 1, // http://www.wowhead.com/achievement=2045 + DATA_AMBER_VOID = 2 // http://www.wowhead.com/achievement=2046 +}; + class boss_eregos : public CreatureScript { public: @@ -126,12 +133,15 @@ public: struct boss_eregosAI : public BossAI { boss_eregosAI(Creature* creature) : BossAI(creature, DATA_EREGOS_EVENT) { } - + void Reset() { _Reset(); + _phase = PHASE_NORMAL; - phase = PHASE_NORMAL; + _rubyVoid = true; + _emeraldVoid = true; + _amberVoid = true; DoAction(ACTION_SET_NORMAL_EVENTS); } @@ -141,6 +151,31 @@ public: _EnterCombat(); Talk(SAY_AGGRO); + /* Checks for present drakes vehicles from each type and deactivate achievement that corresponds to each found + The checks are so big in case some party try weird things like pulling boss down or hiding out of check range, the only thing player need is to get the boss kill credit after the check /even if he or his drake die/ + Drakes mechanic would despawn all after unmount and also drakes should be auto mounted after item use, item use after Eregos is engaged leads to his despawn - based on retail data. */ + if (me->FindNearestCreature(NPC_RUBY_DRAKE_VEHICLE, 500.0f, true)) + _rubyVoid = false; + if (me->FindNearestCreature(NPC_EMERALD_DRAKE_VEHICLE, 500.0f, true)) + _emeraldVoid = false; + if (me->FindNearestCreature(NPC_AMBER_DRAKE_VEHICLE, 500.0f, true)) + _amberVoid = false; + } + + uint32 GetData(uint32 type) + { + switch (type) + { + case DATA_RUBY_VOID: + return _rubyVoid; + case DATA_EMERALD_VOID: + return _emeraldVoid; + case DATA_AMBER_VOID: + return _amberVoid; + default: + break; + } + return 0; } void DoAction(const int32 action) @@ -180,11 +215,11 @@ public: if (!me->GetMap()->IsHeroic()) return; - if ( (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f && phase < PHASE_FIRST_PLANAR) - || (me->GetHealthPct() < 20.0f && phase < PHASE_SECOND_PLANAR) ) + if ( (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f && _phase < PHASE_FIRST_PLANAR) + || (me->GetHealthPct() < 20.0f && _phase < PHASE_SECOND_PLANAR) ) { events.Reset(); - phase = (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f) ? PHASE_FIRST_PLANAR : PHASE_SECOND_PLANAR; + _phase = (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f) ? PHASE_FIRST_PLANAR : PHASE_SECOND_PLANAR; DoCast(SPELL_PLANAR_SHIFT); @@ -241,8 +276,11 @@ public: _JustDied(); } - private: - uint8 phase; + private: + uint8 _phase; + bool _rubyVoid; + bool _emeraldVoid; + bool _amberVoid; }; }; @@ -274,8 +312,25 @@ class spell_eregos_planar_shift : public SpellScriptLoader } }; -void AddSC_boss_eregos() +class achievement_gen_eregos_void : public AchievementCriteriaScript { + public: + achievement_gen_eregos_void(char const* name, uint32 data) : AchievementCriteriaScript(name), _data(data) { } + + bool OnCheck(Player* /*player*/, Unit* target) + { + return target && target->GetAI()->GetData(_data); + } + + private: + uint32 _data; +}; + + void AddSC_boss_eregos() + { new boss_eregos(); new spell_eregos_planar_shift(); -} + new achievement_gen_eregos_void("achievement_ruby_void", DATA_RUBY_VOID); + new achievement_gen_eregos_void("achievement_emerald_void", DATA_EMERALD_VOID); + new achievement_gen_eregos_void("achievement_amber_void", DATA_AMBER_VOID); + } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 7ee67060f97..dcd3a3a91f5 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -1328,7 +1328,7 @@ class spell_algalon_supermassive_fail : public SpellScriptLoader if (!GetHitPlayer()) return; - GetHitPlayer()->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true); + GetHitPlayer()->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT, GetSpellInfo()->Id, true); } void Register() diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index 48667053373..aaa95631792 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -56,13 +56,16 @@ enum Events EVENT_DARK_SMASH, EVENT_DREADFUL_ROAR, EVENT_WOE_STRIKE, - EVENT_SHADOW_AXE + EVENT_SHADOW_AXE, + EVENT_JUST_TRANSFORMED, + EVENT_SUMMON_BANSHEE }; enum Phases { PHASE_HUMAN = 1, PHASE_UNDEAD, + PHASE_EVENT }; enum Spells @@ -83,7 +86,7 @@ enum Spells SPELL_WOE_STRIKE = 42730, ENTRY_THROW_TARGET = 23996, - SPELL_SHADOW_AXE_SUMMON = 42749 + SPELL_SHADOW_AXE_SUMMON = 42748 }; class boss_ingvar_the_plunderer : public CreatureScript @@ -107,9 +110,6 @@ public: InstanceScript* instance; bool bIsUndead; - bool bEventInProgress; - - uint32 uiSpawnResTimer; void Reset() { @@ -117,7 +117,6 @@ public: me->UpdateEntry(MOB_INGVAR_HUMAN); bIsUndead = false; - bEventInProgress = false; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); me->SetStandState(UNIT_STAND_STATE_STAND); @@ -130,13 +129,6 @@ public: events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN); events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN); - events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD); - events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD); - events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD); - events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); - - uiSpawnResTimer = 3000; - if (instance) instance->SetData(DATA_INGVAR_EVENT, NOT_STARTED); } @@ -156,37 +148,34 @@ public: me->SetStandState(UNIT_STAND_STATE_DEAD); // visuel hack end - bEventInProgress = true; - bIsUndead = true; - events.SetPhase(PHASE_UNDEAD); + events.SetPhase(PHASE_EVENT); + events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT); DoScriptText(YELL_DEAD_1, me); } - if (bEventInProgress) - { + if (events.GetPhaseMask() & (1 << PHASE_EVENT)) damage = 0; - } } void StartZombiePhase() { bIsUndead = true; - bEventInProgress = false; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->UpdateEntry(MOB_INGVAR_UNDEAD); - me->SetInCombatWith(me->getVictim()); - me->GetMotionMaster()->MoveChase(me->getVictim()); + events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT); DoScriptText(YELL_AGGRO_2, me); } void EnterCombat(Unit* /*who*/) { - DoScriptText(YELL_AGGRO_1, me); + if (!bIsUndead) + DoScriptText(YELL_AGGRO_1, me); if (instance) instance->SetData(DATA_INGVAR_EVENT, IN_PROGRESS); + + me->SetInCombatWithZone(); } void JustDied(Unit* /*killer*/) @@ -201,6 +190,15 @@ public: } } + void ScheduleSecondPhase() + { + events.SetPhase(PHASE_UNDEAD); + events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,18)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); + } + void KilledUnit(Unit* /*victim*/) { if (bIsUndead) @@ -211,24 +209,9 @@ public: void UpdateAI(const uint32 diff) { - if (!UpdateVictim()) + if (!UpdateVictim() && !(events.GetPhaseMask() & (1 << PHASE_EVENT))) return; - if (bEventInProgress) - { - if (uiSpawnResTimer) - { - if (uiSpawnResTimer <= diff) - { - DoCast(me, SPELL_SUMMON_BANSHEE); // Summons directly on caster position - // DoCast(me, SPELL_SCOURG_RESURRECTION, true); // Not needed ? - uiSpawnResTimer = 0; - } else uiSpawnResTimer -= diff; - } - - return; - } - events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) @@ -245,24 +228,33 @@ public: break; case EVENT_STAGGERING_ROAR: DoCast(me, SPELL_STAGGERING_ROAR); - events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_HUMAN); + events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,22)*IN_MILLISECONDS, 0, PHASE_HUMAN); break; case EVENT_ENRAGE: DoCast(me, SPELL_ENRAGE); events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN); break; case EVENT_SMASH: - DoCastVictim(SPELL_SMASH); - events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN); + DoCastAOE(SPELL_SMASH); + events.ScheduleEvent(EVENT_SMASH, urand(12,16)*IN_MILLISECONDS, 0, PHASE_HUMAN); break; + case EVENT_JUST_TRANSFORMED: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetInCombatWithZone(); + me->GetMotionMaster()->MoveChase(me->getVictim()); + ScheduleSecondPhase(); + return; + case EVENT_SUMMON_BANSHEE: + DoCast(me, SPELL_SUMMON_BANSHEE); + return; // PHASE TWO case EVENT_DARK_SMASH: DoCastVictim(SPELL_DARK_SMASH); - events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_DARK_SMASH, urand(12,16)*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; case EVENT_DREADFUL_ROAR: DoCast(me, SPELL_DREADFUL_ROAR); - events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; case EVENT_WOE_STRIKE: DoCastVictim(SPELL_WOE_STRIKE); @@ -271,8 +263,7 @@ public: case EVENT_SHADOW_AXE: if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1)) { - me->SummonCreature(ENTRY_THROW_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2000); - DoCast(me, SPELL_SHADOW_AXE_SUMMON); + DoCast(target, SPELL_SHADOW_AXE_SUMMON); } events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); break; @@ -411,7 +402,8 @@ public: enum eShadowAxe { SPELL_SHADOW_AXE_DAMAGE = 42750, - H_SPELL_SHADOW_AXE_DAMAGE = 59719 + H_SPELL_SHADOW_AXE_DAMAGE = 59719, + POINT_TARGET = 28 }; class mob_ingvar_throw_dummy : public CreatureScript @@ -430,32 +422,34 @@ public: { } - uint32 uiDespawnTimer; - void Reset() { - Unit* target = me->FindNearestCreature(ENTRY_THROW_TARGET, 50); - if (target) + if (Creature* target = me->FindNearestCreature(ENTRY_THROW_TARGET, 50.0f)) { - DoCast(me, SPELL_SHADOW_AXE_DAMAGE); float x, y, z; target->GetPosition(x, y, z); - me->GetMotionMaster()->MovePoint(0, x, y, z); + me->GetMotionMaster()->MoveCharge(x, y, z, 42.0f, POINT_TARGET); + target->DisappearAndDie(); + } + else + { + me->DisappearAndDie(); } - uiDespawnTimer = 7000; } - void AttackStart(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - void EnterCombat(Unit* /*who*/) {} - void UpdateAI(const uint32 diff) + void MovementInform(uint32 type, uint32 id) { - if (uiDespawnTimer <= diff) + if (type == EFFECT_MOTION_TYPE && id == POINT_TARGET) { - me->DealDamage(me, me->GetHealth()); - me->RemoveCorpse(); - uiDespawnTimer = 0; - } else uiDespawnTimer -= diff; + DoCast(me, SPELL_SHADOW_AXE_DAMAGE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + if (TempSummon* summon = me->ToTempSummon()) + { + summon->UnSummon(10000); + } + else + me->DisappearAndDie(); + } } }; }; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp index f53020a72c4..e718942d091 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp @@ -43,6 +43,9 @@ enum KelsethEncounter NPC_FROSTTOMB = 23965, NPC_SKELETON = 23970, + NPC_RUNEMAGE = 23960, + NPC_STRATEGIST = 23956, + SAY_START_COMBAT = 1, SAY_SUMMON_SKELETONS, SAY_FROST_TOMB, @@ -118,14 +121,12 @@ public: struct boss_kelesethAI : public BossAI { - boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCEKELESETH_EVENT) - { - creature->SetReactState(REACT_DEFENSIVE); - } + boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCEKELESETH_EVENT){} void Reset() { - instance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED); + if (instance) + instance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED); events.Reset(); events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2,3)*IN_MILLISECONDS); @@ -137,16 +138,43 @@ public: onTheRocks = true; } - void EnterCombat(Unit* /*who*/) + void EnterCombat(Unit* who) { me->SetInCombatWithZone(); - instance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS); + if (instance) + instance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS); Talk(SAY_START_COMBAT); + + if (!who) + return; + + std::list<Creature*> runemages; + me->GetCreatureListWithEntryInGrid(runemages, NPC_RUNEMAGE, 60.0f); + if (!runemages.empty()) + { + for (std::list<Creature*>::iterator itr = runemages.begin(); itr != runemages.end(); ++itr) + { + if ((*itr)->isAlive() && (*itr)->IsWithinLOSInMap(me)) + (*itr)->AI()->AttackStart(who); + } + } + + std::list<Creature*> strategists; + me->GetCreatureListWithEntryInGrid(strategists, NPC_STRATEGIST, 60.0f); + if (!strategists.empty()) + { + for (std::list<Creature*>::iterator itr = strategists.begin(); itr != strategists.end(); ++itr) + { + if ((*itr)->isAlive() && (*itr)->IsWithinLOSInMap(me)) + (*itr)->AI()->AttackStart(who); + } + } } void JustDied(Unit* /*killer*/) { - instance->SetData(DATA_PRINCEKELESETH_EVENT, DONE); + if (instance) + instance->SetData(DATA_PRINCEKELESETH_EVENT, DONE); summons.DespawnAll(); Talk(SAY_DEATH); } @@ -165,10 +193,20 @@ public: return 0; } - void ExecuteEvent(uint32 const eventId) + void UpdateAI(uint32 const diff) { - switch (eventId) + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { + switch (eventId) + { case EVENT_SUMMON_SKELETONS: Talk(SAY_SUMMON_SKELETONS); SummonSkeletons(); @@ -189,7 +227,10 @@ public: } events.ScheduleEvent(EVENT_FROST_TOMB, urand(14,19)*IN_MILLISECONDS); break; + } } + + DoMeleeAttackIfReady(); } void SummonSkeletons() @@ -222,7 +263,6 @@ public: events.Reset(); events.ScheduleEvent(EVENT_DECREPIFY, urand(4,6)*IN_MILLISECONDS); - DoCast(SPELL_BONE_ARMOR); } void DamageTaken(Unit* /*done_by*/, uint32 &damage) @@ -275,6 +315,13 @@ public: break; case EVENT_SHADOW_FISSURE: DoCast(me, SPELL_SHADOW_FISSURE, true); + if (TempSummon* temp = me->ToTempSummon()) + { + if (Unit* summoner = temp->GetSummoner()) + { + DoCast(summoner, SPELL_BONE_ARMOR); + } + } me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); me->GetMotionMaster()->MoveChase(me->getVictim()); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp index be8d60fbeb9..7c977250e79 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp @@ -47,6 +47,7 @@ enum eEnums SPELL_CHARGE = 43651, SPELL_STONE_STRIKE = 48583, SPELL_SUMMON_SKARVALD_GHOST = 48613, + SPELL_ENRAGE = 48193, MOB_SKARVALD_GHOST = 27390, //Spells of Dalronn and his Ghost MOB_DALRONN_THE_CONTROLLER = 24201, @@ -58,6 +59,20 @@ enum eEnums MOB_DALRONN_GHOST = 27389 }; +class SkarvaldChargePredicate +{ + public: + SkarvaldChargePredicate(Unit* unit) : me(unit) {} + + bool operator() (WorldObject* object) const + { + return object->GetDistance2d(me) >= 5.0f && object->GetDistance2d(me) <= 30.0f; + } + + private: + Unit* me; +}; + class boss_skarvald_the_constructor : public CreatureScript { public: @@ -83,6 +98,7 @@ public: uint32 Response_Timer; uint32 Check_Timer; bool Dalronn_isDead; + bool Enraged; void Reset() { @@ -90,6 +106,7 @@ public: StoneStrike_Timer = 10000; Dalronn_isDead = false; Check_Timer = 5000; + Enraged = false; ghost = (me->GetEntry() == MOB_SKARVALD_GHOST); if (!ghost && instance) @@ -116,6 +133,15 @@ public: } } + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (!Enraged && !ghost && me->HealthBelowPctDamaged(15, damage)) + { + Enraged = true; + DoCast(me, SPELL_ENRAGE); + } + } + void JustDied(Unit* killer) { if (!ghost && instance) @@ -194,7 +220,7 @@ public: if (Charge_Timer <= diff) { - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_CHARGE); + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, SkarvaldChargePredicate(me)), SPELL_CHARGE); Charge_Timer = 5000+rand()%5000; } else Charge_Timer -= diff; @@ -204,7 +230,8 @@ public: StoneStrike_Timer = 5000+rand()%5000; } else StoneStrike_Timer -= diff; - DoMeleeAttackIfReady(); + if (!me->HasUnitState(UNIT_STATE_CASTING)) + DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp index 2d53e7062eb..35bf7ee0b10 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp @@ -18,6 +18,8 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "utgarde_keep.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" uint32 entry_search[3] = { @@ -164,7 +166,82 @@ public: }; }; +enum TickingTimeBomb +{ + SPELL_TICKING_TIME_BOMB_EXPLODE = 59687 +}; +class spell_ticking_time_bomb : public SpellScriptLoader +{ + public: + spell_ticking_time_bomb() : SpellScriptLoader("spell_ticking_time_bomb") { } + + class spell_ticking_time_bomb_AuraScript : public AuraScript + { + PrepareAuraScript(spell_ticking_time_bomb_AuraScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + return (bool) sSpellMgr->GetSpellInfo(SPELL_TICKING_TIME_BOMB_EXPLODE); + } + + void HandleOnEffectRemove(AuraEffect const* /* aurEff */, AuraEffectHandleModes /* mode */) + { + if (GetCaster() == GetTarget()) + { + GetTarget()->CastSpell(GetTarget(), SPELL_TICKING_TIME_BOMB_EXPLODE, true); + } + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_ticking_time_bomb_AuraScript::HandleOnEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_ticking_time_bomb_AuraScript(); + } +}; + +enum Fixate +{ + SPELL_FIXATE_TRIGGER = 40415 +}; +class spell_fixate : public SpellScriptLoader +{ + public: + spell_fixate() : SpellScriptLoader("spell_fixate") { } + + class spell_fixate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_fixate_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + return (bool) sSpellMgr->GetSpellInfo(SPELL_FIXATE_TRIGGER); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + // The unit has to cast the taunt on hisself, but we need the original caster for SPELL_AURA_MOD_TAUNT + GetCaster()->CastSpell(GetCaster(), SPELL_FIXATE_TRIGGER, true, 0, 0, GetHitUnit()->GetGUID()); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_fixate_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_fixate_SpellScript(); + } +}; void AddSC_utgarde_keep() { new npc_dragonflayer_forge_master(); + new spell_ticking_time_bomb(); + new spell_fixate(); } diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index 122d051f1dd..870ea893b78 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -782,10 +782,13 @@ struct violet_hold_trashAI : public npc_escortAI void JustDied(Unit* /*killer*/) { - if (Creature* portal = Unit::GetCreature((*me), instance->GetData64(DATA_TELEPORTATION_PORTAL))) - CAST_AI(npc_teleportation_portal_vh::npc_teleportation_portalAI, portal->AI())->SummonedMobDied(me); if (instance) + { + if (Creature* portal = Unit::GetCreature((*me), instance->GetData64(DATA_TELEPORTATION_PORTAL))) + CAST_AI(npc_teleportation_portal_vh::npc_teleportation_portalAI, portal->AI())->SummonedMobDied(me); + instance->SetData(DATA_NPC_PRESENCE_AT_DOOR_REMOVE, 1); + } } void CreatureStartAttackDoor() diff --git a/src/server/scripts/Northrend/borean_tundra.cpp b/src/server/scripts/Northrend/borean_tundra.cpp index 9b207c257fc..f4139f2ffc2 100644 --- a/src/server/scripts/Northrend/borean_tundra.cpp +++ b/src/server/scripts/Northrend/borean_tundra.cpp @@ -1667,7 +1667,6 @@ public: /*###### ## npc_imprisoned_beryl_sorcerer ######*/ - enum eImprisionedBerylSorcerer { SPELL_NEURAL_NEEDLE = 45634, @@ -1692,103 +1691,81 @@ public: { npc_imprisoned_beryl_sorcererAI(Creature* creature) : ScriptedAI(creature) {} - uint64 CasterGUID; - - uint32 uiStep; - uint32 uiPhase; + uint32 rebuff; void Reset() { - uiStep = 1; - uiPhase = 0; - CasterGUID = 0; + if (me->GetReactState() != REACT_PASSIVE) + { + me->SetReactState(REACT_PASSIVE); + } + + rebuff = 0; + } + + void UpdateAI(const uint32 diff) + { + UpdateVictim(); + + if (rebuff <= diff) + { + if (!me->HasAura(SPELL_COSMETIC_ENSLAVE_CHAINS_SELF)) + { + DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF); + } + rebuff = 180000; + } + else + rebuff -= diff; + + DoMeleeAttackIfReady(); } void EnterCombat(Unit* /*who*/) { } - void SpellHit(Unit* unit, const SpellInfo* pSpell) + void SpellHit(Unit* unit, const SpellInfo* spell) { - if (pSpell->Id == SPELL_NEURAL_NEEDLE && unit->GetTypeId() == TYPEID_PLAYER) + if (spell->Id == SPELL_NEURAL_NEEDLE && unit->GetTypeId() == TYPEID_PLAYER) { - ++uiPhase; - CasterGUID = unit->GetGUID(); + if (Player* player = unit->ToPlayer()) + { + GotStinged(player->GetGUID()); + } } } - void UpdateAI(const uint32 uiDiff) + void GotStinged(uint64 casterGUID) { - ScriptedAI::UpdateAI(uiDiff); - - if (!me->HasAura(SPELL_COSMETIC_ENSLAVE_CHAINS_SELF)) - DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF); - - if (me->GetReactState() != REACT_PASSIVE) - me->SetReactState(REACT_PASSIVE); - - switch (uiPhase) + if(Player* caster = Player::GetPlayer(*me, casterGUID)) { + uint32 step = caster->GetAuraCount(SPELL_NEURAL_NEEDLE) + 1; + switch (step) + { case 1: - if (uiStep == 1) - { - DoScriptText(SAY_IMPRISIONED_BERYL_1, me); - uiStep = 2; - } + DoScriptText(SAY_IMPRISIONED_BERYL_1, me); break; - case 2: - if (uiStep == 2) - { - DoScriptText(SAY_IMPRISIONED_BERYL_2, me); - uiStep = 3; - } + DoScriptText(SAY_IMPRISIONED_BERYL_2, me, caster); break; - case 3: - if (uiStep == 3) - { - DoScriptText(SAY_IMPRISIONED_BERYL_3, me); - uiStep = 4; - } + DoScriptText(SAY_IMPRISIONED_BERYL_3, me); break; - case 4: - if (uiStep == 4) - { - DoScriptText(SAY_IMPRISIONED_BERYL_4, me); - uiStep = 5; - } + DoScriptText(SAY_IMPRISIONED_BERYL_4, me); break; - case 5: - if (uiStep == 5) - { - if (Player* pCaster = Unit::GetPlayer(*me, CasterGUID)) - { - DoScriptText(SAY_IMPRISIONED_BERYL_5, me); - pCaster->KilledMonsterCredit(25478, 0); - uiStep = 6; - } - } + DoScriptText(SAY_IMPRISIONED_BERYL_5, me); break; - case 6: - if (uiStep == 6) - { - DoScriptText(SAY_IMPRISIONED_BERYL_6, me); - uiStep = 7; - } + DoScriptText(SAY_IMPRISIONED_BERYL_6, me, caster); break; - case 7: - if (uiStep == 7) - { - DoScriptText(SAY_IMPRISIONED_BERYL_7, me); - uiStep = 1; - uiPhase = 0; - } + DoScriptText(SAY_IMPRISIONED_BERYL_7, me); + caster->KilledMonsterCredit(25478, 0); break; + } } } }; diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp index 1f1d24453ee..a26ee4e9270 100644 --- a/src/server/scripts/Northrend/dragonblight.cpp +++ b/src/server/scripts/Northrend/dragonblight.cpp @@ -190,7 +190,7 @@ class npc_wyrmrest_defender : public CreatureScript npc_wyrmrest_defender() : CreatureScript("npc_wyrmrest_defender") { } bool OnGossipHello(Player* player, Creature* creature) - { + { if (player->GetQuestStatus(QUEST_DEFENDING_WYRMREST_TEMPLE) == QUEST_STATUS_INCOMPLETE) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); diff --git a/src/server/scripts/Northrend/storm_peaks.cpp b/src/server/scripts/Northrend/storm_peaks.cpp index 60c289dc8de..976a6e5dba5 100644 --- a/src/server/scripts/Northrend/storm_peaks.cpp +++ b/src/server/scripts/Northrend/storm_peaks.cpp @@ -20,6 +20,7 @@ #include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "Vehicle.h" +#include "CombatAI.h" /*###### ## npc_agnetta_tyrsdottar @@ -131,132 +132,6 @@ public: } }; -/*###### -## npc_thorim -######*/ - -#define GOSSIP_HN "Thorim?" -#define GOSSIP_SN1 "Can you tell me what became of Sif?" -#define GOSSIP_SN2 "He did more than that, Thorim. He controls Ulduar now." -#define GOSSIP_SN3 "It needn't end this way." - -enum eThorim -{ - QUEST_SIBLING_RIVALRY = 13064, - NPC_THORIM = 29445, - GOSSIP_TEXTID_THORIM1 = 13799, - GOSSIP_TEXTID_THORIM2 = 13801, - GOSSIP_TEXTID_THORIM3 = 13802, - GOSSIP_TEXTID_THORIM4 = 13803 -}; - -class npc_thorim : public CreatureScript -{ -public: - npc_thorim() : CreatureScript("npc_thorim") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_SIBLING_RIVALRY) == QUEST_STATUS_INCOMPLETE) { - player->ADD_GOSSIP_ITEM(0, GOSSIP_HN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM1, creature->GetGUID()); - return true; - } - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(0, GOSSIP_SN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(0, GOSSIP_SN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM3, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(0, GOSSIP_SN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM4, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->CompleteQuest(QUEST_SIBLING_RIVALRY); - break; - } - return true; - } -}; - -/*###### -## npc_loklira_crone -######*/ - -#define GOSSIP_LOKLIRACRONE "Tell me about this proposal" -#define GOSSIP_LOKLIRACRONE1 "What happened then?" -#define GOSSIP_LOKLIRACRONE2 "You want me to take part in the Hyldsmeet to end the war?" -#define GOSSIP_LOKLIRACRONE3 "Very well. I'll take part in this competition." - -enum eLokliraCrone -{ - QUEST_HYLDSMEET = 12970, - - GOSSIP_TEXTID_LOK1 = 13778, - GOSSIP_TEXTID_LOK2 = 13779, - GOSSIP_TEXTID_LOK3 = 13780 -}; - -class npc_loklira_crone : public CreatureScript -{ -public: - npc_loklira_crone() : CreatureScript("npc_loklira_crone") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_HYLDSMEET) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK1, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK3, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->CompleteQuest(QUEST_HYLDSMEET); - break; - } - return true; - } -}; - ///////////////////// ///npc_injured_goblin ///////////////////// @@ -409,14 +284,12 @@ public: ## npc_brunnhildar_prisoner ######*/ -enum brunhildar { - NPC_QUEST_GIVER = 29592, - +enum BrunnhildarPrisoner { SPELL_ICE_PRISON = 54894, - SPELL_KILL_CREDIT_PRISONER = 55144, - SPELL_KILL_CREDIT_DRAKE = 55143, - SPELL_SUMMON_LIBERATED = 55073, - SPELL_ICE_LANCE = 55046 + SPELL_ICE_LANCE = 55046, + SPELL_FREE_PRISONER = 55048, + SPELL_RIDE_DRAKE = 55074, + SPELL_SHARD_IMPACT = 55047 }; class npc_brunnhildar_prisoner : public CreatureScript @@ -428,129 +301,169 @@ public: { npc_brunnhildar_prisonerAI(Creature* creature) : ScriptedAI(creature) {} - uint64 drakeGUID; - uint16 enter_timer; - bool hasEmptySeats; + bool freed; void Reset() { + freed = false; me->CastSpell(me, SPELL_ICE_PRISON, true); - enter_timer = 0; - drakeGUID = 0; - hasEmptySeats = false; } - void UpdateAI(const uint32 diff) + void JustRespawned() { - //TODO: not good script - if (!drakeGUID) + Reset(); + } + + void UpdateAI(const uint32 /*diff*/) + { + if (!freed) return; - Creature* drake = Unit::GetCreature(*me, drakeGUID); - if (!drake) + if (!me->HasUnitState(UNIT_STATE_ONVEHICLE)) { - drakeGUID = 0; - return; + me->DespawnOrUnsummon(); } + } - // drake unsummoned, passengers dropped - if (!me->IsOnVehicle(drake) && !hasEmptySeats) - me->DespawnOrUnsummon(3000); - - if (enter_timer <= 0) + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id != SPELL_ICE_LANCE) return; - if (enter_timer < diff) + if (caster->GetVehicleKit()->GetAvailableSeatCount() != 0) { - enter_timer = 0; - if (hasEmptySeats) - me->JumpTo(drake, 25.0f); - else - Reset(); + me->CastSpell(me, SPELL_FREE_PRISONER, true); + me->CastSpell(caster, SPELL_RIDE_DRAKE, true); + me->CastSpell(me, SPELL_SHARD_IMPACT, true); + freed = true; } - else - enter_timer -= diff; } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_brunnhildar_prisonerAI(creature); + } +}; + +/*###### +## npc_freed_protodrake +######*/ + +enum FreedProtoDrake +{ + AREA_VALLEY_OF_ANCIENT_WINTERS = 4437, + TEXT_EMOTE = 0, + SPELL_KILL_CREDIT_PRISONER = 55144, + SPELL_SUMMON_LIBERATED = 55073, + SPELL_KILL_CREDIT_DRAKE = 55143 +}; + +const Position FreedDrakeWaypoints[16] = +{ + {7294.96f, -2418.733f, 823.869f, 0.0f}, + {7315.984f, -2331.46f, 826.3972f, 0.0f}, + {7271.826f, -2271.479f, 833.5917f, 0.0f}, + {7186.253f, -2218.475f, 847.5632f, 0.0f}, + {7113.195f, -2164.288f, 850.2301f, 0.0f}, + {7078.018f, -2063.106f, 854.7581f, 0.0f}, + {7073.221f, -1983.382f, 861.9246f, 0.0f}, + {7061.455f, -1885.899f, 865.119f, 0.0f}, + {7033.32f, -1826.775f, 876.2578f, 0.0f}, + {6999.902f, -1784.012f, 897.4521f, 0.0f}, + {6954.913f, -1747.043f, 897.4521f, 0.0f}, + {6933.856f, -1720.698f, 882.2022f, 0.0f}, + {6932.729f, -1687.306f, 866.1189f, 0.0f}, + {6952.458f, -1663.802f, 849.8133f, 0.0f}, + {7002.819f, -1651.681f, 831.397f, 0.0f}, + {7026.531f, -1649.239f, 828.8406f, 0.0f} +}; - void MoveInLineOfSight(Unit* who) + +class npc_freed_protodrake : public CreatureScript +{ +public: + npc_freed_protodrake() : CreatureScript("npc_freed_protodrake") { } + + struct npc_freed_protodrakeAI : public VehicleAI + { + npc_freed_protodrakeAI(Creature* creature) : VehicleAI(creature) {} + + bool autoMove; + bool wpReached; + uint16 CheckTimer; + uint16 countWP; + + void Reset() { - if (!who || !drakeGUID) + autoMove = false; + wpReached = false; + CheckTimer = 5000; + countWP = 0; + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) return; - Creature* drake = Unit::GetCreature(*me, drakeGUID); - if (!drake) + if (id < 15) { - drakeGUID = 0; - return; + ++countWP; + wpReached = true; } - - if (!me->IsOnVehicle(drake) && !me->HasAura(SPELL_ICE_PRISON)) + else + // drake reached village { - if (who->IsVehicle() && me->IsWithinDist(who, 25.0f, true) && who->ToCreature() && who->ToCreature()->GetEntry() == 29709) + // get player that rides drake (from seat 0) + Unit* player = me->GetVehicleKit()->GetPassenger(0); + if (player && player->GetTypeId() == TYPEID_PLAYER) { - uint8 seat = who->GetVehicleKit()->GetNextEmptySeat(0, true); - if (seat <= 0) - return; - - me->EnterVehicle(who, seat); - me->SendMovementFlagUpdate(); - hasEmptySeats = false; + // for each prisoner on drake,give credit + for (uint8 i = 1; i < 4; ++i) + if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i)) + { + if (prisoner->GetTypeId() != TYPEID_UNIT) + return; + prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true); + prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true); + prisoner->ExitVehicle(); + } + me->CastSpell(me, SPELL_KILL_CREDIT_DRAKE, true); + player->ExitVehicle(); } } + } - if (who->ToCreature() && me->IsOnVehicle(drake)) + void UpdateAI(const uint32 diff) + { + if (!autoMove) { - if (who->ToCreature()->GetEntry() == NPC_QUEST_GIVER && me->IsWithinDist(who, 15.0f, false)) + if (CheckTimer < diff) { - Unit* rider = drake->GetVehicleKit()->GetPassenger(0); - if (!rider) - return; - - rider->CastSpell(rider, SPELL_KILL_CREDIT_PRISONER, true); - - me->ExitVehicle(); - me->CastSpell(me, SPELL_SUMMON_LIBERATED, true); - me->DespawnOrUnsummon(500); - - // drake is empty now, deliver credit for drake and despawn him - if (drake->GetVehicleKit()->HasEmptySeat(1) && - drake->GetVehicleKit()->HasEmptySeat(2) && - drake->GetVehicleKit()->HasEmptySeat(3)) + CheckTimer = 5000; + if (me->GetAreaId() == AREA_VALLEY_OF_ANCIENT_WINTERS) { - // not working rider->CastSpell(rider, SPELL_KILL_CREDIT_DRAKE, true); - if (rider->ToPlayer()) - rider->ToPlayer()->KilledMonsterCredit(29709, 0); - - drake->DespawnOrUnsummon(0); + Talk(TEXT_EMOTE, me->GetVehicleKit()->GetPassenger(0)->GetGUID()); + autoMove = true; + wpReached = true; } } + else + CheckTimer -= diff; } - } - - void SpellHit(Unit* hitter, const SpellInfo* spell) - { - if (!hitter || !spell) - return; - - if (spell->Id != SPELL_ICE_LANCE) - return; - me->RemoveAura(SPELL_ICE_PRISON); - enter_timer = 500; - - if (hitter->IsVehicle()) - drakeGUID = hitter->GetGUID(); - else - return; - - if (hitter->GetVehicleKit()->GetNextEmptySeat(0, true)) - hasEmptySeats = true; + if (wpReached && autoMove) + { + wpReached = false; + me->GetMotionMaster()->MovePoint(countWP, FreedDrakeWaypoints[countWP]); + } } }; CreatureAI* GetAI(Creature* creature) const { - return new npc_brunnhildar_prisonerAI(creature); + return new npc_freed_protodrakeAI(creature); } }; @@ -655,11 +568,10 @@ void AddSC_storm_peaks() { new npc_agnetta_tyrsdottar(); new npc_frostborn_scout(); - new npc_thorim(); - new npc_loklira_crone(); new npc_injured_goblin(); new npc_roxi_ramrocket(); new npc_brunnhildar_prisoner(); + new npc_freed_protodrake(); new npc_icefang(); new npc_hyldsmeet_protodrake(); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index 44c37fc9753..ec9e4e116bf 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -181,6 +181,23 @@ public: me->RemoveAurasDueToSpell(SPELL_SUBMERGE); } + void MoveInLineOfSight(Unit* who) + { + if (!who) + return; + + if (me->isInCombat()) + return; + + if (who->GetTypeId() != TYPEID_PLAYER) + return; + + if (me->GetDistance(who) > 50.0f) + return; + + AttackStartNoMove(who); + } + void EnterCombat(Unit* who) { me->AddThreat(who, 10000.0f); @@ -412,6 +429,7 @@ public: me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->Yell(SUFF_SAY_RECAP, LANG_UNIVERSAL, 0); DoScriptText(SUFF_SAY_RECAP, me); + me->SetReactState(REACT_PASSIVE); } } @@ -532,6 +550,7 @@ public: damage = 0; me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoScriptText(SUFF_SAY_RECAP, me); + me->SetReactState(REACT_PASSIVE); } else { diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp index 84d292e1fe4..b42641c5171 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp @@ -160,7 +160,7 @@ class go_broggok_lever : public GameObjectScript public: go_broggok_lever() : GameObjectScript("go_broggok_lever") {} - bool OnGossipHello(Player* player, GameObject* go) + bool OnGossipHello(Player* /*player*/, GameObject* go) { if (InstanceScript* instance = go->GetInstanceScript()) if (instance->GetData(TYPE_BROGGOK_EVENT) != DONE && instance->GetData(TYPE_BROGGOK_EVENT) != IN_PROGRESS) diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp index 893f97fe711..233a8d82497 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp @@ -133,7 +133,7 @@ class instance_blood_furnace : public InstanceMapScript } } - void OnCreatureDeath(Creature* unit) + void OnUnitDeath(Unit* unit) { if (unit && unit->GetTypeId() == TYPEID_UNIT && unit->GetEntry() == 17398) PrisonerDied(unit->GetGUID()); @@ -350,10 +350,10 @@ class instance_blood_furnace : public InstanceMapScript ++PrisonerCounter8; } else - return; + return; } else - return; + return; ResetPrisoner(creature); } diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp index 1656f7221ed..c84df2ee3d4 100644 --- a/src/server/scripts/Outland/shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/shadowmoon_valley.cpp @@ -839,19 +839,10 @@ public: return 1500; break; case 16: - if (player) - { - Illi->CastSpell(player, SPELL_TWO, true); - player->RemoveAurasDueToSpell(SPELL_THREE); - player->RemoveAurasDueToSpell(SPELL_FOUR); - return 5000; - } - else - { - player->FailQuest(QUEST_LORD_ILLIDAN_STORMRAGE); - Step = 30; - return 100; - } + Illi->CastSpell(player, SPELL_TWO, true); + player->RemoveAurasDueToSpell(SPELL_THREE); + player->RemoveAurasDueToSpell(SPELL_FOUR); + return 5000; break; case 17: DoScriptText(LORD_ILLIDAN_SAY_5, Illi); @@ -1871,8 +1862,8 @@ public: enum ZuluhedChains { - QUEST_ZULUHED = 10866, - NPC_KARYNAKU = 22112, + QUEST_ZULUHED = 10866, + NPC_KARYNAKU = 22112, }; class spell_unlocking_zuluheds_chains : public SpellScriptLoader @@ -1884,18 +1875,21 @@ class spell_unlocking_zuluheds_chains : public SpellScriptLoader { PrepareSpellScript(spell_unlocking_zuluheds_chains_SpellScript); - void HandleOnCast() + bool Load() { - // FIXME: Hackish solution, a better way to reward killcredit should be found - if (Unit* caster = GetCaster()) - if(Player* player = caster->ToPlayer()) - if (player->GetQuestStatus(QUEST_ZULUHED) == QUEST_STATUS_INCOMPLETE) - player->CastedCreatureOrGO(NPC_KARYNAKU, MAKE_NEW_GUID(0, NPC_KARYNAKU, HIGHGUID_UNIT), 0); + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleAfterHit() + { + Player* caster = GetCaster()->ToPlayer(); + if (caster->GetQuestStatus(QUEST_ZULUHED) == QUEST_STATUS_INCOMPLETE) + caster->KilledMonsterCredit(NPC_KARYNAKU, 0); } void Register() { - OnCast += SpellCastFn(spell_unlocking_zuluheds_chains_SpellScript::HandleOnCast); + AfterHit += SpellHitFn(spell_unlocking_zuluheds_chains_SpellScript::HandleAfterHit); } }; @@ -1905,6 +1899,96 @@ class spell_unlocking_zuluheds_chains : public SpellScriptLoader } }; +enum ShadowMoonTuberEnum +{ + SPELL_WHISTLE = 36652, + SPELL_SHADOWMOON_TUBER = 36462, + + NPC_BOAR_ENTRY = 21195, + GO_SHADOWMOON_TUBER_MOUND = 184701, + + POINT_TUBER = 1, + TYPE_BOAR = 1, + DATA_BOAR = 1 +}; + +class npc_shadowmoon_tuber_node : public CreatureScript +{ +public: + npc_shadowmoon_tuber_node() : CreatureScript("npc_shadowmoon_tuber_node") {} + + struct npc_shadowmoon_tuber_nodeAI : public ScriptedAI + { + npc_shadowmoon_tuber_nodeAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + tapped = false; + tuberGUID = 0; + resetTimer = 60000; + } + + void SetData(uint32 id, uint32 data) + { + if (id == TYPE_BOAR && data == DATA_BOAR) + { + // Spawn chest GO + DoCast(SPELL_SHADOWMOON_TUBER); + + // Despawn the tuber + if (GameObject* tuber = me->FindNearestGameObject(GO_SHADOWMOON_TUBER_MOUND, 5.0f)) + { + tuberGUID = tuber->GetGUID(); + // @Workaround: find how to properly despawn the GO + tuber->SetPhaseMask(2, true); + } + } + } + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + { + if (!tapped && spell->Id == SPELL_WHISTLE) + { + if (Creature* boar = me->FindNearestCreature(NPC_BOAR_ENTRY, 30.0f)) + { + // Disable trigger and force nearest boar to walk to him + tapped = true; + boar->SetWalk(false); + boar->GetMotionMaster()->MovePoint(POINT_TUBER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (tapped) + { + if (resetTimer <= diff) + { + // Respawn the tuber + if (tuberGUID) + if (GameObject* tuber = GameObject::GetGameObject(*me, tuberGUID)) + // @Workaround: find how to properly respawn the GO + tuber->SetPhaseMask(1, true); + + Reset(); + } + else + resetTimer -= diff; + } + } + private: + bool tapped; + uint64 tuberGUID; + uint32 resetTimer; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_shadowmoon_tuber_nodeAI(creature); + } +}; + void AddSC_shadowmoon_valley() { new mob_mature_netherwing_drake(); @@ -1923,4 +2007,5 @@ void AddSC_shadowmoon_valley() new mob_torloth_the_magnificent(); new npc_enraged_spirit(); new spell_unlocking_zuluheds_chains(); + new npc_shadowmoon_tuber_node(); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index b213f3df624..32a92da5e3a 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -34,6 +34,36 @@ enum DruidSpells DRUID_SURVIVAL_INSTINCTS = 50322, DRUID_SAVAGE_ROAR = 62071, SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, + SPELL_KING_OF_THE_JUNGLE = 48492, + SPELL_TIGER_S_FURY_ENERGIZE = 51178, + SPELL_ENRAGE_MOD_DAMAGE = 51185, +}; + +class spell_dru_enrage : public SpellScriptLoader +{ + public: + spell_dru_enrage() : SpellScriptLoader("spell_dru_enrage") { } + + class spell_dru_enrage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_enrage_SpellScript); + + void OnHit() + { + if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffectOfRankedSpell(SPELL_KING_OF_THE_JUNGLE, EFFECT_0)) + GetHitUnit()->CastCustomSpell(SPELL_ENRAGE_MOD_DAMAGE, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetHitUnit(), true); + } + + void Register() + { + AfterHit += SpellHitFn(spell_dru_enrage_SpellScript::OnHit); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dru_enrage_SpellScript(); + } }; // 54846 Glyph of Starfire @@ -88,6 +118,115 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader } }; +class spell_dru_insect_swarm : public SpellScriptLoader +{ + public: + spell_dru_insect_swarm() : SpellScriptLoader("spell_dru_insect_swarm") { } + + class spell_dru_insect_swarm_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_insect_swarm_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32 & amount, bool & /*canBeRecalculated*/) + { + if (Unit* caster = GetCaster()) + if (AuraEffect const* relicAurEff = caster->GetAuraEffect(SPELL_DRUID_ITEM_T8_BALANCE_RELIC, EFFECT_0)) + amount += relicAurEff->GetAmount() / aurEff->GetTotalTicks(); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_insect_swarm_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_insect_swarm_AuraScript(); + } +}; + +class spell_dru_lifebloom : public SpellScriptLoader +{ + public: + spell_dru_lifebloom() : SpellScriptLoader("spell_dru_lifebloom") { } + + class spell_dru_lifebloom_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_lifebloom_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_FINAL_HEAL)) + return false; + if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_ENERGIZE)) + return false; + return true; + } + + void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + // Final heal only on duration end + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + // final heal + int32 stack = GetStackAmount(); + int32 healAmount = aurEff->GetAmount(); + if (Unit* caster = GetCaster()) + { + healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack); + healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack); + + GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + + // restore mana + int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2; + caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + return; + } + + GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); + } + + void HandleDispel(DispelInfo* dispelInfo) + { + if (Unit* target = GetUnitOwner()) + { + if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) + { + // final heal + int32 healAmount = aurEff->GetAmount(); + if (Unit* caster = GetCaster()) + { + healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); + healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); + target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + + // restore mana + int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * dispelInfo->GetRemovedCharges() / 2; + caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + return; + } + + target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + } + } + } + + void Register() + { + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_lifebloom_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterDispel += AuraDispelFn(spell_dru_lifebloom_AuraScript::HandleDispel); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_lifebloom_AuraScript(); + } +}; + // 69366 - Moonkin Form passive class spell_dru_moonkin_form_passive : public SpellScriptLoader { @@ -132,6 +271,34 @@ class spell_dru_moonkin_form_passive : public SpellScriptLoader } }; +class spell_dru_predatory_strikes : public SpellScriptLoader +{ + public: + spell_dru_predatory_strikes() : SpellScriptLoader("spell_dru_predatory_strikes") { } + + class spell_dru_predatory_strikes_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_predatory_strikes_AuraScript); + + void UpdateAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Player* target = GetTarget()->ToPlayer()) + target->UpdateAttackPowerAndDamage(); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dru_predatory_strikes_AuraScript(); + } +}; + // 33851 - Primal Tenacity class spell_dru_primal_tenacity : public SpellScriptLoader { @@ -219,57 +386,67 @@ class spell_dru_savage_defense : public SpellScriptLoader } }; -class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader +class spell_dru_savage_roar : public SpellScriptLoader { public: - spell_dru_t10_restoration_4p_bonus() : SpellScriptLoader("spell_dru_t10_restoration_4p_bonus") { } + spell_dru_savage_roar() : SpellScriptLoader("spell_dru_savage_roar") { } - class spell_dru_t10_restoration_4p_bonus_SpellScript : public SpellScript + class spell_dru_savage_roar_SpellScript : public SpellScript { - PrepareSpellScript(spell_dru_t10_restoration_4p_bonus_SpellScript); + PrepareSpellScript(spell_dru_savage_roar_SpellScript); - bool Load() + SpellCastResult CheckCast() { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; + Unit* caster = GetCaster(); + if (caster->GetShapeshiftForm() != FORM_CAT) + return SPELL_FAILED_ONLY_SHAPESHIFT; + + return SPELL_CAST_OK; } - void FilterTargets(std::list<WorldObject*>& targets) + void Register() { - if (!GetCaster()->ToPlayer()->GetGroup()) - { - targets.clear(); - targets.push_back(GetCaster()); - } - else - { - targets.remove(GetExplTargetUnit()); - std::list<Unit*> tempTargets; - for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) - if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith((*itr)->ToUnit())) - tempTargets.push_back((*itr)->ToUnit()); + OnCheckCast += SpellCheckCastFn(spell_dru_savage_roar_SpellScript::CheckCast); + } + }; - if (tempTargets.empty()) - { - targets.clear(); - FinishCast(SPELL_FAILED_DONT_REPORT); - return; - } + class spell_dru_savage_roar_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_savage_roar_AuraScript); - Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets); - targets.clear(); - targets.push_back(target); - } + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(DRUID_SAVAGE_ROAR)) + return false; + return true; + } + + void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, DRUID_SAVAGE_ROAR, true, NULL, aurEff, GetCasterGUID()); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(DRUID_SAVAGE_ROAR); } void Register() { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); + AfterEffectApply += AuraEffectApplyFn(spell_dru_savage_roar_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_savage_roar_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; SpellScript* GetSpellScript() const { - return new spell_dru_t10_restoration_4p_bonus_SpellScript(); + return new spell_dru_savage_roar_SpellScript(); + } + + AuraScript* GetAuraScript() const + { + return new spell_dru_savage_roar_AuraScript(); } }; @@ -299,40 +476,6 @@ class spell_dru_starfall_aoe : public SpellScriptLoader } }; -// 40121 - Swift Flight Form (Passive) -class spell_dru_swift_flight_passive : public SpellScriptLoader -{ - public: - spell_dru_swift_flight_passive() : SpellScriptLoader("spell_dru_swift_flight_passive") { } - - class spell_dru_swift_flight_passive_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dru_swift_flight_passive_AuraScript); - - bool Load() - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - if (Player* caster = GetCaster()->ToPlayer()) - if (caster->Has310Flyer(false)) - amount = 310; - } - - void Register() - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_swift_flight_passive_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_dru_swift_flight_passive_AuraScript(); - } -}; - class spell_dru_starfall_dummy : public SpellScriptLoader { public: @@ -378,128 +521,19 @@ class spell_dru_starfall_dummy : public SpellScriptLoader } }; -class spell_dru_lifebloom : public SpellScriptLoader -{ - public: - spell_dru_lifebloom() : SpellScriptLoader("spell_dru_lifebloom") { } - - class spell_dru_lifebloom_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dru_lifebloom_AuraScript); - - bool Validate(SpellInfo const* /*spell*/) - { - if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_FINAL_HEAL)) - return false; - if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_ENERGIZE)) - return false; - return true; - } - - void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - // Final heal only on duration end - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - // final heal - int32 stack = GetStackAmount(); - int32 healAmount = aurEff->GetAmount(); - if (Unit* caster = GetCaster()) - { - healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack); - healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack); - - GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); - - // restore mana - int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2; - caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); - return; - } - - GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID()); - } - - void HandleDispel(DispelInfo* dispelInfo) - { - if (Unit* target = GetUnitOwner()) - { - if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) - { - // final heal - int32 healAmount = aurEff->GetAmount(); - if (Unit* caster = GetCaster()) - { - healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); - healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges()); - target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); - - // restore mana - int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * dispelInfo->GetRemovedCharges() / 2; - caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, NULL, GetCasterGUID()); - return; - } - - target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID()); - } - } - } - - void Register() - { - AfterEffectRemove += AuraEffectRemoveFn(spell_dru_lifebloom_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterDispel += AuraDispelFn(spell_dru_lifebloom_AuraScript::HandleDispel); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_dru_lifebloom_AuraScript(); - } -}; - -class spell_dru_predatory_strikes : public SpellScriptLoader -{ - public: - spell_dru_predatory_strikes() : SpellScriptLoader("spell_dru_predatory_strikes") { } - - class spell_dru_predatory_strikes_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dru_predatory_strikes_AuraScript); - - void UpdateAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Player* target = GetTarget()->ToPlayer()) - target->UpdateAttackPowerAndDamage(); - } - - void Register() - { - AfterEffectApply += AuraEffectApplyFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); - AfterEffectRemove += AuraEffectRemoveFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_dru_predatory_strikes_AuraScript(); - } -}; - -class spell_dru_savage_roar : public SpellScriptLoader +class spell_dru_survival_instincts : public SpellScriptLoader { public: - spell_dru_savage_roar() : SpellScriptLoader("spell_dru_savage_roar") { } + spell_dru_survival_instincts() : SpellScriptLoader("spell_dru_survival_instincts") { } - class spell_dru_savage_roar_SpellScript : public SpellScript + class spell_dru_survival_instincts_SpellScript : public SpellScript { - PrepareSpellScript(spell_dru_savage_roar_SpellScript); + PrepareSpellScript(spell_dru_survival_instincts_SpellScript); SpellCastResult CheckCast() { Unit* caster = GetCaster(); - if (caster->GetShapeshiftForm() != FORM_CAT) + if (!caster->IsInFeralForm()) return SPELL_FAILED_ONLY_SHAPESHIFT; return SPELL_CAST_OK; @@ -507,17 +541,17 @@ class spell_dru_savage_roar : public SpellScriptLoader void Register() { - OnCheckCast += SpellCheckCastFn(spell_dru_savage_roar_SpellScript::CheckCast); + OnCheckCast += SpellCheckCastFn(spell_dru_survival_instincts_SpellScript::CheckCast); } }; - class spell_dru_savage_roar_AuraScript : public AuraScript + class spell_dru_survival_instincts_AuraScript : public AuraScript { - PrepareAuraScript(spell_dru_savage_roar_AuraScript); + PrepareAuraScript(spell_dru_survival_instincts_AuraScript); bool Validate(SpellInfo const* /*spell*/) { - if (!sSpellMgr->GetSpellInfo(DRUID_SAVAGE_ROAR)) + if (!sSpellMgr->GetSpellInfo(DRUID_SURVIVAL_INSTINCTS)) return false; return true; } @@ -525,138 +559,163 @@ class spell_dru_savage_roar : public SpellScriptLoader void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { Unit* target = GetTarget(); - target->CastSpell(target, DRUID_SAVAGE_ROAR, true, NULL, aurEff, GetCasterGUID()); + int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount()); + target->CastCustomSpell(target, DRUID_SURVIVAL_INSTINCTS, &bp0, NULL, NULL, true); } void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetTarget()->RemoveAurasDueToSpell(DRUID_SAVAGE_ROAR); + GetTarget()->RemoveAurasDueToSpell(DRUID_SURVIVAL_INSTINCTS); } void Register() { - AfterEffectApply += AuraEffectApplyFn(spell_dru_savage_roar_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_dru_savage_roar_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectApply += AuraEffectApplyFn(spell_dru_survival_instincts_AuraScript::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_dru_survival_instincts_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); } }; SpellScript* GetSpellScript() const { - return new spell_dru_savage_roar_SpellScript(); + return new spell_dru_survival_instincts_SpellScript(); } AuraScript* GetAuraScript() const { - return new spell_dru_savage_roar_AuraScript(); + return new spell_dru_survival_instincts_AuraScript(); } }; -class spell_dru_survival_instincts : public SpellScriptLoader +// 40121 - Swift Flight Form (Passive) +class spell_dru_swift_flight_passive : public SpellScriptLoader { public: - spell_dru_survival_instincts() : SpellScriptLoader("spell_dru_survival_instincts") { } + spell_dru_swift_flight_passive() : SpellScriptLoader("spell_dru_swift_flight_passive") { } - class spell_dru_survival_instincts_SpellScript : public SpellScript + class spell_dru_swift_flight_passive_AuraScript : public AuraScript { - PrepareSpellScript(spell_dru_survival_instincts_SpellScript); + PrepareAuraScript(spell_dru_swift_flight_passive_AuraScript); - SpellCastResult CheckCast() + bool Load() { - Unit* caster = GetCaster(); - if (!caster->IsInFeralForm()) - return SPELL_FAILED_ONLY_SHAPESHIFT; + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } - return SPELL_CAST_OK; + void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + { + if (Player* caster = GetCaster()->ToPlayer()) + if (caster->Has310Flyer(false)) + amount = 310; } void Register() { - OnCheckCast += SpellCheckCastFn(spell_dru_survival_instincts_SpellScript::CheckCast); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_swift_flight_passive_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED); } }; - class spell_dru_survival_instincts_AuraScript : public AuraScript + AuraScript* GetAuraScript() const { - PrepareAuraScript(spell_dru_survival_instincts_AuraScript); + return new spell_dru_swift_flight_passive_AuraScript(); + } +}; - bool Validate(SpellInfo const* /*spell*/) - { - if (!sSpellMgr->GetSpellInfo(DRUID_SURVIVAL_INSTINCTS)) - return false; - return true; - } +class spell_dru_tiger_s_fury : public SpellScriptLoader +{ + public: + spell_dru_tiger_s_fury() : SpellScriptLoader("spell_dru_tiger_s_fury") { } - void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount()); - target->CastCustomSpell(target, DRUID_SURVIVAL_INSTINCTS, &bp0, NULL, NULL, true); - } + class spell_dru_tiger_s_fury_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dru_tiger_s_fury_SpellScript); - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void OnHit() { - GetTarget()->RemoveAurasDueToSpell(DRUID_SURVIVAL_INSTINCTS); + if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffectOfRankedSpell(SPELL_KING_OF_THE_JUNGLE, EFFECT_1)) + GetHitUnit()->CastCustomSpell(SPELL_TIGER_S_FURY_ENERGIZE, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetHitUnit(), true); } void Register() { - AfterEffectApply += AuraEffectApplyFn(spell_dru_survival_instincts_AuraScript::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); - AfterEffectRemove += AuraEffectRemoveFn(spell_dru_survival_instincts_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK); + AfterHit += SpellHitFn(spell_dru_tiger_s_fury_SpellScript::OnHit); } }; SpellScript* GetSpellScript() const { - return new spell_dru_survival_instincts_SpellScript(); - } - - AuraScript* GetAuraScript() const - { - return new spell_dru_survival_instincts_AuraScript(); + return new spell_dru_tiger_s_fury_SpellScript(); } }; -class spell_dru_insect_swarm : public SpellScriptLoader +class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader { public: - spell_dru_insect_swarm() : SpellScriptLoader("spell_dru_insect_swarm") { } + spell_dru_t10_restoration_4p_bonus() : SpellScriptLoader("spell_dru_t10_restoration_4p_bonus") { } - class spell_dru_insect_swarm_AuraScript : public AuraScript + class spell_dru_t10_restoration_4p_bonus_SpellScript : public SpellScript { - PrepareAuraScript(spell_dru_insect_swarm_AuraScript); + PrepareSpellScript(spell_dru_t10_restoration_4p_bonus_SpellScript); - void CalculateAmount(AuraEffect const* aurEff, int32 & amount, bool & /*canBeRecalculated*/) + bool Load() { - if (Unit* caster = GetCaster()) - if (AuraEffect const* relicAurEff = caster->GetAuraEffect(SPELL_DRUID_ITEM_T8_BALANCE_RELIC, EFFECT_0)) - amount += relicAurEff->GetAmount() / aurEff->GetTotalTicks(); + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (!GetCaster()->ToPlayer()->GetGroup()) + { + targets.clear(); + targets.push_back(GetCaster()); + } + else + { + targets.remove(GetExplTargetUnit()); + std::list<Unit*> tempTargets; + for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) + if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith((*itr)->ToUnit())) + tempTargets.push_back((*itr)->ToUnit()); + + if (tempTargets.empty()) + { + targets.clear(); + FinishCast(SPELL_FAILED_DONT_REPORT); + return; + } + + Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets); + targets.clear(); + targets.push_back(target); + } } void Register() { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_insect_swarm_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); } }; - AuraScript* GetAuraScript() const + SpellScript* GetSpellScript() const { - return new spell_dru_insect_swarm_AuraScript(); + return new spell_dru_t10_restoration_4p_bonus_SpellScript(); } }; void AddSC_druid_spell_scripts() { + new spell_dru_enrage(); new spell_dru_glyph_of_starfire(); + new spell_dru_insect_swarm(); + new spell_dru_lifebloom(); new spell_dru_moonkin_form_passive(); + new spell_dru_predatory_strikes(); new spell_dru_primal_tenacity(); new spell_dru_savage_defense(); - new spell_dru_t10_restoration_4p_bonus(); + new spell_dru_savage_roar(); new spell_dru_starfall_aoe(); - new spell_dru_swift_flight_passive(); new spell_dru_starfall_dummy(); - new spell_dru_lifebloom(); - new spell_dru_predatory_strikes(); - new spell_dru_savage_roar(); new spell_dru_survival_instincts(); - new spell_dru_insect_swarm(); + new spell_dru_swift_flight_passive(); + new spell_dru_tiger_s_fury(); + new spell_dru_t10_restoration_4p_bonus(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 5153010c0cc..3085472749c 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -907,9 +907,22 @@ class spell_gen_profession_research : public SpellScriptLoader return SPELL_CAST_OK; } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + uint32 spellId = GetSpellInfo()->Id; + + // learn random explicit discovery recipe (if any) + if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) + caster->learnSpell(discoveredSpellId, false); + + caster->UpdateCraftSkill(spellId); + } + void Register() { OnCheckCast += SpellCheckCastFn(spell_gen_profession_research_SpellScript::CheckRequirement); + OnEffectHitTarget += SpellEffectFn(spell_gen_profession_research_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -2428,7 +2441,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader case NPC_ARGENT_STEED_ASPIRANT: case NPC_STORMWIND_STEED: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_STORMWIND)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_STORMWIND)) return SPELL_PENNANT_STORMWIND_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_STORMWIND) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_STORMWIND)) return SPELL_PENNANT_STORMWIND_VALIANT; @@ -2437,7 +2450,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_GNOMEREGAN_MECHANOSTRIDER: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_GNOMEREGAN)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_GNOMEREGAN)) return SPELL_PENNANT_GNOMEREGAN_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_GNOMEREGAN) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_GNOMEREGAN)) return SPELL_PENNANT_GNOMEREGAN_VALIANT; @@ -2446,7 +2459,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_DARK_SPEAR_RAPTOR: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_SEN_JIN)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_SEN_JIN)) return SPELL_PENNANT_SEN_JIN_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_SEN_JIN) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_SEN_JIN)) return SPELL_PENNANT_SEN_JIN_VALIANT; @@ -2456,7 +2469,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader case NPC_ARGENT_HAWKSTRIDER_ASPIRANT: case NPC_SILVERMOON_HAWKSTRIDER: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_SILVERMOON)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_SILVERMOON)) return SPELL_PENNANT_SILVERMOON_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_SILVERMOON) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_SILVERMOON)) return SPELL_PENNANT_SILVERMOON_VALIANT; @@ -2465,7 +2478,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_DARNASSIAN_NIGHTSABER: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_DARNASSUS)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_DARNASSUS)) return SPELL_PENNANT_DARNASSUS_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_DARNASSUS) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_DARNASSUS)) return SPELL_PENNANT_DARNASSUS_VALIANT; @@ -2474,7 +2487,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_EXODAR_ELEKK: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_THE_EXODAR)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_THE_EXODAR)) return SPELL_PENNANT_EXODAR_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_THE_EXODAR) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_THE_EXODAR)) return SPELL_PENNANT_EXODAR_VALIANT; @@ -2483,7 +2496,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_IRONFORGE_RAM: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_IRONFORGE)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_IRONFORGE)) return SPELL_PENNANT_IRONFORGE_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_IRONFORGE) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_IRONFORGE)) return SPELL_PENNANT_IRONFORGE_VALIANT; @@ -2492,7 +2505,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_FORSAKEN_WARHORSE: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_UNDERCITY)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_UNDERCITY)) return SPELL_PENNANT_UNDERCITY_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_UNDERCITY) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_UNDERCITY)) return SPELL_PENNANT_UNDERCITY_VALIANT; @@ -2501,7 +2514,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_ORGRIMMAR_WOLF: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_ORGRIMMAR)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_ORGRIMMAR)) return SPELL_PENNANT_ORGRIMMAR_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_ORGRIMMAR) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_ORGRIMMAR)) return SPELL_PENNANT_ORGRIMMAR_VALIANT; @@ -2510,7 +2523,7 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_THUNDER_BLUFF_KODO: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_THUNDER_BLUFF)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_THUNDER_BLUFF)) return SPELL_PENNANT_THUNDER_BLUFF_CHAMPION; else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_THUNDER_BLUFF) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_THUNDER_BLUFF)) return SPELL_PENNANT_THUNDER_BLUFF_VALIANT; @@ -2519,9 +2532,9 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader } case NPC_ARGENT_WARHORSE: { - if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_ALLIANCE) || player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_HORDE)) + if (player->HasAchieved(ACHIEVEMENT_CHAMPION_ALLIANCE) || player->HasAchieved(ACHIEVEMENT_CHAMPION_HORDE)) return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_CHAMPION : SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION; - else if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_ARGENT_VALOR)) + else if (player->HasAchieved(ACHIEVEMENT_ARGENT_VALOR)) return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_VALIANT : SPELL_PENNANT_ARGENT_CRUSADE_VALIANT; else return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_ASPIRANT : SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT; @@ -3237,6 +3250,58 @@ class spell_gen_bonked : public SpellScriptLoader } }; +class spell_gen_gift_of_naaru : public SpellScriptLoader +{ + public: + spell_gen_gift_of_naaru() : SpellScriptLoader("spell_gen_gift_of_naaru") { } + + class spell_gen_gift_of_naaru_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_gift_of_naaru_AuraScript); + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (!GetCaster()) + return; + + float heal = 0.0f; + switch (GetSpellInfo()->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + case SPELLFAMILY_WARLOCK: + case SPELLFAMILY_PRIEST: + heal = 1.885f * float(GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask())); + break; + case SPELLFAMILY_PALADIN: + case SPELLFAMILY_SHAMAN: + heal = std::max(1.885f * float(GetCaster()->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask())), 1.1f * float(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK))); + break; + case SPELLFAMILY_WARRIOR: + case SPELLFAMILY_HUNTER: + case SPELLFAMILY_DEATHKNIGHT: + heal = 1.1f * float(std::max(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK), GetCaster()->GetTotalAttackPowerValue(RANGED_ATTACK))); + break; + case SPELLFAMILY_GENERIC: + default: + break; + } + + int32 healTick = floor(heal / aurEff->GetTotalTicks()); + amount += int32(std::max(healTick, 0)); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_gift_of_naaru_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_gift_of_naaru_AuraScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3312,4 +3377,5 @@ void AddSC_generic_spell_scripts() new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310); new spell_gen_upper_deck_create_foam_sword(); new spell_gen_bonked(); + new spell_gen_gift_of_naaru(); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 3c89cb7005a..0508d95a60b 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -836,9 +836,20 @@ class spell_item_book_of_glyph_mastery : public SpellScriptLoader return SPELL_CAST_OK; } + void HandleScript(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + uint32 spellId = GetSpellInfo()->Id; + + // learn random explicit discovery recipe (if any) + if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) + caster->learnSpell(discoveredSpellId, false); + } + void Register() { OnCheckCast += SpellCheckCastFn(spell_item_book_of_glyph_mastery_SpellScript::CheckRequirement); + OnEffectHitTarget += SpellEffectFn(spell_item_book_of_glyph_mastery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index cbf45910495..06d3602d8e8 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -25,6 +25,9 @@ #include "ScriptedCreature.h" #include "SpellScript.h" #include "Vehicle.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "CellImpl.h" class spell_generic_quest_update_entry_SpellScript : public SpellScript { @@ -1314,6 +1317,174 @@ class spell_q12372_destabilize_azure_dragonshrine_dummy : public SpellScriptLoad } }; +// "Bombing Run" and "Bomb Them Again!" +enum Quest11010_11102_11023Data +{ + // Spell + SPELL_FLAK_CANNON_TRIGGER = 40110, + SPELL_CHOOSE_LOC = 40056, + SPELL_AGGRO_CHECK = 40112, + // NPCs + NPC_FEL_CANNON2 = 23082 +}; + +// 40113 Knockdown Fel Cannon: The Aggro Check Aura +class spell_q11010_q11102_q11023_aggro_check_aura : public SpellScriptLoader +{ + public: + spell_q11010_q11102_q11023_aggro_check_aura() : SpellScriptLoader("spell_q11010_q11102_q11023_aggro_check_aura") { } + + class spell_q11010_q11102_q11023_aggro_check_aura_AuraScript : public AuraScript + { + PrepareAuraScript(spell_q11010_q11102_q11023_aggro_check_aura_AuraScript); + + void HandleTriggerSpell(AuraEffect const* /*aurEff*/) + { + if (Unit* target = GetTarget()) + // On trigger proccing + target->CastSpell(target, SPELL_AGGRO_CHECK); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_q11010_q11102_q11023_aggro_check_aura_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_q11010_q11102_q11023_aggro_check_aura_AuraScript(); + } +}; + +// 40112 Knockdown Fel Cannon: The Aggro Check +class spell_q11010_q11102_q11023_aggro_check : public SpellScriptLoader +{ + public: + spell_q11010_q11102_q11023_aggro_check() : SpellScriptLoader("spell_q11010_q11102_q11023_aggro_check") { } + + class spell_q11010_q11102_q11023_aggro_check_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q11010_q11102_q11023_aggro_check_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Player* playerTarget = GetHitPlayer()) + // Check if found player target is on fly mount or using flying form + if (playerTarget->HasAuraType(SPELL_AURA_FLY) || playerTarget->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)) + playerTarget->CastSpell(playerTarget, SPELL_FLAK_CANNON_TRIGGER, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q11010_q11102_q11023_aggro_check_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q11010_q11102_q11023_aggro_check_SpellScript(); + } +}; + +// 40119 Knockdown Fel Cannon: The Aggro Burst +class spell_q11010_q11102_q11023_aggro_burst : public SpellScriptLoader +{ + public: + spell_q11010_q11102_q11023_aggro_burst() : SpellScriptLoader("spell_q11010_q11102_q11023_aggro_burst") { } + + class spell_q11010_q11102_q11023_aggro_burst_AuraScript : public AuraScript + { + PrepareAuraScript(spell_q11010_q11102_q11023_aggro_burst_AuraScript); + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + if (Unit* target = GetTarget()) + // On each tick cast Choose Loc to trigger summon + target->CastSpell(target, SPELL_CHOOSE_LOC); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_q11010_q11102_q11023_aggro_burst_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_q11010_q11102_q11023_aggro_burst_AuraScript(); + } +}; + +// 40056 Knockdown Fel Cannon: Choose Loc +class spell_q11010_q11102_q11023_choose_loc : public SpellScriptLoader +{ + public: + spell_q11010_q11102_q11023_choose_loc() : SpellScriptLoader("spell_q11010_q11102_q11023_choose_loc") { } + + class spell_q11010_q11102_q11023_choose_loc_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q11010_q11102_q11023_choose_loc_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + // Check for player that is in 65 y range + std::list<Player*> playerList; + Trinity::AnyPlayerInObjectRangeCheck checker(caster, 765.0f); + Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(caster, playerList, checker); + caster->VisitNearbyWorldObject(65.0f, searcher); + for (std::list<Player*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) + // Check if found player target is on fly mount or using flying form + if ((*itr)->HasAuraType(SPELL_AURA_FLY) || (*itr)->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)) + // Summom Fel Cannon (bunny version) at found player + caster->SummonCreature(NPC_FEL_CANNON2, (*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ()); + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_q11010_q11102_q11023_choose_loc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q11010_q11102_q11023_choose_loc_SpellScript(); + } +}; + +// 39844 - Skyguard Blasting Charge +// 40160 - Throw Bomb +class spell_q11010_q11102_q11023_q11008_check_fly_mount : public SpellScriptLoader +{ + public: + spell_q11010_q11102_q11023_q11008_check_fly_mount() : SpellScriptLoader("spell_q11010_q11102_q11023_q11008_check_fly_mount") { } + + class spell_q11010_q11102_q11023_q11008_check_fly_mount_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q11010_q11102_q11023_q11008_check_fly_mount_SpellScript); + + SpellCastResult CheckRequirement() + { + Unit* caster = GetCaster(); + // This spell will be cast only if caster has one of these auras + if (!(caster->HasAuraType(SPELL_AURA_FLY) || caster->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED))) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_q11010_q11102_q11023_q11008_check_fly_mount_SpellScript::CheckRequirement); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q11010_q11102_q11023_q11008_check_fly_mount_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -1345,4 +1516,9 @@ void AddSC_quest_spell_scripts() new spell_q12735_song_of_cleansing(); new spell_q12372_cast_from_gossip_trigger(); new spell_q12372_destabilize_azure_dragonshrine_dummy(); + new spell_q11010_q11102_q11023_aggro_check_aura(); + new spell_q11010_q11102_q11023_aggro_check(); + new spell_q11010_q11102_q11023_aggro_burst(); + new spell_q11010_q11102_q11023_choose_loc(); + new spell_q11010_q11102_q11023_q11008_check_fly_mount(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index e0131190916..0def62b7d3a 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -41,6 +41,10 @@ enum WarlockSpells WARLOCK_HAUNT_HEAL = 48210, WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117, WARLOCK_CURSE_OF_DOOM_EFFECT = 18662, + WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703, + WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704, + WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1 = 60955, + WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, }; class spell_warl_banish : public SpellScriptLoader @@ -671,6 +675,48 @@ class spell_warl_curse_of_doom : public SpellScriptLoader } }; +class spell_warl_health_funnel : public SpellScriptLoader +{ +public: + spell_warl_health_funnel() : SpellScriptLoader("spell_warl_health_funnel") { } + + class spell_warl_health_funnel_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_health_funnel_AuraScript); + + void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + Unit* target = GetTarget(); + if (caster->HasAura(WARLOCK_IMPROVED_HEALTH_FUNNEL_R2)) + target->CastSpell(target, WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2, true); + else if (caster->HasAura(WARLOCK_IMPROVED_HEALTH_FUNNEL_R1)) + target->CastSpell(target, WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1, true); + } + + void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->RemoveAurasDueToSpell(WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1); + target->RemoveAurasDueToSpell(WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2); + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_warl_health_funnel_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); + OnEffectApply += AuraEffectApplyFn(spell_warl_health_funnel_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_warl_health_funnel_AuraScript(); + } +}; + void AddSC_warlock_spell_scripts() { new spell_warl_banish(); @@ -686,4 +732,5 @@ void AddSC_warlock_spell_scripts() new spell_warl_haunt(); new spell_warl_unstable_affliction(); new spell_warl_curse_of_doom(); + new spell_warl_health_funnel(); } diff --git a/src/server/shared/AutoPtr.h b/src/server/shared/AutoPtr.h index 19f0680c267..f4199880abd 100644 --- a/src/server/shared/AutoPtr.h +++ b/src/server/shared/AutoPtr.h @@ -48,6 +48,6 @@ namespace Trinity return ACE_Strong_Bound_Ptr<Pointer, Lock>::get() != x; } }; -}; +} -#endif
\ No newline at end of file +#endif diff --git a/src/server/shared/Containers.h b/src/server/shared/Containers.h index f0242cbff0e..0a1b6738f1a 100644 --- a/src/server/shared/Containers.h +++ b/src/server/shared/Containers.h @@ -63,9 +63,9 @@ namespace Trinity std::advance(it, urand(0, container.size() - 1)); return *it; } - }; + } //! namespace Containers -}; +} //! namespace Trinity -#endif //! #ifdef TRINITY_CONTAINERS_H
\ No newline at end of file +#endif //! #ifdef TRINITY_CONTAINERS_H diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp index 146b2c37ad3..8e424e9bcdb 100755 --- a/src/server/shared/Cryptography/BigNumber.cpp +++ b/src/server/shared/Cryptography/BigNumber.cpp @@ -164,7 +164,7 @@ uint32 BigNumber::AsDword() bool BigNumber::isZero() const { - return BN_is_zero(_bn)!=0; + return BN_is_zero(_bn); } uint8 *BigNumber::AsByteArray(int minSize, bool reverse) diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/server/shared/DataStores/DBCFileLoader.cpp index 85b61c4f143..6f78ce5a02d 100755 --- a/src/server/shared/DataStores/DBCFileLoader.cpp +++ b/src/server/shared/DataStores/DBCFileLoader.cpp @@ -23,7 +23,7 @@ #include "DBCFileLoader.h" #include "Errors.h" -DBCFileLoader::DBCFileLoader() : stringTable(NULL), data(NULL), fieldsOffset(NULL) +DBCFileLoader::DBCFileLoader() : fieldsOffset(NULL), data(NULL), stringTable(NULL) { } diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 001e74fc6c6..a0816686734 100755 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -507,7 +507,7 @@ class DatabaseWorkerPool { IDX_ASYNC, IDX_SYNCH, - IDX_SIZE, + IDX_SIZE }; ACE_Activation_Queue* _queue; //! Queue shared by async worker threads. diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index e1530f36e44..823ad874de9 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -513,7 +513,7 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, - MAX_CHARACTERDATABASE_STATEMENTS, + MAX_CHARACTERDATABASE_STATEMENTS }; #endif diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 7c2a94eec94..b4f6713d118 100755 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -108,7 +108,7 @@ enum LoginDatabaseStatements LOGIN_SEL_REALMLIST_SECURITY_LEVEL, LOGIN_DEL_ACCOUNT, - MAX_LOGINDATABASE_STATEMENTS, + MAX_LOGINDATABASE_STATEMENTS }; #endif diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index 6d7df87cc80..195d2ea8da5 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -113,7 +113,7 @@ enum WorldDatabaseStatements WORLD_INS_DISABLES, WORLD_DEL_DISABLES, - MAX_WORLDDATABASE_STATEMENTS, + MAX_WORLDDATABASE_STATEMENTS }; #endif diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h index c05c4e62c96..c597476967d 100755 --- a/src/server/shared/Database/MySQLConnection.h +++ b/src/server/shared/Database/MySQLConnection.h @@ -33,7 +33,7 @@ enum ConnectionFlags { CONNECTION_ASYNC = 0x1, CONNECTION_SYNCH = 0x2, - CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH, + CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH }; struct MySQLConnectionInfo diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/shared/Database/QueryHolder.cpp index 0908ad410cd..ed228c74667 100755 --- a/src/server/shared/Database/QueryHolder.cpp +++ b/src/server/shared/Database/QueryHolder.cpp @@ -24,7 +24,7 @@ bool SQLQueryHolder::SetQuery(size_t index, const char *sql) { if (m_queries.size() <= index) { - sLog->outError(LOG_FILTER_SQL, "Query index (%zu) out of range (size: %u) for query: %s", index, (uint32)m_queries.size(), sql); + sLog->outError(LOG_FILTER_SQL, "Query index (%u) out of range (size: %u) for query: %s", uint32(index), (uint32)m_queries.size(), sql); return false; } @@ -44,7 +44,7 @@ bool SQLQueryHolder::SetPQuery(size_t index, const char *format, ...) { if (!format) { - sLog->outError(LOG_FILTER_SQL, "Query (index: %zu) is empty.", index); + sLog->outError(LOG_FILTER_SQL, "Query (index: %u) is empty.", uint32(index)); return false; } @@ -67,7 +67,7 @@ bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatement* stmt) { if (m_queries.size() <= index) { - sLog->outError(LOG_FILTER_SQL, "Query index (%zu) out of range (size: %u) for prepared statement", index, (uint32)m_queries.size()); + sLog->outError(LOG_FILTER_SQL, "Query index (%u) out of range (size: %u) for prepared statement", uint32(index), (uint32)m_queries.size()); return false; } diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/shared/Database/SQLOperation.h index b911c1c92aa..401535e39f7 100755 --- a/src/server/shared/Database/SQLOperation.h +++ b/src/server/shared/Database/SQLOperation.h @@ -37,7 +37,7 @@ union SQLElementUnion enum SQLElementDataType { SQL_ELEMENT_RAW, - SQL_ELEMENT_PREPARED, + SQL_ELEMENT_PREPARED }; //- The element diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index febc5ef3573..96a115f8057 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -409,11 +409,12 @@ void WheatyExceptionReport::printTracesForAllThreads() CONTEXT context; context.ContextFlags = 0xffffffff; HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, false, te32.th32ThreadID); - if (threadHandle && GetThreadContext(threadHandle, &context)) + if (threadHandle) { - WriteStackDetails(&context, false, threadHandle); + if (GetThreadContext(threadHandle, &context)) + WriteStackDetails(&context, false, threadHandle); + CloseHandle(threadHandle); } - CloseHandle(threadHandle); } } while (Thread32Next(hThreadSnap, &te32)); @@ -521,7 +522,7 @@ PEXCEPTION_POINTERS pExceptionInfo) _tprintf(_T("Global Variables\r\n")); SymEnumSymbols(GetCurrentProcess(), - (DWORD64)GetModuleHandle(szFaultingModule), + (UINT_PTR)GetModuleHandle(szFaultingModule), 0, EnumerateSymbolsCallback, 0); // #endif // X86 Only! @@ -989,7 +990,7 @@ PVOID pAddress) if (!IsBadStringPtr(*(PSTR*)pAddress, 32)) { pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"", - *(PDWORD)pAddress); + *(PSTR*)pAddress); } else pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", diff --git a/src/server/shared/Dynamic/TypeContainerFunctions.h b/src/server/shared/Dynamic/TypeContainerFunctions.h index 19ebfb3adfc..5011ec1c1be 100755 --- a/src/server/shared/Dynamic/TypeContainerFunctions.h +++ b/src/server/shared/Dynamic/TypeContainerFunctions.h @@ -36,7 +36,7 @@ namespace Trinity template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE* /*fake*/) { return elements._element.getSize(); - }; + } template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE* /*fake*/) { @@ -64,7 +64,7 @@ namespace Trinity //elements._element[hdl] = obj; obj->AddToGrid(elements._element); return obj; - }; + } template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/) { diff --git a/src/server/shared/Dynamic/TypeContainerVisitor.h b/src/server/shared/Dynamic/TypeContainerVisitor.h index beddb31f343..155989f15f6 100755 --- a/src/server/shared/Dynamic/TypeContainerVisitor.h +++ b/src/server/shared/Dynamic/TypeContainerVisitor.h @@ -35,7 +35,7 @@ template<class T, class Y> class TypeContainerVisitor; template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c) { v.Visit(c); -}; +} // terminate condition for container list template<class VISITOR> void VisitorHelper(VISITOR &v, ContainerList<TypeNull> &c) diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index c0e03b13db1..5c4b009ef67 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -80,7 +80,7 @@ enum LogLevel LOG_LEVEL_INFO = 3, LOG_LEVEL_WARN = 4, LOG_LEVEL_ERROR = 5, - LOG_LEVEL_FATAL = 6, + LOG_LEVEL_FATAL = 6 }; const uint8 MaxLogLevels = 6; @@ -90,7 +90,7 @@ enum AppenderType APPENDER_NONE, APPENDER_CONSOLE, APPENDER_FILE, - APPENDER_DB, + APPENDER_DB }; enum AppenderFlags diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp index 839f8512ad7..be6dc6c807f 100644 --- a/src/server/shared/Logging/AppenderConsole.cpp +++ b/src/server/shared/Logging/AppenderConsole.cpp @@ -59,7 +59,7 @@ void AppenderConsole::InitColors(std::string const& str) void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color) { - #if PLATFORM == PLATFORWINDOWS + #if PLATFORM == PLATFORM_WINDOWS static WORD WinColorFG[MaxColors] = { 0, // BLACK @@ -146,7 +146,7 @@ void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color) void AppenderConsole::ResetColor(bool stdout_stream) { - #if PLATFORM == PLATFORWINDOWS + #if PLATFORM == PLATFORM_WINDOWS HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); #else diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 88259831095..ed65104d6ac 100755 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -272,19 +272,6 @@ void Log::EnableDBAppenders() ((AppenderDB *)it->second)->setEnable(true); } -void Log::log(LogFilterType filter, LogLevel level, char const* str, ...) -{ - if (!str || !ShouldLog(filter, level)) - return; - - va_list ap; - va_start(ap, str); - - vlog(filter, level, str, ap); - - va_end(ap); -} - void Log::vlog(LogFilterType filter, LogLevel level, char const* str, va_list argptr) { char text[MAX_QUERY_LEN]; diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index 7980df0d52a..b66e774b527 100755 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -45,8 +45,6 @@ class Log bool ShouldLog(LogFilterType type, LogLevel level) const; bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true); - void log(LogFilterType f, LogLevel level, char const* str, ...) ATTR_PRINTF(4,5); - void outTrace(LogFilterType f, char const* str, ...) ATTR_PRINTF(3,4); void outDebug(LogFilterType f, char const* str, ...) ATTR_PRINTF(3,4); void outInfo(LogFilterType f, char const* str, ...) ATTR_PRINTF(3,4); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 760fcfd48d9..1fa3148504a 100755 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -359,6 +359,28 @@ class ByteBuffer } } + uint32 ReadPackedTime() + { + uint32 packedDate = read<uint32>(); + tm lt; + memset(<, 0, sizeof(lt)); + + lt.tm_min = packedDate & 0x3F; + lt.tm_hour = (packedDate >> 6) & 0x1F; + //lt.tm_wday = (packedDate >> 11) & 7; + lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1; + lt.tm_mon = (packedDate >> 20) & 0xF; + lt.tm_year = ((packedDate >> 24) & 0x1F) + 100; + + return mktime(<) + timezone; + } + + ByteBuffer& ReadPackedTime(uint32& time) + { + time = ReadPackedTime(); + return *this; + } + const uint8 *contents() const { return &_storage[0]; } size_t size() const { return _storage.size(); } @@ -438,6 +460,12 @@ class ByteBuffer append(packGUID, size); } + void AppendPackedTime(time_t time) + { + tm* lt = localtime(&time); + append<uint32>((lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min); + } + void put(size_t pos, const uint8 *src, size_t cnt) { if (pos + cnt > size()) diff --git a/src/server/shared/Threading/Threading.h b/src/server/shared/Threading/Threading.h index 8b10e223828..7cc74574873 100755 --- a/src/server/shared/Threading/Threading.h +++ b/src/server/shared/Threading/Threading.h @@ -51,7 +51,7 @@ namespace ACE_Based Normal, High, Highest, - Realtime, + Realtime }; #define MAXPRIORITYNUM (Realtime + 1) diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index 9917bbb5309..89942b978df 100755 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -92,7 +92,7 @@ Tokens::Tokens(const std::string &src, const char sep, uint32 vectorReserve) void stripLineInvisibleChars(std::string &str) { - static std::string invChars = " \t\7\n"; + static std::string const invChars = " \t\7\n"; size_t wpos = 0; diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index 196882dc2a0..37782c31d8b 100755 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -48,12 +48,6 @@ std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hou uint32 TimeStringToSecs(const std::string& timestring); std::string TimeToTimestampStr(time_t t); -inline uint32 secsToTimeBitFields(time_t secs) -{ - tm* lt = localtime(&secs); - return (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min; -} - /* Return a random number in the range min..max; (max-min) must be smaller than 32768. */ int32 irand(int32 min, int32 max); @@ -89,22 +83,6 @@ inline bool roll_chance_i(int chance) return chance > irand(0, 99); } -inline void ApplyModUInt32Var(uint32& var, int32 val, bool apply) -{ - int32 cur = var; - cur += (apply ? val : -val); - if (cur < 0) - cur = 0; - var = cur; -} - -inline void ApplyModFloatVar(float& var, float val, bool apply) -{ - var += (apply ? val : -val); - if (var < 0) - var = 0; -} - inline void ApplyPercentModFloatVar(float& var, float val, bool apply) { if (val == -100.0f) // prevent set var to zero @@ -475,7 +453,7 @@ public: return 0; } return 0; - }; + } template<class type> inline bool operator < (type & right) const @@ -488,7 +466,7 @@ public: return 0; } return 0; - }; + } template<class type> inline bool operator != (type & right) @@ -508,7 +486,7 @@ public: || part[2]!=right.part[2]) return true; return false; - }; + } template<class type> inline bool operator == (type & right) @@ -518,7 +496,7 @@ public: || part[2]!=right.part[2]) return false; return true; - }; + } template<class type> inline bool operator == (type & right) const @@ -528,7 +506,7 @@ public: || part[2]!=right.part[2]) return false; return true; - }; + } template<class type> inline void operator = (type & right) @@ -536,7 +514,7 @@ public: part[0]=right.part[0]; part[1]=right.part[1]; part[2]=right.part[2]; - }; + } template<class type> inline flag96 operator & (type & right) @@ -544,20 +522,21 @@ public: flag96 ret(part[0] & right.part[0], part[1] & right.part[1], part[2] & right.part[2]); return ret; - }; + } + template<class type> inline flag96 operator & (type & right) const { flag96 ret(part[0] & right.part[0], part[1] & right.part[1], part[2] & right.part[2]); return ret; - }; + } template<class type> inline void operator &= (type & right) { *this=*this & right; - }; + } template<class type> inline flag96 operator | (type & right) @@ -565,7 +544,7 @@ public: flag96 ret(part[0] | right.part[0], part[1] | right.part[1], part[2] | right.part[2]); return ret; - }; + } template<class type> inline flag96 operator | (type & right) const @@ -573,13 +552,13 @@ public: flag96 ret(part[0] | right.part[0], part[1] | right.part[1], part[2] | right.part[2]); return ret; - }; + } template<class type> inline void operator |= (type & right) { *this=*this | right; - }; + } inline void operator ~ () { @@ -594,7 +573,7 @@ public: flag96 ret(part[0] ^ right.part[0], part[1] ^ right.part[1], part[2] ^ right.part[2]); return ret; - }; + } template<class type> inline flag96 operator ^ (type & right) const @@ -602,13 +581,13 @@ public: flag96 ret(part[0] ^ right.part[0], part[1] ^ right.part[1], part[2] ^ right.part[2]); return ret; - }; + } template<class type> inline void operator ^= (type & right) { *this=*this^right; - }; + } inline operator bool() const { diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index ce65517298f..55443f4253b 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -400,8 +400,8 @@ PersistentCharacterCleanFlags = 0 # # PidFile # Description: World daemon PID file -# Example: "./worldd.pid" - (Enabled) -# Default: "" - (Disabled) +# Example: "./world.pid" - (Enabled) +# Default: "" - (Disabled) PidFile = "" @@ -1210,6 +1210,14 @@ Warden.BanDuration = 86400 AllowTwoSide.Accounts = 1 # +# AllowTwoSide.Interaction.Calendar +# Description: Allow calendar invites between factions. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AllowTwoSide.Interaction.Calendar = 0 + +# # AllowTwoSide.Interaction.Chat # Description: Allow say chat between factions. # Default: 0 - (Disabled) diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index bde62c24c70..55a136f6329 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -43,5 +43,5 @@ add_dependencies(mapextractor mpq) if( UNIX ) install(TARGETS mapextractor DESTINATION bin) elseif( WIN32 ) - install(TARGETS mapextractor DESTINATION "${CMAKE_INSTALL_PREFIX}") + install(TARGETS mapextractor DESTINATION "${CMAKE_INSTALL_PREFIX}") endif() diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index f474925313e..d0342717324 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -9,6 +9,7 @@ #include "direct.h" #else #include <sys/stat.h> +#include <unistd.h> #endif #include "dbcfile.h" |