From 45b209df50d90613e5f5579db3082577fa5f7c1a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 16 May 2009 10:03:09 +0400 Subject: [PATCH 01/22] [7836] Fixes for distance range checks. * ignore 0.0f min range limit (this correct case when 2 object overlapped) * typo in CreatureEventAI::CanCast Also use int32 for temporary store GetSessionDbLocaleIndex result. --- src/game/CreatureEventAI.cpp | 2 +- src/game/GridNotifiersImpl.h | 4 ++-- src/game/Object.cpp | 30 +++++++++++++++++++++--------- src/shared/revision_nr.h | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 10addd297..ddae14fdd 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1581,7 +1581,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge return false; //Unit is out of range of this spell - if (!m_creature->IsInRange(Target,TempRange->minRange,TempRange->minRange)) + if (!m_creature->IsInRange(Target,TempRange->minRange,TempRange->maxRange)) return false; return true; diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 75d1ef9c9..583732a65 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -540,7 +540,7 @@ void MaNGOS::PlayerSearcher::Visit(PlayerMapType &m) template void MaNGOS::LocalizedPacketDo::operator()( Player* p ) { - uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); + int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); uint32 cache_idx = loc_idx+1; WorldPacket* data; @@ -565,7 +565,7 @@ void MaNGOS::LocalizedPacketDo::operator()( Player* p ) template void MaNGOS::LocalizedPacketListDo::operator()( Player* p ) { - uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); + int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); uint32 cache_idx = loc_idx+1; WorldPacketList* data_list; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 81ff11d97..ee0ec2edc 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1207,9 +1207,13 @@ bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRan float sizefactor = GetObjectSize() + obj->GetObjectSize(); - float mindist = minRange + sizefactor; - if(distsq < mindist * mindist) - return false; + // check only for real range + if(minRange > 0.0f) + { + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + } float maxdist = maxRange + sizefactor; return distsq < maxdist * maxdist; @@ -1223,9 +1227,13 @@ bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) float sizefactor = GetObjectSize(); - float mindist = minRange + sizefactor; - if(distsq < mindist * mindist) - return false; + // check only for real range + if(minRange > 0.0f) + { + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + } float maxdist = maxRange + sizefactor; return distsq < maxdist * maxdist; @@ -1240,9 +1248,13 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m float sizefactor = GetObjectSize(); - float mindist = minRange + sizefactor; - if(distsq < mindist * mindist) - return false; + // check only for real range + if(minRange > 0.0f) + { + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + } float maxdist = maxRange + sizefactor; return distsq < maxdist * maxdist; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 13bd699da..d73142f5b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7835" + #define REVISION_NR "7836" #endif // __REVISION_NR_H__ From 8cf9dc035b3f90a8e2c2cddfdca0114546dc4057 Mon Sep 17 00:00:00 2001 From: xILOSWag Date: Sat, 16 May 2009 12:33:56 +0400 Subject: [PATCH 02/22] [7837] Implement missed item enchant type (stat mana, stat health) Signed-off-by: DiSlord --- src/game/Player.cpp | 8 ++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index aba7012ab..3d567d896 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -11626,6 +11626,14 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a sLog.outDebug("Adding %u to stat nb %u",enchant_amount,enchant_spell_id); switch (enchant_spell_id) { + case ITEM_MOD_MANA: + sLog.outDebug("+ %u MANA",enchant_amount); + HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(enchant_amount), apply); + break; + case ITEM_MOD_HEALTH: + sLog.outDebug("+ %u HEALTH",enchant_amount); + HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(enchant_amount), apply); + break; case ITEM_MOD_AGILITY: sLog.outDebug("+ %u AGILITY",enchant_amount); HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d73142f5b..096e37697 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7836" + #define REVISION_NR "7837" #endif // __REVISION_NR_H__ From 122c9c57852bd1ab977d2e7fbd3cdf1131571c32 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 16 May 2009 17:01:03 +0400 Subject: [PATCH 03/22] [7838] More fixes in pet's levelup spells. * Fixed not updating levelup spells at warlock pet summon firsy time (overwriting by default original ranks in fact) * Correctly upgrade/doungrade spell ranks in action bar. * Fixed spell learning spam at warlock pet re-summon in some cases. TODO: currently (before this commit and in it) PetSpellInitialize() called too oftern. Maybe possible cache update flag and do it one time somewhere in Pet::Update.... --- src/game/Level3.cpp | 11 ++--- src/game/Pet.cpp | 88 ++++++++++++++++++++++++++++----------- src/game/Pet.h | 12 +++--- src/game/SpellEffects.cpp | 3 ++ src/game/Unit.cpp | 29 +++++++++---- src/shared/revision_nr.h | 2 +- 6 files changed, 97 insertions(+), 48 deletions(-) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 2da83263e..9a147e5a5 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4792,13 +4792,10 @@ bool ChatHandler::HandleResetLevelCommand(const char * args) player->InitTalentForLevel(); player->SetUInt32Value(PLAYER_XP,0); - // reset level to summoned pet - Pet* pet = player->GetPet(); - if(pet && pet->getPetType()==SUMMON_PET) - { - pet->InitStatsForLevel(1); - pet->InitTalentForLevel(); - } + // reset level for pet + if(Pet* pet = player->GetPet()) + pet->SynchronizeLevelWithOwner(); + return true; } diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index e8b5bb04e..e7e195581 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -340,6 +340,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool } } + InitLevelupSpellsForLevel(); + m_loading = false; SynchronizeLevelWithOwner(); @@ -653,6 +655,9 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid) for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) { + if(itr->second.state == PETSPELL_REMOVED) + continue; + if(IsPassiveSpell(itr->first)) continue; @@ -746,6 +751,7 @@ void Pet::GivePetLevel(uint32 level) return; InitStatsForLevel(level); + InitLevelupSpellsForLevel(); InitTalentForLevel(); } @@ -994,9 +1000,6 @@ bool Pet::InitStatsForLevel(uint32 petlevel) for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i])); - if(cinfo->family) - learnLevelupSpells(); - UpdateAllStats(); SetHealth(GetMaxHealth()); @@ -1118,7 +1121,7 @@ void Pet::_LoadSpells() { Field *fields = result->Fetch(); - addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED); + addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED); } while( result->NextRow() ); @@ -1284,7 +1287,7 @@ void Pet::_SaveAuras() } } -bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/) +bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); if (!spellInfo) @@ -1356,26 +1359,33 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState // skip unknown ranks if(!HasSpell(rankSpellId)) continue; - removeSpell(rankSpellId); + removeSpell(rankSpellId,false); } } } - else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id)) + else if(spellmgr.GetSpellRank(spell_id)!=0) { for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2) { if(itr2->second.state == PETSPELL_REMOVED) continue; - if(spellmgr.GetFirstSpellInChain(itr2->first) == chainstart) + if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr2->first) ) { - newspell.active = itr2->second.active; + // replace by new high rank + if(spellmgr.IsHighRankOfSpell(spell_id,itr2->first)) + { + newspell.active = itr2->second.active; - if(newspell.active == ACT_ENABLED) - ToggleAutocast(itr2->first, false); + if(newspell.active == ACT_ENABLED) + ToggleAutocast(itr2->first, false); - oldspell_id = itr2->first; - unlearnSpell(itr2->first); - break; + oldspell_id = itr2->first; + unlearnSpell(itr2->first,false); + break; + } + // ignore new lesser rank + else if(spellmgr.IsHighRankOfSpell(itr2->first,spell_id)) + return false; } } } @@ -1384,7 +1394,7 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState if (IsPassiveSpell(spell_id)) CastSpell(this, spell_id, true); - else if(state == PETSPELL_NEW) + else m_charmInfo->AddSpellToAB(oldspell_id, spell_id); if(newspell.active == ACT_ENABLED) @@ -1422,26 +1432,33 @@ bool Pet::learnSpell(uint32 spell_id) return true; } -void Pet::learnLevelupSpells() +void Pet::InitLevelupSpellsForLevel() { - PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family); + uint32 family = GetCreatureInfo()->family; + if(!family) + return; + + PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(family); if(!levelupSpells) return; uint32 level = getLevel(); - for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr) + // PetLevelupSpellSet ordered by levels, process in reversed order + for(PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr) { - if(itr->first <= level) - learnSpell(itr->second); + // will called first if level down + if(itr->first > level) + unlearnSpell(itr->second,true); // will learn prev rank if any + // will called if level up else - unlearnSpell(itr->second); + learnSpell(itr->second); // will unlearn prev rank if any } } -bool Pet::unlearnSpell(uint32 spell_id) +bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev) { - if(removeSpell(spell_id)) + if(removeSpell(spell_id,learn_prev)) { if(GetOwner()->GetTypeId() == TYPEID_PLAYER) { @@ -1457,7 +1474,7 @@ bool Pet::unlearnSpell(uint32 spell_id) return false; } -bool Pet::removeSpell(uint32 spell_id) +bool Pet::removeSpell(uint32 spell_id, bool learn_prev) { PetSpellMap::iterator itr = m_spells.find(spell_id); if (itr == m_spells.end()) @@ -1485,6 +1502,27 @@ bool Pet::removeSpell(uint32 spell_id) SetFreeTalentPoints(free_points > 0 ? free_points : 0); } + if (learn_prev) + { + if (uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id)) + { + // replace to next spell + if(!talentCost && !IsPassiveSpell(prev_id)) + m_charmInfo->AddSpellToAB(spell_id, prev_id); + + learnSpell(prev_id); + } + else + { + m_charmInfo->AddSpellToAB(spell_id, 0); + + // need update action bar for last removed rank + if (Unit* owner = GetOwner()) + if (owner->GetTypeId() == TYPEID_PLAYER) + ((Player*)owner)->PetSpellInitialize(); + } + } + return true; } @@ -1620,7 +1658,7 @@ bool Pet::resetTalents(bool no_cost) // unlearn if first rank is talent or learned by talent if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId)) { - removeSpell(itr->first); + removeSpell(itr->first,false); itr = m_spells.begin(); continue; } diff --git a/src/game/Pet.h b/src/game/Pet.h index 07e1036ce..1b987b8ce 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -69,7 +69,7 @@ enum PetSpellType struct PetSpell { - uint16 active; + ActiveStates active : 16; PetSpellState state : 8; PetSpellType type : 8; @@ -196,12 +196,12 @@ class Pet : public Creature void _LoadSpells(); void _SaveSpells(); - bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL); + bool addSpell(uint32 spell_id,ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL); bool learnSpell(uint32 spell_id); void learnSpellHighRank(uint32 spellid); - void learnLevelupSpells(); - bool unlearnSpell(uint32 spell_id); - bool removeSpell(uint32 spell_id); + void InitLevelupSpellsForLevel(); + bool unlearnSpell(uint32 spell_id, bool learn_prev); + bool removeSpell(uint32 spell_id, bool learn_prev); PetSpellMap m_spells; TeachSpellMap m_teachspells; @@ -252,4 +252,4 @@ class Pet : public Creature assert(false); } }; -#endif +#endif \ No newline at end of file diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index ce4528ec0..c1cfd684d 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3259,6 +3259,7 @@ void Spell::EffectSummon(uint32 i) spawnCreature->AIM_Initialize(); spawnCreature->InitPetCreateSpells(); + spawnCreature->InitLevelupSpellsForLevel(); spawnCreature->SetHealth(spawnCreature->GetMaxHealth()); spawnCreature->SetPower(POWER_MANA, spawnCreature->GetMaxPower(POWER_MANA)); @@ -4171,6 +4172,7 @@ void Spell::EffectSummonPet(uint32 i) NewSummon->InitStatsForLevel(petlevel); NewSummon->InitPetCreateSpells(); + NewSummon->InitLevelupSpellsForLevel(); NewSummon->InitTalentForLevel(); if(NewSummon->getPetType()==SUMMON_PET) @@ -5967,6 +5969,7 @@ void Spell::EffectSummonCritter(uint32 i) critter->AIM_Initialize(); critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... + //critter->InitLevelupSpellsForLevel(); // none? critter->SelectLevel(critter->GetCreatureInfo()); // some summoned creaters have different from 1 DB data for level/hp critter->SetUInt32Value(UNIT_NPC_FLAGS, critter->GetCreatureInfo()->npcflag); // some mini-pets have quests diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 474b6009e..7f150e1df 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10396,20 +10396,30 @@ void CharmInfo::InitCharmCreateSpells() bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate) { + // new spell already listed for example in case prepered switch to lesser rank in Pet::removeSpell + for(uint8 i = 0; i < 10; ++i) + if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) + if (newid && PetActionBar[i].SpellOrAction == newid) + return true; + + // old spell can be leasted for example in case learn high rank for(uint8 i = 0; i < 10; ++i) { - if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid) + if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) { - PetActionBar[i].SpellOrAction = newid; - if(!oldid) + if (PetActionBar[i].SpellOrAction == oldid) { - if(newstate == ACT_DECIDE) - PetActionBar[i].Type = ACT_DISABLED; - else - PetActionBar[i].Type = newstate; - } + PetActionBar[i].SpellOrAction = newid; + if (!oldid) + { + if (newstate == ACT_DECIDE) + PetActionBar[i].Type = ACT_DISABLED; + else + PetActionBar[i].Type = newstate; + } - return true; + return true; + } } } return false; @@ -11399,6 +11409,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) // this enables pet details window (Shift+P) pet->AIM_Initialize(); pet->InitPetCreateSpells(); + pet->InitLevelupSpellsForLevel(); pet->InitTalentForLevel(); pet->SetHealth(pet->GetMaxHealth()); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 096e37697..d86a931cf 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7837" + #define REVISION_NR "7838" #endif // __REVISION_NR_H__ From 1f2670facfb8346c56d9b325adca5a7c82e8a1c5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 17 May 2009 12:42:53 +0400 Subject: [PATCH 04/22] [7839] Rafactoring player targeting code in chat command and related cleanups/improvments. * New extractOptFirstArg function for easy get 2 args in case option playe name as first arg. * New extractPlayerTarget function for get player pointer/guid/name for online/offline player base at provided name or if not provided by current seelction with error cases processing. * Property apply mute/unmute in case use different character name from loggined currently for account. * .reset commands can be used from console now * .repairitems comamnd can be used from console now but only to online player. --- sql/mangos.sql | 26 +- sql/updates/7839_01_mangos_mangos_string.sql | 6 + sql/updates/7839_02_mangos_command.sql | 22 + sql/updates/Makefile.am | 4 + src/game/Chat.cpp | 91 ++- src/game/Chat.h | 5 + src/game/Language.h | 6 +- src/game/Level1.cpp | 337 ++++----- src/game/Level2.cpp | 414 +++------- src/game/Level3.cpp | 747 +++++-------------- src/game/World.cpp | 25 - src/game/World.h | 1 - src/shared/revision_nr.h | 2 +- 13 files changed, 558 insertions(+), 1128 deletions(-) create mode 100644 sql/updates/7839_01_mangos_mangos_string.sql create mode 100644 sql/updates/7839_02_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 6451c9815..7ccf0900a 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_7830_01_mangos_spell_chain` bit(1) default NULL + `required_7839_02_mangos_command` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -271,9 +271,9 @@ INSERT INTO `command` VALUES ('ban account',3,'Syntax: .ban account $Name $bantime $reason\r\nBan account kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), ('ban character',3,'Syntax: .ban character $Name $bantime $reason\r\nBan account and kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), ('ban ip',3,'Syntax: .ban ip $Ip $bantime $reason\r\nBan IP.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), -('baninfo account',3,'Syntax: .baninfo account\r\nWatch full information about a specific ban.'), -('baninfo character',3,'Syntax: .baninfo character\r\nWatch full information about a specific ban.'), -('baninfo ip',3,'Syntax: .baninfo ip\r\nWatch full information about a specific ban.'), +('baninfo account',3,'Syntax: .baninfo account $accountid\r\nWatch full information about a specific ban.'), +('baninfo character',3,'Syntax: .baninfo character $charactername \r\nWatch full information about a specific ban.'), +('baninfo ip',3,'Syntax: .baninfo ip $ip\r\nWatch full information about a specific ban.'), ('bank',3,'Syntax: .bank\r\n\r\nShow your bank inventory.'), ('banlist account',3,'Syntax: .banlist account [$Name]\r\nSearches the banlist for a account name pattern or show full list account bans.'), ('banlist character',3,'Syntax: .banlist character $Name\r\nSearches the banlist for a character name pattern. Pattern required.'), @@ -335,15 +335,15 @@ INSERT INTO `command` VALUES ('gobject setphase',2,'Syntax: .gobject setphase #guid #phasemask\r\n\r\nGameobject with DB guid #guid phasemask changed to #phasemask with related world vision update for players. Gameobject state saved to DB and persistent.'), ('gobject turn',2,'Syntax: .gobject turn #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'), ('gobject target',2,'Syntax: .gobject target [#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'), -('goname',1,'Syntax: .goname $charactername\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group.'), +('goname',1,'Syntax: .goname [$charactername]\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group. Character can be offline.'), ('gps',1,'Syntax: .gps [$name|$shift-link]\r\n\r\nDisplay the position information for a selected character or creature (also if player name $name provided then for named player, or if creature/gameobject shift-link provided then pointed creature/gameobject if it loaded). Position information includes X, Y, Z, and orientation, map Id and zone Id'), -('groupgo',1,'Syntax: .groupgo $charactername\r\n\r\nTeleport the given character and his group to you.'), +('groupgo',1,'Syntax: .groupgo [$charactername]\r\n\r\nTeleport the given character and his group to you. Teleported only online characters but original selected group member can be offline.'), ('guid',2,'Syntax: .guid\r\n\r\nDisplay the GUID for the selected character.'), -('guild create',2,'Syntax: .guild create $GuildLeaderName $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName as leader.'), +('guild create',2,'Syntax: .guild create [$GuildLeaderName] $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName (or selected) as leader.'), ('guild delete',2,'Syntax: .guild delete $GuildName\r\n\r\nDelete guild $GuildName.'), -('guild invite',2,'Syntax: .guild invite $CharacterName $GuildName\r\n\r\nAdd $CharacterName into a guild $GuildName.'), +('guild invite',2,'Syntax: .guild invite [$CharacterName] $GuildName\r\n\r\nAdd player $CharacterName (or selected) into a guild $GuildName.'), ('guild rank',2,'Syntax: .guild rank $CharacterName #Rank\r\n\r\nSet for $CharacterName rank #Rank in a guild.'), -('guild uninvite',2,'Syntax: .guild uninvite $CharacterName\r\n\r\nRemove $CharacterName from a guild.'), +('guild uninvite',2,'Syntax: .guild uninvite [$CharacterName]\r\n\r\nRemove player $CharacterName (or selected) from a guild.'), ('help',0,'Syntax: .help [$command]\r\n\r\nDisplay usage instructions for the given $command. If no $command provided show list available commands.'), ('hidearea',3,'Syntax: .hidearea #areaid\r\n\r\nHide the area of #areaid to the selected character. If no character is selected, hide this area to you.'), ('honor add',2,'Syntax: .honor add $amount\r\n\r\nAdd a certain amount of honor (gained today) to the selected player.'), @@ -414,8 +414,8 @@ INSERT INTO `command` VALUES ('modify swim',1,'Syntax: .modify swim #rate\r\n\r\nModify the swim speed of the selected player to \"normal swim speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'), ('modify titles',1,'Syntax: .modify titles #mask\r\n\r\nAllows user to use all titles from #mask.\r\n\r\n #mask=0 disables the title-choose-field'), ('movegens',3,'Syntax: .movegens\r\n Show movement generators stack for selected creature or player.'), -('mute',1,'Syntax: .mute $playerName $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName at $timeInMinutes minutes.'), -('namego',1,'Syntax: .namego $charactername\r\n\r\nTeleport the given character to you.'), +('mute',1,'Syntax: .mute [$playerName] $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName (or currently selected) at $timeInMinutes minutes. Player can be offline.'), +('namego',1,'Syntax: .namego [$charactername]\r\n\r\nTeleport the given character to you. Character can be offline.'), ('neargrave',3,'Syntax: .neargrave [alliance|horde]\r\n\r\nFind nearest graveyard linked to zone (or only nearest from accepts alliance or horde faction ghosts).'), ('notify',1,'Syntax: .notify $MessageToBroadcast\r\n\r\nSend a global message to all players online in screen.'), ('npc add',2,'Syntax: .npc add #creatureid\r\n\r\nSpawn a creature by the given template id of #creatureid.'), @@ -497,7 +497,7 @@ INSERT INTO `command` VALUES ('tele add',3,'Syntax: .tele add $name\r\n\r\nAdd current your position to .tele command target locations list with name $name.'), ('tele del',3,'Syntax: .tele del $name\r\n\r\nRemove location with name $name for .tele command locations list.'), ('tele group',1,'Syntax: .tele group#location\r\n\r\nTeleport a selected player and his group members to a given location.'), -('tele name',1,'Syntax: .tele name #playername #location\r\n\r\nTeleport a player to a given location.'), +('tele name',1,'Syntax: .tele name [#playername] #location\r\n\r\nTeleport the given character to a given location. Character can be offline.'), ('ticket',2,'Syntax: .ticket on\r\n .ticket off\r\n .ticket #num\r\n .ticket $character_name\r\n\r\non/off for GMs to show or not a new ticket directly, $character_name to show ticket of this character, #num to show ticket #num.'), ('unaura',3,'Syntax: .unaura #spellid\r\n\r\nRemove aura due to spell #spellid from the selected Unit.'), ('unban account',3,'Syntax: .unban account $Name\r\nUnban accounts for account name pattern.'), @@ -2540,6 +2540,7 @@ INSERT INTO `mangos_string` VALUES (168,'Locations found are:\n %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (169,'Mail sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (170,'You try to hear sound %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(171,'You can\'t teleport self to self!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (172,'server console command',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (173,'You changed runic power of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (174,'%s changed your runic power to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2627,7 +2628,6 @@ INSERT INTO `mangos_string` VALUES (280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(283,'Player %s not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), diff --git a/sql/updates/7839_01_mangos_mangos_string.sql b/sql/updates/7839_01_mangos_mangos_string.sql new file mode 100644 index 000000000..1474a2f8e --- /dev/null +++ b/sql/updates/7839_01_mangos_mangos_string.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_7830_01_mangos_spell_chain required_7839_01_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN(171,283); + +INSERT INTO mangos_string VALUES +(171,'You can\'t teleport self to self!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/7839_02_mangos_command.sql b/sql/updates/7839_02_mangos_command.sql new file mode 100644 index 000000000..a83d279c8 --- /dev/null +++ b/sql/updates/7839_02_mangos_command.sql @@ -0,0 +1,22 @@ +ALTER TABLE db_version CHANGE COLUMN required_7839_01_mangos_mangos_string required_7839_02_mangos_command bit; + +DELETE FROM `command` WHERE `name` IN ( + 'baninfo account','baninfo character','baninfo ip','goname','groupgo', + 'guild create','guild invite','guild rank','guild uninvite','mute', + 'namego','tele name','unmute' +); + +INSERT INTO `command` VALUES +('baninfo account',3,'Syntax: .baninfo account $accountid\r\nWatch full information about a specific ban.'), +('baninfo character',3,'Syntax: .baninfo character $charactername \r\nWatch full information about a specific ban.'), +('baninfo ip',3,'Syntax: .baninfo ip $ip\r\nWatch full information about a specific ban.'), +('goname',1,'Syntax: .goname [$charactername]\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group. Character can be offline.'), +('groupgo',1,'Syntax: .groupgo [$charactername]\r\n\r\nTeleport the given character and his group to you. Teleported only online characters but original selected group member can be offline.'), +('guild create',2,'Syntax: .guild create [$GuildLeaderName] $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName (or selected) as leader.'), +('guild invite',2,'Syntax: .guild invite [$CharacterName] $GuildName\r\n\r\nAdd player $CharacterName (or selected) into a guild $GuildName.'), +('guild rank',2,'Syntax: .guild rank [$CharacterName] #Rank\r\n\r\nSet for player $CharacterName (or selected) rank #Rank in a guild.'), +('guild uninvite',2,'Syntax: .guild uninvite [$CharacterName]\r\n\r\nRemove player $CharacterName (or selected) from a guild.'), +('mute',1,'Syntax: .mute [$playerName] $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName (or currently selected) at $timeInMinutes minutes. Player can be offline.'), +('namego',1,'Syntax: .namego [$charactername]\r\n\r\nTeleport the given character to you. Character can be offline.'), +('tele name',1,'Syntax: .tele name [#playername] #location\r\n\r\nTeleport the given character to a given location. Character can be offline.'), +('unmute',1,'Syntax: .unmute [$playerName]\r\n\r\nRestore chat messaging for any character from account of character $playerName (or selected). Character can be ofline.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index d20edfdf0..1ff110a9b 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -186,6 +186,8 @@ pkgdata_DATA = \ 7802_02_characters_character_achievement_progress.sql \ 7823_01_mangos_item_template.sql \ 7830_01_mangos_spell_chain.sql \ + 7839_01_mangos_mangos_string.sql \ + 7839_02_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -352,4 +354,6 @@ EXTRA_DIST = \ 7802_02_characters_character_achievement_progress.sql \ 7823_01_mangos_item_template.sql \ 7830_01_mangos_spell_chain.sql \ + 7839_01_mangos_mangos_string.sql \ + 7839_02_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 029fddda1..29572cfd4 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -454,13 +454,13 @@ ChatCommand * ChatHandler::getCommandTable() static ChatCommand resetCommandTable[] = { - { "achievements", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAchievementsCommand, "", NULL }, - { "honor", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetHonorCommand, "", NULL }, - { "level", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetLevelCommand, "", NULL }, - { "spells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetSpellsCommand, "", NULL }, - { "stats", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetStatsCommand, "", NULL }, - { "talents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetTalentsCommand, "", NULL }, - { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAllCommand, "", NULL }, + { "achievements", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAchievementsCommand, "", NULL }, + { "honor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetHonorCommand, "", NULL }, + { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetLevelCommand, "", NULL }, + { "spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetSpellsCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetStatsCommand, "", NULL }, + { "talents", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetTalentsCommand, "", NULL }, + { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAllCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; @@ -573,7 +573,7 @@ ChatCommand * ChatHandler::getCommandTable() { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable }, { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable }, { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable }, - { "reset", SEC_ADMINISTRATOR, false, NULL, "", resetCommandTable }, + { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable }, { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable }, { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable }, @@ -633,7 +633,7 @@ ChatCommand * ChatHandler::getCommandTable() { "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL }, { "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL }, { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL }, - { "repairitems", SEC_GAMEMASTER, false, &ChatHandler::HandleRepairitemsCommand, "", NULL }, + { "repairitems", SEC_GAMEMASTER, true, &ChatHandler::HandleRepairitemsCommand, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } @@ -1219,7 +1219,7 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** s *something1 = strtok(NULL, ":|"); // extract something strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces - strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function + strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function return cKey; } @@ -1497,6 +1497,77 @@ std::string ChatHandler::extractPlayerNameFromLink(char* text) return name; } +bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* player_guid /*=NULL*/,std::string* player_name /*= NULL*/) +{ + if (args && *args) + { + std::string name = extractPlayerNameFromLink(args); + if (name.empty()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + Player* pl = objmgr.GetPlayer(name.c_str()); + + // if allowed player pointer + if(player) + *player = pl; + + // if need guid value from DB (in name case for check player existence) + uint64 guid = !pl && (player_guid || player_name) ? objmgr.GetPlayerGUIDByName(name) : 0; + + // if allowed player guid (if no then only online players allowed) + if(player_guid) + *player_guid = pl ? pl->GetGUID() : guid; + + if(player_name) + *player_name = pl || guid ? name : ""; + } + else + { + Player* pl = getSelectedPlayer(); + // if allowed player pointer + if(player) + *player = pl; + // if allowed player guid (if no then only online players allowed) + if(player_guid) + *player_guid = pl ? pl->GetGUID() : 0; + + if(player_name) + *player_name = pl ? pl->GetName() : ""; + } + + // some from req. data must be provided (note: name is empty if player not exist) + if((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty())) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + return true; +} + +void ChatHandler::extractOptFirstArg(char* args, char** arg1, char** arg2) +{ + char* p1 = strtok(args, " "); + char* p2 = strtok(NULL, " "); + + if(!p2) + { + p2 = p1; + p1 = NULL; + } + + if(arg1) + *arg1 = p1; + + if(arg2) + *arg2 = p2; +} + bool ChatHandler::needReportToTarget(Player* chr) const { Player* pl = m_session->GetPlayer(); diff --git a/src/game/Chat.h b/src/game/Chat.h index 43d2eb8a3..c71b635ea 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -484,10 +484,15 @@ class ChatHandler char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL); char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL); + // if args have single value then it return in arg2 and arg1 == NULL + void extractOptFirstArg(char* args, char** arg1, char** arg2); + uint32 extractSpellIdFromLink(char* text); uint64 extractGuidFromLink(char* text); GameTele const* extractGameTeleFromLink(char* text); std::string extractPlayerNameFromLink(char* text); + // select by arg (name/link) or in-game selection online/offline player + bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL); std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; } virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); } diff --git a/src/game/Language.h b/src/game/Language.h index 5b64cf570..e1c15fb01 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -94,7 +94,6 @@ enum MangosStrings LANG_CANNOT_GO_TO_INST_GM = 105, LANG_CANNOT_GO_INST_INST = 106, LANG_CANNOT_SUMMON_INST_INST = 107, - LANG_SUMMONING = 108, LANG_SUMMONED_BY = 109, LANG_TELEPORTING_TO = 110, @@ -102,7 +101,6 @@ enum MangosStrings LANG_NO_PLAYER = 112, LANG_APPEARING_AT = 113, LANG_APPEARING_TO = 114, - LANG_BAD_VALUE = 115, LANG_NO_CHAR_SELECTED = 116, LANG_NOT_IN_GROUP = 117, @@ -167,7 +165,7 @@ enum MangosStrings LANG_MAIL_SENT = 169, LANG_SOUND_NOT_EXIST = 170, - // 171, // not used + LANG_CANT_TELEPORT_SELF = 171, LANG_CONSOLE_COMMAND = 172, LANG_YOU_CHANGE_RUNIC_POWER = 173, LANG_YOURS_RUNIC_POWER_CHANGED = 174, @@ -266,7 +264,7 @@ enum MangosStrings LANG_COMMAND_ADDVENDORITEMITEMS = 280, LANG_COMMAND_KICKSELF = 281, LANG_COMMAND_KICKMESSAGE = 282, - LANG_COMMAND_KICKNOTFOUNDPLAYER = 283, + // 283, not used LANG_COMMAND_WHISPERACCEPTING = 284, LANG_COMMAND_WHISPERON = 285, LANG_COMMAND_WHISPEROFF = 286, diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 79b9ab1c5..ba2280b97 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -343,26 +343,28 @@ bool ChatHandler::HandleGPSCommand(const char* args) //Summon Player bool ChatHandler::HandleNamegoCommand(const char* args) { - if(!*args) + Player* target; + uint64 target_guid; + std::string target_name; + if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) + Player* _player = m_session->GetPlayer(); + if (target == _player || target_guid == _player->GetGUID()) { - SendSysMessage(LANG_PLAYER_NOT_FOUND); + PSendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } - Player *chr = objmgr.GetPlayer(name.c_str()); - if (chr) + if (target) { - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); // check online security - if (HasLowerSecurity(chr, 0)) + if (HasLowerSecurity(target, 0)) return false; - if(chr->IsBeingTeleported()) + if (target->IsBeingTeleported()) { PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); SetSentErrorMessage(true); @@ -371,32 +373,32 @@ bool ChatHandler::HandleNamegoCommand(const char* args) Map* pMap = m_session->GetPlayer()->GetMap(); - if(pMap->IsBattleGroundOrArena()) + if (pMap->IsBattleGroundOrArena()) { // only allow if gm mode is on - if (!chr->isGameMaster()) + if (!target->isGameMaster()) { - PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chr->GetName()); + PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,nameLink.c_str()); SetSentErrorMessage(true); return false; } // if both players are in different bgs - else if (chr->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != chr->GetBattleGroundId()) + else if (target->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != target->GetBattleGroundId()) { - PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chr->GetName()); + PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,nameLink.c_str()); SetSentErrorMessage(true); return false; } // all's well, set bg id // when porting out from the bg, it will be reset to 0 - chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId()); + target->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId()); // remember current position as entry point for return at bg end teleportation - chr->SetBattleGroundEntryPoint(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation()); + target->SetBattleGroundEntryPoint(target->GetMapId(),target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),target->GetOrientation()); } - else if(pMap->IsDungeon()) + else if (pMap->IsDungeon()) { - Map* cMap = chr->GetMap(); - if( cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId() ) + Map* cMap = target->GetMap(); + if (cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId()) { // cannot summon from instance to instance PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str()); @@ -405,9 +407,9 @@ bool ChatHandler::HandleNamegoCommand(const char* args) } // we are in instance, and can summon only player in our group with us as lead - if ( !m_session->GetPlayer()->GetGroup() || !chr->GetGroup() || - (chr->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || - (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) ) + if (!m_session->GetPlayer()->GetGroup() || !target->GetGroup() || + (target->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || + (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID())) // the last check is a bit excessive, but let it be, just in case { PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str()); @@ -417,31 +419,31 @@ bool ChatHandler::HandleNamegoCommand(const char* args) } PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),""); - if (needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str()); + if (needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str()); // stop flight if need - if(chr->isInFlight()) + if (target->isInFlight()) { - chr->GetMotionMaster()->MovementExpired(); - chr->m_taxi.ClearTaxiDestinations(); + target->GetMotionMaster()->MovementExpired(); + target->m_taxi.ClearTaxiDestinations(); } // save only in non-flight case else - chr->SaveRecallPosition(); + target->SaveRecallPosition(); // before GM float x,y,z; - m_session->GetPlayer()->GetClosePoint(x,y,z,chr->GetObjectSize()); - chr->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,chr->GetOrientation()); + m_session->GetPlayer()->GetClosePoint(x,y,z,target->GetObjectSize()); + target->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,target->GetOrientation()); } - else if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) + else { // check offline security - if (HasLowerSecurity(NULL, guid)) + if (HasLowerSecurity(NULL, target_guid)) return false; - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetMangosString(LANG_OFFLINE)); @@ -452,12 +454,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args) m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetOrientation(), m_session->GetPlayer()->GetZoneId(), - guid); - } - else - { - PSendSysMessage(LANG_NO_PLAYER, args); - SetSentErrorMessage(true); + target_guid); } return true; @@ -466,30 +463,31 @@ bool ChatHandler::HandleNamegoCommand(const char* args) //Teleport to Player bool ChatHandler::HandleGonameCommand(const char* args) { - if(!*args) + Player* target; + uint64 target_guid; + std::string target_name; + if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; Player* _player = m_session->GetPlayer(); - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) + if (target == _player || target_guid == _player->GetGUID()) { - SendSysMessage(LANG_PLAYER_NOT_FOUND); + SendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } - Player *chr = objmgr.GetPlayer(name.c_str()); - if (chr) + + if (target) { // check online security - if (HasLowerSecurity(chr, 0)) + if (HasLowerSecurity(target, 0)) return false; - std::string chrNameLink = playerLink(name); + std::string chrNameLink = playerLink(target_name); - Map* cMap = chr->GetMap(); - if(cMap->IsBattleGroundOrArena()) + Map* cMap = target->GetMap(); + if (cMap->IsBattleGroundOrArena()) { // only allow if gm mode is on if (!_player->isGameMaster()) @@ -499,7 +497,7 @@ bool ChatHandler::HandleGonameCommand(const char* args) return false; } // if both players are in different bgs - else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != chr->GetBattleGroundId()) + else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != target->GetBattleGroundId()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chrNameLink.c_str()); SetSentErrorMessage(true); @@ -507,7 +505,7 @@ bool ChatHandler::HandleGonameCommand(const char* args) } // all's well, set bg id // when porting out from the bg, it will be reset to 0 - _player->SetBattleGroundId(chr->GetBattleGroundId(), chr->GetBattleGroundTypeId()); + _player->SetBattleGroundId(target->GetBattleGroundId(), target->GetBattleGroundTypeId()); // remember current position as entry point for return at bg end teleportation _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation()); } @@ -519,7 +517,7 @@ bool ChatHandler::HandleGonameCommand(const char* args) if (_player->GetGroup()) { // we are in group, we can go only if we are in the player group - if (_player->GetGroup() != chr->GetGroup()) + if (_player->GetGroup() != target->GetGroup()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str()); SetSentErrorMessage(true); @@ -539,28 +537,27 @@ bool ChatHandler::HandleGonameCommand(const char* args) // if the player or the player's group is bound to another instance // the player will not be bound to another one - InstancePlayerBind *pBind = _player->GetBoundInstance(chr->GetMapId(), chr->GetDifficulty()); - if(!pBind) + InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty()); + if (!pBind) { Group *group = _player->GetGroup(); - InstanceGroupBind *gBind = group ? group->GetBoundInstance(chr->GetMapId(), chr->GetDifficulty()) : NULL; - if(!gBind) - { - // if no bind exists, create a solo bind - InstanceSave *save = sInstanceSaveManager.GetInstanceSave(chr->GetInstanceId()); - if(save) _player->BindToInstance(save, !save->CanReset()); - } + // if no bind exists, create a solo bind + InstanceGroupBind *gBind = group ? group->GetBoundInstance(target->GetMapId(), target->GetDifficulty()) : NULL; + // if no bind exists, create a solo bind + if (!gBind) + if (InstanceSave *save = sInstanceSaveManager.GetInstanceSave(target->GetInstanceId())) + _player->BindToInstance(save, !save->CanReset()); } - _player->SetDifficulty(chr->GetDifficulty()); + _player->SetDifficulty(target->GetDifficulty()); } PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); - if (_player->IsVisibleGloballyFor(chr)) - ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str()); + if (needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str()); // stop flight if need - if(_player->isInFlight()) + if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->m_taxi.ClearTaxiDestinations(); @@ -571,20 +568,17 @@ bool ChatHandler::HandleGonameCommand(const char* args) // to point to see at target with same orientation float x,y,z; - chr->GetContactPoint(m_session->GetPlayer(),x,y,z); + target->GetContactPoint(_player,x,y,z); - _player->TeleportTo(chr->GetMapId(), x, y, z, _player->GetAngle( chr ), TELE_TO_GM_MODE); - - return true; + _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); } - - if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) + else { // check offline security - if (HasLowerSecurity(NULL, guid)) + if (HasLowerSecurity(NULL, target_guid)) return false; - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); @@ -592,83 +586,51 @@ bool ChatHandler::HandleGonameCommand(const char* args) float x,y,z,o; uint32 map; bool in_flight; - if(Player::LoadPositionFromDB(map,x,y,z,o,in_flight,guid)) - { - // stop flight if need - if(_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); + if (!Player::LoadPositionFromDB(map,x,y,z,o,in_flight,target_guid)) + return false; - _player->TeleportTo(map, x, y, z,_player->GetOrientation()); - return true; + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(map, x, y, z,_player->GetOrientation()); } - PSendSysMessage(LANG_NO_PLAYER, args); - - SetSentErrorMessage(true); - return false; + return true; } // Teleport player to last position bool ChatHandler::HandleRecallCommand(const char* args) { - Player* chr = NULL; + Player* target; + if(!extractPlayerTarget((char*)args,&target)) + return false; - if(!*args) + // check online security + if (HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) { - chr = getSelectedPlayer(); - if(!chr) - chr = m_session->GetPlayer(); - - // check online security - else if (HasLowerSecurity(chr, 0)) - return false; - } - else - { - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - chr = objmgr.GetPlayer(name.c_str()); - - if(!chr) - { - PSendSysMessage(LANG_NO_PLAYER, args); - SetSentErrorMessage(true); - return false; - } - - // check online security - if (HasLowerSecurity(chr, 0)) - return false; - } - - if(chr->IsBeingTeleported()) - { - PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(chr).c_str()); + PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(target).c_str()); SetSentErrorMessage(true); return false; } // stop flight if need - if(chr->isInFlight()) + if(target->isInFlight()) { - chr->GetMotionMaster()->MovementExpired(); - chr->m_taxi.ClearTaxiDestinations(); + target->GetMotionMaster()->MovementExpired(); + target->m_taxi.ClearTaxiDestinations(); } - chr->TeleportTo(chr->m_recallMap, chr->m_recallX, chr->m_recallY, chr->m_recallZ, chr->m_recallO); + target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); return true; } @@ -1989,18 +1951,12 @@ bool ChatHandler::HandleSaveAllCommand(const char* /*args*/) //Send mail by command bool ChatHandler::HandleSendMailCommand(const char* args) { - if(!*args) - return false; - // format: name "subject text" "mail text" - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; - } char* tail1 = strtok(NULL, ""); if(!tail1) @@ -2042,14 +1998,6 @@ bool ChatHandler::HandleSendMailCommand(const char* args) std::string subject = msgSubject; std::string text = msgText; - uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); - if(!receiver_guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - // from console show not existed sender uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; @@ -2057,11 +2005,9 @@ bool ChatHandler::HandleSendMailCommand(const char* args) uint32 stationery = MAIL_STATIONERY_GM; uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; - Player *receiver = objmgr.GetPlayer(receiver_guid); + WorldSession::SendMailTo(target,messagetype, stationery, sender_guidlo, GUID_LOPART(target_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE); - WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE); - - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; } @@ -2069,23 +2015,20 @@ bool ChatHandler::HandleSendMailCommand(const char* args) // teleport player to given game_tele.entry bool ChatHandler::HandleTeleNameCommand(const char * args) { - if(!*args) + char* nameStr; + char* teleStr; + extractOptFirstArg((char*)args,&nameStr,&teleStr); + if(!teleStr) return false; - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - char* tail = strtok(NULL, ""); - if(!tail) + + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(teleStr,&target,&target_guid,&target_name)) return false; // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r - GameTele const* tele = extractGameTeleFromLink(tail); + GameTele const* tele = extractGameTeleFromLink(teleStr); if(!tele) { SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); @@ -2093,16 +2036,15 @@ bool ChatHandler::HandleTeleNameCommand(const char * args) return false; } - Player *chr = objmgr.GetPlayer(name.c_str()); - if (chr) + if (target) { // check online security - if (HasLowerSecurity(chr, 0)) + if (HasLowerSecurity(target, 0)) return false; - std::string chrNameLink = playerLink(name); + std::string chrNameLink = playerLink(target_name); - if(chr->IsBeingTeleported()==true) + if(target->IsBeingTeleported()==true) { PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str()); SetSentErrorMessage(true); @@ -2110,35 +2052,33 @@ bool ChatHandler::HandleTeleNameCommand(const char * args) } PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(),"", tele->name.c_str()); - if (needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str()); + if (needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str()); // stop flight if need - if(chr->isInFlight()) + if(target->isInFlight()) { - chr->GetMotionMaster()->MovementExpired(); - chr->m_taxi.ClearTaxiDestinations(); + target->GetMotionMaster()->MovementExpired(); + target->m_taxi.ClearTaxiDestinations(); } // save only in non-flight case else - chr->SaveRecallPosition(); + target->SaveRecallPosition(); - chr->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation); + target->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation); } - else if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) + else { // check offline security - if (HasLowerSecurity(NULL, guid)) + if (HasLowerSecurity(NULL, target_guid)) return false; - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str()); Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation, - MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),guid); + MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid); } - else - PSendSysMessage(LANG_NO_PLAYER, name.c_str()); return true; } @@ -2222,32 +2162,17 @@ bool ChatHandler::HandleTeleGroupCommand(const char * args) //Summon group of player bool ChatHandler::HandleGroupgoCommand(const char* args) { - if(!*args) + Player* target; + if(!extractPlayerTarget((char*)args,&target)) return false; - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - Player *player = objmgr.GetPlayer(name.c_str()); - if (!player) - { - PSendSysMessage(LANG_NO_PLAYER, args); - SetSentErrorMessage(true); - return false; - } - // check online security - if (HasLowerSecurity(player, 0)) + if (HasLowerSecurity(target, 0)) return false; - Group *grp = player->GetGroup(); + Group *grp = target->GetGroup(); - std::string nameLink = playerLink(name); + std::string nameLink = GetNameLink(target); if(!grp) { @@ -2281,7 +2206,7 @@ bool ChatHandler::HandleGroupgoCommand(const char* args) if (HasLowerSecurity(pl, 0)) return false; - std::string plNameLink = playerLink(name); + std::string plNameLink = GetNameLink(pl); if(pl->IsBeingTeleported()==true) { diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 31211c5ac..a41bc6dd6 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -52,104 +52,89 @@ static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] = //mute player for some times bool ChatHandler::HandleMuteCommand(const char* args) { - if (!*args) + char* nameStr; + char* delayStr; + extractOptFirstArg((char*)args,&nameStr,&delayStr); + if(!delayStr) return false; - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) return false; + + uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid); + + // find only player from same account if any + if(!target) + { + if(WorldSession* session = sWorld.FindSession(account_id)) + target = session->GetPlayer(); } - char *timetonotspeak = strtok(NULL, " "); - if(!timetonotspeak) - return false; - - uint32 notspeaktime = (uint32) atoi(timetonotspeak); - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - if(!guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - Player *chr = objmgr.GetPlayer(guid); + uint32 notspeaktime = (uint32) atoi(delayStr); // must have strong lesser security level - if(HasLowerSecurity (chr,guid,true)) + if(HasLowerSecurity (target,target_guid,true)) return false; - uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid); - time_t mutetime = time(NULL) + notspeaktime*60; - if (chr) - chr->GetSession()->m_muteTime = mutetime; + if (target) + target->GetSession()->m_muteTime = mutetime; loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); - if(chr) - ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); + if(target) + ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime); - return true; } //unmute player bool ChatHandler::HandleUnmuteCommand(const char* args) { - if (!*args) + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) + uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid); + + // find only player from same account if any + if(!target) { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; + if(WorldSession* session = sWorld.FindSession(account_id)) + target = session->GetPlayer(); } - uint64 guid = objmgr.GetPlayerGUIDByName(name); - if(!guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - Player *chr = objmgr.GetPlayer(guid); - // must have strong lesser security level - if(HasLowerSecurity (chr,guid,true)) + if(HasLowerSecurity (target,target_guid,true)) return false; - uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid); - - if (chr) + if (target) { - if(chr->CanSpeak()) + if(target->CanSpeak()) { SendSysMessage(LANG_CHAT_ALREADY_ENABLED); SetSentErrorMessage(true); return false; } - chr->GetSession()->m_muteTime = 0; + target->GetSession()->m_muteTime = 0; } loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id ); - if(chr) - ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); + if(target) + ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); return true; @@ -2077,62 +2062,24 @@ bool ChatHandler::HandleModifyMorphCommand(const char* args) //kick player bool ChatHandler::HandleKickPlayerCommand(const char *args) { - if (!*args) + Player* target; + if(!extractPlayerTarget((char*)args,&target)) + return false; + + if (m_session && target==m_session->GetPlayer()) { - Player* player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if(player==m_session->GetPlayer()) - { - SendSysMessage(LANG_COMMAND_KICKSELF); - SetSentErrorMessage(true); - return false; - } - - // check online security - if (HasLowerSecurity(player, 0)) - return false; - - player->GetSession()->KickPlayer(); - } - else - { - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - if(m_session && name==m_session->GetPlayer()->GetName()) - { - SendSysMessage(LANG_COMMAND_KICKSELF); - SetSentErrorMessage(true); - return false; - } - - // check online security - Player* player = ObjectAccessor::Instance().FindPlayerByName(name.c_str()); - if (player && HasLowerSecurity(player, 0)) - return false; - - std::string nameLink = playerLink(name); - - if(sWorld.KickPlayer(name)) - { - PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str()); - } - else - PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str()); + SendSysMessage(LANG_COMMAND_KICKSELF); + SetSentErrorMessage(true); + return false; } + // check online security + if (HasLowerSecurity(target, 0)) + return false; + + // send before target pointer invalidate + PSendSysMessage(LANG_COMMAND_KICKMESSAGE,GetNameLink(target).c_str()); + target->GetSession()->KickPlayer(); return true; } @@ -2160,48 +2107,15 @@ bool ChatHandler::HandleModifyPhaseCommand(const char* args) //show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { - Player* target = NULL; - uint64 targetGUID = 0; + char* nameStr; + char* subcommandStr; + extractOptFirstArg((char*)args,&nameStr,&subcommandStr); - char* px = strtok((char*)args, " "); - char* py = NULL; - - std::string name; - - if (px) - { - name = extractPlayerNameFromLink(px); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - target = objmgr.GetPlayer(name.c_str()); - if (target) - py = strtok(NULL, " "); - else - { - targetGUID = objmgr.GetPlayerGUIDByName(name); - if(targetGUID) - py = strtok(NULL, " "); - else - py = px; - } - } - - if(!target && !targetGUID) - { - target = getSelectedPlayer(); - } - - if(!target && !targetGUID) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) return false; - } uint32 accId = 0; uint32 money = 0; @@ -2216,8 +2130,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args) if (HasLowerSecurity(target, 0)) return false; - targetGUID = target->GetGUID(); - name = target->GetName(); // re-read for case getSelectedPlayer() target accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); @@ -2228,33 +2140,25 @@ bool ChatHandler::HandlePInfoCommand(const char* args) else { // check offline security - if (HasLowerSecurity(NULL, targetGUID)) + if (HasLowerSecurity(NULL, target_guid)) return false; // 0 - QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID)); + QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid)); if (!result) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); return false; - } + Field *fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); delete result; Tokens data; - if (!Player::LoadValuesArrayFromDB(data,targetGUID)) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + if (!Player::LoadValuesArrayFromDB(data,target_guid)) return false; - } money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE); level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL); - - accId = objmgr.GetPlayerAccountIdByGUID(targetGUID); + accId = objmgr.GetPlayerAccountIdByGUID(target_guid); } std::string username = GetMangosString(LANG_ERROR); @@ -2283,9 +2187,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args) delete result; } - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); - PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency); + PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency); std::string timeStr = secsToTimeString(total_player_time,true,true); uint32 gold = money /GOLD; @@ -2293,7 +2197,7 @@ bool ChatHandler::HandlePInfoCommand(const char* args) uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp ); - if ( py && strncmp(py, "rep", 3) == 0 ) + if( subcommandStr && strncmp(subcommandStr, "rep", 3) == 0 ) { if(!target) { @@ -2422,27 +2326,18 @@ bool ChatHandler::HandleTicketCommand(const char* args) return true; } - std::string name = extractPlayerNameFromLink(px); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - - if(!guid) + uint64 target_guid; + if(!extractPlayerTarget(px,NULL,&target_guid)) return false; // ticket $char_name - GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid)); + GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(target_guid)); if(!ticket) return false; std::string time = TimeToTimestampStr(ticket->GetLastUpdate()); - ShowTicket(guid, ticket->GetText(), time.c_str()); + ShowTicket(target_guid, ticket->GetText(), time.c_str()); return true; } @@ -2492,27 +2387,20 @@ bool ChatHandler::HandleDelTicketCommand(const char *args) return true; } - std::string name = extractPlayerNameFromLink(px); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - - if(!guid) + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(px,&target,&target_guid,&target_name)) return false; // delticket $char_name - ticketmgr.Delete(GUID_LOPART(guid)); + ticketmgr.Delete(GUID_LOPART(target_guid)); // notify players about ticket deleting - if(Player* sender = objmgr.GetPlayer(guid)) - sender->GetSession()->SendGMTicketGetTicket(0x0A,0); + if(target) + target->GetSession()->SendGMTicketGetTicket(0x0A,0); - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str()); return true; @@ -3663,39 +3551,11 @@ bool ChatHandler::HandleWpImportCommand(const char *args) //rename characters bool ChatHandler::HandleCharacterRenameCommand(const char* args) { - Player* target = NULL; - uint64 targetGUID = 0; - std::string oldname; - - char* px = strtok((char*)args, " "); - - if(px) - { - oldname = extractPlayerNameFromLink(px); - if(oldname.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - target = objmgr.GetPlayer(oldname.c_str()); - - if (!target) - targetGUID = objmgr.GetPlayerGUIDByName(oldname); - } - - if(!target && !targetGUID) - { - target = getSelectedPlayer(); - } - - if(!target && !targetGUID) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; - } if(target) { @@ -3710,13 +3570,13 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args) else { // check offline security - if (HasLowerSecurity(NULL, targetGUID)) + if (HasLowerSecurity(NULL, target_guid)) return false; - std::string oldNameLink = playerLink(oldname); + std::string oldNameLink = playerLink(target_name); - PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID)); - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID)); + PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid)); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid)); } return true; @@ -3725,39 +3585,11 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args) // customize characters bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) { - Player* target = NULL; - uint64 targetGUID = 0; - std::string oldname; - - char* px = strtok((char*)args, " "); - - if(px) - { - oldname = extractPlayerNameFromLink(px); - if(oldname.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - target = objmgr.GetPlayer(oldname.c_str()); - - if (!target) - targetGUID = objmgr.GetPlayerGUIDByName(oldname); - } - - if(!target && !targetGUID) - { - target = getSelectedPlayer(); - } - - if(!target && !targetGUID) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; - } if(target) { @@ -3767,10 +3599,10 @@ bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) } else { - std::string oldNameLink = playerLink(oldname); + std::string oldNameLink = playerLink(target_name); - PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID)); - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); + PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid)); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid)); } return true; @@ -4054,41 +3886,16 @@ bool ChatHandler::HandleEventStopCommand(const char* args) bool ChatHandler::HandleCombatStopCommand(const char* args) { - Player *player; - - if(*args) - { - std::string playername = extractPlayerNameFromLink((char*)args); - if(playername.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(playername.c_str()); - - if(!player) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - } - else - { - player = getSelectedPlayer(); - - if (!player) - player = m_session->GetPlayer(); - } - - // check online security - if (HasLowerSecurity(player, 0)) + Player* target; + if(!extractPlayerTarget((char*)args,&target)) return false; - player->CombatStop(); - player->getHostilRefManager().deleteReferences(); + // check online security + if (HasLowerSecurity(target, 0)) + return false; + + target->CombatStop(); + target->getHostilRefManager().deleteReferences(); return true; } @@ -4320,16 +4127,11 @@ bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/) return true; } -bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/) +bool ChatHandler::HandleRepairitemsCommand(const char* args) { - Player *target = getSelectedPlayer(); - - if(!target) - { - PSendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); + Player* target; + if(!extractPlayerTarget((char*)args,&target)) return false; - } // check online security if (HasLowerSecurity(target, 0)) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 9a147e5a5..b79351edd 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -1919,33 +1919,14 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/) bool ChatHandler::HandleLearnAllDefaultCommand(const char* args) { - Player *player = NULL; - if (*args) - { - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(name.c_str()); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); + Player* target; + if(!extractPlayerTarget((char*)args,&target)) return false; - } - player->learnDefaultSpells(); - player->learnQuestRewardedSpells(); + target->learnDefaultSpells(); + target->learnQuestRewardedSpells(); - PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(player).c_str()); + PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST,GetNameLink(target).c_str()); return true; } @@ -3153,41 +3134,26 @@ bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args) */ bool ChatHandler::HandleGuildCreateCommand(const char* args) { - - if (!*args) + char* nameStr; + char* guildStr; + extractOptFirstArg((char*)args,&nameStr,&guildStr); + if(!guildStr) return false; - char *lname = strtok ((char*)args, " "); - char *gname = strtok (NULL, ""); - - if (!lname) + Player* target; + if(!extractPlayerTarget(nameStr,&target)) return false; - if (!gname) - { - SendSysMessage (LANG_INSERT_GUILD_NAME); - SetSentErrorMessage (true); - return false; - } + std::string guildname = guildStr; - std::string guildname = gname; - - Player* player = ObjectAccessor::Instance ().FindPlayerByName (lname); - if (!player) - { - SendSysMessage (LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage (true); - return false; - } - - if (player->GetGuildId()) + if (target->GetGuildId()) { SendSysMessage (LANG_PLAYER_IN_GUILD); return true; } Guild *guild = new Guild; - if (!guild->create (player,guildname)) + if (!guild->create (target,guildname)) { delete guild; SendSysMessage (LANG_GUILD_NOT_CREATED); @@ -3201,38 +3167,23 @@ bool ChatHandler::HandleGuildCreateCommand(const char* args) bool ChatHandler::HandleGuildInviteCommand(const char *args) { - if (!*args) + char* nameStr; + char* guildNameStr; + extractOptFirstArg((char*)args,&nameStr,&guildNameStr); + if(!guildNameStr) return false; - char* par1 = strtok ((char*)args, " "); - char* par2 = strtok (NULL, ""); - if(!par1 || !par2) + uint64 target_guid; + if(!extractPlayerTarget(nameStr,NULL,&target_guid)) return false; - std::string glName = par2; + std::string glName = guildNameStr; Guild* targetGuild = objmgr.GetGuildByName (glName); if (!targetGuild) return false; - std::string plName = extractPlayerNameFromLink(par1); - if(plName.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 plGuid = 0; - if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) - plGuid = targetPlayer->GetGUID (); - else - plGuid = objmgr.GetPlayerGUIDByName (plName); - - if (!plGuid) - return false; - // player's guild membership checked in AddMember before add - if (!targetGuild->AddMember (plGuid,targetGuild->GetLowestRank ())) + if (!targetGuild->AddMember (target_guid,targetGuild->GetLowestRank ())) return false; return true; @@ -3240,91 +3191,50 @@ bool ChatHandler::HandleGuildInviteCommand(const char *args) bool ChatHandler::HandleGuildUninviteCommand(const char *args) { - if (!*args) + Player* target; + uint64 target_guid; + if(!extractPlayerTarget((char*)args,&target,&target_guid)) return false; - char* par1 = strtok ((char*)args, " "); - if(!par1) - return false; - - std::string plName = extractPlayerNameFromLink(par1); - if(plName.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 plGuid = 0; - uint32 glId = 0; - if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) - { - plGuid = targetPlayer->GetGUID (); - glId = targetPlayer->GetGuildId (); - } - else - { - plGuid = objmgr.GetPlayerGUIDByName (plName); - glId = Player::GetGuildIdFromDB (plGuid); - } - - if (!plGuid || !glId) + uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid); + if (!glId) return false; Guild* targetGuild = objmgr.GetGuildById (glId); if (!targetGuild) return false; - targetGuild->DelMember (plGuid); - + targetGuild->DelMember (target_guid); return true; } bool ChatHandler::HandleGuildRankCommand(const char *args) { - if (!*args) + char* nameStr; + char* rankStr; + extractOptFirstArg((char*)args,&nameStr,&rankStr); + if(!rankStr) return false; - char* par1 = strtok ((char*)args, " "); - char* par2 = strtok (NULL, " "); - if (!par1 || !par2) + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) return false; - std::string plName = extractPlayerNameFromLink(par1); - if(plName.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - - uint64 plGuid = 0; - uint32 glId = 0; - if (Player* targetPlayer = ObjectAccessor::Instance ().FindPlayerByName (plName.c_str ())) - { - plGuid = targetPlayer->GetGUID (); - glId = targetPlayer->GetGuildId (); - } - else - { - plGuid = objmgr.GetPlayerGUIDByName (plName); - glId = Player::GetGuildIdFromDB (plGuid); - } - - if (!plGuid || !glId) + uint32 glId = target ? target->GetGuildId () : Player::GetGuildIdFromDB (target_guid); + if (!glId) return false; Guild* targetGuild = objmgr.GetGuildById (glId); if (!targetGuild) return false; - uint32 newrank = uint32 (atoi (par2)); + uint32 newrank = uint32 (atoi (rankStr)); if (newrank > targetGuild->GetLowestRank ()) return false; - targetGuild->ChangeRank (plGuid,newrank); - + targetGuild->ChangeRank (target_guid,newrank); return true; } @@ -3510,43 +3420,20 @@ bool ChatHandler::HandleModifyArenaCommand(const char * args) bool ChatHandler::HandleReviveCommand(const char* args) { - Player* player = NULL; - uint64 player_guid = 0; - - if (*args) - { - std::string name = extractPlayerNameFromLink((char*)args); - if (name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(name.c_str()); - if (!player) - player_guid = objmgr.GetPlayerGUIDByName(name); - } - else - player = getSelectedPlayer(); - - if (player) - { - player->ResurrectPlayer(0.5f); - player->SpawnCorpseBones(); - player->SaveToDB(); - } - else if (player_guid) - { - // will resurrected at login without corpse - ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid); - } - else - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + if(!extractPlayerTarget((char*)args,&target,&target_guid)) return false; + + if (target) + { + target->ResurrectPlayer(0.5f); + target->SpawnCorpseBones(); + target->SaveToDB(); } + else + // will resurrected at login without corpse + ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid); return true; } @@ -3998,26 +3885,27 @@ void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint3 bool ChatHandler::HandleCharacterLevelCommand(const char* args) { - char* px = strtok((char*)args, " "); - char* py = strtok((char*)NULL, " "); + char* nameStr; + char* levelStr; + extractOptFirstArg((char*)args,&nameStr,&levelStr); + if(!levelStr) + return false; - // command format parsing - char* pname = (char*)NULL; - int32 newlevel = 0; + // exception opt second arg: .character level $name + if(isalpha(levelStr[0])) + { + nameStr = levelStr; + levelStr = NULL; // current level will used + } - if(px && py) // .character level $name #level - { - newlevel = atoi(py); - pname = px; - } - else if(px && !py) // .character level $name OR .character level #level - { - if(isalpha(px[0])) // .character level $name - pname = px; - else // .character level #level - newlevel = atoi(px); - } - // // .character level - progress reset + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) + return false; + + int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid); + int32 newlevel = levelStr ? atoi(levelStr) : oldlevel; if(newlevel < 1) return false; // invalid level @@ -4025,60 +3913,11 @@ bool ChatHandler::HandleCharacterLevelCommand(const char* args) if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level newlevel = STRONG_MAX_LEVEL; - // player - Player *chr = NULL; - uint64 chr_guid = 0; + HandleCharacterLevel(target,target_guid,oldlevel,newlevel); - std::string name; - - if(pname) // player by name + if(!m_session || m_session->GetPlayer() != target) // including player==NULL { - name = extractPlayerNameFromLink(pname); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - chr = objmgr.GetPlayer(name.c_str()); - if(!chr) // not in game - { - chr_guid = objmgr.GetPlayerGUIDByName(name); - if (chr_guid == 0) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - } - } - else // player by selection - { - chr = getSelectedPlayer(); - - if (chr == NULL) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - name = chr->GetName(); - } - - assert(chr || chr_guid); - - int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid); - - if(!px && !py) // .character level - progress reset - newlevel = oldlevel; - - HandleCharacterLevel(chr,chr_guid,oldlevel,newlevel); - - if(m_session && m_session->GetPlayer() != chr) // including player==NULL - { - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel); } @@ -4087,83 +3926,38 @@ bool ChatHandler::HandleCharacterLevelCommand(const char* args) bool ChatHandler::HandleLevelUpCommand(const char* args) { - char* px = strtok((char*)args, " "); - char* py = strtok((char*)NULL, " "); + char* nameStr; + char* levelStr; + extractOptFirstArg((char*)args,&nameStr,&levelStr); - // command format parsing - char* pname = (char*)NULL; - int addlevel = 1; - - if(px && py) // .levelup name level + // exception opt second arg: .character level $name + if(levelStr && isalpha(levelStr[0])) { - addlevel = atoi(py); - pname = px; - } - else if(px && !py) // .levelup name OR .levelup level - { - if(isalpha(px[0])) // .levelup name - pname = px; - else // .levelup level - addlevel = atoi(px); - } - // else .levelup - nothing do for preparing - - // player - Player *chr = NULL; - uint64 chr_guid = 0; - - std::string name; - - if(pname) // player by name - { - name = extractPlayerNameFromLink(pname); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - chr = objmgr.GetPlayer(name.c_str()); - if(!chr) // not in game - { - chr_guid = objmgr.GetPlayerGUIDByName(name); - if (chr_guid == 0) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - } - } - else // player by selection - { - chr = getSelectedPlayer(); - - if (chr == NULL) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - name = chr->GetName(); + nameStr = levelStr; + levelStr = NULL; // current level will used } - assert(chr || chr_guid); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) + return false; - int32 oldlevel = chr ? chr->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,chr_guid); + int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid); + int32 addlevel = levelStr ? atoi(levelStr) : 1; int32 newlevel = oldlevel + addlevel; + if(newlevel < 1) newlevel = 1; + if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level newlevel = STRONG_MAX_LEVEL; - HandleCharacterLevel(chr,chr_guid,oldlevel,newlevel); + HandleCharacterLevel(target,target_guid,oldlevel,newlevel); - if(m_session && m_session->GetPlayer() != chr) // including chr==NULL + if(!m_session || m_session->GetPlayer() != target) // including chr==NULL { - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_CHANGE_LVL,nameLink.c_str(),newlevel); } @@ -4620,76 +4414,31 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/) bool ChatHandler::HandleResetAchievementsCommand (const char * args) { - char* pName = strtok((char*)args, ""); - Player *player = NULL; - uint64 guid = 0; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } + Player* target; + uint64 target_guid; + if (!extractPlayerTarget((char*)args,&target,&target_guid)) + return false; - guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } + if(target) + target->GetAchievementMgr().Reset(); else - { - player = getSelectedPlayer(); - if(player) - guid = player->GetGUID(); - } - - if(!player && !guid) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - return true; - } - - if(player) - player->GetAchievementMgr().Reset(); - else if(guid) - AchievementMgr::DeleteFromDB(GUID_LOPART(guid)); + AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid)); return true; } bool ChatHandler::HandleResetHonorCommand (const char * args) { - char* pName = strtok((char*)args, ""); - Player *player = NULL; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } + Player* target; + if (!extractPlayerTarget((char*)args,&target)) + return false; - uint64 guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - return true; - } - - player->SetUInt32Value(PLAYER_FIELD_KILLS, 0); - player->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); - player->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0); - player->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - player->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); - - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); + target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); + target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); + target->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 0); + target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); + target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); return true; } @@ -4751,49 +4500,28 @@ static bool HandleResetStatsOrLevelHelper(Player* player) bool ChatHandler::HandleResetLevelCommand(const char * args) { - char* pName = strtok((char*)args, ""); - Player *player = NULL; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); + Player* target; + if(!extractPlayerTarget((char*)args,&target)) return false; - } - if(!HandleResetStatsOrLevelHelper(player)) + if(!HandleResetStatsOrLevelHelper(target)) return false; // set starting level - uint32 start_level = player->getClass() != CLASS_DEATH_KNIGHT + uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - player->SetLevel(start_level); - player->InitRunes(); - player->InitStatsForLevel(true); - player->InitTaxiNodesForLevel(); - player->InitGlyphsForLevel(); - player->InitTalentForLevel(); - player->SetUInt32Value(PLAYER_XP,0); + target->SetLevel(start_level); + target->InitRunes(); + target->InitStatsForLevel(true); + target->InitTaxiNodesForLevel(); + target->InitGlyphsForLevel(); + target->InitTalentForLevel(); + target->SetUInt32Value(PLAYER_XP,0); // reset level for pet - if(Pet* pet = player->GetPet()) + if(Pet* pet = target->GetPet()) pet->SynchronizeLevelWithOwner(); return true; @@ -4801,84 +4529,42 @@ bool ChatHandler::HandleResetLevelCommand(const char * args) bool ChatHandler::HandleResetStatsCommand(const char * args) { - char* pName = strtok((char*)args, ""); - Player *player = NULL; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint64 guid = objmgr.GetPlayerGUIDByName(name); - player = objmgr.GetPlayer(guid); - } - else - player = getSelectedPlayer(); - - if(!player) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if(!HandleResetStatsOrLevelHelper(player)) + Player* target; + if (!extractPlayerTarget((char*)args,&target)) return false; - player->InitRunes(); - player->InitStatsForLevel(true); - player->InitTaxiNodesForLevel(); - player->InitGlyphsForLevel(); - player->InitTalentForLevel(); + if (!HandleResetStatsOrLevelHelper(target)) + return false; + + target->InitRunes(); + target->InitStatsForLevel(true); + target->InitTaxiNodesForLevel(); + target->InitGlyphsForLevel(); + target->InitTalentForLevel(); return true; } bool ChatHandler::HandleResetSpellsCommand(const char * args) { - char* pName = strtok((char*)args, ""); - Player *player = NULL; - uint64 playerGUID = 0; - if (pName) - { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - player = objmgr.GetPlayer(name.c_str()); - if(!player) - playerGUID = objmgr.GetPlayerGUIDByName(name); - } - else - player = getSelectedPlayer(); - - if(!player && !playerGUID) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); + Player* target; + uint64 target_guid; + std::string target_name; + if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; - } - if(player) + if(target) { - player->resetSpells(); + target->resetSpells(); - ChatHandler(player).SendSysMessage(LANG_RESET_SPELLS); - if(m_session->GetPlayer()!=player) - PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(player).c_str()); + ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS); + if(!m_session || m_session->GetPlayer()!=target) + PSendSysMessage(LANG_RESET_SPELLS_ONLINE,GetNameLink(target).c_str()); } else { - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(playerGUID)); - PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,pName); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid)); + PSendSysMessage(LANG_RESET_SPELLS_OFFLINE,target_name); } return true; @@ -4886,43 +4572,30 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args) bool ChatHandler::HandleResetTalentsCommand(const char * args) { - char* pName = strtok((char*)args, ""); - Player *player = NULL; - uint64 playerGUID = 0; - if (pName) + Player* target; + uint64 target_guid; + std::string target_name; + if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) + return false; + + if (target) { - std::string name = extractPlayerNameFromLink(pName); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } + target->resetTalents(true); - player = objmgr.GetPlayer(name.c_str()); - if(!player) - playerGUID = objmgr.GetPlayerGUIDByName(name); - } - else - player = getSelectedPlayer(); - - if(player) - { - player->resetTalents(true); - - ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS); - if(m_session->GetPlayer()!=player) - PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(player).c_str()); + ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); + if (!m_session || m_session->GetPlayer()!=target) + PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str()); return true; } - else if (playerGUID) + else if (target_guid) { - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) ); - std::string nameLink = playerLink(pName); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(target_guid) ); + std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str()); return true; } + // Try reset talenents as Hunter Pet Creature* creature = getSelectedCreature(); if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET) @@ -4931,10 +4604,10 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args) Unit *owner = creature->GetOwner(); if (owner && owner->GetTypeId() == TYPEID_PLAYER) { - player = (Player *)owner; - ChatHandler(player).SendSysMessage(LANG_RESET_PET_TALENTS); - if(m_session->GetPlayer()!=player) - PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(player).c_str()); + 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; } @@ -4958,11 +4631,15 @@ bool ChatHandler::HandleResetAllCommand(const char * args) { atLogin = AT_LOGIN_RESET_SPELLS; sWorld.SendWorldText(LANG_RESETALL_SPELLS); + if(!m_session) + SendSysMessage(LANG_RESETALL_SPELLS); } else if(casename=="talents") { atLogin = AT_LOGIN_RESET_TALENTS; sWorld.SendWorldText(LANG_RESETALL_TALENTS); + if(!m_session) + SendSysMessage(LANG_RESETALL_TALENTS); } else { @@ -5493,24 +5170,12 @@ bool ChatHandler::HandleBanInfoAccountCommand(const char* args) bool ChatHandler::HandleBanInfoCharacterCommand(const char* args) { - if (!*args) + Player* target; + uint64 target_guid; + if(!extractPlayerTarget((char*)args,&target,&target_guid)) return false; - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - uint32 accountid = objmgr.GetPlayerAccountIdByPlayerName(name); - if(!accountid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } + uint32 accountid = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid); std::string accountname; if(!accmgr.GetName(accountid,accountname)) @@ -6585,18 +6250,12 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args) //Send items by mail bool ChatHandler::HandleSendItemsCommand(const char* args) { - if(!*args) - return false; - // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] - - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* receiver; + uint64 receiver_guid; + std::string receiver_name; + if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name)) return false; - } char* tail1 = strtok(NULL, ""); if(!tail1) @@ -6692,14 +6351,6 @@ bool ChatHandler::HandleSendItemsCommand(const char* args) } } - uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); - if(!receiver_guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - // from console show not existed sender uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; @@ -6707,8 +6358,6 @@ bool ChatHandler::HandleSendItemsCommand(const char* args) uint32 stationery = MAIL_STATIONERY_GM; uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; - Player *receiver = objmgr.GetPlayer(receiver_guid); - // fill mail MailItemsInfo mi; // item list preparing @@ -6723,7 +6372,7 @@ bool ChatHandler::HandleSendItemsCommand(const char* args) WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE); - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(receiver_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; } @@ -6731,18 +6380,13 @@ bool ChatHandler::HandleSendItemsCommand(const char* args) ///Send money by mail bool ChatHandler::HandleSendMoneyCommand(const char* args) { - if (!*args) - return false; - /// format: name "subject text" "mail text" money - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + Player* receiver; + uint64 receiver_guid; + std::string receiver_name; + if(!extractPlayerTarget((char*)args,&receiver,&receiver_guid,&receiver_name)) return false; - } char* tail1 = strtok(NULL, ""); if (!tail1) @@ -6789,14 +6433,6 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args) std::string subject = msgSubject; std::string text = msgText; - uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name); - if (!receiver_guid) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - // from console show not existed sender uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; @@ -6804,11 +6440,9 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args) uint32 stationery = MAIL_STATIONERY_GM; uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; - Player *receiver = objmgr.GetPlayer(receiver_guid); - WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, money, 0, MAIL_CHECK_MASK_NONE); - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(receiver_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; } @@ -6816,28 +6450,17 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args) /// Send a message to a player in game bool ChatHandler::HandleSendMessageCommand(const char* args) { - ///- Get the command line arguments - std::string name = extractPlayerNameFromLink((char*)args); - if(name.empty()) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); + ///- Find the player + Player *rPlayer; + std::string rName; + if(!extractPlayerTarget((char*)args,&rPlayer,NULL,&rName)) return false; - } char* msg_str = strtok(NULL, ""); if(!msg_str) return false; - ///- Find the player and check that he is not logging out. - Player *rPlayer = objmgr.GetPlayer(name.c_str()); - if(!rPlayer) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - + ///- Check that he is not logging out. if(rPlayer->GetSession()->isLogingOut()) { SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -6851,7 +6474,7 @@ bool ChatHandler::HandleSendMessageCommand(const char* args) rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); //Confirmation message - std::string nameLink = playerLink(name); + std::string nameLink = playerLink(rName); PSendSysMessage(LANG_SENDMESSAGE,nameLink.c_str(),msg_str); return true; } diff --git a/src/game/World.cpp b/src/game/World.cpp index da8766889..93d6d6575 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -2452,31 +2452,6 @@ void World::KickAllLess(AccountTypes sec) itr->second->KickPlayer(); } -/// Kick (and save) the designated player -bool World::KickPlayer(const std::string& playerName) -{ - SessionMap::const_iterator itr; - - // session not removed at kick and will removed in next update tick - for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) - { - if(!itr->second) - continue; - Player *player = itr->second->GetPlayer(); - if(!player) - continue; - if( player->IsInWorld() ) - { - if (playerName == player->GetName()) - { - itr->second->KickPlayer(); - return true; - } - } - } - return false; -} - /// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author) { diff --git a/src/game/World.h b/src/game/World.h index 0fd19e9b8..cea53107a 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -472,7 +472,6 @@ class World bool IsPvPRealm() { return (getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); } bool IsFFAPvPRealm() { return getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; } - bool KickPlayer(const std::string& playerName); void KickAll(); void KickAllLess(AccountTypes sec); BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d86a931cf..705b800d5 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7838" + #define REVISION_NR "7839" #endif // __REVISION_NR_H__ From 53699e1aa3bf82b4e10c17d49125e2906687f73e Mon Sep 17 00:00:00 2001 From: Naicisum Date: Sun, 17 May 2009 19:03:26 +0400 Subject: [PATCH 05/22] [7840] Fixed unexpected rounding in pet size scale calculation. Signed-off-by: VladimirMangos --- src/game/Pet.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index e7e195581..df1efee88 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -853,7 +853,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel) else if (getLevel() <= cFamily->minScaleLevel) scale = cFamily->minScale; else - scale = cFamily->minScale + (getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale); + scale = cFamily->minScale + float(getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale); SetFloatValue(OBJECT_FIELD_SCALE_X, scale); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 705b800d5..4a14b4343 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7839" + #define REVISION_NR "7840" #endif // __REVISION_NR_H__ From b7f09eb37c084475be9571023bf7c9cc0aecad3b Mon Sep 17 00:00:00 2001 From: SilverIce Date: Sun, 17 May 2009 19:58:07 +0400 Subject: [PATCH 06/22] [7841] Fixed: Prevent loading maps/vmaps when building enum. Signed-off-by: AlexDereka --- src/game/CharacterHandler.cpp | 8 ++++---- src/game/Player.cpp | 36 +++++++++++++++++++---------------- src/shared/revision_nr.h | 2 +- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index fabdc906c..69ddb7d47 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -159,8 +159,8 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) // ------- Query Without Declined Names -------- // 0 1 2 3 4 5 6 7 8 "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " - // 9 10 11 12 13 - "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid " + // 9 10 11 12 13 14 + "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " "WHERE characters.account = '%u' ORDER BY characters.guid" @@ -168,8 +168,8 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) // --------- Query With Declined Names --------- // 0 1 2 3 4 5 6 7 8 "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " - // 9 10 11 12 13 14 - "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive " + // 9 10 11 12 13 14 15 + "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 3d567d896..42ba06341 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1424,8 +1424,8 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) *p_data << uint8(getLevel()); // player level // do not use GetMap! it will spawn a new instance since the bound instances are not loaded - uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY(),GetPositionZ()); - sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId); + uint32 zoneId = fields[10].GetUInt32(); + sLog.outDebug("Player::BuildEnumData: map:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId); *p_data << uint32(zoneId); *p_data << uint32(GetMapId()); @@ -1434,7 +1434,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) *p_data << GetPositionZ(); // guild id - *p_data << (result ? fields[13].GetUInt32() : 0); + *p_data << uint32(fields[14].GetUInt32()); uint32 char_flags = 0; if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) @@ -1447,7 +1447,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_RENAME; if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) { - if(!fields[14].GetCppString().empty()) + if(!fields[15].GetCppString().empty()) char_flags |= CHARACTER_FLAG_DECLINED; } else @@ -1467,12 +1467,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // show pet at selection character in character list only for non-ghost character if (result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT)) { - uint32 entry = fields[10].GetUInt32(); + uint32 entry = fields[11].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(entry); if(cInfo) { - petDisplayId = fields[11].GetUInt32(); - petLevel = fields[12].GetUInt32(); + petDisplayId = fields[12].GetUInt32(); + petLevel = fields[13].GetUInt32(); petFamily = cInfo->family; } } @@ -13681,20 +13681,23 @@ void Player::SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, u bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) { bool delete_result = true; - if(!result) + if (!result) { - // 0 1 2 3 4 5 6 7 8 9 - result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); - if(!result) return false; + // 0 1 2 3 4 5 6 7 8 9 10 + result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login, zone FROM characters WHERE guid = '%u'",guid); + if (!result) + return false; } - else delete_result = false; + else + delete_result = false; Field *fields = result->Fetch(); - if(!LoadValues( fields[1].GetString())) + if (!LoadValues( fields[1].GetString())) { sLog.outError("Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid)); - if(delete_result) delete result; + if (delete_result) + delete result; return false; } @@ -13717,12 +13720,13 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) _LoadBoundInstances();*/ - if (delete_result) delete result; + if (delete_result) + delete result; for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i) m_items[i] = NULL; - if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) ) + if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) m_deathState = DEAD; return true; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4a14b4343..15354fd4b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7840" + #define REVISION_NR "7841" #endif // __REVISION_NR_H__ From ab3eb09669695783b874f91291c782478bad2ba6 Mon Sep 17 00:00:00 2001 From: DonTomika Date: Sun, 17 May 2009 22:46:11 +0400 Subject: [PATCH 07/22] [7842] Set and stop combat for pets at player enter to GM-mode. Signed-off-by: VladimirMangos --- src/game/Player.cpp | 14 +++++++++++++- src/shared/revision_nr.h | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 42ba06341..bc1778a85 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2073,11 +2073,17 @@ void Player::SetGameMaster(bool on) setFaction(35); SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); + if (Pet* pet = GetPet()) + { + pet->setFaction(35); + pet->getHostilRefManager().setOnlineOfflineState(false); + } + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); ResetContestedPvP(); getHostilRefManager().setOnlineOfflineState(false); - CombatStop(); + CombatStopWithPets(); SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases } @@ -2091,6 +2097,12 @@ void Player::SetGameMaster(bool on) setFactionForRace(getRace()); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); + if (Pet* pet = GetPet()) + { + pet->setFaction(getFaction()); + pet->getHostilRefManager().setOnlineOfflineState(true); + } + // restore FFA PvP Server state if(sWorld.IsFFAPvPRealm()) SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 15354fd4b..cb15c2ea9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7841" + #define REVISION_NR "7842" #endif // __REVISION_NR_H__ From 592adcf6d4ed8ff01beaf4b03cd85424f1e1c835 Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 17 May 2009 23:52:43 +0200 Subject: [PATCH 08/22] [7843] Added newline into Pet.h end to make gcc happy. Signed-off-by: ApoC --- src/game/Pet.h | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Pet.h b/src/game/Pet.h index 1b987b8ce..c16a4a550 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -252,4 +252,4 @@ class Pet : public Creature assert(false); } }; -#endif \ No newline at end of file +#endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cb15c2ea9..4136ee5bd 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7842" + #define REVISION_NR "7843" #endif // __REVISION_NR_H__ From 75d7a4c0cb9cf2d56efb491ef80ba2747f30dc56 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 18 May 2009 12:20:51 +0400 Subject: [PATCH 09/22] [7844] Fixed mangos string storage index type. --- src/game/ObjectMgr.cpp | 6 +----- src/game/ObjectMgr.h | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 5cb337b3e..f6518193f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -6553,11 +6553,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min for(MangosStringLocaleMap::iterator itr = mMangosStringLocaleMap.begin(); itr != mMangosStringLocaleMap.end();) { if (itr->first >= start_value && itr->first < end_value) - { - MangosStringLocaleMap::iterator itr2 = itr; - ++itr; - mMangosStringLocaleMap.erase(itr2); - } + mMangosStringLocaleMap.erase(itr++); else ++itr; } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index d2cb1a766..0a056afef 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -156,7 +156,7 @@ typedef UNORDERED_MAP ItemLocaleMap; typedef UNORDERED_MAP QuestLocaleMap; typedef UNORDERED_MAP NpcTextLocaleMap; typedef UNORDERED_MAP PageTextLocaleMap; -typedef UNORDERED_MAP MangosStringLocaleMap; +typedef UNORDERED_MAP MangosStringLocaleMap; typedef UNORDERED_MAP NpcOptionLocaleMap; typedef UNORDERED_MAP PointOfInterestLocaleMap; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4136ee5bd..f60172600 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7843" + #define REVISION_NR "7844" #endif // __REVISION_NR_H__ From 4617ac1dc1f64315d2459b78aa65153a5b25c176 Mon Sep 17 00:00:00 2001 From: evilstar Date: Mon, 18 May 2009 12:24:14 +0400 Subject: [PATCH 10/22] [7845] Implement reload support for creature eventAI tables. Signed-off-by: VladimirMangos --- src/game/Chat.cpp | 18 +++++++++++------- src/game/Chat.h | 4 ++++ src/game/CreatureEventAI.cpp | 1 + src/game/Level3.cpp | 35 +++++++++++++++++++++++++++++++++++ src/shared/revision_nr.h | 2 +- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 29572cfd4..a4fb9dc56 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -375,28 +375,32 @@ ChatCommand * ChatHandler::getCommandTable() { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL }, { "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL }, { "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL }, + { "all_eventai", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllEventAICommand, "", NULL }, + { "all_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllItemCommand, "", NULL }, + { "all_locales", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL }, { "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL }, { "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL }, { "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL }, { "all_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL }, { "all_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllSpellCommand, "", NULL }, - { "all_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllItemCommand, "", NULL }, - { "all_locales", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL }, { "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL }, { "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL }, { "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL }, + { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL }, { "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL }, { "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL }, - { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL }, - { "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, { "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL }, + { "creature_ai_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAIScriptsCommand, "", NULL }, + { "creature_ai_summons", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAISummonsCommand, "", NULL }, + { "creature_ai_texts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAITextsCommand, "", NULL }, { "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, { "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, { "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL }, { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, + { "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, { "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, { "game_graveyard_zone", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL }, { "game_tele", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameTeleCommand, "", NULL }, @@ -418,15 +422,15 @@ ChatCommand * ChatHandler::getCommandTable() { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL }, { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, { "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL }, + { "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL}, { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, { "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, { "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL }, { "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL}, { "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL}, - { "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL}, { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL }, - { "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL }, { "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL }, + { "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL }, { "quest_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL }, { "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL }, { "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL }, @@ -437,13 +441,13 @@ ChatCommand * ChatHandler::getCommandTable() { "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL }, { "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL }, { "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL }, + { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL }, { "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, { "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL }, { "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, { "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, - { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL }, { "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, { "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL }, { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index c71b635ea..ee22b6160 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -300,6 +300,7 @@ class ChatHandler bool HandleReloadAllNpcCommand(const char* args); bool HandleReloadAllQuestCommand(const char* args); bool HandleReloadAllScriptsCommand(const char* args); + bool HandleReloadAllEventAICommand(const char* args); bool HandleReloadAllSpellCommand(const char* args); bool HandleReloadAllLocalesCommand(const char* args); @@ -310,6 +311,9 @@ class ChatHandler bool HandleReloadAreaTriggerTavernCommand(const char* args); bool HandleReloadAreaTriggerTeleportCommand(const char* args); bool HandleReloadEventScriptsCommand(const char* args); + bool HandleReloadEventAITextsCommand(const char* args); + bool HandleReloadEventAISummonsCommand(const char* args); + bool HandleReloadEventAIScriptsCommand(const char* args); bool HandleReloadCommandCommand(const char* args); bool HandleReloadCreatureQuestRelationsCommand(const char* args); bool HandleReloadCreatureQuestInvRelationsCommand(const char* args); diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index ddae14fdd..18211720d 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -39,6 +39,7 @@ int CreatureEventAI::Permissible(const Creature *creature) CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c) { + // Need make copy for filter unneeded steps and safe in case table reload CreatureEventAI_Event_Map::const_iterator CreatureEvents = CreatureEAI_Mgr.GetCreatureEventAIMap().find(m_creature->GetEntry()); if (CreatureEvents != CreatureEAI_Mgr.GetCreatureEventAIMap().end()) { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index b79351edd..8b6061f29 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -49,6 +49,7 @@ #include "BattleGroundMgr.h" #include "InstanceSaveMgr.h" #include "InstanceData.h" +#include "CreatureEventAIMgr.h" //reload commands bool ChatHandler::HandleReloadAllCommand(const char*) @@ -57,6 +58,7 @@ bool ChatHandler::HandleReloadAllCommand(const char*) HandleReloadAllAchievementCommand(""); HandleReloadAllAreaCommand(""); + HandleReloadAllEventAICommand(""); HandleReloadAllLootCommand(""); HandleReloadAllNpcCommand(""); HandleReloadAllQuestCommand(""); @@ -137,6 +139,14 @@ bool ChatHandler::HandleReloadAllScriptsCommand(const char*) return true; } +bool ChatHandler::HandleReloadAllEventAICommand(const char*) +{ + HandleReloadEventAITextsCommand("a"); + HandleReloadEventAISummonsCommand("a"); + HandleReloadEventAIScriptsCommand("a"); + return true; +} + bool ChatHandler::HandleReloadAllSpellCommand(const char*) { HandleReloadSkillDiscoveryTemplateCommand("a"); @@ -614,6 +624,31 @@ bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg) return true; } +bool ChatHandler::HandleReloadEventAITextsCommand(const char* arg) +{ + + sLog.outString( "Re-Loading Texts from `creature_ai_texts`..."); + CreatureEAI_Mgr.LoadCreatureEventAI_Texts(); + SendGlobalSysMessage("DB table `creature_ai_texts` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadEventAISummonsCommand(const char* arg) +{ + sLog.outString( "Re-Loading Summons from `creature_ai_summons`..."); + CreatureEAI_Mgr.LoadCreatureEventAI_Summons(); + SendGlobalSysMessage("DB table `creature_ai_summons` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadEventAIScriptsCommand(const char* arg) +{ + sLog.outString( "Re-Loading Scripts from `creature_ai_scripts`..."); + CreatureEAI_Mgr.LoadCreatureEventAI_Scripts(); + SendGlobalSysMessage("DB table `creature_ai_scripts` reloaded."); + return true; +} + bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg) { if(sWorld.IsScriptScheduled()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f60172600..ed6f971ce 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7844" + #define REVISION_NR "7845" #endif // __REVISION_NR_H__ From 2d4edd18f6c7f3bc9d91a5cd8aeefb56e823f1d9 Mon Sep 17 00:00:00 2001 From: timmit Date: Mon, 18 May 2009 13:26:55 +0400 Subject: [PATCH 11/22] [7846] Add empty line to end of .h file Signed-off-by: VladimirMangos --- src/game/DBCfmt.h | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index e1a680889..75a795906 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -104,4 +104,4 @@ const char WorldMapAreaEntryfmt[]="xinxffffix"; const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx"; const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx"; -#endif \ No newline at end of file +#endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ed6f971ce..f9e71c994 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7845" + #define REVISION_NR "7846" #endif // __REVISION_NR_H__ From 07d00c39270cd2506e9f363d1a0f9e9bebe80848 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 18 May 2009 22:39:35 +0400 Subject: [PATCH 12/22] [7847] Replace paramter unions by uniton of event ai action type structures. Add/fix some loading checks. * Also send to process function reference to strucutre instead large amount fields. * Specially note that fixed check for first arg of action type 27 that before wrongly test as quest id, when by using code expected creature id. Possible some used data wrongly can be quest ids.... --- src/game/CreatureEventAI.cpp | 392 +++++++++++++------------------- src/game/CreatureEventAI.h | 224 ++++++++++++++++-- src/game/CreatureEventAIMgr.cpp | 346 ++++++++++++++-------------- src/shared/revision_nr.h | 2 +- 4 files changed, 537 insertions(+), 427 deletions(-) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 18211720d..688460212 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -461,37 +461,35 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction //Process actions for (uint32 j = 0; j < MAX_ACTIONS; j++) - ProcessAction(pHolder.Event.action[j].type, pHolder.Event.action[j].param1, pHolder.Event.action[j].param2, pHolder.Event.action[j].param3, rnd, pHolder.Event.event_id, pActionInvoker); + ProcessAction(pHolder.Event.action[j], rnd, pHolder.Event.event_id, pActionInvoker); return true; } -void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, uint32 param3, uint32 rnd, uint32 EventId, Unit* pActionInvoker) +void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker) { - switch (type) + switch (action.type) { case ACTION_T_TEXT: { - if (!param1) + if (!action.text.TextId1) return; - uint32 temp = 0; + int32 temp = 0; - if (param2 && param3) + if (action.text.TextId2 && action.text.TextId3) { switch( rand()%3 ) { - case 0: temp = param1; break; - case 2: temp = param2; break; - case 3: temp = param3; break; + case 0: temp = action.text.TextId1; break; + case 2: temp = action.text.TextId2; break; + case 3: temp = action.text.TextId3; break; } - }else if ( param2 && urand(0,1) ) - { - temp = param2; - }else - { - temp = param1; } + else if (action.text.TextId2 && urand(0,1)) + temp = action.text.TextId2; + else + temp = action.text.TextId1; if (temp) { @@ -517,12 +515,12 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u DoScriptText(temp, m_creature, target); } + break; } - break; case ACTION_T_SET_FACTION: { - if (param1) - m_creature->setFaction(param1); + if (action.set_faction.factionId) + m_creature->setFaction(action.set_faction.factionId); else { if (CreatureInfo const* ci = GetCreatureTemplateStore(m_creature->GetEntry())) @@ -532,16 +530,16 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u m_creature->setFaction(ci->faction_A); } } + break; } - break; case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: { - if (param1 || param2) + if (action.morph.creatireId || action.morph.modelId) { //set model based on entry from creature_template - if (param1) + if (action.morph.creatireId) { - if (CreatureInfo const* ci = GetCreatureTemplateStore(param1)) + if (CreatureInfo const* ci = GetCreatureTemplateStore(action.morph.creatireId)) { //use default display if (ci->DisplayID_A) @@ -550,73 +548,67 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u } //if no param1, then use value from param2 (modelId) else - m_creature->SetDisplayId(param2); + m_creature->SetDisplayId(action.morph.modelId); } else m_creature->DeMorph(); + break; } - break; case ACTION_T_SOUND: - m_creature->PlayDirectSound(param1); + m_creature->PlayDirectSound(action.sound.soundId); break; case ACTION_T_EMOTE: - m_creature->HandleEmoteCommand(param1); + m_creature->HandleEmoteCommand(action.emote.emoteId); break; case ACTION_T_RANDOM_SOUND: { - uint32 temp = GetRandActionParam(rnd, param1, param2, param3); - - if (temp != uint32(0xffffffff)) - m_creature->PlayDirectSound( temp ); + int32 temp = GetRandActionParam(rnd, action.random_sound.soundId1, action.random_sound.soundId2, action.random_sound.soundId3); + if (temp >= 0) + m_creature->PlayDirectSound(temp); + break; } - break; case ACTION_T_RANDOM_EMOTE: { - uint32 temp = GetRandActionParam(rnd, param1, param2, param3); - - if (temp != uint32(0xffffffff)) + int32 temp = GetRandActionParam(rnd, action.random_emote.emoteId1, action.random_emote.emoteId2, action.random_emote.emoteId3); + if (temp >= 0) m_creature->HandleEmoteCommand(temp); + break; } - break; case ACTION_T_CAST: { - Unit* target = GetTargetByType(param2, pActionInvoker); + Unit* target = GetTargetByType(action.cast.target, pActionInvoker); Unit* caster = m_creature; if (!target) return; - //Cast is always triggered if target is forced to cast on self - if (param3 & CAST_FORCE_TARGET_SELF) - { - param3 |= CAST_TRIGGERED; + if (action.cast.castFlags & CAST_FORCE_TARGET_SELF) caster = target; - } //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered - bool canCast = !caster->IsNonMeleeSpellCasted(false) || (param3 & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS)); + bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS)); // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them - if(param3 & CAST_AURA_NOT_PRESENT) + if(action.cast.castFlags & CAST_AURA_NOT_PRESENT) { for(uint8 i = 0; i < 3; ++i) - if(target->HasAura(param1, i)) + if(target->HasAura(action.cast.spellId, i)) return; } if (canCast) { - const SpellEntry* tSpell = GetSpellStore()->LookupEntry(param1); + const SpellEntry* tSpell = GetSpellStore()->LookupEntry(action.cast.spellId); //Verify that spell exists if (tSpell) { //Check if cannot cast spell - if (!(param3 & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)) && - !CanCast(target, tSpell, (param3 & CAST_TRIGGERED))) + if (!(action.cast.castFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)) && + !CanCast(target, tSpell, (action.cast.castFlags & CAST_TRIGGERED))) { //Melee current victim if flag not set - if (!(param3 & CAST_NO_MELEE_IF_OOM)) + if (!(action.cast.castFlags & CAST_NO_MELEE_IF_OOM)) { if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) { @@ -632,111 +624,83 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u else { //Interrupt any previous spell - if (caster->IsNonMeleeSpellCasted(false) && param3 & CAST_INTURRUPT_PREVIOUS) + if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTURRUPT_PREVIOUS) caster->InterruptNonMeleeSpells(false); - caster->CastSpell(target, param1, (param3 & CAST_TRIGGERED)); + caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED)); } - }else - sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), param1); + } + else + sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), action.cast.spellId); } + break; } - break; case ACTION_T_SUMMON: { - Unit* target = GetTargetByType(param2, pActionInvoker); + Unit* target = GetTargetByType(action.summon.target, pActionInvoker); Creature* pCreature = NULL; - if (param3) - pCreature = m_creature->SummonCreature(param1, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, param3); + if (action.summon.duration) + pCreature = m_creature->SummonCreature(action.summon.creatured, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); else - pCreature = m_creature->SummonCreature(param1, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); + pCreature = m_creature->SummonCreature(action.summon.creatured, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); if (!pCreature) - { - - sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", param1, EventId, m_creature->GetEntry()); - } - else if (param2 != TARGET_T_SELF && target) + sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatured, EventId, m_creature->GetEntry()); + else if (action.summon.target != TARGET_T_SELF && target) pCreature->AI()->AttackStart(target); + break; } - break; case ACTION_T_THREAT_SINGLE_PCT: - { - Unit* target = GetTargetByType(param2, pActionInvoker); - - if (target) - m_creature->getThreatManager().modifyThreatPercent(target, param1); - } - break; + if (Unit* target = GetTargetByType(action.threat_single_pct.target, pActionInvoker)) + m_creature->getThreatManager().modifyThreatPercent(target, action.threat_single_pct.percent); + break; case ACTION_T_THREAT_ALL_PCT: { - Unit* Temp = NULL; - - std::list::iterator i = m_creature->getThreatManager().getThreatList().begin(); - for (; i != m_creature->getThreatManager().getThreatList().end(); ++i) - { - Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); - if (Temp) - m_creature->getThreatManager().modifyThreatPercent(Temp, param1); - } + std::list& threatList = m_creature->getThreatManager().getThreatList(); + for (std::list::iterator i = threatList.begin(); i != threatList.end(); ++i) + if(Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid())) + m_creature->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent); + break; } - break; case ACTION_T_QUEST_EVENT: - { - Unit* target = GetTargetByType(param2, pActionInvoker); - - if (target && target->GetTypeId() == TYPEID_PLAYER) - ((Player*)target)->AreaExploredOrEventHappens(param1); - } - break; - case ACTION_T_CASTCREATUREGO: - { - Unit* target = GetTargetByType(param3, pActionInvoker); - - if (target && target->GetTypeId() == TYPEID_PLAYER) - ((Player*)target)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2); - } - break; + if (Unit* target = GetTargetByType(action.quest_event.target, pActionInvoker)) + if (target->GetTypeId() == TYPEID_PLAYER) + ((Player*)target)->AreaExploredOrEventHappens(action.quest_event.questId); + break; + case ACTION_T_CAST_EVENT: + if (Unit* target = GetTargetByType(action.cast_event.target, pActionInvoker)) + if (target->GetTypeId() == TYPEID_PLAYER) + ((Player*)target)->CastedCreatureOrGO(action.cast_event.creatureId, m_creature->GetGUID(), action.cast_event.spellId); + break; case ACTION_T_SET_UNIT_FIELD: { - Unit* target = GetTargetByType(param3, pActionInvoker); + Unit* target = GetTargetByType(action.set_unit_field.target, pActionInvoker); - if (param1 < OBJECT_END || param1 >= UNIT_END) + // not allow modify important for integrity object fields + if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END) return; if (target) - target->SetUInt32Value(param1, param2); + target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value); + + break; } - break; case ACTION_T_SET_UNIT_FLAG: - { - Unit* target = GetTargetByType(param2, pActionInvoker); - - if (target) - target->SetFlag(UNIT_FIELD_FLAGS, param1); - } - break; + if (Unit* target = GetTargetByType(action.unit_flag.target, pActionInvoker)) + target->SetFlag(UNIT_FIELD_FLAGS, action.unit_flag.value); + break; case ACTION_T_REMOVE_UNIT_FLAG: - { - Unit* target = GetTargetByType(param2, pActionInvoker); - - if (target) - target->RemoveFlag(UNIT_FIELD_FLAGS, param1); - } - break; + if (Unit* target = GetTargetByType(action.unit_flag.target, pActionInvoker)) + target->RemoveFlag(UNIT_FIELD_FLAGS, action.unit_flag.value); + break; case ACTION_T_AUTO_ATTACK: - { - if (param1) - MeleeEnabled = true; - else MeleeEnabled = false; - } - break; + MeleeEnabled = action.auto_attack.state != 0; + break; case ACTION_T_COMBAT_MOVEMENT: - { - CombatMovementEnabled = param1; + CombatMovementEnabled = action.combat_movement.state != 0; //Allow movement (create new targeted movement gen only if idle) if (CombatMovementEnabled) @@ -754,69 +718,59 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u m_creature->GetMotionMaster()->MoveIdle(); m_creature->StopMoving(); } - } - break; + break; case ACTION_T_SET_PHASE: - { - Phase = param1; - } - break; + Phase = action.set_phase.phase; + break; case ACTION_T_INC_PHASE: { - Phase += param1; + int32 new_phase = int32(Phase)+action.set_inc_phase.step; + if (new_phase < 0) + { + sLog.outErrorDb( "CreatureEventAI: Event %d decrease Phase under 0. CreatureEntry = %d", EventId, m_creature->GetEntry()); + Phase = 0; + } + else if (new_phase >= MAX_PHASE) + { + sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above %u. Phase mask cannot be used with phases past %u. CreatureEntry = %d", EventId, MAX_PHASE-1, MAX_PHASE-1, m_creature->GetEntry()); + Phase = MAX_PHASE-1; + } + else + Phase = new_phase; - if (Phase > 31) - - sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above 31. Phase mask cannot be used with phases past 31. CreatureEntry = %d", EventId, m_creature->GetEntry()); + break; } - break; case ACTION_T_EVADE: - { EnterEvadeMode(); - } - break; + break; case ACTION_T_FLEE: - { //TODO: Replace with Flee movement generator m_creature->CastSpell(m_creature, SPELL_RUN_AWAY, true); - } - break; + break; case ACTION_T_QUEST_EVENT_ALL: - { - Unit* Temp = NULL; - if( pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER ) + if (pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER) { - Temp = Unit::GetUnit(*m_creature,pActionInvoker->GetGUID()); - if( Temp ) - ((Player*)Temp)->GroupEventHappens(param1,m_creature); + if (Unit* Temp = Unit::GetUnit(*m_creature,pActionInvoker->GetGUID())) + if (Temp->GetTypeId() == TYPEID_PLAYER) + ((Player*)Temp)->GroupEventHappens(action.quest_event_all.questId,m_creature); } - } - break; - case ACTION_T_CASTCREATUREGO_ALL: + break; + case ACTION_T_CAST_EVENT_ALL: { - Unit* Temp = NULL; - - std::list::iterator i = m_creature->getThreatManager().getThreatList().begin(); - for (; i != m_creature->getThreatManager().getThreatList().end(); ++i) - { - Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); - if (Temp && Temp->GetTypeId() == TYPEID_PLAYER) - ((Player*)Temp)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2); - } + std::list& threatList = m_creature->getThreatManager().getThreatList(); + for (std::list::iterator i = threatList.begin(); i != threatList.end(); ++i) + if (Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid())) + if (Temp->GetTypeId() == TYPEID_PLAYER) + ((Player*)Temp)->CastedCreatureOrGO(action.cast_event_all.creatureId, m_creature->GetGUID(), action.cast_event_all.spellId); + break; } - break; case ACTION_T_REMOVEAURASFROMSPELL: - { - Unit* target = GetTargetByType(param1, pActionInvoker); - - if (target) - target->RemoveAurasDueToSpell(param2); - } - break; + if (Unit* target = GetTargetByType(action.remove_aura.target, pActionInvoker)) + target->RemoveAurasDueToSpell(action.remove_aura.spellId); + break; case ACTION_T_RANGED_MOVEMENT: - { - AttackDistance = param1; - AttackAngle = ((float)param2/180)*M_PI; + AttackDistance = action.ranged_movement.distance; + AttackAngle = ((float)action.ranged_movement.angle/180)*M_PI; if (CombatMovementEnabled) { @@ -827,69 +781,52 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle); } } - } - break; + break; case ACTION_T_RANDOM_PHASE: - { - uint32 temp = GetRandActionParam(rnd, param1, param2, param3); - - Phase = temp; - } - break; + Phase = GetRandActionParam(rnd, action.random_phase.phase1, action.random_phase.phase2, action.random_phase.phase3); + break; case ACTION_T_RANDOM_PHASE_RANGE: - { - if (param2 > param1) - { - Phase = param1 + (rnd % (param2 - param1)); - } + if (action.random_phase_range.phaseMax > action.random_phase_range.phaseMin) + Phase = action.random_phase_range.phaseMin + (rnd % (action.random_phase_range.phaseMax - action.random_phase_range.phaseMin)); else sLog.outErrorDb( "CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 <= Param1. Divide by Zero. Event = %d. CreatureEntry = %d", EventId, m_creature->GetEntry()); - } - break; + break; case ACTION_T_SUMMON_ID: { - Unit* target = GetTargetByType(param2, pActionInvoker); + Unit* target = GetTargetByType(action.summon_id.target, pActionInvoker); - //Duration - Creature* pCreature = NULL; - - CreatureEventAI_Summon_Map::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAISummonMap().find(param3); + CreatureEventAI_Summon_Map::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAISummonMap().find(action.summon_id.spawnId); if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end()) { - - sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", param1, param3, EventId, m_creature->GetEntry()); + sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", action.summon_id.creatureId, action.summon_id.spawnId, EventId, m_creature->GetEntry()); return; } + Creature* pCreature = NULL; if ((*i).second.SpawnTimeSecs) - pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs); - else pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); + pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs); + else + pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); if (!pCreature) - { - - sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", param1, EventId, m_creature->GetEntry()); - } - else if (param2 != TARGET_T_SELF && target) + sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, EventId, m_creature->GetEntry()); + else if (action.summon_id.target != TARGET_T_SELF && target) pCreature->AI()->AttackStart(target); + + break; } - break; case ACTION_T_KILLED_MONSTER: - { //first attempt player who tapped creature if (Player* pPlayer = m_creature->GetLootRecipient()) - pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature); + pPlayer->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, m_creature); else { //if not available, use pActionInvoker - if (Unit* pTarget = GetTargetByType(param2, pActionInvoker)) - { + if (Unit* pTarget = GetTargetByType(action.killed_monster.target, pActionInvoker)) if (Player* pPlayer2 = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself()) - pPlayer2->RewardPlayerAndGroupAtEvent(param1, m_creature); - } + pPlayer2->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, m_creature); } - } - break; + break; case ACTION_T_SET_INST_DATA: { InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData(); @@ -899,12 +836,12 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u return; } - pInst->SetData(param1, param2); + pInst->SetData(action.set_inst_data.field, action.set_inst_data.value); + break; } - break; case ACTION_T_SET_INST_DATA64: { - Unit* target = GetTargetByType(param2, pActionInvoker); + Unit* target = GetTargetByType(action.set_inst_data64.target, pActionInvoker); if (!target) { sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry()); @@ -918,19 +855,19 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u return; } - pInst->SetData64(param1, target->GetGUID()); + pInst->SetData64(action.set_inst_data64.field, target->GetGUID()); + break; } - break; case ACTION_T_UPDATE_TEMPLATE: { - if (m_creature->GetEntry() == param1) + if (m_creature->GetEntry() == action.update_template.creatureId) { sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature->GetEntry()); return; } - m_creature->UpdateEntry(param1, param2 ? HORDE : ALLIANCE); + m_creature->UpdateEntry(action.update_template.creatureId, action.update_template.team ? HORDE : ALLIANCE); } break; case ACTION_T_DIE: @@ -1342,15 +1279,20 @@ inline uint32 CreatureEventAI::GetRandActionParam(uint32 rnd, uint32 param1, uin { switch (rnd % 3) { - case 0: - return param1; - break; - case 1: - return param2; - break; - case 2: - return param3; - break; + case 0: return param1; + case 1: return param2; + case 2: return param3; + } + return 0; +} + +inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3) +{ + switch (rnd % 3) + { + case 0: return param1; + case 1: return param2; + case 2: return param3; } return 0; } @@ -1361,28 +1303,20 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke { case TARGET_T_SELF: return m_creature; - break; case TARGET_T_HOSTILE: return m_creature->getVictim(); - break; case TARGET_T_HOSTILE_SECOND_AGGRO: return SelectUnit(ATTACKING_TARGET_TOPAGGRO,1); - break; case TARGET_T_HOSTILE_LAST_AGGRO: return SelectUnit(ATTACKING_TARGET_BOTTOMAGGRO,0); - break; case TARGET_T_HOSTILE_RANDOM: return SelectUnit(ATTACKING_TARGET_RANDOM,0); - break; case TARGET_T_HOSTILE_RANDOM_NOT_TOP: return SelectUnit(ATTACKING_TARGET_RANDOM,1); - break; case TARGET_T_ACTION_INVOKER: return pActionInvoker; - break; default: return NULL; - break; }; } diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index 771d582ef..953596264 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -30,6 +30,7 @@ class WorldObject; #define EVENT_UPDATE_TIME 500 #define SPELL_RUN_AWAY 8225 #define MAX_ACTIONS 3 +#define MAX_PHASE 32 enum EventAI_Type { @@ -78,7 +79,7 @@ enum EventAI_ActionType ACTION_T_THREAT_SINGLE_PCT = 13, //*Threat%, Target ACTION_T_THREAT_ALL_PCT = 14, //Threat% ACTION_T_QUEST_EVENT = 15, //*QuestID, Target - ACTION_T_CASTCREATUREGO = 16, //*QuestID, SpellId, Target + ACTION_T_CAST_EVENT = 16, //*QuestID, SpellId, Target - must be removed as hack? ACTION_T_SET_UNIT_FIELD = 17, //*Field_Number, Value, Target ACTION_T_SET_UNIT_FLAG = 18, //*Flags (may be more than one field OR'd together), Target ACTION_T_REMOVE_UNIT_FLAG = 19, //*Flags (may be more than one field OR'd together), Target @@ -89,7 +90,7 @@ enum EventAI_ActionType ACTION_T_EVADE = 24, //No Params ACTION_T_FLEE = 25, //No Params ACTION_T_QUEST_EVENT_ALL = 26, //*QuestID - ACTION_T_CASTCREATUREGO_ALL = 27, //*QuestId, SpellId + ACTION_T_CAST_EVENT_ALL = 27, //*QuestId, SpellId ACTION_T_REMOVEAURASFROMSPELL = 28, //*Target, Spellid ACTION_T_RANGED_MOVEMENT = 29, //Distance, Angle ACTION_T_RANDOM_PHASE = 30, //PhaseId1, PhaseId2, PhaseId3 @@ -165,6 +166,202 @@ struct StringTextData // Text Maps typedef UNORDERED_MAP CreatureEventAI_TextMap; +struct CreatureEventAI_Action +{ + EventAI_ActionType type: 16; + union + { + // ACTION_T_TEXT = 1 + struct + { + int32 TextId1; + int32 TextId2; + int32 TextId3; + } text; + // ACTION_T_SET_FACTION = 2 + struct + { + uint32 factionId; // faction or 0 for default) + } set_faction; + // ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3 + struct + { + uint32 creatireId; // set one from fields (or 0 for both to demorph) + uint32 modelId; + } morph; + // ACTION_T_SOUND = 4 + struct + { + uint32 soundId; + } sound; + // ACTION_T_EMOTE = 5 + struct + { + uint32 emoteId; + } emote; + // ACTION_T_RANDOM_SOUND = 9 + struct + { + int32 soundId1; // (-1 in any field means no output if randomed that field) + int32 soundId2; + int32 soundId3; + } random_sound; + // ACTION_T_RANDOM_EMOTE = 10 + struct + { + int32 emoteId1; // (-1 in any field means no output if randomed that field) + int32 emoteId2; + int32 emoteId3; + } random_emote; + // ACTION_T_CAST = 11 + struct + { + uint32 spellId; + uint32 target; + uint32 castFlags; + } cast; + // ACTION_T_SUMMON = 12 + struct + { + uint32 creatured; + uint32 target; + uint32 duration; + } summon; + // ACTION_T_THREAT_SINGLE_PCT = 13 + struct + { + int32 percent; + uint32 target; + } threat_single_pct; + // ACTION_T_THREAT_ALL_PCT = 14 + struct + { + int32 percent; + } threat_all_pct; + // ACTION_T_QUEST_EVENT = 15 + struct + { + uint32 questId; + uint32 target; + } quest_event; + // ACTION_T_CAST_EVENT = 16 + struct + { + uint32 creatureId; + uint32 spellId; + uint32 target; + } cast_event; + // ACTION_T_SET_UNIT_FIELD = 17 + struct + { + uint32 field; + uint32 value; + uint32 target; + } set_unit_field; + // ACTION_T_SET_UNIT_FLAG = 18, // value provided mask bits that will be set + // ACTION_T_REMOVE_UNIT_FLAG = 19, // value provided mask bits that will be clear + struct + { + uint32 value; + uint32 target; + } unit_flag; + // ACTION_T_AUTO_ATTACK = 20 + struct + { + uint32 state; // 0 = stop attack, anything else means continue attacking + } auto_attack; + // ACTION_T_COMBAT_MOVEMENT = 21 + struct + { + uint32 state; // 0 = stop combat based movement, anything else continue attacking + } combat_movement; + // ACTION_T_SET_PHASE = 22 + struct + { + uint32 phase; + } set_phase; + // ACTION_T_INC_PHASE = 23 + struct + { + int32 step; + } set_inc_phase; + // ACTION_T_QUEST_EVENT_ALL = 26 + struct + { + uint32 questId; + } quest_event_all; + // ACTION_T_CAST_EVENT_ALL = 27 + struct + { + uint32 creatureId; + uint32 spellId; + } cast_event_all; + // ACTION_T_REMOVEAURASFROMSPELL = 28 + struct + { + uint32 target; + uint32 spellId; + } remove_aura; + // ACTION_T_RANGED_MOVEMENT = 29 + struct + { + uint32 distance; + int32 angle; + } ranged_movement; + // ACTION_T_RANDOM_PHASE = 30 + struct + { + uint32 phase1; + uint32 phase2; + uint32 phase3; + } random_phase; + // ACTION_T_RANDOM_PHASE_RANGE = 31 + struct + { + uint32 phaseMin; + uint32 phaseMax; + } random_phase_range; + // ACTION_T_SUMMON_ID = 32 + struct + { + uint32 creatureId; + uint32 target; + uint32 spawnId; + } summon_id; + // ACTION_T_KILLED_MONSTER = 33 + struct + { + uint32 creatureId; + uint32 target; + } killed_monster; + // ACTION_T_SET_INST_DATA = 34 + struct + { + uint32 field; + uint32 value; + } set_inst_data; + // ACTION_T_SET_INST_DATA64 = 35 + struct + { + uint32 field; + uint32 target; + } set_inst_data64; + // ACTION_T_UPDATE_TEMPLATE = 36, //*Entry, Team + struct + { + uint32 creatureId; + uint32 team; + } update_template; + // RAW + struct + { + uint32 param1; + uint32 param2; + uint32 param3; + } raw; + }; +}; + struct CreatureEventAI_Event { uint32 event_id; @@ -198,25 +395,7 @@ struct CreatureEventAI_Event int32 event_param4_s; }; - struct _action - { - EventAI_ActionType type: 16; - union - { - uint32 param1; - int32 param1_s; - }; - union - { - uint32 param2; - int32 param2_s; - }; - union - { - uint32 param3; - int32 param3_s; - }; - }action[MAX_ACTIONS]; + CreatureEventAI_Action action[MAX_ACTIONS]; }; //Event_Map typedef UNORDERED_MAP > CreatureEventAI_Event_Map; @@ -270,8 +449,9 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI static int Permissible(const Creature *); bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL); - void ProcessAction(uint16 type, uint32 param1, uint32 param2, uint32 param3, uint32 rnd, uint32 EventId, Unit* pActionInvoker); + void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker); inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3); + inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3); inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker); inline Unit* SelectUnit(AttackingTarget target, uint32 position); diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp index bd3631a75..4675da2ce 100644 --- a/src/game/CreatureEventAIMgr.cpp +++ b/src/game/CreatureEventAIMgr.cpp @@ -388,251 +388,252 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() continue; } - temp.action[j].type = EventAI_ActionType(action_type); - temp.action[j].param1 = fields[11+(j*4)].GetUInt32(); - temp.action[j].param2 = fields[12+(j*4)].GetUInt32(); - temp.action[j].param3 = fields[13+(j*4)].GetUInt32(); + CreatureEventAI_Action& action = temp.action[j]; + + action.type = EventAI_ActionType(action_type); + action.raw.param1 = fields[11+(j*4)].GetUInt32(); + action.raw.param2 = fields[12+(j*4)].GetUInt32(); + action.raw.param3 = fields[13+(j*4)].GetUInt32(); //Report any errors in actions - switch (temp.action[j].type) + switch (action.type) { case ACTION_T_NONE: break; case ACTION_T_TEXT: { - if (temp.action[j].param1_s < 0) + if (action.text.TextId1 < 0) { - if (m_CreatureEventAI_TextMap.find(temp.action[j].param1_s) == m_CreatureEventAI_TextMap.end()) + if (m_CreatureEventAI_TextMap.find(action.text.TextId1) == m_CreatureEventAI_TextMap.end()) sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1); } - if (temp.action[j].param2_s < 0) + if (action.text.TextId2 < 0) { - if (m_CreatureEventAI_TextMap.find(temp.action[j].param2_s) == m_CreatureEventAI_TextMap.end()) + if (m_CreatureEventAI_TextMap.find(action.text.TextId2) == m_CreatureEventAI_TextMap.end()) sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1); - if (!temp.action[j].param1_s) + if (!action.text.TextId1) sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1); } - if (temp.action[j].param3_s < 0) + if (action.text.TextId3 < 0) { - if (m_CreatureEventAI_TextMap.find(temp.action[j].param3_s) == m_CreatureEventAI_TextMap.end()) + if (m_CreatureEventAI_TextMap.find(action.text.TextId3) == m_CreatureEventAI_TextMap.end()) sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1); - if (!temp.action[j].param1_s || !temp.action[j].param2_s) + if (!action.text.TextId1 || !action.text.TextId2) sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1); } break; } case ACTION_T_SET_FACTION: - if (temp.action[j].param1 !=0 && !sFactionStore.LookupEntry(temp.action[j].param1)) + if (action.set_faction.factionId !=0 && !sFactionStore.LookupEntry(action.set_faction.factionId)) { - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant FactionId %u.", i, j+1, temp.action[j].param1); - temp.action[j].param1 = 0; + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent FactionId %u.", i, j+1, action.set_faction.factionId); + action.set_faction.factionId = 0; } break; case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: - if (temp.action[j].param1 !=0 || temp.action[j].param2 !=0) + if (action.morph.creatireId !=0 || action.morph.modelId !=0) { - if (temp.action[j].param1 && !sCreatureStorage.LookupEntry(temp.action[j].param1)) + if (action.morph.creatireId && !sCreatureStorage.LookupEntry(action.morph.creatireId)) { - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, temp.action[j].param1); - temp.action[j].param1 = 0; + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatireId); + action.morph.creatireId = 0; } - if (temp.action[j].param2 && !sCreatureDisplayInfoStore.LookupEntry(temp.action[j].param2)) + if (action.morph.modelId) { - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, temp.action[j].param2); - temp.action[j].param2 = 0; + if (action.morph.creatireId) + { + sLog.outErrorDb("CreatureEventAI: Event %u Action %u have unused ModelId %u with also set creature id %u.", i, j+1, action.morph.modelId,action.morph.creatireId); + action.morph.modelId = 0; + } + else if (!sCreatureDisplayInfoStore.LookupEntry(action.morph.modelId)) + { + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, action.morph.modelId); + action.morph.modelId = 0; + } } + + break; } - break; case ACTION_T_SOUND: - if (!sSoundEntriesStore.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1); - break; - case ACTION_T_RANDOM_SOUND: - if (!sSoundEntriesStore.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, temp.action[j].param1); - if (temp.action[j].param2_s >= 0 && !sSoundEntriesStore.LookupEntry(temp.action[j].param2)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, temp.action[j].param2); - if (temp.action[j].param3_s >= 0 && !sSoundEntriesStore.LookupEntry(temp.action[j].param3)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, temp.action[j].param3); + if (!sSoundEntriesStore.LookupEntry(action.sound.soundId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, action.sound.soundId); break; case ACTION_T_EMOTE: - if (!sEmotesStore.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param1); + if (!sEmotesStore.LookupEntry(action.emote.emoteId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, action.emote.emoteId); + break; + case ACTION_T_RANDOM_SOUND: + if (!sSoundEntriesStore.LookupEntry(action.random_sound.soundId1)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId1); + if (action.random_sound.soundId2 >= 0 && !sSoundEntriesStore.LookupEntry(action.random_sound.soundId2)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId2); + if (action.random_sound.soundId3 >= 0 && !sSoundEntriesStore.LookupEntry(action.random_sound.soundId3)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId3); break; case ACTION_T_RANDOM_EMOTE: - if (!sEmotesStore.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param1); - if (temp.action[j].param2_s >= 0 && !sEmotesStore.LookupEntry(temp.action[j].param2)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param2); - if (temp.action[j].param3_s >= 0 && !sEmotesStore.LookupEntry(temp.action[j].param3)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param3); + if (!sEmotesStore.LookupEntry(action.random_emote.emoteId1)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId1); + if (action.random_emote.emoteId2 >= 0 && !sEmotesStore.LookupEntry(action.random_emote.emoteId2)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId2); + if (action.random_emote.emoteId3 >= 0 && !sEmotesStore.LookupEntry(action.random_emote.emoteId3)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId3); break; case ACTION_T_CAST: { - const SpellEntry *spell = sSpellStore.LookupEntry(temp.action[j].param1); + const SpellEntry *spell = sSpellStore.LookupEntry(action.cast.spellId); if (!spell) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1); + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast.spellId); else { if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE) { //output as debug for now, also because there's no general rule all spells have RecoveryTime if (temp.event_param3 < spell->RecoveryTime) - sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,temp.action[j].param1, spell->RecoveryTime, temp.event_param3); + sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,action.cast.spellId, spell->RecoveryTime, temp.event_param3); } } - if (temp.action[j].param2 >= TARGET_T_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; - } - case ACTION_T_REMOVEAURASFROMSPELL: - { - if (!sSpellStore.LookupEntry(temp.action[j].param2)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); + //Cast is always triggered if target is forced to cast on self + if (action.cast.castFlags & CAST_FORCE_TARGET_SELF) + action.cast.castFlags |= CAST_TRIGGERED; - if (temp.action[j].param1 >= TARGET_T_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; - } - case ACTION_T_QUEST_EVENT: - { - if (Quest const* qid = objmgr.GetQuestTemplate(temp.action[j].param1)) - { - if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1); - } - else - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1); - - if (temp.action[j].param2 >= TARGET_T_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - - break; - } - case ACTION_T_QUEST_EVENT_ALL: - { - if (Quest const* qid = objmgr.GetQuestTemplate(temp.action[j].param1)) - { - if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1); - } - else - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1); - break; - } - case ACTION_T_CASTCREATUREGO: - { - if (!sCreatureStorage.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1); - - if (!sSpellStore.LookupEntry(temp.action[j].param2)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); - - if (temp.action[j].param3 >= TARGET_T_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; - } - case ACTION_T_CASTCREATUREGO_ALL: - { - if (!objmgr.GetQuestTemplate(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1); - - if (!sSpellStore.LookupEntry(temp.action[j].param2)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); - break; - } - - //2nd param target - case ACTION_T_SUMMON_ID: - { - if (!sCreatureStorage.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1); - - if (m_CreatureEventAI_Summon_Map.find(temp.action[j].param3) == m_CreatureEventAI_Summon_Map.end()) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, temp.action[j].param3); - - if (temp.action[j].param2 >= TARGET_T_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; - } - case ACTION_T_KILLED_MONSTER: - { - if (!sCreatureStorage.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1); - - if (temp.action[j].param2 >= TARGET_T_END) + if (action.cast.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); break; } case ACTION_T_SUMMON: - { - if (!sCreatureStorage.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1); + if (!sCreatureStorage.LookupEntry(action.summon.creatured)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatured); - if (temp.action[j].param2 >= TARGET_T_END) + if (action.summon.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); break; - } case ACTION_T_THREAT_SINGLE_PCT: + if (std::abs(action.threat_single_pct.percent) > 100) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, action.threat_single_pct.percent); + if (action.threat_single_pct.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + break; + case ACTION_T_THREAT_ALL_PCT: + if (std::abs(action.threat_all_pct.percent) > 100) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, action.threat_all_pct.percent); + break; + case ACTION_T_QUEST_EVENT: + if (Quest const* qid = objmgr.GetQuestTemplate(action.quest_event.questId)) + { + if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, action.quest_event.questId); + } + else + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event.questId); + + if (action.quest_event.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + + break; + case ACTION_T_CAST_EVENT: + if (!sCreatureStorage.LookupEntry(action.cast_event.creatureId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.cast_event.creatureId); + if (!sSpellStore.LookupEntry(action.cast_event.spellId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast_event.spellId); + if (action.cast_event.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + break; + case ACTION_T_SET_UNIT_FIELD: + if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1); + if (action.set_unit_field.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + break; case ACTION_T_SET_UNIT_FLAG: case ACTION_T_REMOVE_UNIT_FLAG: - if (temp.action[j].param2 >= TARGET_T_END) + if (action.unit_flag.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); break; - //3rd param target - case ACTION_T_SET_UNIT_FIELD: - if (temp.action[j].param1 < OBJECT_END || temp.action[j].param1 >= UNIT_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1); - if (temp.action[j].param3 >= TARGET_T_END) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; - case ACTION_T_SET_PHASE: - if (temp.action[j].param1 > 31) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1); + if (action.set_phase.phase >= MAX_PHASE) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1); break; - case ACTION_T_INC_PHASE: - if (!temp.action[j].param1) + if (action.set_inc_phase.step == 0) sLog.outErrorDb("CreatureEventAI: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1); + else if (std::abs(action.set_inc_phase.step) > MAX_PHASE-1) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u is change phase by too large for any use %i.", i, j+1, action.set_inc_phase.step); break; - - case ACTION_T_SET_INST_DATA: - { - if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1); - - if (temp.action[j].param2 > 4/*SPECIAL*/) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1); - + case ACTION_T_QUEST_EVENT_ALL: + if (Quest const* qid = objmgr.GetQuestTemplate(action.quest_event_all.questId)) + { + if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, action.quest_event_all.questId); + } + else + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event_all.questId); break; - } - case ACTION_T_SET_INST_DATA64: - { - if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1); - - if (temp.action[j].param2 >= TARGET_T_END) + case ACTION_T_CAST_EVENT_ALL: + if (!sCreatureStorage.LookupEntry(action.cast_event_all.creatureId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.cast_event_all.creatureId); + if (!sSpellStore.LookupEntry(action.cast_event_all.spellId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast_event_all.spellId); + break; + case ACTION_T_REMOVEAURASFROMSPELL: + if (!sSpellStore.LookupEntry(action.remove_aura.spellId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.remove_aura.spellId); + if (action.remove_aura.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + break; + case ACTION_T_RANDOM_PHASE: //PhaseId1, PhaseId2, PhaseId3 + if (action.random_phase.phase1 >= MAX_PHASE) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase1 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1); + if (action.random_phase.phase2 >= MAX_PHASE) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase2 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1); + if (action.random_phase.phase3 >= MAX_PHASE) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase3 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1); + break; + case ACTION_T_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax + if (action.random_phase_range.phaseMin >= MAX_PHASE) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMin >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1); + if (action.random_phase_range.phaseMin >= MAX_PHASE) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMax >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1); + if (action.random_phase_range.phaseMin >= action.random_phase_range.phaseMax) + { + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMax <= phaseMin.", i, j+1); + std::swap(action.random_phase_range.phaseMin,action.random_phase_range.phaseMax); + // equal case processed at call + } + break; + case ACTION_T_SUMMON_ID: + if (!sCreatureStorage.LookupEntry(action.summon_id.creatureId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.summon_id.creatureId); + if (action.summon_id.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + if (m_CreatureEventAI_Summon_Map.find(action.summon_id.spawnId) == m_CreatureEventAI_Summon_Map.end()) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, action.summon_id.spawnId); + break; + case ACTION_T_KILLED_MONSTER: + if (!sCreatureStorage.LookupEntry(action.killed_monster.creatureId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.killed_monster.creatureId); + if (action.killed_monster.target >= TARGET_T_END) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); + break; + case ACTION_T_SET_INST_DATA: + if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1); + if (action.set_inst_data.value > 4/*SPECIAL*/) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1); + break; + case ACTION_T_SET_INST_DATA64: + if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1); + if (action.set_inst_data64.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; - } case ACTION_T_UPDATE_TEMPLATE: - { - if (!sCreatureStorage.LookupEntry(temp.action[j].param1)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1); + if (!sCreatureStorage.LookupEntry(action.update_template.creatureId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.update_template.creatureId); break; - } - - case ACTION_T_THREAT_ALL_PCT: - if (abs(temp.action[j].param1_s) > 100) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, temp.action[j].param1); - break; - case ACTION_T_EVADE: //No Params case ACTION_T_FLEE: //No Params case ACTION_T_DIE: //No Params @@ -642,11 +643,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() case ACTION_T_RANGED_MOVEMENT: //Distance, Angle break; - case ACTION_T_RANDOM_PHASE: //PhaseId1, PhaseId2, PhaseId3 - case ACTION_T_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax - // check not implemented - break; - case ACTION_T_RANDOM_SAY: case ACTION_T_RANDOM_YELL: case ACTION_T_RANDOM_TEXTEMOTE: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f9e71c994..6d508bccf 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7846" + #define REVISION_NR "7847" #endif // __REVISION_NR_H__ From c672d4d99e8139fa5162f8a33e8b7e10335bccc3 Mon Sep 17 00:00:00 2001 From: SeT Date: Mon, 18 May 2009 23:39:42 +0400 Subject: [PATCH 13/22] [7848] Fix set variable to zero on apply -100% mod Signed-off-by: DiSlord --- src/shared/Util.h | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/Util.h b/src/shared/Util.h index 8fa4faacf..121bbc292 100644 --- a/src/shared/Util.h +++ b/src/shared/Util.h @@ -90,7 +90,7 @@ inline void ApplyModFloatVar(float& var, float val, bool apply) inline void ApplyPercentModFloatVar(float& var, float val, bool apply) { - if (!apply && val == -100.0f) + if (val == -100.0f) // prevent set var to zero val = -99.99f; var *= (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6d508bccf..d0f13bcb4 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7847" + #define REVISION_NR "7848" #endif // __REVISION_NR_H__ From 695d83568a2f17e38bc91c000b38762b86586303 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 18 May 2009 23:43:38 +0400 Subject: [PATCH 14/22] [7849] Fix remove Swiftmend aurastate in some cases Signed-off-by: DiSlord --- src/game/SpellAuras.cpp | 6 +++++- src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 2a50fdc54..2dd62f901 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1075,6 +1075,7 @@ void Aura::_RemoveAura() m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); uint32 removeState = 0; + uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags; switch(m_spellProto->SpellFamilyName) { case SPELLFAMILY_PALADIN: @@ -1089,7 +1090,10 @@ void Aura::_RemoveAura() if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) else if(m_spellProto->SpellFamilyFlags & 0x50) + { + removeFamilyFlag = 0x50; removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state + } break; case SPELLFAMILY_WARRIOR: if(m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) @@ -1113,7 +1117,7 @@ void Aura::_RemoveAura() { SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && - auraSpellInfo->SpellFamilyFlags == m_spellProto->SpellFamilyFlags ) + auraSpellInfo->SpellFamilyFlags & removeFamilyFlag) { found = true; break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d0f13bcb4..23dd51992 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7848" + #define REVISION_NR "7849" #endif // __REVISION_NR_H__ From fdbc22ac93cd4de26836dfc1cac601f91d6c1318 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 19 May 2009 00:45:48 +0400 Subject: [PATCH 15/22] Provide and use universal way for get locale and locale index for chat/console command use. --- src/game/Chat.cpp | 19 +++++++++++++++++++ src/game/Chat.h | 13 ++++++++++--- src/game/Level1.cpp | 12 ++++++------ src/game/Level2.cpp | 12 ++++++------ src/game/Level3.cpp | 28 ++++++++++++++-------------- src/game/World.h | 2 +- 6 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index a4fb9dc56..20ad49e2c 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -1578,6 +1578,16 @@ bool ChatHandler::needReportToTarget(Player* chr) const return pl != chr && pl->IsVisibleGloballyFor(chr); } +LocaleConstant ChatHandler::GetSessionDbcLocale() const +{ + return m_session->GetSessionDbcLocale(); +} + +int ChatHandler::GetSessionDbLocaleIndex() const +{ + return m_session->GetSessionDbLocaleIndex(); +} + const char *CliHandler::GetMangosString(int32 entry) const { return objmgr.GetMangosStringForDBCLocale(entry); @@ -1605,3 +1615,12 @@ bool CliHandler::needReportToTarget(Player* /*chr*/) const return true; } +LocaleConstant CliHandler::GetSessionDbcLocale() const +{ + return sWorld.GetDefaultDbcLocale(); +} + +int CliHandler::GetSessionDbLocaleIndex() const +{ + return objmgr.GetDBCLocaleIndex(); +} diff --git a/src/game/Chat.h b/src/game/Chat.h index ee22b6160..18891a245 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -60,9 +60,10 @@ class ChatHandler static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; } + // function with different implementation for chat/console virtual const char *GetMangosString(int32 entry) const; - virtual void SendSysMessage( const char *str); + void SendSysMessage( int32 entry); void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3); void PSendSysMessage( int32 entry, ... ); @@ -73,8 +74,13 @@ class ChatHandler bool hasStringAbbr(const char* name, const char* part); + // function with different implementation for chat/console virtual bool isAvailable(ChatCommand const& cmd) const; + virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); } virtual bool needReportToTarget(Player* chr) const; + virtual LocaleConstant GetSessionDbcLocale() const; + virtual int GetSessionDbLocaleIndex() const; + bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false); bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false); @@ -115,8 +121,8 @@ class ChatHandler bool HandleCharacterCustomizeCommand(const char * args); bool HandleCharacterDeleteCommand(const char* args); - bool HandleCharacterRenameCommand(const char * args); bool HandleCharacterLevelCommand(const char* args); + bool HandleCharacterRenameCommand(const char * args); bool HandleDebugAnimCommand(const char* args); bool HandleDebugArenaCommand(const char * args); @@ -499,7 +505,6 @@ class ChatHandler bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL); std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; } - virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); } std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); } GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry); @@ -534,6 +539,8 @@ class CliHandler : public ChatHandler void SendSysMessage(const char *str); std::string GetNameLink() const; bool needReportToTarget(Player* chr) const; + LocaleConstant GetSessionDbcLocale() const; + int GetSessionDbLocaleIndex() const; private: Print* m_print; diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index ba2280b97..b0d7ada6d 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -309,9 +309,9 @@ bool ChatHandler::HandleGPSCommand(const char* args) uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0; PSendSysMessage(LANG_MAP_POSITION, - obj->GetMapId(), (mapEntry ? mapEntry->name[m_session->GetSessionDbcLocale()] : "" ), - zone_id, (zoneEntry ? zoneEntry->area_name[m_session->GetSessionDbcLocale()] : "" ), - area_id, (areaEntry ? areaEntry->area_name[m_session->GetSessionDbcLocale()] : "" ), + obj->GetMapId(), (mapEntry ? mapEntry->name[GetSessionDbcLocale()] : "" ), + zone_id, (zoneEntry ? zoneEntry->area_name[GetSessionDbcLocale()] : "" ), + area_id, (areaEntry ? areaEntry->area_name[GetSessionDbcLocale()] : "" ), obj->GetPhaseMask(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(), cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), @@ -1818,7 +1818,7 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args) AreaTableEntry const *areaEntry = sAreaStore.LookupEntry (areaflag); if (areaEntry) { - int loc = m_session ? m_session->GetSessionDbcLocale () : sWorld.GetDefaultDbcLocale(); + int loc = GetSessionDbcLocale (); std::string name = areaEntry->area_name[loc]; if (name.empty()) continue; @@ -1828,7 +1828,7 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args) loc = 0; for(; loc < MAX_LOCALE; ++loc) { - if (m_session && loc==m_session->GetSessionDbcLocale ()) + if (loc==GetSessionDbcLocale ()) continue; name = areaEntry->area_name[loc]; @@ -2432,7 +2432,7 @@ bool ChatHandler::HandleGoZoneXYCommand(const char* args) if(map->Instanceable()) { - PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[m_session->GetSessionDbcLocale()],map->GetId(),map->GetMapName()); + PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName()); SetSentErrorMessage(true); return false; } diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index a41bc6dd6..2fb280ee5 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -880,7 +880,7 @@ bool ChatHandler::HandleLookupFactionCommand(const char* args) { FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL; - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + int loc = GetSessionDbcLocale(); std::string name = factionEntry->name[loc]; if(name.empty()) continue; @@ -890,7 +890,7 @@ bool ChatHandler::HandleLookupFactionCommand(const char* args) loc = 0; for(; loc < MAX_LOCALE; ++loc) { - if(m_session && loc==m_session->GetSessionDbcLocale()) + if(loc==GetSessionDbcLocale()) continue; name = factionEntry->name[loc]; @@ -1035,13 +1035,13 @@ bool ChatHandler::HandleModifyRepCommand(const char * args) if (factionEntry->reputationListID < 0) { - PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId); + PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[GetSessionDbcLocale()], factionId); SetSentErrorMessage(true); return false; } target->GetReputationMgr().SetReputation(factionEntry,amount); - PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, + PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[GetSessionDbcLocale()], factionId, GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); return true; } @@ -2211,7 +2211,7 @@ bool ChatHandler::HandlePInfoCommand(const char* args) for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) { FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); - char const* factionName = factionEntry ? factionEntry->name[m_session->GetSessionDbcLocale()] : "#Not found#"; + char const* factionName = factionEntry ? factionEntry->name[GetSessionDbcLocale()] : "#Not found#"; ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); std::ostringstream ss; @@ -3976,7 +3976,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args) skillInfo->categoryId != SKILL_CATEGORY_SECONDARY ) continue; - int loc = m_session->GetSessionDbcLocale(); + int loc = GetSessionDbcLocale(); std::string name = skillInfo->name[loc]; if(Utf8FitTo(name, wnamepart)) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 8b6061f29..61469006f 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -2584,7 +2584,7 @@ bool ChatHandler::HandleLookupItemCommand(const char* args) if(!pProto) continue; - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); @@ -2649,7 +2649,7 @@ bool ChatHandler::HandleLookupItemSetCommand(const char* args) ItemSetEntry const *set = sItemSetStore.LookupEntry(id); if(set) { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + int loc = GetSessionDbcLocale(); std::string name = set->name[loc]; if(name.empty()) continue; @@ -2659,7 +2659,7 @@ bool ChatHandler::HandleLookupItemSetCommand(const char* args) loc = 0; for(; loc < MAX_LOCALE; ++loc) { - if(m_session && loc==m_session->GetSessionDbcLocale()) + if(loc==GetSessionDbcLocale()) continue; name = set->name[loc]; @@ -2712,7 +2712,7 @@ bool ChatHandler::HandleLookupSkillCommand(const char* args) SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(id); if(skillInfo) { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + int loc = GetSessionDbcLocale(); std::string name = skillInfo->name[loc]; if(name.empty()) continue; @@ -2722,7 +2722,7 @@ bool ChatHandler::HandleLookupSkillCommand(const char* args) loc = 0; for(; loc < MAX_LOCALE; ++loc) { - if(m_session && loc==m_session->GetSessionDbcLocale()) + if(loc==GetSessionDbcLocale()) continue; name = skillInfo->name[loc]; @@ -2790,7 +2790,7 @@ bool ChatHandler::HandleLookupSpellCommand(const char* args) SpellEntry const *spellInfo = sSpellStore.LookupEntry(id); if(spellInfo) { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + int loc = GetSessionDbcLocale(); std::string name = spellInfo->SpellName[loc]; if(name.empty()) continue; @@ -2800,7 +2800,7 @@ bool ChatHandler::HandleLookupSpellCommand(const char* args) loc = 0; for(; loc < MAX_LOCALE; ++loc) { - if(m_session && loc==m_session->GetSessionDbcLocale()) + if(loc==GetSessionDbcLocale()) continue; name = spellInfo->SpellName[loc]; @@ -2889,7 +2889,7 @@ bool ChatHandler::HandleLookupQuestCommand(const char* args) { Quest * qinfo = iter->second; - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { QuestLocale const *il = objmgr.GetQuestLocale(qinfo->GetQuestId()); @@ -2989,7 +2989,7 @@ bool ChatHandler::HandleLookupCreatureCommand(const char* args) if(!cInfo) continue; - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { CreatureLocale const *cl = objmgr.GetCreatureLocale (id); @@ -3054,7 +3054,7 @@ bool ChatHandler::HandleLookupObjectCommand(const char* args) if(!gInfo) continue; - int loc_idx = m_session ? m_session->GetSessionDbLocaleIndex() : objmgr.GetDBCLocaleIndex(); + int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { GameObjectLocale const *gl = objmgr.GetGameObjectLocale(id); @@ -3119,7 +3119,7 @@ bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args) TaxiNodesEntry const *nodeEntry = sTaxiNodesStore.LookupEntry(id); if(nodeEntry) { - int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); + int loc = GetSessionDbcLocale(); std::string name = nodeEntry->name[loc]; if(name.empty()) continue; @@ -3129,7 +3129,7 @@ bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args) loc = 0; for(; loc < MAX_LOCALE; ++loc) { - if(m_session && loc==m_session->GetSessionDbcLocale()) + if(loc==GetSessionDbcLocale()) continue; name = nodeEntry->name[loc]; @@ -4394,7 +4394,7 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/) { bool talent = GetTalentSpellCost(itr->second->GetId()) > 0; - char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()]; + char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()]; if (m_session) { @@ -4425,7 +4425,7 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/) { bool talent = GetTalentSpellCost((*itr)->GetId()) > 0; - char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()]; + char const* name = (*itr)->GetSpellProto()->SpellName[GetSessionDbcLocale()]; if (m_session) { diff --git a/src/game/World.h b/src/game/World.h index cea53107a..048973a01 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -406,7 +406,7 @@ class World /// Get the current Message of the Day const char* GetMotd() const { return m_motd.c_str(); } - uint32 GetDefaultDbcLocale() const { return m_defaultDbcLocale; } + LocaleConstant GetDefaultDbcLocale() const { return m_defaultDbcLocale; } /// Get the path where data (dbc, maps) are stored on disk std::string GetDataPath() const { return m_dataPath; } From 083847541504f02e1a7b97655fb4061af22f0141 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 19 May 2009 00:55:16 +0400 Subject: [PATCH 16/22] [7850] Fixed '.pinfo name' work, move reputation code from it to new command '.character reputation [$name]'. --- sql/mangos.sql | 5 +- sql/updates/7850_01_mangos_command.sql | 7 +++ sql/updates/Makefile.am | 2 + src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Level2.cpp | 84 +++++++++++++------------- src/shared/revision_nr.h | 2 +- 7 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 sql/updates/7850_01_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 7ccf0900a..21a810c23 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_7839_02_mangos_command` bit(1) default NULL + `required_7850_01_mangos_command` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -287,6 +287,7 @@ INSERT INTO `command` VALUES ('character delete',4,'Syntax: .character delete $name\r\n\r\nDelete character $name.'), ('character level',3,'Syntax: .character level [$playername] [#level]\r\n\r\nSet the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.'), ('character rename',2,'Syntax: .character rename [$name]\r\n\r\nMark selected in game or by $name in command character for rename at next login.'), +('character reputation',2,'Syntax: .character reputation [$player_name]\r\n\r\nShow reputation information for selected player or player find by $player_name.'), ('combatstop',2,'Syntax: .combatstop [$playername]\r\nStop combat for selected character. If selected non-player then command applied to self. If $playername provided then attempt applied to online player $playername.'), ('commands',0,'Syntax: .commands\r\n\r\nDisplay a list of available commands for your account level.'), ('cooldown',3,'Syntax: .cooldown [#spell_id]\r\n\r\nRemove all (if spell_id not provided) or #spel_id spell cooldown from selected character or you (if no selection).'), @@ -446,7 +447,7 @@ INSERT INTO `command` VALUES ('npc unfollow',2,'Syntax: .npc unfollow\r\n\r\nSelected creature (non pet) stop follow you.'), ('pdump write',3,'Syntax: .pdump write $filename $playerNameOrGUID\r\nWrite character dump with name/guid $playerNameOrGUID to file $filename.'), ('pdump load',3,'Syntax: .pdump load $filename $account [$newname] [$newguid]\r\nLoad character dump from dump file into character list of $account with saved or $newname, with saved (or first free) or $newguid guid.'), -('pinfo',2,'Syntax: .pinfo [$player_name] [rep]\r\n\r\nOutput account information for selected player or player find by $player_name. If \"rep\" parameter provided show reputation information for player.'), +('pinfo',2,'Syntax: .pinfo [$player_name]\r\n\r\nOutput account information for selected player or player find by $player_name.'), ('quest add',3,'Syntax: .quest add #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'), ('quest complete',3,'Syntax: .quest complete #questid\r\nMark all quest objectives as completed for target character active quest. After this target character can go and get quest reward.'), ('quest remove',3,'Syntax: .quest remove #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'), diff --git a/sql/updates/7850_01_mangos_command.sql b/sql/updates/7850_01_mangos_command.sql new file mode 100644 index 000000000..5dd0274bc --- /dev/null +++ b/sql/updates/7850_01_mangos_command.sql @@ -0,0 +1,7 @@ +ALTER TABLE db_version CHANGE COLUMN required_7839_02_mangos_command required_7850_01_mangos_command bit; + +DELETE FROM `command` WHERE `name` IN ('character reputation','pinfo'); + +INSERT INTO `command` VALUES +('pinfo',2,'Syntax: .pinfo [$player_name]\r\n\r\nOutput account information for selected player or player find by $player_name.'), +('character reputation',2,'Syntax: .character reputation [$player_name]\r\n\r\nShow reputation information for selected player or player find by $player_name.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 1ff110a9b..a23ae16e3 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -188,6 +188,7 @@ pkgdata_DATA = \ 7830_01_mangos_spell_chain.sql \ 7839_01_mangos_mangos_string.sql \ 7839_02_mangos_command.sql \ + 7850_01_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -356,4 +357,5 @@ EXTRA_DIST = \ 7830_01_mangos_spell_chain.sql \ 7839_01_mangos_mangos_string.sql \ 7839_02_mangos_command.sql \ + 7850_01_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 20ad49e2c..f376dfbc6 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -114,6 +114,7 @@ ChatCommand * ChatHandler::getCommandTable() { "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL }, { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL }, { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL }, + { "reputation", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterReputationCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/Chat.h b/src/game/Chat.h index 18891a245..9f7370401 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -123,6 +123,7 @@ class ChatHandler bool HandleCharacterDeleteCommand(const char* args); bool HandleCharacterLevelCommand(const char* args); bool HandleCharacterRenameCommand(const char * args); + bool HandleCharacterReputationCommand(const char* args); bool HandleDebugAnimCommand(const char* args); bool HandleDebugArenaCommand(const char * args); diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 2fb280ee5..de471e626 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -2107,14 +2107,10 @@ bool ChatHandler::HandleModifyPhaseCommand(const char* args) //show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { - char* nameStr; - char* subcommandStr; - extractOptFirstArg((char*)args,&nameStr,&subcommandStr); - Player* target; uint64 target_guid; std::string target_name; - if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) + if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; uint32 accId = 0; @@ -2197,43 +2193,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args) uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp ); - if( subcommandStr && strncmp(subcommandStr, "rep", 3) == 0 ) - { - if(!target) - { - // rep option not implemented for offline case - SendSysMessage(LANG_PINFO_NO_REP); - SetSentErrorMessage(true); - return false; - } - - FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); - for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) - { - FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); - char const* factionName = factionEntry ? factionEntry->name[GetSessionDbcLocale()] : "#Not found#"; - ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); - std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); - std::ostringstream ss; - ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << "]|h|r " << rankName << "|h|r (" - << target->GetReputationMgr().GetReputation(factionEntry) << ")"; - - if(itr->second.Flags & FACTION_FLAG_VISIBLE) - ss << GetMangosString(LANG_FACTION_VISIBLE); - if(itr->second.Flags & FACTION_FLAG_AT_WAR) - ss << GetMangosString(LANG_FACTION_ATWAR); - if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED) - ss << GetMangosString(LANG_FACTION_PEACE_FORCED); - if(itr->second.Flags & FACTION_FLAG_HIDDEN) - ss << GetMangosString(LANG_FACTION_HIDDEN); - if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED) - ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED); - if(itr->second.Flags & FACTION_FLAG_INACTIVE) - ss << GetMangosString(LANG_FACTION_INACTIVE); - - SendSysMessage(ss.str().c_str()); - } - } return true; } @@ -3608,6 +3567,47 @@ bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) return true; } +bool ChatHandler::HandleCharacterReputationCommand(const char* args) +{ + Player* target; + if(!extractPlayerTarget((char*)args,&target)) + return false; + + LocaleConstant loc = GetSessionDbcLocale(); + + FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); + for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) + { + FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID); + char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#"; + ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); + std::string rankName = GetMangosString(ReputationRankStrIndex[rank]); + std::ostringstream ss; + if (m_session) + ss << itr->second.ID << " - |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << " " << localeNames[loc] << "]|h|r"; + else + ss << itr->second.ID << " - " << factionName << " " << localeNames[loc]; + + ss << " " << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ")"; + + if(itr->second.Flags & FACTION_FLAG_VISIBLE) + ss << GetMangosString(LANG_FACTION_VISIBLE); + if(itr->second.Flags & FACTION_FLAG_AT_WAR) + ss << GetMangosString(LANG_FACTION_ATWAR); + if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED) + ss << GetMangosString(LANG_FACTION_PEACE_FORCED); + if(itr->second.Flags & FACTION_FLAG_HIDDEN) + ss << GetMangosString(LANG_FACTION_HIDDEN); + if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED) + ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED); + if(itr->second.Flags & FACTION_FLAG_INACTIVE) + ss << GetMangosString(LANG_FACTION_INACTIVE); + + SendSysMessage(ss.str().c_str()); + } + return true; +} + //change standstate bool ChatHandler::HandleModifyStandStateCommand(const char* args) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 23dd51992..17a0bcf3d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7849" + #define REVISION_NR "7850" #endif // __REVISION_NR_H__ From e712baa58c4247aed7280e1e389c2ec7c52f9680 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 19 May 2009 01:35:51 +0400 Subject: [PATCH 17/22] [7851] Fixed typo to allow work '.tele name' command. --- src/game/Level1.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index b0d7ada6d..89154a0bf 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -2024,7 +2024,7 @@ bool ChatHandler::HandleTeleNameCommand(const char * args) Player* target; uint64 target_guid; std::string target_name; - if(!extractPlayerTarget(teleStr,&target,&target_guid,&target_name)) + if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name)) return false; // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 17a0bcf3d..125d5013c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7850" + #define REVISION_NR "7851" #endif // __REVISION_NR_H__ From 72b4ff2fac2c95fbe01495102238b5c9dd36c303 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 19 May 2009 22:10:30 +0400 Subject: [PATCH 18/22] [7852] Use union of per-event type structures, more checks at creature event ai loading. Including: * Fixed check for EVENT_T_SPELLHIT school field. Add check at loading. Note: this event expect before and now schol _mask_ in param2. * In EVENT_T_RECEIVE_EMOTE use original player condition check code instead copy of related code. --- src/game/CreatureEventAI.cpp | 400 +++++++------------------------- src/game/CreatureEventAI.h | 132 +++++++++-- src/game/CreatureEventAIMgr.cpp | 131 +++++------ src/shared/revision_nr.h | 2 +- 4 files changed, 262 insertions(+), 403 deletions(-) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 688460212..83b082c65 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -30,6 +30,22 @@ #include "WorldPacket.h" #include "InstanceData.h" +bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeatMin, uint32 repeatMax ) +{ + if (repeatMin == repeatMax) + Time = repeatMin; + else if (repeatMax > repeatMin) + Time = urand(repeatMin, repeatMax); + else + { + sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", creature->GetEntry(), Event.event_id, Event.event_type); + Enabled = false; + return false; + } + + return true; +} + int CreatureEventAI::Permissible(const Creature *creature) { if( creature->GetAIName() == "EventAI" ) @@ -106,53 +122,25 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction if (pHolder.Event.event_chance <= rnd % 100) return false; - uint32 param1 = pHolder.Event.event_param1; - uint32 param2 = pHolder.Event.event_param2; - uint32 param3 = pHolder.Event.event_param3; - uint32 param4 = pHolder.Event.event_param4; + CreatureEventAI_Event const& event = pHolder.Event; //Check event conditions based on the event type, also reset events - switch (pHolder.Event.event_type) + switch (event.event_type) { case EVENT_T_TIMER: - { if (!m_creature->isInCombat()) return false; //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } - break; + pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax); + break; case EVENT_T_TIMER_OOC: - { if (m_creature->isInCombat()) return false; //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } - break; + pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax); + break; case EVENT_T_HP: { if (!m_creature->isInCombat() || !m_creature->GetMaxHealth()) @@ -160,24 +148,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth(); - if (perc > param1 || perc < param2) + if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); + break; } - break; case EVENT_T_MANA: { if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA)) @@ -185,109 +162,38 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA); - if (perc > param1 || perc < param2) + if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); + break; } - break; case EVENT_T_AGGRO: - { - } - break; + break; case EVENT_T_KILL: - { //Repeat Timers - if (param1 == param2) - { - pHolder.Time = param1; - - }else if (param2 > param1) - pHolder.Time = urand(param1, param2); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } + pHolder.UpdateRepeatTimer(m_creature,event.kill.repeatMin,event.kill.repeatMax); + break; case EVENT_T_DEATH: - { - } - break; case EVENT_T_EVADE: - { - } - break; + break; case EVENT_T_SPELLHIT: - { //Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } - break; + pHolder.UpdateRepeatTimer(m_creature,event.spell_hit.repeatMin,event.spell_hit.repeatMax); + break; case EVENT_T_RANGE: - { //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } - break; + pHolder.UpdateRepeatTimer(m_creature,event.range.repeatMin,event.range.repeatMax); + break; case EVENT_T_OOC_LOS: - { //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } - break; + pHolder.UpdateRepeatTimer(m_creature,event.ooc_los.repeatMin,event.ooc_los.repeatMax); + break; case EVENT_T_SPAWNED: - { - } - break; + break; case EVENT_T_TARGET_HP: { if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth()) @@ -295,78 +201,42 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth(); - if (perc > param1 || perc < param2) + if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); + break; } - break; case EVENT_T_TARGET_CASTING: - { if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true)) return false; //Repeat Timers - if (param1 == param2) - { - pHolder.Time = param1; - - }else if (param2 > param1) - pHolder.Time = urand(param1, param2); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } - } - break; + pHolder.UpdateRepeatTimer(m_creature,event.target_casting.repeatMin,event.target_casting.repeatMax); + break; case EVENT_T_FRIENDLY_HP: { if (!m_creature->isInCombat()) return false; - Unit* pUnit = DoSelectLowestHpFriendly(param2, param1); - + Unit* pUnit = DoSelectLowestHpFriendly(event.friendly_hp.radius, event.friendly_hp.hpDeficit); if (!pUnit) return false; pActionInvoker = pUnit; //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.friendly_hp.repeatMin,event.friendly_hp.repeatMax); + break; } - break; case EVENT_T_FRIENDLY_IS_CC: { if (!m_creature->isInCombat()) return false; std::list pList; - DoFindFriendlyCC(pList, param2); + DoFindFriendlyCC(pList, event.friendly_is_cc.radius); //List is empty if (pList.empty()) @@ -376,23 +246,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction pActionInvoker = *(pList.begin()); //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.friendly_is_cc.repeatMin,event.friendly_is_cc.repeatMax); + break; } - break; case EVENT_T_FRIENDLY_MISSING_BUFF: { std::list pList; - DoFindFriendlyMissingBuff(pList, param2, param1); + DoFindFriendlyMissingBuff(pList, event.friendly_buff.radius, event.friendly_buff.spellId); //List is empty if (pList.empty()) @@ -402,20 +262,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction pActionInvoker = *(pList.begin()); //Repeat Timers - if (param3 == param4) - { - pHolder.Time = param3; - - }else if (param4 > param3) - pHolder.Time = urand(param3, param4); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.friendly_buff.repeatMin,event.friendly_buff.repeatMax); + break; } - break; case EVENT_T_SUMMONED_UNIT: { //Prevent event from occuring on no unit or non creatures @@ -423,34 +272,31 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction return false; //Creature id doesn't match up - if (param1 && ((Creature*)pActionInvoker)->GetEntry() != param1) + if (((Creature*)pActionInvoker)->GetEntry() != event.summon_unit.creatureId) return false; //Repeat Timers - if (param2 == param3) - { - pHolder.Time = param2; - - }else if (param3 > param2) - pHolder.Time = urand(param2, param3); - else - { - - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); - pHolder.Enabled = false; - } + pHolder.UpdateRepeatTimer(m_creature,event.summon_unit.repeatMin,event.summon_unit.repeatMax); } break; + case EVENT_T_TARGET_MANA: + { + if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxPower(POWER_MANA)) + return false; + + uint32 perc = (m_creature->getVictim()->GetPower(POWER_MANA)*100) / m_creature->getVictim()->GetMaxPower(POWER_MANA); + + if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) + return false; + + //Repeat Timers + pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); + break; + } case EVENT_T_REACHED_HOME: - { - } - break; case EVENT_T_RECEIVE_EMOTE: - { - } - break; + break; default: - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); break; } @@ -922,25 +768,16 @@ void CreatureEventAI::Reset() //Reset all events to enabled for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { - switch ((*i).Event.event_type) + CreatureEventAI_Event const& event = (*i).Event; + switch (event.event_type) { //Reset all out of combat timers case EVENT_T_TIMER_OOC: { - if ((*i).Event.event_param2 == (*i).Event.event_param1) - { - (*i).Time = (*i).Event.event_param1; + if ((*i).UpdateRepeatTimer(m_creature,event.timer.initialMin,event.timer.initialMax)) (*i).Enabled = true; - } - else if ((*i).Event.event_param2 > (*i).Event.event_param1) - { - (*i).Time = urand((*i).Event.event_param1, (*i).Event.event_param2); - (*i).Enabled = true; - } - else - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type); + break; } - break; //default: //TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro() //(*i).Enabled = true; @@ -1034,7 +871,8 @@ void CreatureEventAI::EnterCombat(Unit *enemy) { for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { - switch ((*i).Event.event_type) + CreatureEventAI_Event const& event = (*i).Event; + switch (event.event_type) { case EVENT_T_AGGRO: (*i).Enabled = true; @@ -1042,18 +880,8 @@ void CreatureEventAI::EnterCombat(Unit *enemy) break; //Reset all in combat timers case EVENT_T_TIMER: - if ((*i).Event.event_param2 == (*i).Event.event_param1) - { - (*i).Time = (*i).Event.event_param1; + if ((*i).UpdateRepeatTimer(m_creature,event.timer.initialMin,event.timer.initialMax)) (*i).Enabled = true; - } - else if ((*i).Event.event_param2 > (*i).Event.event_param1) - { - (*i).Time = urand((*i).Event.event_param1, (*i).Event.event_param2); - (*i).Enabled = true; - } - else - sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type); break; //All normal events need to be re-enabled and their time set to 0 default: @@ -1104,14 +932,14 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who) if ((*itr).Event.event_type == EVENT_T_OOC_LOS) { //can trigger if closer than fMaxAllowedRange - float fMaxAllowedRange = (*itr).Event.event_param2; + float fMaxAllowedRange = (*itr).Event.ooc_los.maxRange; //if range is ok and we are actually in LOS if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who)) { //if friendly event&&who is not hostile OR hostile event&&who is hostile - if (((*itr).Event.event_param1 && !m_creature->IsHostileTo(who)) || - ((!(*itr).Event.event_param1) && m_creature->IsHostileTo(who))) + if (((*itr).Event.ooc_los.noHostile && !m_creature->IsHostileTo(who)) || + ((!(*itr).Event.ooc_los.noHostile) && m_creature->IsHostileTo(who))) ProcessEvent(*itr, who); } } @@ -1151,17 +979,11 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell) return; for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) - { if ((*i).Event.event_type == EVENT_T_SPELLHIT) - { //If spell id matches (or no spell id) & if spell school matches (or no spell school) - if (!(*i).Event.event_param1 || pSpell->Id == (*i).Event.event_param1) - { - if ((*i).Event.event_param2_s == -1 || pSpell->SchoolMask == (*i).Event.event_param2) + if (!(*i).Event.spell_hit.spellId || pSpell->Id == (*i).Event.spell_hit.spellId) + if (pSpell->SchoolMask & (*i).Event.spell_hit.schoolMask) ProcessEvent(*i, pUnit); - } - } - } } void CreatureEventAI::UpdateAI(const uint32 diff) @@ -1216,8 +1038,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff) case EVENT_T_RANGE: if (Combat) if (m_creature->IsInMap(m_creature->getVictim())) - if (m_creature->IsInRange(m_creature->getVictim(), - (float)(*i).Event.event_param1,(float)(*i).Event.event_param2)) + if (m_creature->IsInRange(m_creature->getVictim(),(float)(*i).Event.range.minDist,(float)(*i).Event.range.maxDist)) ProcessEvent(*i); break; } @@ -1531,60 +1352,11 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote) { if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE) { - if ((*itr).Event.event_param1 != text_emote) + if ((*itr).Event.receive_emote.emoteId != text_emote) return; - bool bProcess = false; - - switch((*itr).Event.event_param2) - { - //enum ConditionType - case CONDITION_NONE: // 0 0 - bProcess = true; - break; - case CONDITION_AURA: // spell_id effindex - if (pPlayer->HasAura((*itr).Event.event_param3,(*itr).Event.event_param4)) - bProcess = true; - break; - case CONDITION_ITEM: // item_id count - if (pPlayer->HasItemCount((*itr).Event.event_param3,(*itr).Event.event_param4)) - bProcess = true; - break; - case CONDITION_ITEM_EQUIPPED: // item_id count - if (pPlayer->HasItemOrGemWithIdEquipped((*itr).Event.event_param3,(*itr).Event.event_param4)) - bProcess = true; - break; - case CONDITION_ZONEID: // zone_id 0 - if (pPlayer->GetZoneId() == (*itr).Event.event_param3) - bProcess = true; - break; - case CONDITION_REPUTATION_RANK: // faction_id min_rank - if (pPlayer->GetReputationRank((*itr).Event.event_param3) >= (*itr).Event.event_param4) - bProcess = true; - break; - case CONDITION_TEAM: // player_team 0, (469 - Alliance 67 - Horde) - if (pPlayer->GetTeam() == (*itr).Event.event_param3) - bProcess = true; - break; - case CONDITION_SKILL: // skill_id min skill_value - if (pPlayer->HasSkill((*itr).Event.event_param3) && pPlayer->GetSkillValue((*itr).Event.event_param3) >= (*itr).Event.event_param4) - bProcess = true; - break; - case CONDITION_QUESTREWARDED: // quest_id 0 - if (pPlayer->GetQuestRewardStatus((*itr).Event.event_param3)) - bProcess = true; - break; - case CONDITION_QUESTTAKEN: // quest_id 0, for condition true while quest active. - if (pPlayer->GetQuestStatus((*itr).Event.event_param3) == QUEST_STATUS_INCOMPLETE) - bProcess = true; - break; - case CONDITION_ACTIVE_EVENT: // event_id 0 - if (IsHolidayActive(HolidayIds((*itr).Event.event_param3))) - bProcess = true; - break; - } - - if (bProcess) + PlayerCondition pcon((*itr).Event.receive_emote.condition,(*itr).Event.receive_emote.conditionValue1,(*itr).Event.receive_emote.conditionValue2); + if (pcon.Meets(pPlayer)) { sLog.outDebug("CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing"); ProcessEvent(*itr, pPlayer); diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index 953596264..d357e5829 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -44,7 +44,7 @@ enum EventAI_Type EVENT_T_EVADE = 7, // NONE EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax - EVENT_T_OOC_LOS = 10, // NoHostile, NoFriendly, RepeatMin, RepeatMax + EVENT_T_OOC_LOS = 10, // NoHostile, MaxRnage, RepeatMin, RepeatMax EVENT_T_SPAWNED = 11, // NONE EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax @@ -376,23 +376,116 @@ struct CreatureEventAI_Event union { - uint32 event_param1; - int32 event_param1_s; - }; - union - { - uint32 event_param2; - int32 event_param2_s; - }; - union - { - uint32 event_param3; - int32 event_param3_s; - }; - union - { - uint32 event_param4; - int32 event_param4_s; + // EVENT_T_TIMER = 0 + // EVENT_T_TIMER_OOC = 1 + struct + { + uint32 initialMin; + uint32 initialMax; + uint32 repeatMin; + uint32 repeatMax; + } timer; + // EVENT_T_HP = 2 + // EVENT_T_MANA = 3 + // EVENT_T_TARGET_HP = 12 + // EVENT_T_TARGET_MANA = 18 + struct + { + uint32 percentMax; + uint32 percentMin; + uint32 repeatMin; + uint32 repeatMax; + } percent_range; + // EVENT_T_KILL = 5 + struct + { + uint32 repeatMin; + uint32 repeatMax; + } kill; + // EVENT_T_SPELLHIT = 8 + struct + { + uint32 spellId; + uint32 schoolMask; // -1 (==0xffffffff) is ok value for full mask, or must be more limited mask like (0 < 1) = 1 for normal/physical school + uint32 repeatMin; + uint32 repeatMax; + } spell_hit; + // EVENT_T_RANGE = 9 + struct + { + uint32 minDist; + uint32 maxDist; + uint32 repeatMin; + uint32 repeatMax; + } range; + // EVENT_T_OOC_LOS = 10 + struct + { + uint32 noHostile; + uint32 maxRange; + uint32 repeatMin; + uint32 repeatMax; + } ooc_los; + // EVENT_T_TARGET_CASTING = 13 + struct + { + uint32 repeatMin; + uint32 repeatMax; + } target_casting; + // EVENT_T_FRIENDLY_HP = 14 + struct + { + uint32 hpDeficit; + uint32 radius; + uint32 repeatMin; + uint32 repeatMax; + } friendly_hp; + // EVENT_T_FRIENDLY_IS_CC = 15 + struct + { + uint32 dispelType; // unused ? + uint32 radius; + uint32 repeatMin; + uint32 repeatMax; + } friendly_is_cc; + // EVENT_T_FRIENDLY_MISSING_BUFF = 16 + struct + { + uint32 spellId; + uint32 radius; + uint32 repeatMin; + uint32 repeatMax; + } friendly_buff; + // EVENT_T_SUMMONED_UNIT = 17 + struct + { + uint32 creatureId; + uint32 repeatMin; + uint32 repeatMax; + } summon_unit; + // EVENT_T_QUEST_ACCEPT = 19 + // EVENT_T_QUEST_COMPLETE = 20 + struct + { + uint32 questId; + } quest; + // EVENT_T_RECEIVE_EMOTE = 22 + struct + { + uint32 emoteId; + uint32 condition; + uint32 conditionValue1; + uint32 conditionValue2; + } receive_emote; + + // RAW + struct + { + uint32 param1; + uint32 param2; + uint32 param3; + uint32 param4; + } raw; }; CreatureEventAI_Action action[MAX_ACTIONS]; @@ -421,6 +514,9 @@ struct CreatureEventAIHolder CreatureEventAI_Event Event; uint32 Time; bool Enabled; + + // helper + bool UpdateRepeatTimer(Creature* creature, uint32 repeatMin, uint32 repeatMax); }; class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp index 4675da2ce..b870ff4e4 100644 --- a/src/game/CreatureEventAIMgr.cpp +++ b/src/game/CreatureEventAIMgr.cpp @@ -205,10 +205,10 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() temp.event_inverse_phase_mask = fields[3].GetUInt32(); temp.event_chance = fields[4].GetUInt8(); temp.event_flags = fields[5].GetUInt8(); - temp.event_param1 = fields[6].GetUInt32(); - temp.event_param2 = fields[7].GetUInt32(); - temp.event_param3 = fields[8].GetUInt32(); - temp.event_param4 = fields[9].GetUInt32(); + temp.raw.param1 = fields[6].GetUInt32(); + temp.raw.param2 = fields[7].GetUInt32(); + temp.raw.param3 = fields[8].GetUInt32(); + temp.raw.param4 = fields[9].GetUInt32(); //Creature does not exist in database if (!sCreatureStorage.LookupEntry(temp.creature_id)) @@ -232,87 +232,97 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { case EVENT_T_TIMER: case EVENT_T_TIMER_OOC: - { - if (temp.event_param2 < temp.event_param1) + if (temp.timer.initialMax < temp.timer.initialMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i); - - if (temp.event_param4 < temp.event_param3) + if (temp.timer.repeatMax < temp.timer.repeatMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); - break; - } - case EVENT_T_HP: case EVENT_T_MANA: case EVENT_T_TARGET_HP: - { - if (temp.event_param2 > 100) + case EVENT_T_TARGET_MANA: + if (temp.percent_range.percentMax > 100) sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i); - if (temp.event_param1 <= temp.event_param2) + if (temp.percent_range.percentMax <= temp.percent_range.percentMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i); - if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4) + if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax) { sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i); temp.event_flags &= ~EFLAG_REPEATABLE; } break; - } - case EVENT_T_SPELLHIT: - { - if (temp.event_param1) + if (temp.spell_hit.spellId) { - SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.event_param1); + SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId); if (!pSpell) { - sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i); + sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i); continue; } - if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask) - sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i); + if ((temp.spell_hit.schoolMask & pSpell->SchoolMask) != pSpell->SchoolMask) + sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.spell_hit.schoolMask, i); } - //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0 - //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit() - if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL) - sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i); + if (!temp.spell_hit.schoolMask) + sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.spell_hit.schoolMask, i); - if (temp.event_param4 < temp.event_param3) + if (temp.spell_hit.repeatMax < temp.spell_hit.repeatMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); break; - } - case EVENT_T_RANGE: + if (temp.range.maxDist < temp.range.minDist) + sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (MaxDist < MinDist). Event will never repeat.", temp.creature_id, i); + if (temp.range.repeatMax < temp.range.repeatMin) + sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); + break; case EVENT_T_OOC_LOS: + if (temp.ooc_los.repeatMax < temp.ooc_los.repeatMin) + sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); + break; case EVENT_T_FRIENDLY_HP: + if (temp.friendly_hp.repeatMax < temp.friendly_hp.repeatMin) + sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); + break; case EVENT_T_FRIENDLY_IS_CC: + if (temp.friendly_is_cc.repeatMax < temp.friendly_is_cc.repeatMin) + sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); + break; case EVENT_T_FRIENDLY_MISSING_BUFF: { - //Disabled check for now. Check code related to events and adjust accordingly before enable. - //Events should have min/max or alternative set to a static value. - /*if (!temp.event_param3 && !temp.event_param4) + SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId); + if (!pSpell) { - sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) without param3/param4 (RepeatMin/RepeatMax). Using minimum values.", temp.creature_id, i); - temp.event_param3 = 2500; - temp.event_param4 = 2500; - }*/ - - if (temp.event_param4 < temp.event_param3) + sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i); + continue; + } + if (temp.friendly_buff.repeatMax < temp.friendly_buff.repeatMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); break; } - case EVENT_T_KILL: - case EVENT_T_TARGET_CASTING: - { - if (temp.event_param2 < temp.event_param1) + if (temp.kill.repeatMax < temp.kill.repeatMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); - break; - } + case EVENT_T_TARGET_CASTING: + if (temp.target_casting.repeatMax < temp.target_casting.repeatMin) + sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); + break; + case EVENT_T_SUMMONED_UNIT: + if (!sCreatureStorage.LookupEntry(temp.summon_unit.creatureId)) + sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.summon_unit.creatureId); + if (temp.summon_unit.repeatMax < temp.summon_unit.repeatMin) + sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); + break; + case EVENT_T_QUEST_ACCEPT: + case EVENT_T_QUEST_COMPLETE: + if (!objmgr.GetQuestTemplate(temp.quest.questId)) + sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed qyest id (%u) in param1, skipped.", temp.creature_id, i, temp.quest.questId); + sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i); + continue; case EVENT_T_AGGRO: case EVENT_T_DEATH: @@ -331,21 +341,15 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() case EVENT_T_RECEIVE_EMOTE: { - if (!sEmotesTextStore.LookupEntry(temp.event_param1)) + if (!sEmotesTextStore.LookupEntry(temp.receive_emote.emoteId)) { - sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.event_param1); + sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.receive_emote.emoteId); continue; } - if (temp.event_param2 == CONDITION_AD_COMMISSION_AURA || temp.event_param2 == CONDITION_NO_AURA) + if (!PlayerCondition::IsValid(ConditionType(temp.receive_emote.condition), temp.receive_emote.conditionValue1, temp.receive_emote.conditionValue2)) { - sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not implemented for EventAI.",temp.creature_id, i, temp.event_param2); - continue; - } - - if (!PlayerCondition::IsValid(ConditionType(temp.event_param2), temp.event_param3, temp.event_param4)) - { - sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.event_param2); + sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition); continue; } @@ -358,21 +362,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() break; } - case EVENT_T_SUMMONED_UNIT: - { - if (!sCreatureStorage.LookupEntry(temp.event_param1)) - sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.event_param1); - - if (temp.event_param3 < temp.event_param2) - sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param3 < param2 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); - - break; - } - - case EVENT_T_QUEST_ACCEPT: - case EVENT_T_QUEST_COMPLETE: - sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i); - continue; default: sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i); break; @@ -486,6 +475,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() const SpellEntry *spell = sSpellStore.LookupEntry(action.cast.spellId); if (!spell) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast.spellId); + /* FIXME: temp.raw.param3 not have event tipes with recovery time in it.... else { if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE) @@ -495,6 +485,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,action.cast.spellId, spell->RecoveryTime, temp.event_param3); } } + */ //Cast is always triggered if target is forced to cast on self if (action.cast.castFlags & CAST_FORCE_TARGET_SELF) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 125d5013c..4404a8fb1 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7851" + #define REVISION_NR "7852" #endif // __REVISION_NR_H__ From 4e748b37867301ff18b21a56ec11ef98f0e3148e Mon Sep 17 00:00:00 2001 From: Astellar Date: Tue, 19 May 2009 23:08:14 +0400 Subject: [PATCH 19/22] [7853] Start casting including take reagents/power and set cooldown aftre fill targets and re-check spell cast continue. Signed-off-by: VladimirMangos --- src/game/Spell.cpp | 15 ++++++++------- src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 3c874ee56..da6f652b2 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2417,18 +2417,19 @@ void Spell::cast(bool skipCheck) ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); } + FillTargetMap(); + + if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in FillTargetMap + { + SetExecutedCurrently(false); + return; + } + // CAST SPELL SendSpellCooldown(); TakePower(); TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot - FillTargetMap(); - - if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap - { - SetExecutedCurrently(false); - return; - } SendCastResult(castResult); SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4404a8fb1..c50138bb8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7852" + #define REVISION_NR "7853" #endif // __REVISION_NR_H__ From 83beb6ec1dc9f83bb537a3e47e6dce5614640114 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Tue, 19 May 2009 23:23:50 +0400 Subject: [PATCH 20/22] [7854] Fixed typo in random text selection code. Signed-off-by: VladimirMangos --- src/game/CreatureEventAI.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 83b082c65..9e663107f 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -328,8 +328,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 switch( rand()%3 ) { case 0: temp = action.text.TextId1; break; - case 2: temp = action.text.TextId2; break; - case 3: temp = action.text.TextId3; break; + case 1: temp = action.text.TextId2; break; + case 2: temp = action.text.TextId3; break; } } else if (action.text.TextId2 && urand(0,1)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c50138bb8..389367190 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7853" + #define REVISION_NR "7854" #endif // __REVISION_NR_H__ From c014560b456710f4846a86a6cb573da6eae01466 Mon Sep 17 00:00:00 2001 From: Seizerkiller Date: Tue, 19 May 2009 23:39:05 +0400 Subject: [PATCH 21/22] [7855] Add description command to pool_* tables for simplify DB development. Note: this fields not used and not loaded by mangos. Signed-off-by: VladimirMangos --- sql/mangos.sql | 6 +++++- sql/updates/7855_01_mangos_pools.sql | 13 +++++++++++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 sql/updates/7855_01_mangos_pools.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 21a810c23..e9874df24 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_7850_01_mangos_command` bit(1) default NULL + `required_7855_01_mangos_pools` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -12960,6 +12960,7 @@ CREATE TABLE `pool_creature` ( `guid` int(10) unsigned NOT NULL default '0', `pool_entry` mediumint(8) unsigned NOT NULL default '0', `chance` float unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL, PRIMARY KEY (`pool_entry`,`guid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -12982,6 +12983,7 @@ CREATE TABLE `pool_gameobject` ( `guid` int(10) unsigned NOT NULL default '0', `pool_entry` mediumint(8) unsigned NOT NULL default '0', `chance` float unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL, PRIMARY KEY (`guid`,`pool_entry`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -13003,6 +13005,7 @@ CREATE TABLE `pool_pool` ( `pool_id` mediumint(8) unsigned NOT NULL default '0', `mother_pool` mediumint(8) unsigned NOT NULL default '0', `chance` float NOT NULL default '0', + `description` varchar(255) NOT NULL, PRIMARY KEY (`pool_id`,`mother_pool`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -13023,6 +13026,7 @@ DROP TABLE IF EXISTS `pool_template`; CREATE TABLE `pool_template` ( `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Pool entry', `max_limit` int(10) unsigned NOT NULL default '0' COMMENT 'Max number of objects (0) is no limit', + `description` varchar(255) NOT NULL, PRIMARY KEY (`entry`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/7855_01_mangos_pools.sql b/sql/updates/7855_01_mangos_pools.sql new file mode 100644 index 000000000..b5ac676c3 --- /dev/null +++ b/sql/updates/7855_01_mangos_pools.sql @@ -0,0 +1,13 @@ +ALTER TABLE db_version CHANGE COLUMN required_7850_01_mangos_command required_7855_01_mangos_pools bit; + +ALTER TABLE pool_creature + ADD COLUMN description varchar(255) NOT NULL AFTER chance; + +ALTER TABLE pool_gameobject + ADD COLUMN description varchar(255) NOT NULL AFTER chance; + +ALTER TABLE pool_pool + ADD COLUMN description varchar(255) NOT NULL AFTER chance; + +ALTER TABLE pool_template + ADD COLUMN description varchar(255) NOT NULL AFTER max_limit; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index a23ae16e3..decb87867 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -189,6 +189,7 @@ pkgdata_DATA = \ 7839_01_mangos_mangos_string.sql \ 7839_02_mangos_command.sql \ 7850_01_mangos_command.sql \ + 7855_01_mangos_pools.sql \ README ## Additional files to include when running 'make dist' @@ -358,4 +359,5 @@ EXTRA_DIST = \ 7839_01_mangos_mangos_string.sql \ 7839_02_mangos_command.sql \ 7850_01_mangos_command.sql \ + 7855_01_mangos_pools.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 389367190..badad2657 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7854" + #define REVISION_NR "7855" #endif // __REVISION_NR_H__ From ea1ca701edfca35e73cd00d780b674997d82f2ef Mon Sep 17 00:00:00 2001 From: Astellar Date: Wed, 20 May 2009 06:56:29 +0400 Subject: [PATCH 22/22] [7856] Fix cast 51525 and ranks charge on target (not owner) Signed-off-by: DiSlord --- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 7f150e1df..65219bf78 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5942,7 +5942,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu default: return false; } - CastSpell(this, spell, true, castItem, triggeredByAura); + CastSpell(target, spell, true, castItem, triggeredByAura); if ((*itr)->DropAuraCharge()) RemoveAurasDueToSpell((*itr)->GetId()); return true; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index badad2657..0f17c3c58 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7855" + #define REVISION_NR "7856" #endif // __REVISION_NR_H__