/
white.sheikh
/
mangoszero-server
Обзор
Документация
Войти
/
white.sheikh
/
mangoszero-server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/game/Object/Formulas.h
445 строк
13 KB
Antz
Rename CreatureFlagsExtra Enum values to match other cores
31 янв 2023, 17:18
Не верифицирован
31 янв 2023, 17:18
b2382fc
Код
Авторство
О чём код?
/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2023 MaNGOS <https://getmangos.eu> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #ifndef MANGOS_FORMULAS_H #define MANGOS_FORMULAS_H #include "World.h" struct HonorScores { float FX[15]; float FY[15]; float BRK[14]; }; namespace MaNGOS { namespace Honor { inline float hk_honor_at_level(uint32 level, uint32 count = 1) { return (float)ceil(count * (-0.53177f + 0.59357f * exp((level + 23.54042f) / 26.07859f))); } // set passed rank info to default inline void InitRankInfo(HonorRankInfo& prk) { prk.positive = true; prk.rank = 0; prk.visualRank = 0; prk.maxRP = 2000.00f; prk.minRP = 0.00f; } inline HonorRankInfo CalculateRankInfo(HonorRankInfo prk) { if (prk.rank != 0) { int8 rank = prk.positive ? prk.rank - NEGATIVE_HONOR_RANK_COUNT - 1 : prk.rank - NEGATIVE_HONOR_RANK_COUNT; prk.maxRP = (rank) * 5000.00f; if (prk.maxRP < 0) // in negative rank case { prk.maxRP *= -1; } prk.minRP = prk.maxRP > 5000.0f ? prk.maxRP - 5000.00f : 2000.00f; prk.visualRank = prk.rank > NEGATIVE_HONOR_RANK_COUNT ? prk.rank - NEGATIVE_HONOR_RANK_COUNT : prk.rank * -1; } else { InitRankInfo(prk); } return prk; } // What is Player's rank... private, scout... inline HonorRankInfo CalculateHonorRank(float honor_points) { HonorRankInfo prk; InitRankInfo(prk); // rank none if (honor_points == 0) { return prk; } prk.positive = honor_points > 0; if (!prk.positive) { honor_points *= -1; } uint8 rCount = prk.positive ? POSITIVE_HONOR_RANK_COUNT - 2 : NEGATIVE_HONOR_RANK_COUNT; uint8 firstRank = prk.positive ? NEGATIVE_HONOR_RANK_COUNT + 1 : 1; if (honor_points < 2000.00f) { prk.rank = prk.positive ? firstRank : NEGATIVE_HONOR_RANK_COUNT; } else { if (honor_points > (rCount - 1) * 5000.00f) { prk.rank = prk.positive ? HONOR_RANK_COUNT - 1 : firstRank; } else { prk.rank = uint32(honor_points / 5000.00f) + firstRank; prk.rank = (prk.positive ? prk.rank + 1 : NEGATIVE_HONOR_RANK_COUNT - prk.rank); } } prk = CalculateRankInfo(prk); return prk; } inline HonorScores GenerateScores(HonorStandingList standingList, uint32 team) { HonorScores sc; // initialize the breakpoint values sc.BRK[13] = 0.002f; sc.BRK[12] = 0.007f; sc.BRK[11] = 0.017f; sc.BRK[10] = 0.037f; sc.BRK[ 9] = 0.077f; sc.BRK[ 8] = 0.137f; sc.BRK[ 7] = 0.207f; sc.BRK[ 6] = 0.287f; sc.BRK[ 5] = 0.377f; sc.BRK[ 4] = 0.477f; sc.BRK[ 3] = 0.587f; sc.BRK[ 2] = 0.715f; sc.BRK[ 1] = 0.858f; sc.BRK[ 0] = 1.000f; // get the WS scores at the top of each break point for (uint8 group = 0; group < 14; group++) { sc.BRK[group] = floor((sc.BRK[group] * standingList.size()) + 0.5f); } // initialize RP array // set the low point sc.FY[ 0] = 0; // the Y values for each breakpoint are fixed sc.FY[ 1] = 400; for (uint8 i = 2; i <= 13; i++) { sc.FY[i] = (i - 1) * 1000; } // and finally sc.FY[14] = 13000; // ... gets 13000 RP // the X values for each breakpoint are found from the CP scores // of the players around that point in the WS scores HonorStanding* tempSt; float honor; // initialize CP array sc.FX[ 0] = 0; for (uint8 i = 1; i <= 13; i++) { honor = 0.0f; tempSt = sObjectMgr.GetHonorStandingByPosition(sc.BRK[i], team); if (tempSt) { honor += tempSt->honorPoints; tempSt = sObjectMgr.GetHonorStandingByPosition(sc.BRK[i] + 1, team); if (tempSt) { honor += tempSt->honorPoints; } } sc.FX[i] = honor ? honor / 2 : 0; } // set the high point if FX full filled before sc.FX[14] = sc.FX[13] ? standingList.begin()->honorPoints : 0; // top scorer return sc; } inline float CalculateRpEarning(float CP, HonorScores sc) { // search the function for the two points that bound the given CP uint8 i = 0; while (i < 14 && sc.BRK[i] > 0 && sc.FX[i] <= CP) { i++; } // we now have i such that FX[i] > CP >= FX[i-1] // so interpolate return (sc.FY[i] - sc.FY[i - 1]) * (CP - sc.FX[i - 1]) / (sc.FX[i] - sc.FX[i - 1]) + sc.FY[i - 1]; } inline float CalculateRpDecay(float rpEarning, float RP) { float Decay = floor((0.2f * RP) + 0.5f); float Delta = rpEarning - Decay; if (Delta < 0) { Delta = Delta / 2; } if (Delta < -2500) { Delta = -2500; } return RP + Delta; } inline float DishonorableKillPoints(int level) { float result = 10; if (level >= 30 && level <= 35) { result = result + 1.5 * (level - 29); } if (level >= 36 && level <= 41) { result = result + 9 + 2 * (level - 35); } if (level >= 42 && level <= 50) { result = result + 21 + 3.2 * (level - 41); } if (level >= 51) { result = result + 50 + 4 * (level - 50); } if (result > 100) { return 100.0; } else { return result; } } inline float HonorableKillPoints(Player* killer, Player* victim, uint32 groupsize) { if (!killer || !victim || !groupsize) { return 0.0; } uint32 today = sWorld.GetDateToday(); int total_kills = killer->CalculateTotalKills(victim, today, today); // int k_rank = killer->CalculateHonorRank( killer->GetTotalHonor() ); uint32 v_rank = victim->GetHonorRankInfo().visualRank; uint32 k_level = killer->getLevel(); // int v_level = victim->getLevel(); float diff_honor = (victim->GetRankPoints() / (killer->GetRankPoints() + 1)) + 1; float diff_level = (victim->getLevel() * (1.0 / (killer->getLevel()))); int f = (10 - total_kills) >= 0 ? (10 - total_kills) : 0; int honor_points = int(((float)(f * 0.25) * (float)((k_level + (v_rank * 5 + 1)) * (1 + 0.05 * diff_honor) * diff_level))); return (honor_points <= 400 ? honor_points : 400) / groupsize; } } namespace XP { enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY }; inline uint32 GetGrayLevel(uint32 pl_level) { if (pl_level <= 5) { return 0; } else if (pl_level <= 39) { return pl_level - 5 - pl_level / 10; } else if (pl_level == 60) { return 51; } else { return pl_level - 1 - pl_level / 5; } } inline XPColorChar GetColorCode(uint32 pl_level, uint32 mob_level) { if (mob_level >= pl_level + 5) { return RED; } else if (mob_level >= pl_level + 3) { return ORANGE; } else if (mob_level >= pl_level - 2) { return YELLOW; } else if (mob_level > GetGrayLevel(pl_level)) { return GREEN; } else { return GRAY; } } inline uint32 GetZeroDifference(uint32 pl_level) { if (pl_level < 8) { return 5; } if (pl_level < 10) { return 6; } if (pl_level < 12) { return 7; } if (pl_level < 16) { return 8; } if (pl_level < 20) { return 9; } if (pl_level < 30) { return 11; } if (pl_level < 40) { return 12; } if (pl_level < 45) { return 13; } if (pl_level < 50) { return 14; } if (pl_level < 55) { return 15; } if (pl_level < 60) { return 16; } return 17; } inline uint32 BaseGain(uint32 pl_level, uint32 mob_level) { const uint32 nBaseExp = 45; if (mob_level >= pl_level) { uint32 nLevelDiff = mob_level - pl_level; if (nLevelDiff > 4) { nLevelDiff = 4; } return ((pl_level * 5 + nBaseExp) * (20 + nLevelDiff) / 10 + 1) / 2; } else { uint32 gray_level = GetGrayLevel(pl_level); if (mob_level > gray_level) { uint32 ZD = GetZeroDifference(pl_level); return (pl_level * 5 + nBaseExp) * (ZD + mob_level - pl_level) / ZD; } return 0; } } inline uint32 Gain(Player* pl, Unit* u) { if (u->GetTypeId() == TYPEID_UNIT && ( ((Creature*)u)->IsTotem() || ((Creature*)u)->IsPet() || (((Creature*)u)->GetCreatureInfo()->ExtraFlags & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL))) { return 0; } uint32 xp_gain = BaseGain(pl->getLevel(), u->getLevel()); if (xp_gain == 0) { return 0; } if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->IsElite()) { xp_gain *= 2; } return (uint32)(xp_gain * sWorld.getConfig(CONFIG_FLOAT_RATE_XP_KILL)); } inline float xp_in_group_rate(uint32 count, bool isRaid) { if (isRaid) { // FIX ME: must apply decrease modifiers dependent from raid size return 1.0f; } else { switch (count) { case 0: case 1: case 2: return 1.0f; case 3: return 1.166f; case 4: return 1.3f; case 5: default: return 1.4f; } } } } } #endif