From 6cd78a520a61ba59ecf721f47fc5ac9166b139e5 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 16 Nov 2011 10:31:38 +0100 Subject: Core/World * Update character name cache after player rename * Add character name data for characters loaded with PlayerDump Closes #3653 Closes #3970 --- .../game/Server/Protocol/Handlers/CharacterHandler.cpp | 4 +++- src/server/game/Tools/PlayerDump.cpp | 12 +++++++++--- src/server/game/World/World.cpp | 14 +++++++++----- src/server/game/World/World.h | 6 +++--- 4 files changed, 24 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp index 512cccb9bc9..6863ef17685 100755 --- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp @@ -1170,6 +1170,8 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std: data << uint64(guid); data << newname; SendPacket(&data); + + sWorld->UpdateCharacterNameData(guidLow, newname); } void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) @@ -1634,7 +1636,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("UPDATE `characters` SET name='%s', race='%u', at_login=at_login & ~ %u WHERE guid='%u'", newname.c_str(), race, used_loginFlag, lowGuid); trans->PAppend("DELETE FROM character_declinedname WHERE guid ='%u'", lowGuid); - sWorld->UpdateCharacterNameData(GUID_LOPART(guid), newname, gender, race); + sWorld->UpdateCharacterNameData(GUID_LOPART(guid), newname, gender, race); BattlegroundTeamId team = BG_TEAM_ALLIANCE; diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 92fa001fe46..bdb912aa8b0 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -443,6 +443,9 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s typedef PetIds::value_type PetIdsPair; PetIds petids; + uint8 gender; + uint8 race; + uint8 playerClass; SQLTransaction trans = CharacterDatabase.BeginTransaction(); while (!feof(fin)) { @@ -512,6 +515,9 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s if (!changenth(line, 2, chraccount)) // characters.account update ROLLBACK(DUMP_FILE_BROKEN); + race = uint8(atol(getnth(line, 4).c_str())); + playerClass = uint8(atol(getnth(line, 5).c_str())); + gender = uint8(atol(getnth(line, 6).c_str())); if (name == "") { // check if the original name already exists @@ -520,10 +526,8 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str()); if (result) - { if (!changenth(line, 37, "1")) // characters.at_login set to "rename on login" ROLLBACK(DUMP_FILE_BROKEN); - } } else if (!changenth(line, 3, name.c_str())) // characters.name ROLLBACK(DUMP_FILE_BROKEN); @@ -654,6 +658,9 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s CharacterDatabase.CommitTransaction(trans); + // in case of name conflict player has to rename at login anyway + sWorld->AddCharacterNameData(guid, name, gender, race, playerClass); + sObjectMgr->m_hiItemGuid += items.size(); sObjectMgr->m_mailid += mails.size(); @@ -664,4 +671,3 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s return DUMP_SUCCESS; } - diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 408db187aae..8aca4563b91 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2869,7 +2869,7 @@ void World::LoadCharacterNameData() sLog->outString("Loaded name data for %u characters", count); } -void World::AddCharacterNameData(uint32 guid, const std::string& name, uint8 gender, uint8 race, uint8 playerClass) +void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass) { CharacterNameData& data = _characterNameDataMap[guid]; data.m_name = name; @@ -2878,18 +2878,22 @@ void World::AddCharacterNameData(uint32 guid, const std::string& name, uint8 gen data.m_class = playerClass; } -void World::UpdateCharacterNameData(uint32 guid, const std::string& name, uint8 gender, uint8 race) +void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender /*= GENDER_NONE*/, uint8 race /*= RACE_NONE*/) { std::map::iterator itr = _characterNameDataMap.find(guid); if (itr == _characterNameDataMap.end()) return; + itr->second.m_name = name; - itr->second.m_gender = gender; - if(race != RACE_NONE) + + if (gender != GENDER_NONE) + itr->second.m_gender = gender; + + if (race != RACE_NONE) itr->second.m_race = race; } -const CharacterNameData* World::GetCharacterNameData(uint32 guid) const +CharacterNameData const* World::GetCharacterNameData(uint32 guid) const { std::map::const_iterator itr = _characterNameDataMap.find(guid); if (itr != _characterNameDataMap.end()) diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index b493b8b0c7b..f643ae60287 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -738,9 +738,9 @@ class World bool isEventKillStart; - const CharacterNameData* GetCharacterNameData(uint32 guid) const; - void AddCharacterNameData(uint32 guid, const std::string& name, uint8 gender, uint8 race, uint8 playerClass); - void UpdateCharacterNameData(uint32 guid, const std::string& name, uint8 gender, uint8 race = RACE_NONE); + CharacterNameData const* GetCharacterNameData(uint32 guid) const; + void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass); + void UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender = GENDER_NONE, uint8 race = RACE_NONE); void DeleteCharaceterNameData(uint32 guid) { _characterNameDataMap.erase(guid); } uint32 GetCleaningFlags() const { return m_CleaningFlags; } -- cgit v1.2.3 From c67af87eda3001a141288cfc55a39cc233719618 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 16 Nov 2011 19:09:51 +0100 Subject: Core/Spells: Fix SPELL_EFFECT_SEND_EVENT handler being executed more than once when targets != (0, 0). Closes #3934 --- src/server/game/Spells/SpellEffects.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3767b6ba560..db48f2b8693 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2141,6 +2141,16 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex) && effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; + //! it's possible for spells with this spell effect to either have a target or no target + //! in case of a target, we will execute this handler on SPELL_EFFECT_HANDLE_HIT_TARGET + //! with all relevant variables, and we will skip SPELL_EFFECT_HANDLE_HIT + if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT) + { + if (GetSpellInfo()->Effects[effIndex].TargetA.GetTarget() != 0 || + GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() != 0) + return; + } + WorldObject* target = NULL; // call events for target if present -- cgit v1.2.3 From 70b558dd391d4b43b68bbc85a3149ad26b08403f Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 16 Nov 2011 21:02:37 +0100 Subject: Core/Units: Fix Unit::_IsValidAttackTarget (UNIT_FLAG_OOC_NOT_ATTACKABLE check specifically) Closes #3172 --- src/server/game/Entities/Unit/Unit.cpp | 9 ++++++++- .../UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c685417a835..04ede4576cb 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12165,17 +12165,24 @@ 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 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_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)) + //! 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_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))) + || (!ignoreOwnOOCFlag && 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 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 55211f3f047..dc2d34326a7 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 @@ -130,7 +130,7 @@ public: me->SetHealth(0); me->InterruptNonMeleeSpells(true); me->RemoveAllAuras(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->GetMotionMaster()->MovementExpired(false); me->GetMotionMaster()->MoveIdle(); me->SetStandState(UNIT_STAND_STATE_DEAD); @@ -152,7 +152,7 @@ public: { bIsUndead = true; bEventInProgress = false; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->UpdateEntry(MOB_INGVAR_UNDEAD); me->SetInCombatWith(me->getVictim()); me->GetMotionMaster()->MoveChase(me->getVictim()); -- cgit v1.2.3 From 8ea8dd4f3d0f73599aad6441925b8ab555939877 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 16 Nov 2011 23:12:31 +0100 Subject: Core/Units: Replace wrong usage of UNIT_FLAG_PVP_ATTACKABLE with UNIT_FLAG_PLAYER_CONTROLLED in Unit::IsValidAttackTarget, Unit::IsValidAssistTarget and Unit::GetReactionTo. Using 4.1 flags in 3.3.5 doesn't always work out like it should... Also remove now unneeded change from 70b558d Fixes SPELL_AURA_FORCE_REACTION amongst other things --- src/server/game/Entities/Unit/Unit.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 04ede4576cb..e74712299c0 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -9232,9 +9232,10 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const if (GetCharmerOrOwnerOrSelf() == target->GetCharmerOrOwnerOrSelf()) return REP_FRIENDLY; - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) + // this is 0x8 in the 13580 client + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { - if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { Player const* selfPlayerOwner = GetAffectingPlayer(); Player const* targetPlayerOwner = target->GetAffectingPlayer(); @@ -12177,16 +12178,17 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co } // 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_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_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_PVP_ATTACKABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)) - || (!ignoreOwnOOCFlag && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))) + || (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))) return false; // CvC case - can attack each other only when one of them is hostile - if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) + if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE; // PvP, PvC, CvP case @@ -12199,8 +12201,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_PVP_ATTACKABLE) ? GetAffectingPlayer() : NULL; - Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? target->GetAffectingPlayer() : NULL; + 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; // check duel - before sanctuary checks if (playerAffectingAttacker && playerAffectingTarget) @@ -12209,7 +12211,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_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && ((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY) || (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY))) return false; @@ -12287,10 +12289,10 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co return false; // PvP case - if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) + if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { Player const* targetPlayerOwner = target->GetAffectingPlayer(); - if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)) + if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { Player const* selfPlayerOwner = GetAffectingPlayer(); if (selfPlayerOwner && targetPlayerOwner) @@ -12312,7 +12314,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_PVP_ATTACKABLE) + else if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && (!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_UNK3)) && !((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_PVP))) { -- cgit v1.2.3 From 28d1cc9cfe8ba1b7f30f0d918b40eaf6d54170b3 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Thu, 17 Nov 2011 19:05:25 +0100 Subject: Core/Units: Fix more issues in Unit::_IsValidAttackTarget. (Documentation on changes compared to the client function included) --- src/server/game/Entities/Unit/Unit.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e74712299c0..718c2e95fe5 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12166,13 +12166,8 @@ 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; } @@ -12184,11 +12179,12 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co || (!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))) + || (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && 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 (GetTypeId() == TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) + && target->GetTypeId() == TYPEID_UNIT && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE; // PvP, PvC, CvP case @@ -12201,8 +12197,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 = GetAffectingPlayer(); + Player const* playerAffectingTarget = target->GetAffectingPlayer(); // check duel - before sanctuary checks if (playerAffectingAttacker && playerAffectingTarget) @@ -12211,8 +12207,10 @@ 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) - && ((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY) || (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY))) + //! Machiavelli edit: I don't know if the unit flag check is correct here. In the above checks UNIT_FLAG_PVP_ATTACKABLE (0x80 in 12340) was replaced + //! with the proper flag which has 0x80 in 13580 - however I cannot find proof if this flag is correctly used here or not. + 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; // additional checks - only PvP case -- cgit v1.2.3 From cab3def3a4f81a9763f9bea84864e7aa9ae6f794 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sun, 20 Nov 2011 12:56:14 +0100 Subject: Core/Units: Revert previous 3 commits about Unit::_IsValidAttackTarget and Unit::GetReactionn until some conclusive research can be done --- src/server/game/Entities/Unit/Unit.cpp | 35 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 718c2e95fe5..c685417a835 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -9232,10 +9232,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(); @@ -12171,20 +12170,16 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co 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)) - || (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 (GetTypeId() == TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) - && target->GetTypeId() == TYPEID_UNIT && !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 @@ -12197,8 +12192,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 = GetAffectingPlayer(); - Player const* playerAffectingTarget = target->GetAffectingPlayer(); + 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) @@ -12207,10 +12202,8 @@ 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 - //! Machiavelli edit: I don't know if the unit flag check is correct here. In the above checks UNIT_FLAG_PVP_ATTACKABLE (0x80 in 12340) was replaced - //! with the proper flag which has 0x80 in 13580 - however I cannot find proof if this flag is correctly used here or not. - 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))) + 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; // additional checks - only PvP case @@ -12287,10 +12280,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) @@ -12312,7 +12305,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))) { -- cgit v1.2.3 From 831f2f4a9dedb6ca4ef422bd725ca7b95a2988c2 Mon Sep 17 00:00:00 2001 From: thumsoul Date: Sun, 20 Nov 2011 13:43:58 +0100 Subject: Core/Commands: Allow "$home" to be second parameter of .tele name, to teleport players to homebind Signed-off-by: Machiavelli --- sql/updates/world/2011_11_20_world_command.sql | 1 + src/server/scripts/Commands/cs_tele.cpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 sql/updates/world/2011_11_20_world_command.sql (limited to 'src') diff --git a/sql/updates/world/2011_11_20_world_command.sql b/sql/updates/world/2011_11_20_world_command.sql new file mode 100644 index 00000000000..ad276641f9b --- /dev/null +++ b/sql/updates/world/2011_11_20_world_command.sql @@ -0,0 +1 @@ +UPDATE `commands` SET `help`='Syntax: .tele name [#playername] #location\n\nTeleport the given character to a given location. Character can be offline.\n\nTo teleport to homebind, set #location to "$home" (without quotes).' WHERE `name` = 'tele name`; diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index 85e0ff2390b..9ee05361953 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) -- cgit v1.2.3 From 682c3289c71b4135c41f0fe6628f1b71bace47d2 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sun, 20 Nov 2011 13:46:53 +0100 Subject: Tabs --- src/server/scripts/Commands/cs_tele.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index 9ee05361953..8bfa010463a 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -125,15 +125,15 @@ public: if (!handler->extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) return false; - if (strcmp(teleStr, "$home") == 0) // References target's homebind - { + 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(); -- cgit v1.2.3 From 32bcee40bf3e1197873b04ae78e6adb41a651d81 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sun, 20 Nov 2011 16:04:41 +0100 Subject: Core/Spells: Fix crash in Glyph of Rake --- src/server/game/Entities/Unit/Unit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c685417a835..dc1c4105fea 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6290,7 +6290,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; -- cgit v1.2.3