[8053] At character talents reset using chat command also reset talents for all character pets.

This applied to .reset talents and .reset all talents commands.
This commit is contained in:
VladimirMangos 2009-06-21 00:23:47 +04:00
parent 5564346c58
commit d56de2cd77
10 changed files with 152 additions and 36 deletions

View file

@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`required_8050_02_mangos_spell_bonus_data` bit(1) default NULL
`required_8053_01_mangos_command` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -461,12 +461,12 @@ INSERT INTO `command` VALUES
('reload config',3,'Syntax: .reload config\r\n\r\nReload config settings (by default stored in mangosd.conf). Not all settings can be change at reload: some new setting values will be ignored until restart, some values will applied with delay or only to new objects/maps, some values will explicitly rejected to change at reload.'),
('repairitems',2,'Syntax: .repairitems\r\n\r\nRepair all selected player''s items.'),
('reset achievements',3,'Syntax: .reset achievements [$playername]\r\n\r\nReset achievements data for selected or named (online or offline) character. Achievements for persistance progress data like completed quests/etc re-filled at reset. Achievements for events like kills/casts/etc will lost.'),
('reset all',3,'Syntax: .reset all spells\r\n\r\nSyntax: .reset all talents\r\n\r\nRequest reset spells or talents at next login each existed character.'),
('reset all',3,'Syntax: .reset all spells\r\n\r\nSyntax: .reset all talents\r\n\r\nRequest reset spells or talents (including talents for all character\'s pets if any) at next login each existed character.'),
('reset honor',3,'Syntax: .reset honor [Playername]\r\n Reset all honor data for targeted character.'),
('reset level',3,'Syntax: .reset level [Playername]\r\n Reset level to 1 including reset stats and talents. Equipped items with greater level requirement can be lost.'),
('reset spells',3,'Syntax: .reset spells [Playername]\r\n Removes all non-original spells from spellbook.\r\n. Playername can be name of offline character.'),
('reset stats',3,'Syntax: .reset stats [Playername]\r\n Resets(recalculate) all stats of the targeted player to their original VALUESat current level.'),
('reset talents',3,'Syntax: .reset talents [Playername]\r\n Removes all talents of the targeted player. Playername can be name of offline character.'),
('reset talents',3,'Syntax: .reset talents [Playername]\r\n Removes all talents of the targeted player or pet or named player. Playername can be name of offline character. With player talents also will be reset talents for all character\'s pets if any.'),
('respawn',3,'Syntax: .respawn\r\n\r\nRespawn selected creature or respawn all nearest creatures (if none selected) and GO without waiting respawn time expiration.'),
('revive',3,'Syntax: .revive\r\n\r\nRevive the selected player. If no player is selected, it will revive you.'),
('save',0,'Syntax: .save\r\n\r\nSaves your character.'),

View file

@ -0,0 +1,7 @@
ALTER TABLE db_version CHANGE COLUMN required_8050_02_mangos_spell_bonus_data required_8053_01_mangos_command bit;
DELETE FROM `command` WHERE `name` IN ('reset all','reset talents');
INSERT INTO `command` VALUES
('reset all',3,'Syntax: .reset all spells\r\n\r\nSyntax: .reset all talents\r\n\r\nRequest reset spells or talents (including talents for all character\'s pets if any) at next login each existed character.'),
('reset talents',3,'Syntax: .reset talents [Playername]\r\n Removes all talents of the targeted player or pet or named player. Playername can be name of offline character. With player talents also will be reset talents for all character\'s pets if any.');

View file

@ -228,6 +228,7 @@ pkgdata_DATA = \
8030_03_mangos_npc_trainer.sql \
8050_01_mangos_spell_proc_event.sql \
8050_02_mangos_spell_bonus_data.sql \
8053_01_mangos_command.sql \
README
## Additional files to include when running 'make dist'
@ -436,4 +437,5 @@ EXTRA_DIST = \
8030_03_mangos_npc_trainer.sql \
8050_01_mangos_spell_proc_event.sql \
8050_02_mangos_spell_bonus_data.sql \
8053_01_mangos_command.sql \
README

View file

@ -797,6 +797,10 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
SendDoFlight( mountDisplayId, path, startNode );
}
// reset for all pets before pet loading
if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
Pet::resetTalentsForAllPetsOf(pCurrChar);
// Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
pCurrChar->LoadPet();

View file

@ -4632,42 +4632,52 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
{
// Try reset talents as Hunter Pet
Creature* creature = getSelectedCreature();
if (!*args && creature && creature->isPet())
{
Unit *owner = creature->GetOwner();
if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner))
{
((Pet *)creature)->resetTalents(true);
((Player*)owner)->SendTalentsInfoData(true);
ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS);
if(!m_session || m_session->GetPlayer()!=((Player*)owner))
PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str());
}
return true;
}
SendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false;
}
if (target)
{
target->resetTalents(true);
target->SendTalentsInfoData(false);
ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
if (!m_session || m_session->GetPlayer()!=target)
PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str());
Pet* pet = target->GetPet();
Pet::resetTalentsForAllPetsOf(target,pet);
if(pet)
target->SendTalentsInfoData(true);
return true;
}
else if (target_guid)
{
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(target_guid) );
uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid) );
std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str());
return true;
}
// Try reset talents as Hunter Pet
Creature* creature = getSelectedCreature();
if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET)
{
((Pet *)creature)->resetTalents(true);
Unit *owner = creature->GetOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
{
Player* owner_player = (Player *)owner;
ChatHandler(owner_player).SendSysMessage(LANG_RESET_PET_TALENTS);
if(!m_session || m_session->GetPlayer()!=owner_player)
PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(owner_player).c_str());
}
return true;
}
SendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false;
@ -4692,7 +4702,7 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
}
else if(casename=="talents")
{
atLogin = AT_LOGIN_RESET_TALENTS;
atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
sWorld.SendWorldText(LANG_RESETALL_TALENTS);
if(!m_session)
SendSysMessage(LANG_RESETALL_TALENTS);

View file

@ -1547,6 +1547,10 @@ bool Pet::resetTalents(bool no_cost)
if (!owner || owner->GetTypeId()!=TYPEID_PLAYER)
return false;
// not need after this call
if(((Player*)owner)->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
((Player*)owner)->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS,true);
CreatureInfo const * ci = GetCreatureInfo();
if(!ci)
return false;
@ -1632,6 +1636,90 @@ bool Pet::resetTalents(bool no_cost)
return true;
}
void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/)
{
// not need after this call
if(((Player*)owner)->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
((Player*)owner)->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS,true);
// reset for online
if(online_pet)
online_pet->resetTalents(true);
// now need only reset for offline pets (all pets except online case)
uint32 except_petnumber = online_pet ? online_pet->GetCharmInfo()->GetPetNumber() : 0;
QueryResult *resultPets = CharacterDatabase.PQuery(
"SELECT id FROM character_pet WHERE owner = '%u' AND id <> '%u'",
owner->GetGUIDLow(),except_petnumber);
// no offline pets
if(!resultPets)
return;
QueryResult *result = CharacterDatabase.PQuery(
"SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet "
"WHERE character_pet.owner = '%u' AND character_pet.id = pet_spell.guid AND character_pet.id <> %u",
owner->GetGUIDLow(),except_petnumber);
if(!result)
{
delete resultPets;
return;
}
bool need_comma = false;
std::ostringstream ss;
ss << "DELETE FROM pet_spell WHERE guid IN (";
do
{
Field *fields = resultPets->Fetch();
uint32 id = fields[0].GetUInt32();
if(need_comma)
ss << ",";
ss << id;
need_comma = true;
}
while( resultPets->NextRow() );
delete resultPets;
ss << ") AND spell IN (";
bool need_execute = false;
do
{
Field *fields = result->Fetch();
uint32 spell = fields[0].GetUInt32();
if(!GetTalentSpellCost(spell))
continue;
if(need_execute)
ss << ",";
ss << spell;
need_execute = true;
}
while( result->NextRow() );
delete result;
if(!need_execute)
return;
ss << ")";
CharacterDatabase.Execute(ss.str().c_str());
}
void Pet::InitTalentForLevel()
{
uint32 level = getLevel();

View file

@ -208,6 +208,7 @@ class Pet : public Creature
void InitPetCreateSpells();
bool resetTalents(bool no_cost = false);
static void resetTalentsForAllPetsOf(Player* owner, Pet* online_pet = NULL);
uint32 resetTalentsCost() const;
void InitTalentForLevel();

View file

@ -3402,10 +3402,7 @@ bool Player::resetTalents(bool no_cost)
{
// not need after this call
if(HasAtLoginFlag(AT_LOGIN_RESET_TALENTS))
{
m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_TALENTS;
CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_TALENTS), GetGUIDLow());
}
RemoveAtLoginFlag(AT_LOGIN_RESET_TALENTS,true);
uint32 talentPointsForLevel = CalculateTalentsPoints();
@ -18088,10 +18085,7 @@ void Player::resetSpells()
{
// not need after this call
if(HasAtLoginFlag(AT_LOGIN_RESET_SPELLS))
{
m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_SPELLS;
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_SPELLS), GetGUIDLow());
}
RemoveAtLoginFlag(AT_LOGIN_RESET_SPELLS,true);
// make full copy of map (spells removed and marked as deleted at another spell remove
// and we can't use original map for safe iterative with visit each spell at loop end
@ -20298,3 +20292,11 @@ void Player::ActivateSpec(uint32 specNum)
resetTalents(true);
}
void Player::RemoveAtLoginFlag( AtLoginFlags f, bool in_db_also /*= false*/ )
{
m_atLoginFlags &= ~f;
if(in_db_also)
CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(f), GetGUIDLow());
}

View file

@ -507,11 +507,12 @@ enum PlayerExtraFlags
// 2^n values
enum AtLoginFlags
{
AT_LOGIN_NONE = 0,
AT_LOGIN_RENAME = 1,
AT_LOGIN_RESET_SPELLS = 2,
AT_LOGIN_RESET_TALENTS = 4,
AT_LOGIN_CUSTOMIZE = 8
AT_LOGIN_NONE = 0x00,
AT_LOGIN_RENAME = 0x01,
AT_LOGIN_RESET_SPELLS = 0x02,
AT_LOGIN_RESET_TALENTS = 0x04,
AT_LOGIN_CUSTOMIZE = 0x08,
AT_LOGIN_RESET_PET_TALENTS = 0x10,
};
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
@ -2007,6 +2008,7 @@ class MANGOS_DLL_SPEC Player : public Unit
bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; }
void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; }
void RemoveAtLoginFlag(AtLoginFlags f, bool in_db_also = false);
LookingForGroup m_lookingForGroup;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8052"
#define REVISION_NR "8053"
#endif // __REVISION_NR_H__