mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[7168] Spell shift-link and command improvements.
* Support Htrade shift link (it created by client at click by crafting profession spell icon in spellbook) in spell comands. * Support "all" second arg for .learn for learning not provided spell id but it's all ranks. * Drop support range for .unlearn command but support instead "all" second arg for unlearn not specific spell id but it's all ranks. * In .list auras output print spell names as shift links for better readable view. * Add to beggining Chat.cpp lists all supported by commands shift-links (client generated and server-side)
This commit is contained in:
parent
ae5b65765d
commit
4dc06d6d9e
9 changed files with 148 additions and 83 deletions
|
|
@ -22,7 +22,7 @@
|
|||
DROP TABLE IF EXISTS `db_version`;
|
||||
CREATE TABLE `db_version` (
|
||||
`version` varchar(120) default NULL,
|
||||
`required_7156_01_mangos_spell_proc_event` bit(1) default NULL
|
||||
`required_7168_01_mangos_command` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -322,7 +322,7 @@ INSERT INTO `command` VALUES
|
|||
('instance savedata',3,'Syntax: .instance savedata\r\n Save the InstanceData for the current player\'s map to the DB.'),
|
||||
('itemmove',2,'Syntax: .itemmove #sourceslotid #destinationslotid\r\n\r\nMove an item from slots #sourceslotid to #destinationslotid in your inventory\r\n\r\nNot yet implemented'),
|
||||
('kick',2,'Syntax: .kick [$charactername]\r\n\r\nKick the given character name from the world. If no character name is provided then the selected player (except for yourself) will be kicked.'),
|
||||
('learn',3,'Syntax: .learn #parameter\r\n\r\nSelected character learn a spell of id #parameter.'),
|
||||
('learn',3,'Syntax: .learn #spell [all]\r\n\r\nSelected character learn a spell of id #spell. If \'all\' provided then all ranks learned.'),
|
||||
('learn all',3,'Syntax: .learn all\r\n\r\nLearn all big set different spell maybe useful for Administaror.'),
|
||||
('learn all_crafts',2,'Syntax: .learn crafts\r\n\r\nLearn all professions and recipes.'),
|
||||
('learn all_default',1,'Syntax: .learn all_default [$playername]\r\n\r\nLearn for selected/$playername player all default spells for his race/class and spells rewarded by completed quests.'),
|
||||
|
|
@ -464,7 +464,7 @@ INSERT INTO `command` VALUES
|
|||
('unban account',3,'Syntax is: unban account $Name\r\nUnban accounts for account name pattern.'),
|
||||
('unban character',3,'Syntax is: unban character $Name\r\nUnban accounts for character name pattern.'),
|
||||
('unban ip',3,'Syntax is: unban ip $Ip\r\nUnban accounts for IP pattern.'),
|
||||
('unlearn',3,'Syntax: .unlearn #startspell #endspell\r\n\r\nUnlearn for selected player the range of spells between id #startspell and #endspell. If no #endspell is provided, just unlearn spell of id #startspell.'),
|
||||
('unlearn',3,'Syntax: .unlearn #spell [all]\r\n\r\nUnlearn for selected player a spell #spell. If \'all\' provided then all ranks unlearned.'),
|
||||
('unmute',1,'Syntax: .unmute $playerName\r\n\r\nRestore chat messaging for any character from account of character $playerName.'),
|
||||
('waterwalk',2,'Syntax: .waterwalk on/off\r\n\r\nSet on/off waterwalk state for selected player.'),
|
||||
('wchange',3,'Syntax: .wchange #weathertype #status\r\n\r\nSet current weather to #weathertype with an intensity of #status.\r\n\r\n#weathertype can be 1 for rain, 2 for snow, and 3 for sand. #status can be 0 for disabled, and 1 for enabled.'),
|
||||
|
|
|
|||
6
sql/updates/7168_01_mangos_command.sql
Normal file
6
sql/updates/7168_01_mangos_command.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7156_01_mangos_spell_proc_event required_7168_01_mangos_command bit;
|
||||
|
||||
DELETE FROM `command` WHERE `name` IN ('learn','unlearn');
|
||||
INSERT INTO `command` VALUES
|
||||
('learn',3,'Syntax: .learn #spell [all]\r\n\r\nSelected character learn a spell of id #spell. If \'all\' provided then all ranks learned.'),
|
||||
('unlearn',3,'Syntax: .unlearn #spell [all]\r\n\r\nUnlearn for selected player a spell #spell. If \'all\' provided then all ranks unlearned.');
|
||||
|
|
@ -150,6 +150,7 @@ pkgdata_DATA = \
|
|||
7149_01_mangos_spell_proc_event.sql \
|
||||
7150_01_mangos_playercreateinfo_spell.sql \
|
||||
7156_01_mangos_spell_proc_event.sql \
|
||||
7168_01_mangos_command.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -280,4 +281,5 @@ EXTRA_DIST = \
|
|||
7149_01_mangos_spell_proc_event.sql \
|
||||
7150_01_mangos_playercreateinfo_spell.sql \
|
||||
7156_01_mangos_spell_proc_event.sql \
|
||||
7168_01_mangos_command.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -33,6 +33,22 @@
|
|||
#include "CellImpl.h"
|
||||
#include "AccountMgr.h"
|
||||
|
||||
// Supported shift-links (client generated and server side)
|
||||
// |color|Harea:area_id|h[name]|h|r
|
||||
// |color|Hcreature:creature_guid|h[name]|h|r
|
||||
// |color|Hcreature_entry:creature_id|h[name]|h|r
|
||||
// |color|Hgameevent:id|h[name]|h|r
|
||||
// |color|Hgameobject:go_guid|h[name]|h|r
|
||||
// |color|Hgameobject_entry:go_id|h[name]|h|r
|
||||
// |color|Hitem:item_id:perm_ench_id:0:0|h[name]|h|r
|
||||
// |color|Hitemset:itemset_id|h[name]|h|r
|
||||
// |color|Hquest:quest_id|h[name]|h|r
|
||||
// |color|Hskill:skill_id|h[name]|h|r
|
||||
// |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
|
||||
// |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click
|
||||
// |color|Htele:id|h[name]|h|r
|
||||
// |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
|
||||
|
||||
bool ChatHandler::load_command_table = true;
|
||||
|
||||
ChatCommand * ChatHandler::getCommandTable()
|
||||
|
|
@ -1236,9 +1252,18 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid
|
|||
return obj;
|
||||
}
|
||||
|
||||
static char const* const spellTalentKeys[] = {
|
||||
"Hspell",
|
||||
"Htalent",
|
||||
enum SpellLinkType
|
||||
{
|
||||
SPELL_LINK_SPELL = 0,
|
||||
SPELL_LINK_TALENT = 1,
|
||||
SPELL_LINK_TRADE = 2
|
||||
};
|
||||
|
||||
static char const* const spellKeys[] =
|
||||
{
|
||||
"Hspell", // normal spell
|
||||
"Htalent", // talent spell
|
||||
"Htrade", // profession/skill spell
|
||||
0
|
||||
};
|
||||
|
||||
|
|
@ -1246,31 +1271,41 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
|
|||
{
|
||||
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
|
||||
// number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
|
||||
// number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
|
||||
int type = 0;
|
||||
char* rankS = NULL;
|
||||
char* idS = extractKeyFromLink(text,spellTalentKeys,&type,&rankS);
|
||||
char* param1_str = NULL;
|
||||
char* idS = extractKeyFromLink(text,spellKeys,&type,¶m1_str);
|
||||
if(!idS)
|
||||
return 0;
|
||||
|
||||
uint32 id = (uint32)atol(idS);
|
||||
|
||||
// spell
|
||||
if(type==0)
|
||||
return id;
|
||||
switch(type)
|
||||
{
|
||||
case SPELL_LINK_SPELL:
|
||||
return id;
|
||||
case SPELL_LINK_TALENT:
|
||||
{
|
||||
// talent
|
||||
TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
|
||||
if(!talentEntry)
|
||||
return 0;
|
||||
|
||||
// talent
|
||||
TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
|
||||
if(!talentEntry)
|
||||
return 0;
|
||||
int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
|
||||
if(rank >= 5)
|
||||
return 0;
|
||||
|
||||
int32 rank = rankS ? (uint32)atol(rankS) : 0;
|
||||
if(rank >= 5)
|
||||
return 0;
|
||||
if(rank < 0)
|
||||
rank = 0;
|
||||
|
||||
if(rank < 0)
|
||||
rank = 0;
|
||||
return talentEntry->RankID[rank];
|
||||
}
|
||||
case SPELL_LINK_TRADE:
|
||||
return id;
|
||||
}
|
||||
|
||||
return talentEntry->RankID[rank];
|
||||
// unknown type?
|
||||
return 0;
|
||||
}
|
||||
|
||||
GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
|
||||
|
|
|
|||
|
|
@ -442,8 +442,10 @@ class ChatHandler
|
|||
Player* getSelectedPlayer();
|
||||
Creature* getSelectedCreature();
|
||||
Unit* getSelectedUnit();
|
||||
|
||||
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
|
||||
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
|
||||
|
||||
uint32 extractSpellIdFromLink(char* text);
|
||||
GameTele const* extractGameTeleFromLink(char* text);
|
||||
|
||||
|
|
|
|||
|
|
@ -876,7 +876,7 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
|
|||
{
|
||||
// number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
|
||||
char* skill_p = extractKeyFromLink((char*)args,"Hskill");
|
||||
if(!skill_p)
|
||||
if(!skill_p)
|
||||
return false;
|
||||
|
||||
char *level_p = strtok (NULL, " ");
|
||||
|
|
@ -887,7 +887,6 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
|
|||
char *max_p = strtok (NULL, " ");
|
||||
|
||||
int32 skill = atoi(skill_p);
|
||||
|
||||
if (skill <= 0)
|
||||
{
|
||||
PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
|
||||
|
|
@ -937,27 +936,12 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
|
|||
return false;
|
||||
|
||||
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
|
||||
uint32 min_id = extractSpellIdFromLink((char*)args);
|
||||
if(!min_id)
|
||||
uint32 spell_id = extractSpellIdFromLink((char*)args);
|
||||
if(!spell_id)
|
||||
return false;
|
||||
|
||||
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
|
||||
char* tail = strtok(NULL,"");
|
||||
|
||||
uint32 max_id = extractSpellIdFromLink(tail);
|
||||
|
||||
if (!max_id)
|
||||
{
|
||||
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
|
||||
max_id = min_id+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (max_id < min_id)
|
||||
std::swap(min_id,max_id);
|
||||
|
||||
max_id=max_id+1;
|
||||
}
|
||||
char const* allStr = strtok(NULL," ");
|
||||
bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
|
||||
|
||||
Player* target = getSelectedPlayer();
|
||||
if(!target)
|
||||
|
|
@ -967,13 +951,13 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
for(uint32 spell=min_id;spell<max_id;spell++)
|
||||
{
|
||||
if (target->HasSpell(spell))
|
||||
target->removeSpell(spell);
|
||||
else
|
||||
SendSysMessage(LANG_FORGET_SPELL);
|
||||
}
|
||||
if(allRanks)
|
||||
spell_id = spellmgr.GetFirstSpellInChain (spell_id);
|
||||
|
||||
if (target->HasSpell(spell_id))
|
||||
target->removeSpell(spell_id);
|
||||
else
|
||||
SendSysMessage(LANG_FORGET_SPELL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1733,16 +1717,6 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void learnAllHighRanks(Player* player, uint32 spellid)
|
||||
{
|
||||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
|
||||
{
|
||||
player->learnSpell(itr->second,false);
|
||||
learnAllHighRanks(player,itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
|
||||
{
|
||||
Player* player = m_session->GetPlayer();
|
||||
|
|
@ -1780,11 +1754,8 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
|
|||
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
|
||||
continue;
|
||||
|
||||
// learn highest rank of talent
|
||||
player->learnSpell(spellid,false);
|
||||
|
||||
// and learn all non-talent spell ranks (recursive by tree)
|
||||
learnAllHighRanks(player,spellid);
|
||||
// learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
|
||||
player->learnSpellHighRank(spellid);
|
||||
}
|
||||
|
||||
SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
|
||||
|
|
@ -1851,15 +1822,8 @@ bool ChatHandler::HandleLearnCommand(const char* args)
|
|||
if(!spell || !sSpellStore.LookupEntry(spell))
|
||||
return false;
|
||||
|
||||
if (targetPlayer->HasSpell(spell))
|
||||
{
|
||||
if(targetPlayer == m_session->GetPlayer())
|
||||
SendSysMessage(LANG_YOU_KNOWN_SPELL);
|
||||
else
|
||||
PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
char const* allStr = strtok(NULL," ");
|
||||
bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
|
||||
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
|
||||
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
|
||||
|
|
@ -1869,7 +1833,20 @@ bool ChatHandler::HandleLearnCommand(const char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
targetPlayer->learnSpell(spell,false);
|
||||
if (!allRanks && targetPlayer->HasSpell(spell))
|
||||
{
|
||||
if(targetPlayer == m_session->GetPlayer())
|
||||
SendSysMessage(LANG_YOU_KNOWN_SPELL);
|
||||
else
|
||||
PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(allRanks)
|
||||
targetPlayer->learnSpellHighRank(spell);
|
||||
else
|
||||
targetPlayer->learnSpell(spell,false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4244,11 +4221,28 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
|
|||
for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
|
||||
{
|
||||
bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
|
||||
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
|
||||
itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
|
||||
itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
|
||||
(itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
|
||||
IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
|
||||
|
||||
char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
|
||||
|
||||
if (m_session)
|
||||
{
|
||||
std::ostringstream ss_name;
|
||||
ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
|
||||
|
||||
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
|
||||
itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
|
||||
ss_name.str().c_str(),
|
||||
(itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
|
||||
IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
|
||||
itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
|
||||
name,
|
||||
(itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
|
||||
IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < TOTAL_AURAS; i++)
|
||||
{
|
||||
|
|
@ -4258,9 +4252,24 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
|
|||
for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
|
||||
{
|
||||
bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
|
||||
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
|
||||
(*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
|
||||
IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
|
||||
|
||||
char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
|
||||
|
||||
if (m_session)
|
||||
{
|
||||
std::ostringstream ss_name;
|
||||
ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
|
||||
|
||||
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
|
||||
ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
|
||||
IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
|
||||
name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
|
||||
IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -19485,3 +19485,13 @@ bool Player::IsAllowUseFlyMountsHere() const
|
|||
uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), GetZoneId());
|
||||
return v_map == 530 || v_map == 571 && HasSpell(54197);
|
||||
}
|
||||
|
||||
void Player::learnSpellHighRank(uint32 spellid)
|
||||
{
|
||||
learnSpell(spellid,false);
|
||||
|
||||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
|
||||
learnSpellHighRank(itr->second);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1490,6 +1490,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void learnDefaultSpells();
|
||||
void learnQuestRewardedSpells();
|
||||
void learnQuestRewardedSpells(Quest const* quest);
|
||||
void learnSpellHighRank(uint32 spellid);
|
||||
|
||||
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
|
||||
void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7167"
|
||||
#define REVISION_NR "7168"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue