diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 3 | ||||
| -rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 21 | ||||
| -rwxr-xr-x | src/server/game/Globals/ObjectMgr.h | 2 | ||||
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 57 | ||||
| -rw-r--r-- | src/server/game/Tools/PlayerDump.cpp | 4 | ||||
| -rwxr-xr-x | src/server/game/World/World.cpp | 16 | ||||
| -rwxr-xr-x | src/server/game/World/World.h | 4 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_character.cpp | 2 | ||||
| -rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.cpp | 6 | ||||
| -rw-r--r-- | src/server/shared/Database/Implementation/CharacterDatabase.h | 2 |
10 files changed, 97 insertions, 20 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8fc519b2f4a..c1f7a5a1fe5 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13659,6 +13659,9 @@ void Unit::SetLevel(uint8 lvl) // group update if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetGroup()) ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_LEVEL); + + if (GetTypeId() == TYPEID_PLAYER) + sWorld->UpdateCharacterNameDataLevel(ToPlayer()->GetGUIDLow(), lvl); } void Unit::SetHealth(uint32 val) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 95a27fd14e1..b28f8be7805 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -7590,6 +7590,27 @@ SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spell_id) return SpellScriptsBounds(_spellScriptsStore.lower_bound(spell_id), _spellScriptsStore.upper_bound(spell_id)); } +// this allows calculating base reputations to offline players, just by race and class +int32 ObjectMgr::GetBaseReputation(FactionEntry const* factionEntry, uint8 race, uint8 playerClass) +{ + if (!factionEntry) + return 0; + + uint32 raceMask = (1 << (race - 1)); + uint32 classMask = (1 << (playerClass-1)); + + for (int i = 0; i < 4; i++) + { + if ((!factionEntry->BaseRepClassMask[i] || + factionEntry->BaseRepClassMask[i] & classMask) && + (!factionEntry->BaseRepRaceMask[i] || + factionEntry->BaseRepRaceMask[i] & raceMask)) + return factionEntry->BaseRepValue[i]; + } + + return 0; +} + SkillRangeType GetSkillRangeType(SkillLineEntry const* pSkill, bool racial) { switch (pSkill->categoryId) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index bbd95e22685..7871bbe3239 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -749,6 +749,8 @@ class ObjectMgr return NULL; } + int32 GetBaseReputation(FactionEntry const* factionEntry, uint8 race, uint8 playerClass); + RepSpilloverTemplate const* GetRepSpilloverTemplate(uint32 factionId) const { RepSpilloverTemplateContainer::const_iterator itr = _repSpilloverTemplateStore.find(factionId); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 5c603e46086..853e71fd732 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -660,7 +660,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte std::string IP_str = GetRemoteAddress(); sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow()); sScriptMgr->OnPlayerCreate(&newChar); - sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass()); + sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass(), newChar.getLevel()); newChar.CleanupsBeforeDelete(); delete createInfo; @@ -1625,10 +1625,14 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) uint32 lowGuid = GUID_LOPART(guid); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN); + // get the players old (at this moment current) race + CharacterNameData const* nameData = sWorld->GetCharacterNameData(lowGuid); + uint8 oldRace = nameData->m_race; + uint8 playerClass = nameData->m_class; + uint8 level = nameData->m_level; + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES); stmt->setUInt32(0, lowGuid); - PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) @@ -1640,11 +1644,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) } Field* fields = result->Fetch(); - uint32 playerClass = uint32(fields[0].GetUInt8()); - uint32 level = uint32(fields[1].GetUInt8()); - uint32 at_loginFlags = fields[2].GetUInt16(); + uint32 at_loginFlags = fields[0].GetUInt16(); + char const* knownTitlesStr = fields[1].GetCString(); uint32 used_loginFlag = ((recv_data.GetOpcode() == CMSG_CHAR_RACE_CHANGE) ? AT_LOGIN_CHANGE_RACE : AT_LOGIN_CHANGE_FACTION); - char const* knownTitlesStr = fields[3].GetCString(); if (!sObjectMgr->GetPlayerInfo(race, playerClass)) { @@ -2003,16 +2005,47 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) { uint32 reputation_alliance = it->first; uint32 reputation_horde = it->second; + uint32 newReputation = (team == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde; + uint32 oldReputation = (team == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance; + + // select old standing set in db + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION); + stmt->setUInt32(0, oldReputation); + stmt->setUInt32(1, lowGuid); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (!result) + { + WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1); + data << uint8(CHAR_CREATE_ERROR); + SendPacket(&data); + return; + } + + Field* fields = result->Fetch(); + int32 oldDBRep = fields[0].GetInt32(); + FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION); - stmt->setUInt32(0, uint16(team == TEAM_ALLIANCE ? reputation_alliance : reputation_horde)); + // old base reputation + int32 oldBaseRep = sObjectMgr->GetBaseReputation(factionEntry, oldRace, playerClass); + + // new base reputation + int32 newBaseRep = sObjectMgr->GetBaseReputation(sFactionStore.LookupEntry(newReputation), race, playerClass); + + // final reputation shouldnt change + int32 FinalRep = oldDBRep + oldBaseRep; + int32 newDBRep = FinalRep - newBaseRep; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION); + stmt->setUInt32(0, newReputation); stmt->setUInt32(1, lowGuid); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE); - stmt->setUInt16(0, uint16(team == TEAM_ALLIANCE ? reputation_alliance : reputation_horde)); - stmt->setUInt16(1, uint16(team == TEAM_ALLIANCE ? reputation_horde : reputation_alliance)); - stmt->setUInt32(2, lowGuid); + stmt->setUInt16(0, uint16(newReputation)); + stmt->setInt32(1, newDBRep); + stmt->setUInt16(2, uint16(oldReputation)); + stmt->setUInt32(3, lowGuid); trans->Append(stmt); } diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index f6d0de28d28..ef516a0ba4f 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -457,6 +457,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s uint8 gender = GENDER_NONE; uint8 race = RACE_NONE; uint8 playerClass = 0; + uint8 level = 1; SQLTransaction trans = CharacterDatabase.BeginTransaction(); while (!feof(fin)) @@ -531,6 +532,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s race = uint8(atol(getnth(line, 4).c_str())); playerClass = uint8(atol(getnth(line, 5).c_str())); gender = uint8(atol(getnth(line, 6).c_str())); + level = uint8(atol(getnth(line, 7).c_str())); if (name == "") { // check if the original name already exists @@ -674,7 +676,7 @@ 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); + sWorld->AddCharacterNameData(guid, name, gender, race, playerClass, level); sObjectMgr->_hiItemGuid += items.size(); sObjectMgr->_mailId += mails.size(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index eef53e17774..06e8d3eccbe 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2937,7 +2937,7 @@ void World::LoadCharacterNameData() { sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading character name data"); - QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class FROM characters WHERE deleteDate IS NULL"); + QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class, level FROM characters WHERE deleteDate IS NULL"); if (!result) { sLog->outInfo(LOG_FILTER_SERVER_LOADING, "No character name data loaded, empty query"); @@ -2950,20 +2950,21 @@ void World::LoadCharacterNameData() { Field* fields = result->Fetch(); AddCharacterNameData(fields[0].GetUInt32(), fields[1].GetString(), - fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/); + fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/, fields[5].GetUInt8() /*level*/); ++count; } while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loaded name data for %u characters", count); } -void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass) +void World::AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level) { CharacterNameData& data = _characterNameDataMap[guid]; data.m_name = name; data.m_race = race; data.m_gender = gender; data.m_class = playerClass; + data.m_level = level; } void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender /*= GENDER_NONE*/, uint8 race /*= RACE_NONE*/) @@ -2981,6 +2982,15 @@ void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 itr->second.m_race = race; } +void World::UpdateCharacterNameDataLevel(uint32 guid, uint8 level) +{ + std::map<uint32, CharacterNameData>::iterator itr = _characterNameDataMap.find(guid); + if (itr == _characterNameDataMap.end()) + return; + + itr->second.m_level = level; +} + CharacterNameData const* World::GetCharacterNameData(uint32 guid) const { std::map<uint32, CharacterNameData>::const_iterator itr = _characterNameDataMap.find(guid); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 90bb82f1c2e..66b52549e93 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -538,6 +538,7 @@ struct CharacterNameData uint8 m_class; uint8 m_race; uint8 m_gender; + uint8 m_level; }; /// The World @@ -759,8 +760,9 @@ class World bool isEventKillStart; CharacterNameData const* GetCharacterNameData(uint32 guid) const; - void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass); + void AddCharacterNameData(uint32 guid, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level); void UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 gender = GENDER_NONE, uint8 race = RACE_NONE); + void UpdateCharacterNameDataLevel(uint32 guid, uint8 level); void DeleteCharaceterNameData(uint32 guid) { _characterNameDataMap.erase(guid); } uint32 GetCleaningFlags() const { return m_CleaningFlags; } diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index f5fbfa33cae..080b2416c9a 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -224,7 +224,7 @@ public: stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA); stmt->setUInt32(0, delInfo.lowGuid); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) - sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8()); + sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8(), (*result)[2].GetUInt8()); } static void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel, ChatHandler* handler) diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index add782cf517..c29d8313c20 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -49,7 +49,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender, level FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC); @@ -421,6 +421,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, "SELECT class, level, at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_AT_LOGIN_TITLES, "SELECT at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_PET_SPELL_LIST, "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet WHERE character_pet.owner = ? AND character_pet.id = pet_spell.guid AND character_pet.id <> ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_CHAR_PET, "SELECT id FROM character_pet WHERE owner = ? AND id <> ?", CONNECTION_SYNCH); @@ -497,8 +498,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, "UPDATE item_instance ii, character_inventory ci SET ii.itemEntry = ? WHERE ii.itemEntry = ? AND ci.guid = ? AND ci.item = ii.guid", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL_BY_SPELL, "DELETE FROM character_spell WHERE spell = ? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, "UPDATE character_spell SET spell = ? where spell = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_CHAR_REP_BY_FACTION, "SELECT standing FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_CHAR_REP_BY_FACTION, "DELETE FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ? where faction = ? AND guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ?, standing = ? WHERE faction = ? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET knownTitles = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_RES_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET chosenTitle = 0 WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_SPELL_COOLDOWN, "DELETE FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index fedf0022fcc..88018997e4b 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -384,6 +384,7 @@ enum CharacterDatabaseStatements CHAR_SEL_POOL_QUEST_SAVE, CHAR_SEL_CHARACTER_AT_LOGIN, CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, + CHAR_SEL_CHAR_AT_LOGIN_TITLES, CHAR_SEL_INSTANCE, CHAR_SEL_PET_SPELL_LIST, CHAR_SEL_CHAR_PET, @@ -460,6 +461,7 @@ enum CharacterDatabaseStatements CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, CHAR_DEL_CHAR_SPELL_BY_SPELL, CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, + CHAR_SEL_CHAR_REP_BY_FACTION, CHAR_DEL_CHAR_REP_BY_FACTION, CHAR_UPD_CHAR_REP_FACTION_CHANGE, CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, |
