[11831] Implement player gear score calculation

Signed-off-by: Laise <fenrisse@gmail.com>
This commit is contained in:
C:/Program Files (x86)/git/dev/rsa 2011-10-17 16:13:06 +02:00 committed by Laise
parent fdc68c580d
commit 70a8a350d7
11 changed files with 246 additions and 4 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_11827_01_mangos_creature_linking_template` bit(1) default NULL `required_11831_02_mangos_command` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -581,6 +581,7 @@ INSERT INTO `command` VALUES
('event stop',2,'Syntax: .event stop #event_id\r\nStop event #event_id. Set start time for event to time in past that make current moment is event stop time (change not saved in DB).'), ('event stop',2,'Syntax: .event stop #event_id\r\nStop event #event_id. Set start time for event to time in past that make current moment is event stop time (change not saved in DB).'),
('explorecheat',3,'Syntax: .explorecheat #flag\r\n\r\nReveal or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\n\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'), ('explorecheat',3,'Syntax: .explorecheat #flag\r\n\r\nReveal or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\n\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'),
('flusharenapoints','3','Syntax: .flusharenapoints\r\n\r\nUse it to distribute arena points based on arena team ratings, and start a new week.'), ('flusharenapoints','3','Syntax: .flusharenapoints\r\n\r\nUse it to distribute arena points based on arena team ratings, and start a new week.'),
('gearscore',3,'Syntax: .gearscore [#withBags] [#withBank]\r\n\r\nShow selected player\'s gear score. Check items in bags if #withBags != 0 and check items in Bank if #withBank != 0. Default: 1 for bags and 0 for bank'),
('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'), ('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'),
('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'), ('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'),
('gm fly',3,'Syntax: .gm fly [on/off]\r\nEnable/disable gm fly mode.'), ('gm fly',3,'Syntax: .gm fly [on/off]\r\nEnable/disable gm fly mode.'),
@ -3965,6 +3966,7 @@ INSERT INTO `mangos_string` VALUES
(1189,'Yellow',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1189,'Yellow',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1190,'Amount of %s items is set to %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1190,'Amount of %s items is set to %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1191,'Items ratio for %s is set to %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1191,'Items ratio for %s is set to %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1193,'Gear Score of Player %s is %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1200,'You try to view cinemitic %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1201,'You try to view movie %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1202,'Spell %u %s = %f (*1.88 = %f) DB = %f AP = %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1202,'Spell %u %s = %f (*1.88 = %f) DB = %f AP = %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_11827_01_mangos_creature_linking_template required_11831_01_mangos_mangos_string bit;
delete from mangos_string where entry = 1193;
insert into mangos_string values (1193,'Gear Score of Player %s is %u.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_11831_01_mangos_mangos_string required_11831_02_mangos_command bit;
DELETE FROM command WHERE name = 'gearscore';
INSERT INTO command (name, security, help) VALUES
('gearscore',3,'Syntax: .gearscore [#withBags] [#withBank]\r\n\r\nShow selected player\'s gear score. Check items in bags if #withBags != 0 and check items in Bank if #withBank != 0. Default: 1 for bags and 0 for bank');

View file

@ -812,6 +812,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "stable", SEC_ADMINISTRATOR, false, &ChatHandler::HandleStableCommand, "", NULL }, { "stable", SEC_ADMINISTRATOR, false, &ChatHandler::HandleStableCommand, "", NULL },
{ "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
{ "quit", SEC_CONSOLE, true, &ChatHandler::HandleQuitCommand, "", NULL }, { "quit", SEC_CONSOLE, true, &ChatHandler::HandleQuitCommand, "", NULL },
{ "gearscore", SEC_ADMINISTRATOR, false, &ChatHandler::HandleShowGearScoreCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL } { NULL, 0, false, NULL, "", NULL }
}; };

View file

@ -597,6 +597,7 @@ class MANGOS_DLL_SPEC ChatHandler
bool HandleStableCommand(char* args); bool HandleStableCommand(char* args);
bool HandleWaterwalkCommand(char* args); bool HandleWaterwalkCommand(char* args);
bool HandleQuitCommand(char* args); bool HandleQuitCommand(char* args);
bool HandleShowGearScoreCommand(char* args);
//! Development Commands //! Development Commands
bool HandleSaveAllCommand(char* args); bool HandleSaveAllCommand(char* args);

View file

@ -938,7 +938,8 @@ enum MangosStrings
LANG_AHBOT_ITEMS_AMOUNT = 1190, LANG_AHBOT_ITEMS_AMOUNT = 1190,
LANG_AHBOT_ITEMS_RATIO = 1191, LANG_AHBOT_ITEMS_RATIO = 1191,
LANG_MOVEGENS_EFFECT = 1192, LANG_MOVEGENS_EFFECT = 1192,
// Room for more level 3 1193-1199 not used LANG_GEARSCORE = 1193,
// Room for more level 3 1194-1199 not used
// Debug commands // Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200, LANG_CINEMATIC_NOT_EXIST = 1200,

View file

@ -7074,3 +7074,31 @@ bool ChatHandler::HandleModifyGenderCommand(char *args)
return true; return true;
} }
bool ChatHandler::HandleShowGearScoreCommand(char *args)
{
Player *player = getSelectedPlayer();
if (!player)
{
PSendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
uint32 withBags, withBank;
if (!ExtractOptUInt32(&args, withBags, 1))
return false;
if (!ExtractOptUInt32(&args, withBank, 0))
return false;
// always recalculate gear score for display
player->ResetCachedGearScore();
uint32 gearScore = player->GetEquipGearScore(withBags != 0, withBank != 0);
PSendSysMessage(LANG_GEARSCORE, GetNameLink(player).c_str(), gearScore);
return true;
}

View file

@ -553,6 +553,8 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
m_lastFallTime = 0; m_lastFallTime = 0;
m_lastFallZ = 0; m_lastFallZ = 0;
m_cachedGS = 0;
} }
Player::~Player () Player::~Player ()
@ -22938,3 +22940,193 @@ void Player::SetRestType( RestType n_r_type, uint32 areaTriggerId /*= 0*/)
SetFFAPvP(false); SetFFAPvP(false);
} }
} }
uint32 Player::GetEquipGearScore(bool withBags, bool withBank)
{
if (withBags && withBank && m_cachedGS > 0)
return m_cachedGS;
GearScoreVec gearScore (EQUIPMENT_SLOT_END);
uint32 twoHandScore = 0;
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
gearScore[i] = 0;
}
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
_fillGearScoreData(item, &gearScore, twoHandScore);
}
if (withBags)
{
// check inventory
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
_fillGearScoreData(item, &gearScore, twoHandScore);
}
// check bags
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
{
if(Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
{
if (Item* item2 = pBag->GetItemByPos(j))
_fillGearScoreData(item2, &gearScore, twoHandScore);
}
}
}
}
if (withBank)
{
for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
_fillGearScoreData(item, &gearScore, twoHandScore);
}
for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
if (item->IsBag())
{
Bag* bag = (Bag*)item;
for (uint8 j = 0; j < bag->GetBagSize(); ++j)
{
if (Item* item2 = bag->GetItemByPos(j))
_fillGearScoreData(item2, &gearScore, twoHandScore);
}
}
}
}
}
uint8 count = EQUIPMENT_SLOT_END - 2; // ignore body and tabard slots
uint32 sum = 0;
// check if 2h hand is higher level than main hand + off hand
if ((gearScore[EQUIPMENT_SLOT_MAINHAND] + gearScore[EQUIPMENT_SLOT_OFFHAND]) / 2 < twoHandScore)
{
gearScore[EQUIPMENT_SLOT_OFFHAND] = 0; // off hand is ignored in calculations if 2h weapon has higher score
--count;
gearScore[EQUIPMENT_SLOT_MAINHAND] = twoHandScore;
}
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
sum += gearScore[i];
}
if (count)
{
uint32 res = uint32(sum / count);
DEBUG_LOG("Player: calculating gear score for %u. Result is %u", GetObjectGuid().GetCounter(), res);
if (withBags && withBank)
m_cachedGS = res;
return res;
}
else
return 0;
}
void Player::_fillGearScoreData(Item* item, GearScoreVec* gearScore, uint32& twoHandScore)
{
if (!item)
return;
if (CanUseItem(item->GetProto()) != EQUIP_ERR_OK)
return;
uint8 type = item->GetProto()->InventoryType;
uint32 level = item->GetProto()->ItemLevel;
switch (type)
{
case INVTYPE_2HWEAPON:
twoHandScore = std::max(twoHandScore, level);
break;
case INVTYPE_WEAPON:
case INVTYPE_WEAPONMAINHAND:
(*gearScore)[SLOT_MAIN_HAND] = std::max((*gearScore)[SLOT_MAIN_HAND], level);
break;
case INVTYPE_SHIELD:
case INVTYPE_WEAPONOFFHAND:
(*gearScore)[EQUIPMENT_SLOT_OFFHAND] = std::max((*gearScore)[EQUIPMENT_SLOT_OFFHAND], level);
break;
case INVTYPE_THROWN:
case INVTYPE_RANGEDRIGHT:
case INVTYPE_RANGED:
case INVTYPE_QUIVER:
case INVTYPE_RELIC:
(*gearScore)[EQUIPMENT_SLOT_RANGED] = std::max((*gearScore)[EQUIPMENT_SLOT_RANGED], level);
break;
case INVTYPE_HEAD:
(*gearScore)[EQUIPMENT_SLOT_HEAD] = std::max((*gearScore)[EQUIPMENT_SLOT_HEAD], level);
break;
case INVTYPE_NECK:
(*gearScore)[EQUIPMENT_SLOT_NECK] = std::max((*gearScore)[EQUIPMENT_SLOT_NECK], level);
break;
case INVTYPE_SHOULDERS:
(*gearScore)[EQUIPMENT_SLOT_SHOULDERS] = std::max((*gearScore)[EQUIPMENT_SLOT_SHOULDERS], level);
break;
case INVTYPE_BODY:
(*gearScore)[EQUIPMENT_SLOT_BODY] = std::max((*gearScore)[EQUIPMENT_SLOT_BODY], level);
break;
case INVTYPE_CHEST:
(*gearScore)[EQUIPMENT_SLOT_CHEST] = std::max((*gearScore)[EQUIPMENT_SLOT_CHEST], level);
break;
case INVTYPE_WAIST:
(*gearScore)[EQUIPMENT_SLOT_WAIST] = std::max((*gearScore)[EQUIPMENT_SLOT_WAIST], level);
break;
case INVTYPE_LEGS:
(*gearScore)[EQUIPMENT_SLOT_LEGS] = std::max((*gearScore)[EQUIPMENT_SLOT_LEGS], level);
break;
case INVTYPE_FEET:
(*gearScore)[EQUIPMENT_SLOT_FEET] = std::max((*gearScore)[EQUIPMENT_SLOT_FEET], level);
break;
case INVTYPE_WRISTS:
(*gearScore)[EQUIPMENT_SLOT_WRISTS] = std::max((*gearScore)[EQUIPMENT_SLOT_WRISTS], level);
break;
case INVTYPE_HANDS:
(*gearScore)[EQUIPMENT_SLOT_HEAD] = std::max((*gearScore)[EQUIPMENT_SLOT_HEAD], level);
break;
// equipped gear score check uses both rings and trinkets for calculation, assume that for bags/banks it is the same
// with keeping second highest score at second slot
case INVTYPE_FINGER:
{
if ((*gearScore)[EQUIPMENT_SLOT_FINGER1] < level)
{
(*gearScore)[EQUIPMENT_SLOT_FINGER2] = (*gearScore)[EQUIPMENT_SLOT_FINGER1];
(*gearScore)[EQUIPMENT_SLOT_FINGER1] = level;
}
else if ((*gearScore)[EQUIPMENT_SLOT_FINGER2] < level)
(*gearScore)[EQUIPMENT_SLOT_FINGER2] = level;
break;
}
case INVTYPE_TRINKET:
{
if ((*gearScore)[EQUIPMENT_SLOT_TRINKET1] < level)
{
(*gearScore)[EQUIPMENT_SLOT_TRINKET2] = (*gearScore)[EQUIPMENT_SLOT_TRINKET1];
(*gearScore)[EQUIPMENT_SLOT_TRINKET1] = level;
}
else if ((*gearScore)[EQUIPMENT_SLOT_TRINKET2] < level)
(*gearScore)[EQUIPMENT_SLOT_TRINKET2] = level;
break;
}
case INVTYPE_CLOAK:
(*gearScore)[EQUIPMENT_SLOT_BACK] = std::max((*gearScore)[EQUIPMENT_SLOT_BACK], level);
break;
default:
break;
}
}

View file

@ -1298,6 +1298,10 @@ class MANGOS_DLL_SPEC Player : public Unit
uint32 m_stableSlots; uint32 m_stableSlots;
uint32 GetEquipGearScore(bool withBags = true, bool withBank = false);
void ResetCachedGearScore() { m_cachedGS = 0; }
typedef std::vector<uint32/*item level*/> GearScoreVec;
/*********************************************************/ /*********************************************************/
/*** GOSSIP SYSTEM ***/ /*** GOSSIP SYSTEM ***/
/*********************************************************/ /*********************************************************/
@ -2590,6 +2594,8 @@ class MANGOS_DLL_SPEC Player : public Unit
m_DelayedOperations |= operation; m_DelayedOperations |= operation;
} }
void _fillGearScoreData(Item* item, GearScoreVec* gearScore, uint32& twoHandScore);
Unit *m_mover; Unit *m_mover;
Camera m_camera; Camera m_camera;
@ -2634,6 +2640,8 @@ class MANGOS_DLL_SPEC Player : public Unit
uint32 m_timeSyncTimer; uint32 m_timeSyncTimer;
uint32 m_timeSyncClient; uint32 m_timeSyncClient;
uint32 m_timeSyncServer; uint32 m_timeSyncServer;
uint32 m_cachedGS;
}; };
void AddItemsSetItem(Player*player,Item *item); void AddItemsSetItem(Player*player,Item *item);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11830" #define REVISION_NR "11831"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_11785_02_characters_instance" #define REVISION_DB_CHARACTERS "required_11785_02_characters_instance"
#define REVISION_DB_MANGOS "required_11827_01_mangos_creature_linking_template" #define REVISION_DB_MANGOS "required_11831_02_mangos_command"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__