diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/server/game/DataStores/DBCStores.cpp | 2 | ||||
| -rwxr-xr-x | src/server/game/DataStores/DBCStores.h | 1 | ||||
| -rwxr-xr-x | src/server/game/DataStores/DBCStructure.h | 24 | ||||
| -rwxr-xr-x | src/server/game/DataStores/DBCfmt.h | 3 | ||||
| -rwxr-xr-x | src/server/game/DungeonFinding/LFGMgr.h | 2 | ||||
| -rw-r--r-- | src/server/game/DungeonFinding/LFGScripts.cpp | 1 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.h | 35 | ||||
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 53 | ||||
| -rwxr-xr-x | src/server/game/Maps/MapManager.cpp | 2 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_tele.cpp | 23 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp | 2 |
12 files changed, 121 insertions, 29 deletions
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index faa73cefb11..6815d73d1b3 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -71,6 +71,7 @@ DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt); DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt); DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt); +DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt); DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt); DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt); DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt); @@ -292,6 +293,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 367746616d1..7edfaad03f1 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -81,6 +81,7 @@ extern DBCStorage <ChrRacesEntry> sChrRacesStore; extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore; extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore; +extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore; extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore; extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore; extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index e01acd2e03d..ba7be495c77 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -723,7 +723,7 @@ struct CinematicSequencesEntry struct CreatureDisplayInfoEntry { uint32 Displayid; // 0 m_ID - // 1 m_modelID + uint32 ModelId; // 1 m_modelID // 2 m_soundID // 3 m_extendedDisplayInfoID float scale; // 4 m_creatureModelScale @@ -754,6 +754,28 @@ struct CreatureFamilyEntry // 27 m_iconFile }; +struct CreatureModelDataEntry +{ + uint32 Id; + //uint32 Flags; + //char* ModelPath[16] + //uint32 Unk1; + float Scale; // Used in calculation of unit collision data + //int32 Unk2 + //int32 Unk3 + //uint32 Unk4 + //uint32 Unk5 + //float Unk6 + //uint32 Unk7 + //float Unk8 + //uint32 Unk9 + //uint32 Unk10 + //float CollisionWidth; + float CollisionHeight; + float MountHeight; // Used in calculation of unit collision data when mounted + //float Unks[11] +}; + #define MAX_CREATURE_SPELL_DATA_SLOT 4 struct CreatureSpellDataEntry diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 5d33a3011ab..ac0b60d7f80 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -38,8 +38,9 @@ const char ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; const char CinematicSequencesEntryfmt[]="nxxxxxxxxx"; -const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx"; +const char CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxx"; const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx"; +const char CreatureModelDatafmt[]="nxxxfxxxxxxxxxxffxxxxxxxxxxx"; const char CreatureSpellDatafmt[]="niiiixxxx"; const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx"; const char CurrencyTypesfmt[]="xnxi"; diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 0d11405789d..95cb2e81869 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -292,6 +292,7 @@ class LFGMgr LfgState GetState(uint64 guid); const LfgDungeonSet& GetSelectedDungeons(uint64 guid); uint32 GetDungeon(uint64 guid, bool asId = true); + void SetState(uint64 guid, LfgState state); void ClearState(uint64 guid); void RemovePlayerData(uint64 guid); void RemoveGroupData(uint64 guid); @@ -304,7 +305,6 @@ class LFGMgr uint8 GetRoles(uint64 guid); const std::string& GetComment(uint64 gguid); void RestoreState(uint64 guid); - void SetState(uint64 guid, LfgState state); void SetDungeon(uint64 guid, uint32 dungeon); void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons); void SetLockedDungeons(uint64 guid, const LfgLockMap& lock); diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index f553b069162..42119a02ef8 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -82,6 +82,7 @@ void LFGScripts::OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, } sLFGMgr->ClearState(guid); + sLFGMgr->SetState(guid, LFG_STATE_NONE); if (Player* player = ObjectAccessor::FindPlayer(guid)) { /* diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index bb39d902ae7..9aad63ccb1b 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2493,6 +2493,41 @@ class Player : public Unit, public GridObject<Player> void AddWhisperWhiteList(uint64 guid) { WhisperList.push_back(guid); } bool IsInWhisperWhiteList(uint64 guid); + //! Return collision height sent to client + float GetCollisionHeight(bool mounted) + { + if (mounted) + { + CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID)); + if (!mountDisplayInfo) + return GetCollisionHeight(false); + + CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId); + if (!mountModelData) + return GetCollisionHeight(false); + + CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()); + ASSERT(displayInfo); + CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId); + ASSERT(modelData); + + float scaleMod = GetFloatValue(OBJECT_FIELD_SCALE_X); // 99% sure about this + + return scaleMod * mountModelData->MountHeight + modelData->CollisionHeight * 0.5f; + } + else + { + //! Dismounting case - use basic default model data + CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()); + ASSERT(displayInfo); + CreatureModelDataEntry const* modelData = sCreatureModelDataStore.LookupEntry(displayInfo->ModelId); + ASSERT(modelData); + + return modelData->CollisionHeight; + } + //! TODO: Need a proper calculation for collision height when mounted + } + protected: // Gamemaster whisper whitelist WhisperListContainer WhisperList; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e74712299c0..b99ccd5f35f 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5242,6 +5242,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere break; case CLASS_ROGUE: // 39511, 40997, 40998, 41002, 41005, 41011 case CLASS_WARRIOR: // 39511, 40997, 40998, 41002, 41005, 41011 + case CLASS_DEATH_KNIGHT: triggered_spell_id = RAND(39511, 40997, 40998, 41002, 41005, 41011); cooldown_spell_id = 39511; break; @@ -6290,7 +6291,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere { if (procSpell->SpellVisual[0] == 750 && procSpell->Effects[1].ApplyAuraName == 3) { - if (target->GetTypeId() == TYPEID_UNIT) + if (target && target->GetTypeId() == TYPEID_UNIT) { triggered_spell_id = 54820; break; @@ -9232,10 +9233,9 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const if (GetCharmerOrOwnerOrSelf() == target->GetCharmerOrOwnerOrSelf()) return REP_FRIENDLY; - // this is 0x8 in the 13580 client - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { - if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { Player const* selfPlayerOwner = GetAffectingPlayer(); Player const* targetPlayerOwner = target->GetAffectingPlayer(); @@ -11934,6 +11934,12 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) else player->UnsummonPetTemporaryIfAny(); } + + WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); + data.append(GetPackGUID()); + data << uint32(sWorld->GetGameTime()); // Packet counter + data << player->GetCollisionHeight(true); + player->GetSession()->SendPacket(&data); } RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT); @@ -11947,6 +11953,15 @@ void Unit::Unmount() SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); + if (Player* thisPlayer = ToPlayer()) + { + WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); + data.append(GetPackGUID()); + data << uint32(sWorld->GetGameTime()); // Packet counter + data << thisPlayer->GetCollisionHeight(false); + thisPlayer->GetSession()->SendPacket(&data); + } + WorldPacket data(SMSG_DISMOUNT, 8); data.appendPackGUID(GetGUID()); SendMessageToSet(&data, true); @@ -12166,29 +12181,21 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) return false; - //! since 'this' in the client's context of this function *always* resembles the _player_ (feel free to correct me), - //! in the server context we will ignore the this->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) (possibly misnamed) check for non-players. - //! Feel free to change this if a more proper solution is found. - bool ignoreOwnOOCFlag = true; if (Player const* playerAttacker = ToPlayer()) { - ignoreOwnOOCFlag = false; if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UNK19)) return false; } - // check flags - // UNIT_FLAG_PLAYER_CONTROLLED is 0x8 in 13580 if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_TAXI_FLIGHT | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_UNK_16) - || (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)) - || (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)) - //! Also notable: in CGUnit_C__CanAttack the third parameter is a boolean that determines if the following flag check is exempted or not - || (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) - || (!ignoreOwnOOCFlag && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))) + || (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)) + || (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE)) + || (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) + || (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))) return false; // CvC case - can attack each other only when one of them is hostile - if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE; // PvP, PvC, CvP case @@ -12201,8 +12208,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co if (creatureAttacker && creatureAttacker->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_UNK26) return false; - Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? GetAffectingPlayer() : NULL; - Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? target->GetAffectingPlayer() : NULL; + Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? GetAffectingPlayer() : NULL; + Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? target->GetAffectingPlayer() : NULL; // check duel - before sanctuary checks if (playerAffectingAttacker && playerAffectingTarget) @@ -12211,7 +12218,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co // PvP case - can't attack when attacker or target are in sanctuary // however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp - if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && ((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY) || (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY))) return false; @@ -12289,10 +12296,10 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co return false; // PvP case - if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { Player const* targetPlayerOwner = target->GetAffectingPlayer(); - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) { Player const* selfPlayerOwner = GetAffectingPlayer(); if (selfPlayerOwner && targetPlayerOwner) @@ -12314,7 +12321,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co } // PvC case - player can assist creature only if has specific type flags // !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && - else if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) + else if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_UNK3)) && !((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_PVP))) { diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 78aeb32ab2d..22eaa77cc94 100755 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -248,7 +248,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) instaceIdToCheck = save->GetInstanceId(); // instanceId can never be 0 - will not be found - if (!player->CheckInstanceCount(instaceIdToCheck)) + if (!player->CheckInstanceCount(instaceIdToCheck) && !player->isDead()) { player->SendTransferAborted(mapid, TRANSFER_ABORT_TOO_MANY_INSTANCES); return false; diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index df7816f7cb9..311a94d4217 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1329,7 +1329,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x514*/ { "SMSG_SEND_ALL_COMBAT_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x515*/ { "SMSG_OPEN_LFG_DUNGEON_FINDER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x516*/ { "SMSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x517*/ { "CMSG_MOVE_SET_COLLISION_HGT_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x517*/ { "CMSG_MOVE_SET_COLLISION_HGT_ACK", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x518*/ { "MSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x519*/ { "CMSG_CLEAR_RANDOM_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x51A*/ { "CMSG_CLEAR_HOLIDAY_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index 85e0ff2390b..8bfa010463a 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -125,6 +125,29 @@ public: if (!handler->extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) return false; + if (strcmp(teleStr, "$home") == 0) // References target's homebind + { + if (target) + target->TeleportTo(target->m_homebindMapId, target->m_homebindX, target->m_homebindY, target->m_homebindZ, target->GetOrientation()); + else + { + QueryResult resultDB = CharacterDatabase.PQuery("SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = %u", target_guid); + if (resultDB) + { + Field* fieldsDB = resultDB->Fetch(); + uint32 mapId = fieldsDB[0].GetUInt32(); + uint32 zoneId = fieldsDB[1].GetUInt32(); + float posX = fieldsDB[2].GetFloat(); + float posY = fieldsDB[3].GetFloat(); + float posZ = fieldsDB[4].GetFloat(); + + Player::SavePositionInDB(mapId, posX, posY, posZ, 0, zoneId, target_guid); + } + } + + return true; + } + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r GameTele const* tele = handler->extractGameTeleFromLink(teleStr); if (!tele) 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 38f334058b8..2f4f225561c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -1335,7 +1335,7 @@ class npc_shambling_horror_icc : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& damage) { - if (IsHeroic() && me->HealthBelowPctDamaged(20, damage)) + if (!_frenzied && IsHeroic() && me->HealthBelowPctDamaged(20, damage)) { _frenzied = true; DoCast(me, SPELL_FRENZY, true); |
