diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStores.cpp | 40 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStores.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStructure.h | 5 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCfmt.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 12 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 59 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Formulas.h | 57 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 4 |
10 files changed, 89 insertions, 97 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index cf8701dc0d7..8c82a3c051e 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -37,7 +37,7 @@ enum LevelLimit // Client expected level limitation, like as used in DBC item max levels for "until max player level" // use as default max player level, must be fit max level for used client // also see MAX_LEVEL and STRONG_MAX_LEVEL define - DEFAULT_MAX_LEVEL = 85, + DEFAULT_MAX_LEVEL = 100, // client supported max level for player/pets/etc. Avoid overflow or client stability affected. // also see GT_MAX_LEVEL define diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 20788fde81d..d0d5fbeb9b8 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -124,6 +124,7 @@ GameTable <GtNpcTotalHpExp3Entry> sGtNpcTotalHpExp3Store(GtNpcTotalHpExp3 GameTable <GtNpcTotalHpExp4Entry> sGtNpcTotalHpExp4Store(GtNpcTotalHpExp4fmt); GameTable <GtNpcTotalHpExp5Entry> sGtNpcTotalHpExp5Store(GtNpcTotalHpExp5fmt); GameTable <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt); +GameTable <GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore(GtOCTLevelExperiencefmt); GameTable <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt); GameTable <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore(GtOCTHpPerStaminafmt); GameTable <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); @@ -746,6 +747,7 @@ void LoadDBCStores(const std::string& dataPath) LoadGameTable(bad_dbc_files, "NpcTotalHpExp5", sGtNpcTotalHpExp5Store, dbcPath, "gtNpcTotalHpExp5.dbc"); // 19445 LoadGameTable(bad_dbc_files, "OCTClassCombatRatingScalar", sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc");//19342 LoadGameTable(bad_dbc_files, "OCTHPPerStamina", sGtOCTHpPerStaminaStore, dbcPath, "gtOCTHpPerStamina.dbc");//19342 + LoadGameTable(bad_dbc_files, "OCTLevelExperience", sGtOCTLevelExperienceStore, dbcPath, "gtOCTLevelExperience.dbc"); // 19342 LoadGameTable(bad_dbc_files, "RegenMPPerSpt", sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc");//19342 LoadGameTable(bad_dbc_files, "SpellScaling", sGtSpellScalingStore, dbcPath, "gtSpellScaling.dbc");//19342 LoadGameTable(bad_dbc_files, "OCTBaseHPByClass", sGtOCTBaseHPByClassStore, dbcPath, "gtOCTBaseHPByClass.dbc");//19342 @@ -897,32 +899,20 @@ uint32 GetMaxLevelForExpansion(uint32 expansion) return 0; } -/* -Used only for calculate xp gain by content lvl. -Calculation on Gilneas and group maps of LostIslands calculated as CONTENT_1_60. -*/ -ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) +uint32 GetExpansionForLevel(uint32 level) { - mapid = GetVirtualMapForMapAndZone(mapid, zoneId); - if (mapid < 2) - return CONTENT_1_60; - - MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); - if (!mapEntry) - return CONTENT_1_60; - - // no need enum all maps from phasing - if (mapEntry->ParentMapID >= 0) - mapid = mapEntry->ParentMapID; - - switch (mapid) - { - case 648: //LostIslands - case 654: //Gilneas - return CONTENT_1_60; - default: - return ContentLevels(mapEntry->Expansion()); - } + if (level < 60) + return EXPANSION_CLASSIC; + else if (level < 70) + return EXPANSION_THE_BURNING_CRUSADE; + else if (level < 80) + return EXPANSION_WRATH_OF_THE_LICH_KING; + else if (level < 85) + return EXPANSION_CATACLYSM; + else if (level < 90) + return EXPANSION_MISTS_OF_PANDARIA; + else if (level < 100) + return EXPANSION_WARLORDS_OF_DRAENOR; } bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 7c20baf5e55..8f21d07eb1a 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -59,6 +59,7 @@ enum ContentLevels }; uint32 GetMaxLevelForExpansion(uint32 expansion); +uint32 GetExpansionForLevel(uint32 level); ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); @@ -187,6 +188,7 @@ extern GameTable <GtNpcTotalHpExp3Entry> sGtNpcTotalHpExp3Store; extern GameTable <GtNpcTotalHpExp4Entry> sGtNpcTotalHpExp4Store; extern GameTable <GtNpcTotalHpExp5Entry> sGtNpcTotalHpExp5Store; extern GameTable <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore; +extern GameTable <GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore; extern GameTable <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore; extern GameTable <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore; extern GameTable <GtSpellScalingEntry> sGtSpellScalingStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 8451c955fc2..15a2f537547 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -890,6 +890,11 @@ struct GtOCTClassCombatRatingScalarEntry float ratio; }; +struct GtOCTLevelExperienceEntry +{ + float Data; +}; + struct GtOCTRegenHPEntry { float ratio; diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 3999ec61675..ef707738fd9 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -68,6 +68,7 @@ char const GlyphSlotfmt[] = "nix"; char const GtBarberShopCostBasefmt[] = "xf"; char const GtCombatRatingsfmt[] = "xf"; char const GtOCTHpPerStaminafmt[] = "df"; +char const GtOCTLevelExperiencefmt[] = "xf"; char const GtChanceToMeleeCritBasefmt[] = "xf"; char const GtChanceToMeleeCritfmt[] = "xf"; char const GtChanceToSpellCritBasefmt[] = "xf"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5f1042bb93a..2ec00d8f818 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -512,14 +512,10 @@ inline void KillRewarder::_RewardXP(Player* player, float rate) for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) AddPct(xp, (*i)->GetAmount()); - // 4.2.3. Calculate expansion penalty - if (_victim->GetTypeId() == TYPEID_UNIT && player->getLevel() >= GetMaxLevelForExpansion(_victim->ToCreature()->GetCreatureTemplate()->expansion)) - xp = CalculatePct(xp, 10); // Players get only 10% xp for killing creatures of lower expansion levels than himself - - // 4.2.4. Give XP to player. + // 4.2.3. Give XP to player. player->GiveXP(xp, _victim, _groupRate); if (Pet* pet = player->GetPet()) - // 4.2.5. If player has pet, reward pet with XP (100% for single player, 50% for group case). + // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case). pet->GivePetXP(_group ? xp / 2 : xp); } } @@ -6630,7 +6626,7 @@ int32 Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr break; } - if (rate != 1.0f && creatureOrQuestLevel <= Trinity::XP::GetGrayLevel(getLevel())) + if (rate != 1.0f && creatureOrQuestLevel < Trinity::XP::GetGrayLevel(getLevel())) percent *= rate; if (percent <= 0.0f) @@ -24032,7 +24028,7 @@ bool Player::isHonorOrXPTarget(Unit const* victim) const uint8 k_grey = Trinity::XP::GetGrayLevel(getLevel()); // Victim level less gray level - if (v_level <= k_grey) + if (v_level < k_grey) return false; if (Creature const* const creature = victim->ToCreature()) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index e44d1eeb016..b8352794c06 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3293,52 +3293,57 @@ void ObjectMgr::LoadPlayerInfo() for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) _playerXPperLevel[level] = 0; - // 0 1 - QueryResult result = WorldDatabase.Query("SELECT lvl, xp_for_next_level FROM player_xp_for_level"); + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT Level, Experience FROM player_xp_for_level"); - if (!result) + // load the DBC's levels at first... + GtOCTLevelExperienceEntry const* exp; + for (int level = 0; level < MAX_LEVEL; ++level) { - TC_LOG_ERROR("server.loading", ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty."); - exit(1); + exp = sGtOCTLevelExperienceStore.EvaluateTable(level, 0); + _playerXPperLevel[level + 1] = exp->Data; } uint32 count = 0; - do + // ...overwrite if needed (custom values) + if (result) { - Field* fields = result->Fetch(); + do + { + Field* fields = result->Fetch(); - uint32 current_level = fields[0].GetUInt8(); - uint32 current_xp = fields[1].GetUInt32(); + uint32 current_level = fields[0].GetUInt16(); + uint32 current_xp = uint32(fields[1].GetFloat()); - if (current_level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum - TC_LOG_ERROR("sql.sql", "Wrong (> %u) level %u in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL, current_level); - else + if (current_level >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { - TC_LOG_INFO("misc", "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_xp_for_levels` table, ignoring.", current_level); - ++count; // make result loading percent "expected" correct in case disabled detail mode for example. + if (current_level > STRONG_MAX_LEVEL) // hardcoded level maximum + TC_LOG_ERROR("sql.sql", "Wrong (> %u) level %u in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL, current_level); + else + { + TC_LOG_INFO("misc", "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_xp_for_level` table, ignoring.", current_level); + ++count; // make result loading percent "expected" correct in case disabled detail mode for example. + } + continue; } - continue; - } - //PlayerXPperLevel - _playerXPperLevel[current_level] = current_xp; - ++count; + //PlayerXPperLevel + _playerXPperLevel[current_level] = current_xp; + ++count; + } while (result->NextRow()); } - while (result->NextRow()); - // fill level gaps + // fill level gaps - only accounting levels > MAX_LEVEL for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) { if (_playerXPperLevel[level] == 0) { - TC_LOG_ERROR("sql.sql", "Level %i does not have XP for level data. Using data of level [%i] + 100.", level + 1, level); - _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 100; + TC_LOG_ERROR("sql.sql", "Level %i does not have XP for level data. Using data of level [%i] + 12000.", level + 1, level); + _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 12000; } } - TC_LOG_INFO("server.loading", ">> Loaded %u xp for level definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u xp for level definition(s) from database in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } } @@ -8368,7 +8373,7 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit void ObjectMgr::LoadCreatureClassLevelStats() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 16 + // 0 1 2 3 4 5 6 7 8 9 10 11 QueryResult result = WorldDatabase.Query("SELECT level, class, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, damage_exp3, damage_exp4, damage_exp5 FROM creature_classlevelstats"); if (!result) diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index bdc78479494..7e26f2336e2 100644 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -47,14 +47,18 @@ namespace Trinity { uint8 level; - if (pl_level <= 5) + if (pl_level < 7) level = 0; - else if (pl_level <= 39) - level = pl_level - 5 - pl_level / 10; - else if (pl_level <= 59) - level = pl_level - 1 - pl_level / 5; + else if (pl_level < 35) + { + uint8 count = 0; + for (int i = 15; i <= pl_level; ++i) + if (i % 5 == 0) ++count; + + level = (pl_level - 7) - (count - 1); + } else - level = pl_level - 9; + level = pl_level - 10; sScriptMgr->OnGrayLevelCalculation(level, pl_level); return level; @@ -83,7 +87,7 @@ namespace Trinity { uint8 diff; - if (pl_level < 8) + if (pl_level < 4) diff = 5; else if (pl_level < 10) diff = 6; @@ -112,30 +116,15 @@ namespace Trinity return diff; } - inline uint32 BaseGain(uint8 pl_level, uint8 mob_level, ContentLevels content) + inline uint32 BaseGain(uint8 pl_level, uint8 mob_level) { uint32 baseGain; - uint32 nBaseExp; - switch (content) - { - case CONTENT_1_60: - nBaseExp = 45; - break; - case CONTENT_61_70: - nBaseExp = 235; - break; - case CONTENT_71_80: - nBaseExp = 580; - break; - case CONTENT_81_85: - nBaseExp = 1878; - break; - default: - TC_LOG_ERROR("misc", "BaseGain: Unsupported content level %u", content); - nBaseExp = 45; - break; - } + GtOCTLevelExperienceEntry const* BaseExpPlayer = sGtOCTLevelExperienceStore.EvaluateTable(pl_level - 1, 1); + GtOCTLevelExperienceEntry const* BaseExpMob = sGtOCTLevelExperienceStore.EvaluateTable(mob_level - 1, 1); + + GtOCTLevelExperienceEntry const* CoefPlayer = sGtOCTLevelExperienceStore.EvaluateTable(pl_level - 1, 4); + GtOCTLevelExperienceEntry const* CoefMob = sGtOCTLevelExperienceStore.EvaluateTable(mob_level - 1, 4); if (mob_level >= pl_level) { @@ -143,7 +132,7 @@ namespace Trinity if (nLevelDiff > 4) nLevelDiff = 4; - baseGain = ((pl_level * 5 + nBaseExp) * (20 + nLevelDiff) / 10 + 1) / 2; + baseGain = BaseExpPlayer->Data * (1 + 0.05 * nLevelDiff); } else { @@ -151,13 +140,13 @@ namespace Trinity if (mob_level > gray_level) { uint8 ZD = GetZeroDifference(pl_level); - baseGain = (pl_level * 5 + nBaseExp) * (ZD + mob_level - pl_level) / ZD; + baseGain = round(BaseExpMob->Data * ((1 - ((pl_level - mob_level) / float(ZD))) * (CoefMob->Data / CoefPlayer->Data))); } else baseGain = 0; } - sScriptMgr->OnBaseGainCalculation(baseGain, pl_level, mob_level, content); + sScriptMgr->OnBaseGainCalculation(baseGain, pl_level, mob_level); return baseGain; } @@ -171,10 +160,14 @@ namespace Trinity { float xpMod = 1.0f; - gain = BaseGain(player->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(), u->GetZoneId())); + gain = BaseGain(player->getLevel(), u->getLevel()); if (gain && creature) { + // Players get only 10% xp for killing creatures of lower expansion levels than himself + if ((creature->GetCreatureTemplate()->expansion < GetExpansionForLevel(player->getLevel()))) + gain = uint32(round(gain / 10.0f)); + if (creature->isElite()) { // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus. diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 9c49958f10a..735328a0f1f 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -519,9 +519,9 @@ void ScriptMgr::OnZeroDifferenceCalculation(uint8& diff, uint8 playerLevel) FOREACH_SCRIPT(FormulaScript)->OnZeroDifferenceCalculation(diff, playerLevel); } -void ScriptMgr::OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content) +void ScriptMgr::OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel) { - FOREACH_SCRIPT(FormulaScript)->OnBaseGainCalculation(gain, playerLevel, mobLevel, content); + FOREACH_SCRIPT(FormulaScript)->OnBaseGainCalculation(gain, playerLevel, mobLevel); } void ScriptMgr::OnGainCalculation(uint32& gain, Player* player, Unit* unit) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 0e9cdd9808f..b3e4a2314db 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -294,7 +294,7 @@ class FormulaScript : public ScriptObject virtual void OnZeroDifferenceCalculation(uint8& /*diff*/, uint8 /*playerLevel*/) { } // Called after calculating base experience gain. - virtual void OnBaseGainCalculation(uint32& /*gain*/, uint8 /*playerLevel*/, uint8 /*mobLevel*/, ContentLevels /*content*/) { } + virtual void OnBaseGainCalculation(uint32& /*gain*/, uint8 /*playerLevel*/, uint8 /*mobLevel*/) { } // Called after calculating experience gain. virtual void OnGainCalculation(uint32& /*gain*/, Player* /*player*/, Unit* /*unit*/) { } @@ -944,7 +944,7 @@ class ScriptMgr void OnGrayLevelCalculation(uint8& grayLevel, uint8 playerLevel); void OnColorCodeCalculation(XPColorChar& color, uint8 playerLevel, uint8 mobLevel); void OnZeroDifferenceCalculation(uint8& diff, uint8 playerLevel); - void OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content); + void OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel); void OnGainCalculation(uint32& gain, Player* player, Unit* unit); void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid); |