Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
Yunfan Li
2024-03-17 12:05:57 +08:00
committed by GitHub
15 changed files with 819 additions and 92 deletions

View File

@@ -0,0 +1,3 @@
-- DB update 2024_03_11_01 -> 2024_03_13_00
--
UPDATE `smart_scripts` SET `event_type` = 0, `comment` = 'Tempest Falconer - In Combat - Cast \'Shoot\'', `event_param6` = 0 WHERE `entryorguid` = 20037 AND `source_type` = 0 AND `id` = 1;

View File

@@ -0,0 +1,3 @@
-- DB update 2024_03_13_00 -> 2024_03_13_01
-- fix phaseMask of two 'Bench' spawns
UPDATE `gameobject` SET `phaseMask` = 2 WHERE (`guid` IN (57773, 57784));

View File

@@ -0,0 +1,123 @@
-- DB update 2024_03_13_01 -> 2024_03_15_00
-- [START] // DB Update for .reset items command
/*---------------------------------
Command and associated help
-----------------------------------*/
-- Always delete before insert to ensure script repeatability :
-- One value per line to facilitate readability
DELETE FROM `command` WHERE `name` IN(
'reset items',
'reset items equipped',
'reset items bags',
'reset items bank',
'reset items keyring',
'reset items currency',
'reset items vendor_buyback',
'reset items all',
'reset items allbags');
-- GM Security level associated with the commands
SET @GM_SECURITY_LEVEL = 3;
-- Insert values :
INSERT INTO `command`(`name`,`security`,`help`)
VALUES (
-- .reset items (main command)
'reset items', @GM_SECURITY_LEVEL, 'Syntax : .reset items equipped|bags|bank|keyring|currency|vendor_buyback|all|allbags #playername
Delete items in the player inventory (equipped, bank, bags etc...) depending on the chosen option.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
-- .reset items _____ (Sub-commands)
('reset items equipped', @GM_SECURITY_LEVEL, 'Syntax : .reset items equipped #playername
Delete all items equipped on the target player.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items bags', @GM_SECURITY_LEVEL, 'Syntax : .reset items bags #playername
Delete all items in the selected player\'s bags.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items bank', @GM_SECURITY_LEVEL, 'Syntax : .reset items bank #playername
Delete all items in the selected player\'s bank.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items keyring', @GM_SECURITY_LEVEL, 'Syntax : .reset items keyring #playername
Delete all items in the selected player\'s keyring.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items currency', @GM_SECURITY_LEVEL, 'Syntax : .reset items currency #playername
Delete all items in the selected player\'s currencies list.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items vendor_buyback', @GM_SECURITY_LEVEL, 'Syntax : .reset items vendor_buyback #playername
Delete all items in the selected player\'s vendor buyback tab.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items all', @GM_SECURITY_LEVEL, 'Syntax : .reset items all #playername
Delete all items in the selected player\'s inventory (equipped, in bags, in bank, in keyring, in currency list and in vendor buy back tab).
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.'),
('reset items allbags', @GM_SECURITY_LEVEL, 'Syntax : .reset items allbags #playername
Delete all items in the selected player\'s inventory (equipped, in bags, in bank, in keyring, in currency list and in vendor buy back tab)
This command also deletes the bags.
#playername : Optional target player name (if player is online only). If not provided the command will execute on the selected target player.');
/*---------------------------------------------------------------------------------
LANG_* strings used by the core at command use.
All of them are stored in table `acore_string`
Note : We should think to add a `enum_tag` column to the `acore_string` table
in order to automatize the rebuild of Language.h file
------------------------------------------------------------------------------------*/
-- Always delete before insert to ensure script repeatability :
DELETE FROM `acore_string` WHERE `entry` IN (365, 366, 367, 368, 369, 370, 371, 372);
-- Insert values :
-- Attention : Need to translate in other languages. Since I'm French I will set only english and french ones :-)
INSERT INTO `acore_string` (`entry`, `content_default`, `locale_frFR`)
VALUES (365, '|cffffffff%d|r equipped items deleted for %s', '|cffffffff%d|r objets équipés supprimés pour %s'),
(366, '|cffffffff%d|r items in equipped bags deleted for %s', '|cffffffff%d|r objets supprimés dans les sacs de %s'),
(367, '|cffffffff%d|r items in bank deleted for %s', '|cffffffff%d|r objets supprimés de la banque de %s'),
(368, '|cffffffff%d|r keys in keyring deleted for %s', '|cffffffff%d|r objets supprimés du porte-clés de %s'),
(369, '|cffffffff%d|r currencies deleted for %s', '|cffffffff%d|r types de monnaies supprimées l\'inventaire de %s'),
(370, '|cffffffff%d|r items in vendors buyback deleted for %s', '|cffffffff%d|r objets supprimés dans l\'onglet rachat des vendeurs pour %s'),
(371, 'All items were deleted for %s :
|cffffffff%d|r items equipped
|cffffffff%d|r items in bags
|cffffffff%d|r items in bank
|cffffffff%d|r keys in keyring
|cffffffff%d|r currency types
|cffffffff%d|r items in vendor buyback',
'Tous les objets de %s ont été supprimés :
|cffffffff%d|r objet équipés
|cffffffff%d|r objets dans les sacs
|cffffffff%d|r objets en banque
|cffffffff%d|r clés dans le porte-clés
|cffffffff%d|r types de monnaies
|cffffffff%d|r objets dans l\'onglet rachat des vendeurs'),
(372, 'All items were deleted for %s (bags included):
|cffffffff%d|r equipped
|cffffffff%d|r items in bags
|cffffffff%d|r items in bank
|cffffffff%d|r keys in keyring
|cffffffff%d|r currency types
|cffffffff%d|r items in vendor buyback
|cffffffff%d|r standard bags
|cffffffff%d|r bank bags',
'Tous les objets de %s ont é supprimés (sacs y-compris):
|cffffffff%d|r objet équipés
|cffffffff%d|r objets dans les sacs
|cffffffff%d|r objets en banque
|cffffffff%d|r clés dans le porte-clés
|cffffffff%d|r types de monnaies
|cffffffff%d|r objets dans l\'onglet rachat des vendeurs
|cffffffff%d|r sacs standard
|cffffffff%d|r sacs de banque'
);
-- [END] // DB Update for .reset items command;

View File

@@ -0,0 +1,3 @@
-- DB update 2024_03_15_00 -> 2024_03_16_00
--
UPDATE `item_template` SET `spellppmRate_2` = 60 WHERE `entry` = 30312;

View File

@@ -212,11 +212,9 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
}
data << uint32(_questMenu.GetMenuItemCount()); // max count 0x20
uint32 count = 0;
for (uint32 iI = 0; iI < _questMenu.GetMenuItemCount(); ++iI)
{
++count;
QuestMenuItem const& item = _questMenu.GetItem(iI);
uint32 questID = item.QuestId;
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID))

View File

@@ -721,7 +721,7 @@ enum BankBagSlots // 7 slots
enum BuyBackSlots // 12 slots
{
// stored in m_buybackitems
// stored in m_items, there is no more m_buybackitems
BUYBACK_SLOT_START = 74,
BUYBACK_SLOT_END = 86
};

View File

@@ -2481,8 +2481,6 @@ void ObjectMgr::LoadGameobjects()
{
uint32 oldMSTime = getMSTime();
uint32 count = 0;
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
// 7 8 9 10 11 12 13 14 15 16 17
@@ -2642,7 +2640,6 @@ void ObjectMgr::LoadGameobjects()
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
AddGameobjectToGrid(guid, &data);
++count;
} while (result->NextRow());
LOG_INFO("server.loading", ">> Loaded {} Gameobjects in {} ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
@@ -2871,49 +2868,50 @@ void ObjectMgr::LoadItemTemplates()
// Checks
ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
if (dbcitem)
if (!dbcitem)
{
if (enforceDBCAttributes)
LOG_DEBUG("sql.sql", "Item (Entry: {}) does not exist in item.dbc! (not correct id?).", entry);
continue;
}
if (enforceDBCAttributes)
{
if (itemTemplate.Class != dbcitem->ClassID)
{
if (itemTemplate.Class != dbcitem->ClassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
itemTemplate.Class = dbcitem->ClassID;
}
if (itemTemplate.SubClass != dbcitem->SubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
itemTemplate.SubClass = dbcitem->SubclassID;
}
if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
}
if (itemTemplate.Material != dbcitem->Material)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
itemTemplate.Material = dbcitem->Material;
}
if (itemTemplate.InventoryType != dbcitem->InventoryType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
itemTemplate.InventoryType = dbcitem->InventoryType;
}
if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
}
if (itemTemplate.Sheath != dbcitem->SheatheType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
itemTemplate.Sheath = dbcitem->SheatheType;
}
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({}), must be ({}).", entry, itemTemplate.Class, dbcitem->ClassID);
itemTemplate.Class = dbcitem->ClassID;
}
if (itemTemplate.SubClass != dbcitem->SubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Subclass value ({}) for class {}, must be ({}).", entry, itemTemplate.SubClass, itemTemplate.Class, dbcitem->SubclassID);
itemTemplate.SubClass = dbcitem->SubclassID;
}
if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclassID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct SoundOverrideSubclass ({}), must be {}.", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclassID);
itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclassID;
}
if (itemTemplate.Material != dbcitem->Material)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct material ({}), must be {}.", entry, itemTemplate.Material, dbcitem->Material);
itemTemplate.Material = dbcitem->Material;
}
if (itemTemplate.InventoryType != dbcitem->InventoryType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong InventoryType value ({}), must be {}.", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
itemTemplate.InventoryType = dbcitem->InventoryType;
}
if (itemTemplate.DisplayInfoID != dbcitem->DisplayInfoID)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) does not have a correct display id ({}), must be {}.", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayInfoID);
itemTemplate.DisplayInfoID = dbcitem->DisplayInfoID;
}
if (itemTemplate.Sheath != dbcitem->SheatheType)
{
LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Sheath ({}), must be {}.", entry, itemTemplate.Sheath, dbcitem->SheatheType);
itemTemplate.Sheath = dbcitem->SheatheType;
}
}
else
LOG_ERROR("sql.sql", "Item (Entry: {}) does not exist in item.dbc! (not correct id?).", entry);
if (itemTemplate.Quality >= MAX_ITEM_QUALITY)
{
@@ -6343,8 +6341,6 @@ void ObjectMgr::LoadQuestGreetingsLocales()
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
@@ -6379,8 +6375,6 @@ void ObjectMgr::LoadQuestGreetingsLocales()
QuestGreetingLocale& data = _questGreetingLocaleStore[MAKE_PAIR32(type, id)];
AddLocaleString(fields[3].Get<std::string>(), locale, data.Greeting);
++count;
} while (result->NextRow());
LOG_INFO("server.loading", ">> Loaded {} quest greeting Locale Strings in {} ms", (uint32)_questGreetingLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));

View File

@@ -403,7 +403,19 @@ enum AcoreStrings
LANG_COMMAND_CHEAT_WW = 362,
LANG_COMMAND_WHISPEROFFPLAYER = 363,
LANG_COMMAND_CHEAT_TAXINODES = 364,
// Room for more level 2 365-399 not used
// [START] .reset items command strings:
LANG_COMMAND_RESET_ITEMS_EQUIPPED = 365,
LANG_COMMAND_RESET_ITEMS_BAGS = 366,
LANG_COMMAND_RESET_ITEMS_BANK = 367,
LANG_COMMAND_RESET_ITEMS_KEYRING = 368,
LANG_COMMAND_RESET_ITEMS_CURRENCY = 369,
LANG_COMMAND_RESET_ITEMS_BUYBACK = 370,
LANG_COMMAND_RESET_ITEMS_ALL = 371,
LANG_COMMAND_RESET_ITEMS_ALL_BAGS = 372,
// [END] reset items command strings
// Room for more level 2 373-399 not used
// level 3 chat
LANG_SCRIPTS_RELOADED = 400,

View File

@@ -212,13 +212,19 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({
37790, // Spread Shot
54172, // Divine Storm (heal)
66588, // Flaming Spear
54171 // Divine Storm
66588 // Flaming Spear
}, [](SpellInfo* spellInfo)
{
spellInfo->MaxAffectedTargets = 3;
});
// Divine Storm
ApplySpellFix({ 54171 }, [](SpellInfo* spellInfo)
{
spellInfo->MaxAffectedTargets = 3;
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Divine Storm (Damage)
ApplySpellFix({ 53385 }, [](SpellInfo* spellInfo)
{
@@ -566,12 +572,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
});
// Light's Beacon, Beacon of Light
ApplySpellFix({ 53651 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
// Hand of Reckoning
ApplySpellFix({ 62124 }, [](SpellInfo* spellInfo)
{
@@ -854,6 +854,7 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({ 57330, 57623 }, [](SpellInfo* spellInfo)
{
spellInfo->Effects[EFFECT_1].TargetA = 0;
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Scourge Strike trigger
@@ -1213,6 +1214,7 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({ 59725 }, [](SpellInfo* spellInfo)
{
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER_AREA_PARTY);
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Hymn of Hope
@@ -4033,6 +4035,8 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({ 53651 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx |= SPELL_ATTR1_NO_THREAT;
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
// Shadow Hunter Vosh'gajin - Hex
@@ -4644,10 +4648,154 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Magic Disruption (KT dagger)
ApplySpellFix({ 36478 }, [](SpellInfo* spellInfo)
// Commanding Shout
ApplySpellFix({ 469, 47439, 47440 }, [](SpellInfo* spellInfo)
{
spellInfo->ProcChance = 100;
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Battle Shout
ApplySpellFix({ 2048, 5242, 6192, 6673, 11549, 11550, 11551, 25289, 47436 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Plague Effect
ApplySpellFix({ 19594, 26557 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Prayer of Fortitude
ApplySpellFix({ 21562, 21564, 25392, 48162 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Gift of the Wild
ApplySpellFix({ 21849, 21850, 26991, 48470, 69381 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Arcane Brilliance
ApplySpellFix({ 23028, 27127, 43002 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Prayer of Spirit
ApplySpellFix({ 27681, 32999, 48074 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Prayer of Shadow Protection
ApplySpellFix({ 27683, 39374, 48170 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Nagrand Fort Buff Reward Raid
ApplySpellFix({ 33006 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Demonic Pact
ApplySpellFix({ 48090 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Ancestral Awakening
ApplySpellFix({ 52759 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Turn the Tables
ApplySpellFix({ 52910, 52914, 52915 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Judgements of the Wise
ApplySpellFix({ 54180 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Replenishment
ApplySpellFix({ 57669 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Dalaran Brilliance
ApplySpellFix({ 61316 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// [DND] Dalaran Brilliance
ApplySpellFix({ 61332 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Infinite Replenishment + Wisdom
ApplySpellFix({ 61782 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Renewed Hope
ApplySpellFix({ 63944 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Fortitude
ApplySpellFix({ 69377 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Blessing of Forgotten Kings
ApplySpellFix({ 69378 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Lucky Charm
ApplySpellFix({ 69511 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Shiny Shard of the Scale Heal Targeter
ApplySpellFix({ 69749 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Purified Shard of the Scale Heal Targeter
ApplySpellFix({ 69754 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Brilliance
ApplySpellFix({ 69994 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LINE_OF_SIGHT;
});
// Domination
ApplySpellFix({ 37135 }, [](SpellInfo* spellInfo)
{
spellInfo->MaxAffectedTargets = 5;
});
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)

View File

@@ -1692,7 +1692,7 @@ public:
Item* item = playerTarget->StoreNewItem(dest, itemId, true);
Player* p = handler->GetSession()->GetPlayer();
Player* p = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
// remove binding (let GM give it to another player later)
if (p && p == playerTarget)
{

View File

@@ -36,10 +36,22 @@ using namespace Acore::ChatCommands;
class reset_commandscript : public CommandScript
{
public:
reset_commandscript() : CommandScript("reset_commandscript") { }
ChatCommandTable GetCommands() const override
{
static ChatCommandTable resetItemsCommandTable =
{
{ "equipped", HandleResetItemsEquippedCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "bags", HandleResetItemsInBagsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "bank", HandleResetItemsInBankCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "keyring", HandleResetItemsKeyringCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "currency", HandleResetItemsInCurrenciesListCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "vendor_buyback", HandleResetItemsInVendorBuyBackTabCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "all", HandleResetItemsAllCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "allbags", HandleResetItemsAllAndDeleteBagsCommand, SEC_ADMINISTRATOR, Console::Yes },
};
static ChatCommandTable resetCommandTable =
{
{ "achievements", HandleResetAchievementsCommand, SEC_CONSOLE, Console::Yes },
@@ -48,6 +60,7 @@ public:
{ "spells", HandleResetSpellsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "stats", HandleResetStatsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "talents", HandleResetTalentsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "items", resetItemsCommandTable },
{ "all", HandleResetAllCommand, SEC_CONSOLE, Console::Yes }
};
static ChatCommandTable commandTable =
@@ -296,6 +309,418 @@ public:
return true;
}
static bool HandleResetItemsEquippedCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
int16 deletedItemsCount = ResetItemsEquipped(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_EQUIPPED, deletedItemsCount, handler->GetNameLink(targetPlayer).c_str());
}
return true;
}
static bool HandleResetItemsInBagsCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
int16 deletedItemsCount = ResetItemsInBags(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_BAGS, deletedItemsCount, handler->GetNameLink(targetPlayer).c_str());
}
return true;
}
static bool HandleResetItemsKeyringCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
int16 deletedItemsCount = ResetItemsInKeyring(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_KEYRING, deletedItemsCount, handler->GetNameLink(targetPlayer).c_str());
}
return true;
}
static bool HandleResetItemsInCurrenciesListCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
int16 deletedItemsCount = ResetItemsInCurrenciesList(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_CURRENCY, deletedItemsCount, handler->GetNameLink(targetPlayer).c_str());
}
return true;
}
static bool HandleResetItemsInBankCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
int16 deletedItemsCount = ResetItemsInBank(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_BANK, deletedItemsCount, handler->GetNameLink(targetPlayer).c_str());
}
return true;
}
static bool HandleResetItemsInVendorBuyBackTabCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
int16 deletedItemsCount = ResetItemsInVendorBuyBackTab(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_BUYBACK, deletedItemsCount, handler->GetNameLink(targetPlayer).c_str());
}
return true;
}
static bool HandleResetItemsAllCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
// Delete all items destinations
int16 deletedItemsEquippedCount = ResetItemsEquipped(targetPlayer);
int16 deletedItemsInBagsCount = ResetItemsInBags(targetPlayer);
int16 deletedItemsInBankCount = ResetItemsInBank(targetPlayer);
int16 deletedItemsInKeyringCount = ResetItemsInKeyring(targetPlayer);
int16 deletedItemsInCurrenciesListCount = ResetItemsInCurrenciesList(targetPlayer);
int16 deletedItemsInVendorBuyBackTabCount = ResetItemsInVendorBuyBackTab(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_ALL, handler->GetNameLink(targetPlayer).c_str(),
deletedItemsEquippedCount,
deletedItemsInBagsCount,
deletedItemsInBankCount,
deletedItemsInKeyringCount,
deletedItemsInCurrenciesListCount,
deletedItemsInVendorBuyBackTabCount);
}
return true;
}
static bool HandleResetItemsAllAndDeleteBagsCommand(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = GetPlayerFromIdentifierOrSelectedTarget(handler, target);
if (!targetPlayer)
{
return false;
}
else
{
// Delete all items destinations
int16 deletedItemsEquippedCount = ResetItemsEquipped(targetPlayer);
int16 deletedItemsInBagsCount = ResetItemsInBags(targetPlayer);
int16 deletedItemsInBankCount = ResetItemsInBank(targetPlayer);
int16 deletedItemsInKeyringCount = ResetItemsInKeyring(targetPlayer);
int16 deletedItemsInCurrenciesListCount = ResetItemsInCurrenciesList(targetPlayer);
int16 deletedItemsInVendorBuyBackTabCount = ResetItemsInVendorBuyBackTab(targetPlayer);
int16 deletedItemsStandardBagsCount = ResetItemsDeleteStandardBags(targetPlayer);
int16 deletedItemsBankBagsCount = ResetItemsDeleteBankBags(targetPlayer);
handler->PSendSysMessage(LANG_COMMAND_RESET_ITEMS_ALL_BAGS, handler->GetNameLink(targetPlayer).c_str(),
deletedItemsEquippedCount,
deletedItemsInBagsCount,
deletedItemsInBankCount,
deletedItemsInKeyringCount,
deletedItemsInCurrenciesListCount,
deletedItemsInVendorBuyBackTabCount,
deletedItemsStandardBagsCount,
deletedItemsBankBagsCount);
}
return true;
}
private:
static Player* GetPlayerFromIdentifierOrSelectedTarget(ChatHandler* handler, Optional<PlayerIdentifier> target)
{
Player* targetPlayer = nullptr;
// Check if there is an optional target player name
// Do not use TargetOrSelf, we must be sure to select ourself
if (!target)
{
// No optional target, so try to get selected target
target = PlayerIdentifier::FromTarget(handler);
if (!target)
{
// No character selected
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
return targetPlayer;
}
targetPlayer = target->GetConnectedPlayer();
}
else
{
targetPlayer = target->GetConnectedPlayer();
if (!targetPlayer || !target->IsConnected())
{
// No character selected
handler->SendSysMessage(LANG_PLAYER_NOT_EXIST_OR_OFFLINE);
}
}
return targetPlayer;
}
static int16 ResetItemsEquipped(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
Item* pItem = playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pItem)
{
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
return count;
}
static int16 ResetItemsInBags(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
// Default bagpack :
for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
Item* pItem = playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pItem)
{
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
// Bag slots
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
{
Bag* pBag = (Bag*)playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pBag)
{
for (uint8 j = 0; j < pBag->GetBagSize(); ++j)
{
Item* pItem = pBag->GetItemByPos(j);
if (pItem)
{
playerTarget->DestroyItem(i, j, true);
++count;
}
}
}
}
return count;
}
static int16 ResetItemsInBank(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
// Normal bank slot
for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
{
Item* pItem = playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pItem)
{
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
// Bank bagslots
for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
{
Bag* pBag = (Bag*)playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pBag)
{
for (uint8 j = 0; j < pBag->GetBagSize(); ++j)
{
Item* pItem = pBag->GetItemByPos(j);
if (pItem)
{
playerTarget->DestroyItem(i, j, true);
++count;
}
}
}
}
return count;
}
static int16 ResetItemsInKeyring(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i)
{
Item* pItem = playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pItem)
{
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
return count;
}
static int16 ResetItemsInCurrenciesList(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
for (uint8 i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
{
Item* pItem = playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pItem)
{
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
return count;
}
static int16 ResetItemsInVendorBuyBackTab(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
for (uint8 i = BUYBACK_SLOT_START; i < BUYBACK_SLOT_END; ++i)
{
Item* pItem = playerTarget->GetItemFromBuyBackSlot(i);
if (pItem)
{
playerTarget->RemoveItemFromBuyBackSlot(i, true);
++count;
}
}
return count;
}
static int16 ResetItemsDeleteStandardBags(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
// Standard bag slots
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
{
Bag* pBag = (Bag*)playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pBag)
{
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
return count;
}
static int16 ResetItemsDeleteBankBags(Player* playerTarget)
{
if (!playerTarget)
{
return -1;
}
int16 count = 0;
// Bank bags
for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
{
Bag* pBag = (Bag*)playerTarget->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (pBag)
{
// prevent no empty ?
playerTarget->DestroyItem(INVENTORY_SLOT_BAG_0, i, true);
++count;
}
}
return count;
}
};
void AddSC_reset_commandscript()

View File

@@ -829,7 +829,6 @@ public:
if (Group* EventGroup = player->GetGroup())
{
uint8 GroupMemberCount = 0;
uint8 DeadMemberCount = 0;
uint8 FailedMemberCount = 0;
Group::MemberSlotList const& members = EventGroup->GetMemberSlots();
@@ -845,9 +844,6 @@ public:
++FailedMemberCount;
}
++GroupMemberCount;
if (groupMember->isDead())
++DeadMemberCount;
}
if (GroupMemberCount == FailedMemberCount || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS))

View File

@@ -94,6 +94,10 @@ struct boss_alar : public BossAI
boss_alar(Creature* creature) : BossAI(creature, DATA_ALAR)
{
me->SetCombatMovement(false);
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void JustReachedHome() override
@@ -111,6 +115,8 @@ struct boss_alar : public BossAI
_canAttackCooldown = true;
_baseAttackOverride = false;
_spawnPhoenixes = false;
_hasPretendedToDie = false;
_transitionScheduler.CancelAll();
_platform = 0;
_noMelee = false;
_platformRoll = 0;
@@ -177,30 +183,34 @@ struct boss_alar : public BossAI
if (damage >= me->GetHealth() && _platform < POINT_MIDDLE)
{
damage = 0;
DoCastSelf(SPELL_EMBER_BLAST, true);
PretendToDie(me);
ScheduleUniqueTimedEvent(1s, [&]{
me->SetVisible(false);
}, EVENT_INVISIBLE);
ScheduleUniqueTimedEvent(8s, [&]{
me->SetPosition(alarPoints[POINT_MIDDLE]);
}, EVENT_RELOCATE_MIDDLE);
ScheduleUniqueTimedEvent(12s, [&]
if (!_hasPretendedToDie)
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetVisible(true);
DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true);
DoCastSelf(SPELL_REBIRTH_PHASE2);
}, EVENT_MOVE_TO_PHASE_2);
ScheduleUniqueTimedEvent(16001ms, [&]{
me->SetHealth(me->GetMaxHealth());
me->SetReactState(REACT_AGGRESSIVE);
_noMelee = false;
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
_platform = POINT_MIDDLE;
me->GetMotionMaster()->MoveChase(me->GetVictim());
ScheduleAbilities();
}, EVENT_REBIRTH);
_hasPretendedToDie = true;
DoCastSelf(SPELL_EMBER_BLAST, true);
PretendToDie(me);
_transitionScheduler.Schedule(1s, [this](TaskContext)
{
me->SetVisible(false);
}).Schedule(8s, [this](TaskContext)
{
me->SetPosition(alarPoints[POINT_MIDDLE]);
}).Schedule(12s, [this](TaskContext)
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetVisible(true);
DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true);
DoCastSelf(SPELL_REBIRTH_PHASE2);
}).Schedule(16001ms, [this](TaskContext)
{
me->SetHealth(me->GetMaxHealth());
me->SetReactState(REACT_AGGRESSIVE);
_noMelee = false;
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
_platform = POINT_MIDDLE;
me->GetMotionMaster()->MoveChase(me->GetVictim());
ScheduleAbilities();
});
}
}
}
@@ -219,6 +229,7 @@ struct boss_alar : public BossAI
void ScheduleAbilities()
{
_transitionScheduler.CancelAll();
ScheduleTimedEvent(57s, [&]
{
DoCastVictim(SPELL_MELT_ARMOR);
@@ -264,7 +275,7 @@ struct boss_alar : public BossAI
_noMelee = true;
scheduler.Schedule(2s, [this](TaskContext)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 10.0f, true))
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 110.0f, true))
{
SpawnPhoenixes(2, target);
}
@@ -352,6 +363,8 @@ struct boss_alar : public BossAI
void UpdateAI(uint32 diff) override
{
_transitionScheduler.Update(diff);
if (!UpdateVictim())
{
return;
@@ -401,6 +414,7 @@ struct boss_alar : public BossAI
}
private:
bool _hasPretendedToDie;
bool _canAttackCooldown;
bool _baseAttackOverride;
bool _spawnPhoenixes;
@@ -409,6 +423,7 @@ private:
uint8 _platformRoll;
uint8 _noQuillTimes;
std::chrono::seconds _platformMoveRepeatTimer;
TaskScheduler _transitionScheduler;
};
class CastQuill : public BasicEvent

View File

@@ -36,7 +36,8 @@ enum Spells
SPELL_WRATH_OF_THE_ASTROMANCER = 42783,
SPELL_BLINDING_LIGHT = 33009,
SPELL_PSYCHIC_SCREAM = 34322,
SPELL_VOID_BOLT = 39329
SPELL_VOID_BOLT = 39329,
SPELL_TRUE_BEAM = 33365,
};
enum Misc
@@ -122,7 +123,7 @@ struct boss_high_astromancer_solarian : public BossAI
scheduler.Schedule(3650ms, [this](TaskContext context)
{
me->GetMotionMaster()->Clear();
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true, true, -SPELL_WRATH_OF_THE_ASTROMANCER))
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, false, true, -SPELL_WRATH_OF_THE_ASTROMANCER))
{
DoCast(target, SPELL_ARCANE_MISSILES);
}
@@ -145,6 +146,7 @@ struct boss_high_astromancer_solarian : public BossAI
{
me->SetReactState(REACT_PASSIVE);
Talk(SAY_SUMMON);
me->RemoveAllAuras();
me->SetModelVisible(false);
scheduler.DelayAll(21s);
scheduler.Schedule(6s, [this](TaskContext)
@@ -157,6 +159,7 @@ struct boss_high_astromancer_solarian : public BossAI
{
if (light->GetDistance2d(CENTER_X, CENTER_Y) < 20.0f)
{
DoCast(light, SPELL_TRUE_BEAM);
me->SetPosition(*light);
me->StopMovingOnCurrentPos();
}
@@ -179,6 +182,7 @@ struct boss_high_astromancer_solarian : public BossAI
light->RemoveAllAuras();
if (light->GetDistance2d(CENTER_X, CENTER_Y) < 20.0f)
{
me->RemoveAllAuras();
me->SetModelVisible(true);
}
else

View File

@@ -1159,7 +1159,10 @@ class spell_kaelthas_mind_control : public SpellScript
void SelectTarget(std::list<WorldObject*>& targets)
{
if (Unit* victim = GetCaster()->GetVictim())
{
targets.remove_if(Acore::ObjectGUIDCheck(victim->GetGUID(), true));
}
targets.remove_if(Acore::ObjectTypeIdCheck(TYPEID_PLAYER, false));
}
void Register() override