Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b920ec50ab | |||
| 5918cf7b1a | |||
| e04f0f068c | |||
| 85287568b5 | |||
| 75600c767f | |||
| bfb4aee94b | |||
| 9d7bfe2516 | |||
| b5f3f51208 | |||
| 88ed7f639f | |||
| 889fe02d1b | |||
| 52868e6634 | |||
| a45158f756 | |||
| 4d36c6f702 | |||
| ed017ab51a |
+22
-16
@@ -183,25 +183,25 @@ ACORE_WORLD_DBC_ENFORCE_ITEM_ATTRIBUTES=0
|
||||
ACORE_WORLD_INSTANCE_IGNORE_RAID=1
|
||||
|
||||
# Множитель физического урона обычной элиты.
|
||||
ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_DAMAGE=0.80
|
||||
ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_DAMAGE=1.00
|
||||
|
||||
# Множитель физического урона rare.
|
||||
ACORE_WORLD_RATE_CREATURE_RARE_DAMAGE=0.80
|
||||
ACORE_WORLD_RATE_CREATURE_RARE_DAMAGE=1.00
|
||||
|
||||
# Множитель физического урона rare elite.
|
||||
ACORE_WORLD_RATE_CREATURE_RAREELITE_DAMAGE=0.75
|
||||
ACORE_WORLD_RATE_CREATURE_RAREELITE_DAMAGE=1.00
|
||||
|
||||
# Множитель физического урона world boss.
|
||||
ACORE_WORLD_RATE_CREATURE_WORLDBOSS_DAMAGE=1
|
||||
|
||||
# Множитель spell-урона обычной элиты.
|
||||
ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_SPELL_DAMAGE=0.80
|
||||
ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_SPELL_DAMAGE=1.00
|
||||
|
||||
# Множитель spell-урона rare.
|
||||
ACORE_WORLD_RATE_CREATURE_RARE_SPELL_DAMAGE=0.80
|
||||
ACORE_WORLD_RATE_CREATURE_RARE_SPELL_DAMAGE=1.00
|
||||
|
||||
# Множитель spell-урона rare elite.
|
||||
ACORE_WORLD_RATE_CREATURE_RAREELITE_SPELL_DAMAGE=0.75
|
||||
ACORE_WORLD_RATE_CREATURE_RAREELITE_SPELL_DAMAGE=1.00
|
||||
|
||||
# Множитель spell-урона world boss.
|
||||
ACORE_WORLD_RATE_CREATURE_WORLDBOSS_SPELL_DAMAGE=1
|
||||
@@ -223,10 +223,10 @@ ACORE_WORLD_RATE_CREATURE_WORLDBOSS_HP=1
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Минимальное число игроков, до которого скейлится обычный инст.
|
||||
ACORE_AUTOBALANCE_MIN_PLAYERS=1
|
||||
ACORE_AUTOBALANCE_MIN_PLAYERS=2
|
||||
|
||||
# Минимальное число игроков для heroic 5ppl.
|
||||
ACORE_AUTOBALANCE_MIN_PLAYERS_HEROIC=1
|
||||
ACORE_AUTOBALANCE_MIN_PLAYERS_HEROIC=2
|
||||
|
||||
# Минимальное число игроков для рейдов normal.
|
||||
ACORE_AUTOBALANCE_MIN_PLAYERS_RAID=1
|
||||
@@ -234,23 +234,29 @@ ACORE_AUTOBALANCE_MIN_PLAYERS_RAID=1
|
||||
# Минимальное число игроков для рейдов heroic.
|
||||
ACORE_AUTOBALANCE_MIN_PLAYERS_RAID_HEROIC=1
|
||||
|
||||
# Насколько уровней ниже игрока могут скейлиться мобы обычного подземелья.
|
||||
ACORE_AUTOBALANCE_LEVEL_SCALING_FLOOR_DUNGEONS=1
|
||||
|
||||
# Насколько уровней ниже игрока могут скейлиться мобы heroic-подземелья.
|
||||
ACORE_AUTOBALANCE_LEVEL_SCALING_FLOOR_HEROIC_DUNGEONS=1
|
||||
|
||||
# Множитель HP обычных мобов в normal 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEALTH=1.30
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEALTH=1.55
|
||||
|
||||
# Множитель урона обычных мобов в normal 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_DAMAGE=1.10
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_DAMAGE=2.00
|
||||
|
||||
# Множитель HP боссов в normal 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_HEALTH=1.40
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_HEALTH=2.00
|
||||
|
||||
# Множитель HP обычных мобов в heroic 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_HEALTH=1.25
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_HEALTH=1.65
|
||||
|
||||
# Множитель урона обычных мобов в heroic 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_DAMAGE=1.05
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_DAMAGE=2.20
|
||||
|
||||
# Множитель HP боссов в heroic 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_HEALTH=1.35
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_HEALTH=2.20
|
||||
|
||||
# Кривая скейла рейдов: чем ниже значение, тем быстрее растет сложность с игроками.
|
||||
ACORE_AUTOBALANCE_INFLECTION_POINT_RAID=0.75
|
||||
@@ -265,10 +271,10 @@ ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_HEROIC=0.80
|
||||
ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_HEROIC_BOSS_MODIFIER=1.45
|
||||
|
||||
# Множитель урона боссов в обычных 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_DAMAGE=1.00
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_DAMAGE=2.50
|
||||
|
||||
# Множитель урона боссов в heroic 5ppl.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_DAMAGE=0.90
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_DAMAGE=2.80
|
||||
|
||||
# Общий множитель статов рейда normal.
|
||||
ACORE_AUTOBALANCE_STAT_MODIFIER_RAID_GLOBAL=0.85
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -48,6 +48,9 @@ services:
|
||||
- ./modules:/azerothcore/modules:ro
|
||||
- ./lua_scripts:/azerothcore/lua_scripts
|
||||
- ./client_patch/enUS/DBFilesClient/LFGDungeons.dbc:/azerothcore/env/dist/data/dbc/LFGDungeons.dbc:ro
|
||||
- ./client_patch/enUS/DBFilesClient/BarberShopStyle.dbc:/azerothcore/env/dist/data/dbc/BarberShopStyle.dbc:ro
|
||||
- ./client_patch/enUS/DBFilesClient/CreatureDisplayInfoExtra.dbc:/azerothcore/env/dist/data/dbc/CreatureDisplayInfoExtra.dbc:ro
|
||||
- ./client_patch/enUS/DBFilesClient/SpellVisualKitModelAttach.dbc:/azerothcore/env/dist/data/dbc/SpellVisualKitModelAttach.dbc:ro
|
||||
|
||||
volumes:
|
||||
playerbots-ai-cache:
|
||||
|
||||
+1012
-1775
File diff suppressed because it is too large
Load Diff
Generated
+26646
-10438
File diff suppressed because it is too large
Load Diff
+21
-1
@@ -156,7 +156,7 @@ import_mythicplus_sql() {
|
||||
log "repairing MythicPlus world bootstrap entries"
|
||||
mysql_exec "acore_world" "
|
||||
DELETE FROM creature WHERE id = 900001;
|
||||
DELETE FROM gameobject WHERE id = 900000;
|
||||
DELETE FROM gameobject WHERE id1 = 900000;
|
||||
DELETE FROM creature_template_locale WHERE entry = 900001;
|
||||
DELETE FROM item_template_locale WHERE ID = 900100;
|
||||
DELETE FROM creature_template_model WHERE CreatureID = 900001;
|
||||
@@ -279,6 +279,16 @@ import_playerbots_ru_sql() {
|
||||
import_sql_file "acore_characters" "$names_sql_file"
|
||||
}
|
||||
|
||||
import_transmog_sql() {
|
||||
log "Started importing Transmogrification SQL files"
|
||||
|
||||
local account_transmog_sql="$ROOT_DIR/sql/Transmogrification/auth.sql"
|
||||
local character_transmog_sql="$ROOT_DIR/sql/Transmogrification/char.sql"
|
||||
|
||||
maybe_import_table "acore_auth" "account_transmog" "$account_transmog_sql"
|
||||
maybe_import_table "acore_characters" "character_transmog" "$character_transmog_sql"
|
||||
}
|
||||
|
||||
configure_server_motd() {
|
||||
log "configuring MoonWell login message"
|
||||
mysql_exec "acore_auth" "
|
||||
@@ -331,6 +341,14 @@ import_encounter_journal_sql() {
|
||||
fi
|
||||
}
|
||||
|
||||
import_premium_sql() {
|
||||
log "Started importing Premium SQL files"
|
||||
|
||||
local world_premium_sql="$ROOT_DIR/sql/Premium/world.sql"
|
||||
|
||||
import_sql_file "acore_world" "$world_premium_sql"
|
||||
}
|
||||
|
||||
if (($# > 0)); then
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
@@ -362,6 +380,8 @@ import_aoe_loot_sql
|
||||
import_playerbots_ru_sql
|
||||
import_encounter_journal_sql
|
||||
import_store_sql
|
||||
import_transmog_sql
|
||||
import_premium_sql
|
||||
configure_server_motd
|
||||
|
||||
log "custom SQL bootstrap completed"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
return {}
|
||||
@@ -0,0 +1,172 @@
|
||||
local PLAYER_EVENT_ON_LOGIN = 3
|
||||
local PLAYER_EVENT_ON_SPELL_CAST = 5
|
||||
local PLAYER_EVENT_ON_LOGOUT = 4
|
||||
local PLAYER_EVENT_ON_COMMAND = 42
|
||||
|
||||
local PREMIUM_FLAG_INDEX = 100
|
||||
|
||||
local ACCOUNT_FLAG_RECURRING_BILLING = 8192
|
||||
|
||||
local SUMMON_SQUIRE_SPELL_ID = 80000
|
||||
|
||||
local SQUIRE_CREATURE_TEMPLATE_ID = 9000001
|
||||
|
||||
local NPC_TEXT_ID = 10000000
|
||||
|
||||
---todo extract to utils
|
||||
---@param inputstr string
|
||||
---@param separator string
|
||||
---@return table
|
||||
local function SplitString(inputstr, separator)
|
||||
if separator == nil then
|
||||
separator = "%s"
|
||||
end
|
||||
local t = {}
|
||||
for str in string.gmatch(inputstr, "([^" .. separator .. "]+)") do
|
||||
table.insert(t, str)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
---@return boolean
|
||||
local function IsPremium(player)
|
||||
return player:HasFlag(PREMIUM_FLAG_INDEX, 1)
|
||||
end
|
||||
|
||||
local function OnPremiumPlayer(player)
|
||||
if not IsPremium(player) then
|
||||
return
|
||||
end
|
||||
|
||||
player:SendAreaTriggerMessage(
|
||||
'На вашем аккаунте активна подписка Premium! Благодарим за поддержку проекта MoonWell.')
|
||||
|
||||
player:LearnSpell(SUMMON_SQUIRE_SPELL_ID)
|
||||
player:SendBroadcastMessage("Милостью Элуны вам была выдана способность |cff71d5ff|Hspell:" ..
|
||||
SUMMON_SQUIRE_SPELL_ID .. "|h[" .. "Призыв Оруженосца]h|")
|
||||
end
|
||||
|
||||
local function RefreshPremiumStatus(player)
|
||||
local query = AuthDBQuery("SELECT flags FROM account WHERE id = " .. player:GetAccountId())
|
||||
|
||||
if query then
|
||||
local function HasFlag(mask, flag)
|
||||
return bit_and(mask, flag) == flag
|
||||
end
|
||||
|
||||
|
||||
local flags = query:GetUInt32(0)
|
||||
|
||||
if HasFlag(flags, ACCOUNT_FLAG_RECURRING_BILLING) then
|
||||
player:SetFlag(PREMIUM_FLAG_INDEX, 1)
|
||||
|
||||
OnPremiumPlayer(player)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function ApplyPremium(player)
|
||||
AuthDBExecute(
|
||||
string.format(
|
||||
"UPDATE account SET flags = flags | %d WHERE id = %d",
|
||||
ACCOUNT_FLAG_RECURRING_BILLING,
|
||||
player:GetAccountId()
|
||||
)
|
||||
)
|
||||
|
||||
RefreshPremiumStatus(player)
|
||||
end
|
||||
|
||||
local function OnLogin(event, player)
|
||||
RefreshPremiumStatus(player)
|
||||
end
|
||||
|
||||
--- @param event any
|
||||
--- @param player any
|
||||
--- @param command string
|
||||
--- @param chatHandler any
|
||||
local function OnCommand(event, player, command, chatHandler)
|
||||
---Console is not supported yet
|
||||
if not player then return end
|
||||
|
||||
local parts = SplitString(command:lower(), ' ')
|
||||
|
||||
if parts[1] ~= 'premium' then return end
|
||||
|
||||
if parts[2] == 'add' then
|
||||
ApplyPremium(player:GetSelection())
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function OnSummonSquireCast(player)
|
||||
local x, y, z, o = player:GetLocation()
|
||||
|
||||
local squire = player:SpawnCreature(SQUIRE_CREATURE_TEMPLATE_ID, x + 1, y + 1, z, o, 1, 30000)
|
||||
|
||||
if squire then
|
||||
squire:SetFaction(player:GetFaction())
|
||||
end
|
||||
end
|
||||
|
||||
local function OnSpellCast(event, player, spell, skipCheck)
|
||||
local spellId = spell:GetEntry()
|
||||
|
||||
if spellId == SUMMON_SQUIRE_SPELL_ID then
|
||||
OnSummonSquireCast(player)
|
||||
end
|
||||
end
|
||||
|
||||
local function OnGossipHello(event, player, creature)
|
||||
player:GossipClearMenu()
|
||||
|
||||
player:GossipMenuAddItem(4, "Открыть почтовый ящик", 900001, 1)
|
||||
player:GossipMenuAddItem(1, "Открыть банк", 900001, 2)
|
||||
player:GossipMenuAddItem(6, "Открыть аукцион", 900001, 3)
|
||||
player:GossipMenuAddItem(4, "Отремонтировать снаряжение", 900001, 4)
|
||||
|
||||
player:GossipSendMenu(NPC_TEXT_ID, creature)
|
||||
end
|
||||
|
||||
local function OnGossipSelect(event, player, creature, sender, intid, code)
|
||||
if sender == 900001 then
|
||||
if intid == 1 then
|
||||
player:SendShowMailBox(creature:GetGUID())
|
||||
player:GossipComplete()
|
||||
end
|
||||
|
||||
if intid == 2 then
|
||||
player:SendShowBank(creature)
|
||||
player:GossipComplete()
|
||||
end
|
||||
|
||||
if intid == 3 then
|
||||
player:SendAuctionMenu(creature)
|
||||
player:GossipComplete()
|
||||
end
|
||||
|
||||
if intid == 4 then
|
||||
player:DurabilityRepairAll()
|
||||
player:PlayDirectSound(1116)
|
||||
player:GossipComplete()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function OnLogout(event, player)
|
||||
player:RemoveSpell(SUMMON_SQUIRE_SPELL_ID)
|
||||
end
|
||||
|
||||
RegisterCreatureGossipEvent(SQUIRE_CREATURE_TEMPLATE_ID, 1, OnGossipHello)
|
||||
RegisterCreatureGossipEvent(SQUIRE_CREATURE_TEMPLATE_ID, 2, OnGossipSelect)
|
||||
RegisterPlayerEvent(PLAYER_EVENT_ON_LOGIN, OnLogin)
|
||||
RegisterPlayerEvent(PLAYER_EVENT_ON_LOGOUT, OnLogout)
|
||||
RegisterPlayerEvent(PLAYER_EVENT_ON_COMMAND, OnCommand)
|
||||
RegisterPlayerEvent(PLAYER_EVENT_ON_SPELL_CAST, OnSpellCast)
|
||||
|
||||
@@ -0,0 +1,838 @@
|
||||
-- ╔════════════════════════════════════════════════════════════════════════╗
|
||||
-- ║ Transmog System Eluna Script by DanielTheDeveloper ║
|
||||
-- ╚════════════════════════════════════════════════════════════════════════╝
|
||||
--
|
||||
-- ╔══════════════════════════╗
|
||||
-- ╔══════════════════════║ Transmog System Settings ║══════════════════════╗
|
||||
-- ║ ╚══════════════════════════╝ ║
|
||||
-- ║ Automatically adds transmog appearances to the players account-wide ║
|
||||
-- ║ transmog collection when they equip an item for the first time. ║
|
||||
-- ║ ║
|
||||
-- ║ It is recommended to leave this option enabled. ║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
local ADD_NEWLY_EQUIPPED_ITEMS_TO_THE_TRANSMOG_LIST = true --║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
-- ║ ║
|
||||
-- ║ Automatically adds transmog appearances to the players account-wide ║
|
||||
-- ║ transmog collection when they loot an item for the first time. ║
|
||||
-- ║ ║
|
||||
-- ║ It is recommended to leave this option disabled as it creates the ║
|
||||
-- ║ potential for a more healthy transmog economy to exist inside the ║
|
||||
-- ║ auction house. ║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
local ADD_NEWLY_LOOTED_ITEMS_TO_THE_TRANSMOG_LIST = false --║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
-- ║ ║
|
||||
-- ║ Automatically adds all applicable quest reward items as transmog ║
|
||||
-- ║ appearances to the players account-wide transmog collection when ║
|
||||
-- ║ completing a quest, regardless of which quest reward the player ║
|
||||
-- ║ actually decided to select. ║
|
||||
-- ║ ║
|
||||
-- ║ It is recommended to leave this option enabled as it eliminates the ║
|
||||
-- ║ dilemma of deciding between a potential transmog appearance or gear ║
|
||||
-- ║ that is useful for the character. ║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
local ADD_QUEST_REWARD_ITEMS_TO_THE_TRANSMOG_LIST = true --║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
-- ║ ║
|
||||
-- ║ Restricts armor transmog appearances to items made up of the same ║
|
||||
-- ║ material. As an example, with this option enabled, cloth chest pieces ║
|
||||
-- ║ can only be transmogrified to appear as other cloth chest pieces. ║
|
||||
-- ║ When this option is disabled, cloth chest pieces can be ║
|
||||
-- ║ transmogrified to appear as a cloth, leather, mail, or plate chest ║
|
||||
-- ║ piece. ║
|
||||
-- ║ ║
|
||||
-- ║ It is recommended to leave this option enabled as it leaves the ║
|
||||
-- ║ class fantasy intact. ║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
local RESTRICT_ARMOR_TRANSMOG_TO_SIMILAR_MATERIALS = true --║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
-- ║ ║
|
||||
-- ║ Restricts weapon transmog appearances to the same weapon. As an ║
|
||||
-- ║ example, with this option enabled, two-handed swords can only be ║
|
||||
-- ║ transmogrified to appear as other two-handed swords. When this option ║
|
||||
-- ║ is disabled, two-handed swords can be transmogrified to appear as a ║
|
||||
-- ║ one-handed sword, staff, polearm, fishing pole, etc. ║
|
||||
-- ║ ║
|
||||
-- ║ It is recommended to leave this option enabled as it leaves the ║
|
||||
-- ║ class fantasy intact. ║
|
||||
-- ╟────────────────────────────────────────────────────────────────────────╢
|
||||
local RESTRICT_WEAPON_TRANSMOG_TO_SIMILAR_WEAPONS = true --║
|
||||
-- ╚════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
local AIO = AIO or require("AIO")
|
||||
local TransmogrificationHandler = AIO.AddHandlers("TransmogrificationServer", {})
|
||||
|
||||
local SLOTS = 6
|
||||
local CALC = 281
|
||||
local PLAYER_VISIBLE_ITEM_1_ENTRYID = 283 -- Head
|
||||
local PLAYER_VISIBLE_ITEM_3_ENTRYID = 287 -- Shoulder
|
||||
local PLAYER_VISIBLE_ITEM_4_ENTRYID = 289 -- Shirt
|
||||
local PLAYER_VISIBLE_ITEM_5_ENTRYID = 291 -- Chest
|
||||
local PLAYER_VISIBLE_ITEM_6_ENTRYID = 293 -- Waist
|
||||
local PLAYER_VISIBLE_ITEM_7_ENTRYID = 295 -- Legs
|
||||
local PLAYER_VISIBLE_ITEM_8_ENTRYID = 297 -- Feet
|
||||
local PLAYER_VISIBLE_ITEM_9_ENTRYID = 299 -- Wrist
|
||||
local PLAYER_VISIBLE_ITEM_10_ENTRYID = 301 -- Hands
|
||||
local PLAYER_VISIBLE_ITEM_15_ENTRYID = 311 -- Back
|
||||
local PLAYER_VISIBLE_ITEM_16_ENTRYID = 313 -- Main
|
||||
local PLAYER_VISIBLE_ITEM_17_ENTRYID = 315 -- Off
|
||||
local PLAYER_VISIBLE_ITEM_18_ENTRYID = 317 -- Ranged
|
||||
local PLAYER_VISIBLE_ITEM_19_ENTRYID = 319 -- Tabard
|
||||
local UNUSABLE_INVENTORY_TYPES = {[2] = true, [11] = true, [12] = true, [18] = true, [24] = true, [27] = true, [28] = true}
|
||||
|
||||
-- TODO: Add further language support.
|
||||
local localeMessages = {
|
||||
LOOT_ITEM_LOCALE = {
|
||||
[0] = " has been added to your appearance collection.", -- enUS/enGB
|
||||
[3] = " wurde deiner Transmog-Sammlung hinzugefügt.", -- deDE
|
||||
}
|
||||
}
|
||||
|
||||
local function GetLocalizedMessage(messageID, locale, ...)
|
||||
local message = localeMessages[messageID][locale] or localeMessages[messageID][0]
|
||||
if select("#", ...) > 0 then
|
||||
return string.format(message, ...)
|
||||
end
|
||||
return message
|
||||
end
|
||||
|
||||
function Transmog_CalculateSlot(slot)
|
||||
if (slot == 0) then
|
||||
slot = 1
|
||||
elseif (slot >= 2) then
|
||||
slot = slot + 1
|
||||
end
|
||||
return CALC + (slot * 2);
|
||||
end
|
||||
|
||||
function Transmog_CalculateSlotReverse(slot)
|
||||
local reverseSlot = (slot - CALC) / 2
|
||||
if (reverseSlot == 1) then
|
||||
return 0;
|
||||
end
|
||||
return reverseSlot;
|
||||
end
|
||||
|
||||
function Transmog_OnCharacterCreate(event, player)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_1_ENTRYID .. "', NULL, '');") -- Head
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_3_ENTRYID .. "', NULL, '');") -- Shoulder
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_4_ENTRYID .. "', NULL, '');") -- Shirt
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_5_ENTRYID .. "', NULL, '');") -- Chest
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_6_ENTRYID .. "', NULL, '');") -- Waist
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_7_ENTRYID .. "', NULL, '');") -- Legs
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_8_ENTRYID .. "', NULL, '');") -- Feet
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_9_ENTRYID .. "', NULL, '');") -- Wrist
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_10_ENTRYID .. "', NULL, '');") -- Hands
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_15_ENTRYID .. "', NULL, '');") -- Back
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_16_ENTRYID .. "', NULL, '');") -- Main
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_17_ENTRYID .. "', NULL, '');") -- Off
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_18_ENTRYID .. "', NULL, '');") -- Ranged
|
||||
CharDBQuery("INSERT IGNORE INTO `character_transmog` (`player_guid`, `slot`, `item`, `real_item`) VALUES (" .. playerGUID .. ", '" .. PLAYER_VISIBLE_ITEM_19_ENTRYID .. "', NULL, '');") -- Tabard
|
||||
end
|
||||
|
||||
function Transmog_OnCharacterDelete(event, guid)
|
||||
CharDBQuery("DELETE FROM character_transmog WHERE player_guid = " .. guid .. "")
|
||||
end
|
||||
|
||||
function Transmog_OnCharacterLogin(event, player)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
local playerExistsQuery = CharDBQuery("SELECT COUNT(*) FROM character_transmog WHERE player_guid = " .. playerGUID .. ";")
|
||||
local playerExists = playerExistsQuery:GetUInt32(0) > 0
|
||||
if not playerExists then
|
||||
Transmog_OnCharacterCreate(event, player)
|
||||
end
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.LootItemLocale(player, item, count, locale)
|
||||
local accountGUID = player:GetAccountId()
|
||||
local itemID
|
||||
local itemTemplate
|
||||
|
||||
if type(item) == "number" then
|
||||
itemID = item
|
||||
itemTemplate = GetItemTemplate(itemID)
|
||||
else
|
||||
itemTemplate = item:GetItemTemplate()
|
||||
itemID = itemTemplate:GetItemId()
|
||||
end
|
||||
|
||||
local inventoryType = itemTemplate:GetInventoryType()
|
||||
local inventorySubType = itemTemplate:GetSubClass()
|
||||
local class = itemTemplate:GetClass()
|
||||
|
||||
if (class == 2 or class == 4) and not UNUSABLE_INVENTORY_TYPES[inventoryType] then
|
||||
local countQuery = AuthDBQuery("SELECT COUNT(*) FROM account_transmog WHERE account_id = " .. accountGUID .. " AND unlocked_item_id = " .. itemID .. ";")
|
||||
local count = countQuery:GetUInt32(0)
|
||||
local isNewTransmog = (count == 0)
|
||||
|
||||
local displayID = itemTemplate:GetDisplayId()
|
||||
|
||||
local displayExistsQuery = AuthDBQuery("SELECT COUNT(*) FROM account_transmog WHERE account_id = " .. accountGUID .. " AND display_id = " .. displayID .. ";")
|
||||
local displayExists = displayExistsQuery:GetUInt32(0) > 0
|
||||
|
||||
if isNewTransmog and not displayExists then
|
||||
local itemName = itemTemplate:GetName()
|
||||
local locItemName = itemTemplate:GetName(locale)
|
||||
local itemQuality = itemTemplate:GetQuality()
|
||||
|
||||
itemName = itemName:gsub("'", "''")
|
||||
AuthDBQuery("INSERT IGNORE INTO `account_transmog` (`account_id`, `unlocked_item_id`, `inventory_type`, `inventory_subtype`,`display_id`, `item_name`) VALUES (" .. accountGUID .. ", " .. itemID .. ", " .. inventoryType .. ", " .. inventorySubType .. ", " .. displayID .. ", '" .. itemName .. "');")
|
||||
|
||||
if locItemName == nil then
|
||||
locItemName = itemTemplate:GetName(0)
|
||||
end
|
||||
|
||||
local qualityColors = {
|
||||
[0] = "|cff9d9d9d", -- Poor
|
||||
[1] = "|cffffffff", -- Common
|
||||
[2] = "|cff1eff00", -- Uncommon
|
||||
[3] = "|cff0070dd", -- Rare
|
||||
[4] = "|cffa335ee", -- Epic
|
||||
[5] = "|cffff8000", -- Legendary
|
||||
[6] = "|cffe6cc80" -- Heirloom
|
||||
}
|
||||
|
||||
local colorCode = qualityColors[itemQuality] or "|cffffffff" -- Default to white if quality not found
|
||||
|
||||
local itemLink = "|Hitem:" .. itemID .. ":0:0:0:0:0:0:0:0|h" .. colorCode .. "[" .. locItemName .. "]|r|h|r"
|
||||
player:SendBroadcastMessage(itemLink .. GetLocalizedMessage("LOOT_ITEM_LOCALE", locale))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GetDisplaySlotForEquipmentSlot(equipSlot)
|
||||
local slotMapping = {
|
||||
[0] = PLAYER_VISIBLE_ITEM_1_ENTRYID, -- Head
|
||||
[2] = PLAYER_VISIBLE_ITEM_3_ENTRYID, -- Shoulders
|
||||
[3] = PLAYER_VISIBLE_ITEM_4_ENTRYID, -- Shirt
|
||||
[4] = PLAYER_VISIBLE_ITEM_5_ENTRYID, -- Chest
|
||||
[5] = PLAYER_VISIBLE_ITEM_6_ENTRYID, -- Waist
|
||||
[6] = PLAYER_VISIBLE_ITEM_7_ENTRYID, -- Legs
|
||||
[7] = PLAYER_VISIBLE_ITEM_8_ENTRYID, -- Feet
|
||||
[8] = PLAYER_VISIBLE_ITEM_9_ENTRYID, -- Wrists
|
||||
[9] = PLAYER_VISIBLE_ITEM_10_ENTRYID, -- Hands
|
||||
[14] = PLAYER_VISIBLE_ITEM_15_ENTRYID, -- Back
|
||||
[15] = PLAYER_VISIBLE_ITEM_16_ENTRYID, -- Main Hand
|
||||
[16] = PLAYER_VISIBLE_ITEM_17_ENTRYID, -- Off Hand
|
||||
[17] = PLAYER_VISIBLE_ITEM_18_ENTRYID, -- Ranged
|
||||
[18] = PLAYER_VISIBLE_ITEM_19_ENTRYID -- Tabard
|
||||
}
|
||||
|
||||
return slotMapping[equipSlot]
|
||||
end
|
||||
|
||||
function Transmog_OnEquipItem(event, player, item, bag, slot)
|
||||
local itemID = item:GetItemTemplate():GetItemId()
|
||||
local locale = player:GetDbLocaleIndex()
|
||||
|
||||
if ADD_NEWLY_EQUIPPED_ITEMS_TO_THE_TRANSMOG_LIST then
|
||||
TransmogrificationHandler.LootItemLocale(player, itemID, 1, locale)
|
||||
end
|
||||
|
||||
local class = item:GetItemTemplate():GetClass()
|
||||
local inventoryType = item:GetItemTemplate():GetInventoryType()
|
||||
|
||||
if (class == 2 or class == 4) and not UNUSABLE_INVENTORY_TYPES[inventoryType] then
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
local displaySlot = GetDisplaySlotForEquipmentSlot(slot)
|
||||
|
||||
if displaySlot then
|
||||
CharDBQuery("UPDATE character_transmog SET real_item = " .. itemID .. " WHERE player_guid = " .. playerGUID .. " AND slot = " .. displaySlot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Transmog_OnLootItem(event, player, item, count)
|
||||
local locale = player:GetDbLocaleIndex()
|
||||
TransmogrificationHandler.LootItemLocale(player, item, 1, locale)
|
||||
end
|
||||
|
||||
function Transmog_OnQuestComplete(event, player, quest)
|
||||
local questID = quest:GetId()
|
||||
local locale = player:GetDbLocaleIndex()
|
||||
|
||||
local questRewardsQuery = WorldDBQuery("SELECT RewardItem1, RewardItem2, RewardItem3, RewardItem4, RewardChoiceItemID1, RewardChoiceItemID2, RewardChoiceItemID3, RewardChoiceItemID4, RewardChoiceItemID5, RewardChoiceItemID6 FROM quest_template WHERE ID = " .. questID .. ";")
|
||||
|
||||
if not questRewardsQuery then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 0, 9 do
|
||||
local itemID = questRewardsQuery:GetUInt32(i)
|
||||
if itemID and itemID > 0 then
|
||||
TransmogrificationHandler.LootItemLocale(player, itemID, 1, locale)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GetEquipmentSlot(displaySlot)
|
||||
-- Map from display/visual slots to actual equipment slots
|
||||
local slotMapping = {
|
||||
[PLAYER_VISIBLE_ITEM_1_ENTRYID] = 0, -- Head (0 in equipment slot system)
|
||||
[PLAYER_VISIBLE_ITEM_3_ENTRYID] = 2, -- Shoulders
|
||||
[PLAYER_VISIBLE_ITEM_4_ENTRYID] = 3, -- Shirt
|
||||
[PLAYER_VISIBLE_ITEM_5_ENTRYID] = 4, -- Chest
|
||||
[PLAYER_VISIBLE_ITEM_6_ENTRYID] = 5, -- Waist
|
||||
[PLAYER_VISIBLE_ITEM_7_ENTRYID] = 6, -- Legs
|
||||
[PLAYER_VISIBLE_ITEM_8_ENTRYID] = 7, -- Feet
|
||||
[PLAYER_VISIBLE_ITEM_9_ENTRYID] = 8, -- Wrists
|
||||
[PLAYER_VISIBLE_ITEM_10_ENTRYID] = 9, -- Hands
|
||||
[PLAYER_VISIBLE_ITEM_15_ENTRYID] = 14, -- Back/Cloak
|
||||
[PLAYER_VISIBLE_ITEM_16_ENTRYID] = 15, -- Main Hand
|
||||
[PLAYER_VISIBLE_ITEM_17_ENTRYID] = 16, -- Off Hand
|
||||
[PLAYER_VISIBLE_ITEM_18_ENTRYID] = 17, -- Ranged
|
||||
[PLAYER_VISIBLE_ITEM_19_ENTRYID] = 18, -- Tabard
|
||||
}
|
||||
|
||||
return slotMapping[displaySlot] or Transmog_CalculateSlotReverse(displaySlot)
|
||||
end
|
||||
|
||||
-- TODO: add lua/c++ function for unequip!!
|
||||
function TransmogrificationHandler.OnUnequipItem(player)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
-- Check all slots to see if any items were unequipped
|
||||
local slots = {
|
||||
PLAYER_VISIBLE_ITEM_1_ENTRYID, -- Head
|
||||
PLAYER_VISIBLE_ITEM_3_ENTRYID, -- Shoulder
|
||||
PLAYER_VISIBLE_ITEM_4_ENTRYID, -- Shirt
|
||||
PLAYER_VISIBLE_ITEM_5_ENTRYID, -- Chest
|
||||
PLAYER_VISIBLE_ITEM_6_ENTRYID, -- Waist
|
||||
PLAYER_VISIBLE_ITEM_7_ENTRYID, -- Legs
|
||||
PLAYER_VISIBLE_ITEM_8_ENTRYID, -- Feet
|
||||
PLAYER_VISIBLE_ITEM_9_ENTRYID, -- Wrist
|
||||
PLAYER_VISIBLE_ITEM_10_ENTRYID, -- Hands
|
||||
PLAYER_VISIBLE_ITEM_15_ENTRYID, -- Back
|
||||
PLAYER_VISIBLE_ITEM_16_ENTRYID, -- Main
|
||||
PLAYER_VISIBLE_ITEM_17_ENTRYID, -- Off
|
||||
PLAYER_VISIBLE_ITEM_18_ENTRYID, -- Ranged
|
||||
PLAYER_VISIBLE_ITEM_19_ENTRYID -- Tabard
|
||||
}
|
||||
|
||||
for _, slot in ipairs(slots) do
|
||||
-- Get the corresponding equipment slot
|
||||
local equipmentSlot = GetEquipmentSlot(slot)
|
||||
|
||||
-- Check if this slot has an item equipped
|
||||
local currentItem = player:GetEquippedItemBySlot(equipmentSlot)
|
||||
|
||||
-- If the slot is empty but we have a transmog value, we need to clear it
|
||||
if not currentItem then
|
||||
local transmogQuery = CharDBQuery("SELECT item FROM character_transmog WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
|
||||
if transmogQuery and transmogQuery:GetUInt32(0) and transmogQuery:GetUInt32(0) > 0 then
|
||||
-- Clear the transmog by setting both item and real_item to NULL
|
||||
CharDBQuery("UPDATE character_transmog SET item = NULL, real_item = NULL WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
player:SetUInt32Value(tonumber(slot), 0)
|
||||
|
||||
-- Inform the client to update the display for this slot
|
||||
AIO.Handle(player, "TransmogrificationServer", "ClearSlotTransmogrification", slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Transmog_Load(player)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
local transmogs = CharDBQuery("SELECT item, slot FROM character_transmog WHERE player_guid = "..playerGUID..";")
|
||||
if (transmogs == nil) then
|
||||
return;
|
||||
end
|
||||
|
||||
for i = 1, transmogs:GetRowCount(), 1 do
|
||||
local currentRow = transmogs:GetRow()
|
||||
local slot = currentRow["slot"]
|
||||
local item = currentRow["item"]
|
||||
if (item ~= nil and item ~= '') then
|
||||
player:SetUInt32Value(tonumber(slot), item)
|
||||
end
|
||||
transmogs:NextRow()
|
||||
end
|
||||
end
|
||||
|
||||
function Transmog_OnLogin(event, player)
|
||||
-- Apply transmog on login
|
||||
-- Transmog_Load(player)
|
||||
--local item = player:GetEquippedItemBySlot(4)
|
||||
--print(item:GetName())
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.LoadPlayer(player)
|
||||
Transmog_Load(player)
|
||||
player:SetUInt32Value(147, 1) -- use unit padding
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.EquipTransmogItem(player, item, slot)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
if item == nil and item ~= 0 then
|
||||
local oldItem = CharDBQuery("SELECT real_item FROM character_transmog WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
local oldItemID = oldItem:GetUInt32(0)
|
||||
if oldItemID == nil or oldItemID == 0 then
|
||||
CharDBQuery("INSERT INTO character_transmog (`player_guid`, `slot`, `item`) VALUES ("..playerGUID..", '"..slot.."', NULL) ON DUPLICATE KEY UPDATE item = VALUES(item);")
|
||||
player:SetUInt32Value(tonumber(slot), 0)
|
||||
return
|
||||
end
|
||||
|
||||
CharDBQuery("INSERT INTO character_transmog (`player_guid`, `slot`, `item`, `real_item`) VALUES ("..playerGUID..", '"..slot.."', NULL, "..oldItemID..") ON DUPLICATE KEY UPDATE item = VALUES(item), real_item = VALUES(real_item);")
|
||||
player:SetUInt32Value(tonumber(slot), oldItemID)
|
||||
return
|
||||
end
|
||||
|
||||
local oldItem = CharDBQuery("SELECT real_item FROM character_transmog WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
local oldItemID = oldItem:GetUInt32(0)
|
||||
if oldItemID == nil or oldItemID == 0 then
|
||||
CharDBQuery("INSERT INTO character_transmog (`player_guid`, `slot`, `item`) VALUES ("..playerGUID..", '"..slot.."', "..item..") ON DUPLICATE KEY UPDATE item = VALUES(item);")
|
||||
else
|
||||
CharDBQuery("INSERT INTO character_transmog (`player_guid`, `slot`, `item`, `real_item`) VALUES ("..playerGUID..", '"..slot.."', "..item..", "..oldItemID..") ON DUPLICATE KEY UPDATE item = VALUES(item), real_item = VALUES(real_item);")
|
||||
end
|
||||
player:SetUInt32Value(tonumber(slot), item)
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.EquipAllTransmogItems(player, transmogPreview)
|
||||
if (transmogPreview == {}) then
|
||||
return;
|
||||
end
|
||||
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
for slot, item in ipairs(transmogPreview) do
|
||||
player:SetUInt32Value(tonumber(slot), item)
|
||||
CharDBQuery("INSERT INTO character_transmog (`player_guid`, `slot`, `item`) VALUES ("..playerGUID..", '"..slot.."', "..item..") ON DUPLICATE KEY UPDATE item = VALUES(item);")
|
||||
end
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.UnequipTransmogItem(player, slot)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
-- Get the corresponding equipment slot using our mapping function
|
||||
local equipmentSlot = GetEquipmentSlot(slot)
|
||||
|
||||
-- Check if there's an actual item equipped in this slot
|
||||
local currentItem = player:GetEquippedItemBySlot(equipmentSlot)
|
||||
|
||||
-- If no item is currently equipped, we should set the visual to 0
|
||||
if not currentItem then
|
||||
CharDBQuery("UPDATE character_transmog SET item = NULL, real_item = NULL WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
player:SetUInt32Value(tonumber(slot), 0)
|
||||
return
|
||||
end
|
||||
|
||||
-- Otherwise, handle normally but ensure we're setting to the real item or 0
|
||||
local oldItem = CharDBQuery("SELECT real_item FROM character_transmog WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
|
||||
-- If no record or null real_item, set to the actual item's appearance
|
||||
if not oldItem or not oldItem:GetUInt32(0) or oldItem:GetUInt32(0) == 0 then
|
||||
-- Here we set item to NULL (not 0) to indicate no transmog is applied
|
||||
CharDBQuery("UPDATE character_transmog SET item = NULL WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
|
||||
-- Get the current equipped item's ID to display
|
||||
local realItemID = currentItem:GetItemTemplate():GetItemId()
|
||||
player:SetUInt32Value(tonumber(slot), realItemID)
|
||||
return
|
||||
end
|
||||
|
||||
-- If we have a real_item value, restore that appearance
|
||||
local oldItemID = oldItem:GetUInt32(0)
|
||||
CharDBQuery("UPDATE character_transmog SET item = NULL WHERE player_guid = "..playerGUID.." AND slot = "..slot..";")
|
||||
player:SetUInt32Value(tonumber(slot), oldItemID)
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.displayTransmog(player, spellid)
|
||||
AIO.Handle(player, "TransmogrificationServer", "TransmogrificationFrame")
|
||||
return false
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.Print(player, ...)
|
||||
print(...)
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.SetTransmogItemIDs(player)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
local transmogs = CharDBQuery('SELECT item, real_item, slot FROM character_transmog WHERE player_guid = '..playerGUID..';') -- AND slot NOT IN ("313", "315", "317")
|
||||
if (transmogs == nil) then
|
||||
return;
|
||||
end
|
||||
|
||||
for i = 1, transmogs:GetRowCount(), 1 do
|
||||
local currentRow = transmogs:GetRow()
|
||||
local item = currentRow["item"]
|
||||
local slot = currentRow["slot"]
|
||||
local real_item = currentRow["real_item"]
|
||||
local validSlotItem = player:GetUInt32Value(tonumber(slot))
|
||||
if (validSlotItem == 0) then
|
||||
CharDBQuery("INSERT INTO character_transmog (`player_guid`, `slot`, `item`, `real_item`) VALUES ("..playerGUID..", '"..slot.."', 0, "..real_item..") ON DUPLICATE KEY UPDATE item = VALUES(item), real_item = VALUES(real_item);")
|
||||
end
|
||||
if (not item or item == 0 and real_item ~= nil and real_item ~= 0 and (validSlotItem ~= 0 or not validSlotItem)) then
|
||||
AIO.Handle(player, "TransmogrificationServer", "SetTransmogItemIDClient", slot, 0, real_item)
|
||||
else
|
||||
AIO.Handle(player, "TransmogrificationServer", "SetTransmogItemIDClient", slot, item, real_item)
|
||||
end
|
||||
transmogs:NextRow()
|
||||
end
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.SetCurrentSlotItemIDs(player, slot, page)
|
||||
local accountGUID = player:GetAccountId()
|
||||
|
||||
-- Define inventory type mapping
|
||||
local inventoryTypesMapping = {
|
||||
[PLAYER_VISIBLE_ITEM_1_ENTRYID] = "= 1",
|
||||
[PLAYER_VISIBLE_ITEM_3_ENTRYID] = "= 3",
|
||||
[PLAYER_VISIBLE_ITEM_4_ENTRYID] = "= 4",
|
||||
[PLAYER_VISIBLE_ITEM_5_ENTRYID] = "IN (5, 20)",
|
||||
[PLAYER_VISIBLE_ITEM_6_ENTRYID] = "= 6",
|
||||
[PLAYER_VISIBLE_ITEM_7_ENTRYID] = "= 7",
|
||||
[PLAYER_VISIBLE_ITEM_8_ENTRYID] = "= 8",
|
||||
[PLAYER_VISIBLE_ITEM_9_ENTRYID] = "= 9",
|
||||
[PLAYER_VISIBLE_ITEM_10_ENTRYID] = "= 10",
|
||||
[PLAYER_VISIBLE_ITEM_15_ENTRYID] = "= 16",
|
||||
[PLAYER_VISIBLE_ITEM_16_ENTRYID] = "IN (13, 17, 21)",
|
||||
[PLAYER_VISIBLE_ITEM_17_ENTRYID] = "IN (13, 17, 22, 23, 14)",
|
||||
[PLAYER_VISIBLE_ITEM_18_ENTRYID] = "IN (15, 25, 26)",
|
||||
[PLAYER_VISIBLE_ITEM_19_ENTRYID] = "= 19"
|
||||
}
|
||||
|
||||
-- Get the inventory type for the given slot
|
||||
local inventoryTypes = inventoryTypesMapping[slot]
|
||||
if not inventoryTypes then
|
||||
return -- Slot not valid, exit early
|
||||
end
|
||||
|
||||
local equipmentSlot = nil
|
||||
|
||||
if slot == PLAYER_VISIBLE_ITEM_3_ENTRYID then
|
||||
equipmentSlot = 2 -- Shoulder
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_4_ENTRYID then
|
||||
equipmentSlot = 3 -- Shirt
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_5_ENTRYID then
|
||||
equipmentSlot = 4 -- Chest
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_6_ENTRYID then
|
||||
equipmentSlot = 5 -- Waist
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_10_ENTRYID then
|
||||
equipmentSlot = 9 -- Hands
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_15_ENTRYID then
|
||||
equipmentSlot = 14 -- Back
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_16_ENTRYID then
|
||||
equipmentSlot = 15 -- Main
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_17_ENTRYID then
|
||||
equipmentSlot = 16 -- Off
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_18_ENTRYID then
|
||||
equipmentSlot = 17 -- Ranged
|
||||
else
|
||||
equipmentSlot = Transmog_CalculateSlotReverse(slot)
|
||||
end
|
||||
|
||||
local currentItem = player:GetEquippedItemBySlot(equipmentSlot)
|
||||
local equippedItemType = nil
|
||||
local equippedItemSubType = nil
|
||||
|
||||
if currentItem then
|
||||
equippedItemType = currentItem:GetClass()
|
||||
equippedItemSubType = currentItem:GetSubClass()
|
||||
end
|
||||
|
||||
-- Calculate page offset for pagination
|
||||
local pageOffset = (page > 1) and (SLOTS * (page - 1)) or 0
|
||||
|
||||
local queryConditions = "account_id = " .. accountGUID .. " AND inventory_type " .. inventoryTypes
|
||||
|
||||
if equippedItemSubType then
|
||||
if (RESTRICT_ARMOR_TRANSMOG_TO_SIMILAR_MATERIALS and equippedItemType == 4) then
|
||||
if slot == PLAYER_VISIBLE_ITEM_5_ENTRYID then -- Special check for chestpiece/robes.
|
||||
queryConditions = queryConditions .. " AND inventory_subtype = " .. equippedItemSubType
|
||||
else
|
||||
queryConditions = queryConditions .. " AND inventory_subtype = " .. equippedItemSubType
|
||||
end
|
||||
elseif (RESTRICT_WEAPON_TRANSMOG_TO_SIMILAR_WEAPONS and equippedItemType == 2) then
|
||||
queryConditions = queryConditions .. " AND inventory_subtype = " .. equippedItemSubType
|
||||
end
|
||||
end
|
||||
|
||||
-- Query to count matching transmogs
|
||||
local countQuery = string.format(
|
||||
"SELECT COUNT(unlocked_item_id) FROM account_transmog WHERE %s",
|
||||
queryConditions
|
||||
)
|
||||
local countResult = AuthDBQuery(countQuery)
|
||||
if not countResult then
|
||||
AIO.Handle(player, "TransmogrificationServer", "InitTab", {}, page, false)
|
||||
return
|
||||
end
|
||||
|
||||
-- Get the total number of transmogs
|
||||
local totalTransmogs = countResult:GetUInt32(0)
|
||||
local hasMorePages = (totalTransmogs > SLOTS * page)
|
||||
|
||||
-- Query to retrieve transmogs for the current page
|
||||
local transmogQuery = string.format(
|
||||
"SELECT unlocked_item_id FROM account_transmog WHERE %s LIMIT %d OFFSET %d;",
|
||||
queryConditions, SLOTS, pageOffset
|
||||
)
|
||||
local transmogs = AuthDBQuery(transmogQuery)
|
||||
if not transmogs then
|
||||
AIO.Handle(player, "TransmogrificationServer", "InitTab", {}, page, false)
|
||||
return
|
||||
end
|
||||
|
||||
-- Collect the unlocked item IDs
|
||||
local currentSlotItemIDs = {}
|
||||
for i = 1, transmogs:GetRowCount() do
|
||||
local currentRow = transmogs:GetRow()
|
||||
local item = currentRow["unlocked_item_id"]
|
||||
table.insert(currentSlotItemIDs, item)
|
||||
transmogs:NextRow()
|
||||
end
|
||||
|
||||
-- Return the result to the player
|
||||
AIO.Handle(player, "TransmogrificationServer", "InitTab", currentSlotItemIDs, page, hasMorePages)
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.SetSearchCurrentSlotItemIDs(player, slot, page, search)
|
||||
-- Ensure search is not empty or nil
|
||||
if ( search == nil or serach == '' ) then
|
||||
return;
|
||||
end
|
||||
|
||||
-- Escape special characters in search string
|
||||
search = search:gsub("[%'`&\"]", "%%")
|
||||
|
||||
-- Define slot-to-inventory type mapping
|
||||
local inventoryTypesMapping = {
|
||||
[PLAYER_VISIBLE_ITEM_1_ENTRYID] = "= 1",
|
||||
[PLAYER_VISIBLE_ITEM_3_ENTRYID] = "= 3",
|
||||
[PLAYER_VISIBLE_ITEM_4_ENTRYID] = "= 4",
|
||||
[PLAYER_VISIBLE_ITEM_5_ENTRYID] = "IN (5, 20)",
|
||||
[PLAYER_VISIBLE_ITEM_6_ENTRYID] = "= 6",
|
||||
[PLAYER_VISIBLE_ITEM_7_ENTRYID] = "= 7",
|
||||
[PLAYER_VISIBLE_ITEM_8_ENTRYID] = "= 8",
|
||||
[PLAYER_VISIBLE_ITEM_9_ENTRYID] = "= 9",
|
||||
[PLAYER_VISIBLE_ITEM_10_ENTRYID] = "= 10",
|
||||
[PLAYER_VISIBLE_ITEM_15_ENTRYID] = "= 16",
|
||||
[PLAYER_VISIBLE_ITEM_16_ENTRYID] = "IN (13, 17, 21)",
|
||||
[PLAYER_VISIBLE_ITEM_17_ENTRYID] = "IN (13, 17, 22, 23, 14)",
|
||||
[PLAYER_VISIBLE_ITEM_18_ENTRYID] = "IN (15, 25, 26)",
|
||||
[PLAYER_VISIBLE_ITEM_19_ENTRYID] = "= 19"
|
||||
}
|
||||
|
||||
-- Get inventory type for the given slot
|
||||
local inventoryTypes = inventoryTypesMapping[slot]
|
||||
if not inventoryTypes then
|
||||
return -- Slot not valid
|
||||
end
|
||||
|
||||
local equipmentSlot = nil
|
||||
|
||||
if slot == PLAYER_VISIBLE_ITEM_3_ENTRYID then
|
||||
equipmentSlot = 2 -- Shoulder
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_4_ENTRYID then
|
||||
equipmentSlot = 3 -- Shirt
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_5_ENTRYID then
|
||||
equipmentSlot = 4 -- Chest
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_6_ENTRYID then
|
||||
equipmentSlot = 5 -- Waist
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_10_ENTRYID then
|
||||
equipmentSlot = 9 -- Hands
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_15_ENTRYID then
|
||||
equipmentSlot = 14 -- Back
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_16_ENTRYID then
|
||||
equipmentSlot = 15 -- Main
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_17_ENTRYID then
|
||||
equipmentSlot = 16 -- Off
|
||||
elseif slot == PLAYER_VISIBLE_ITEM_18_ENTRYID then
|
||||
equipmentSlot = 17 -- Ranged
|
||||
else
|
||||
equipmentSlot = Transmog_CalculateSlotReverse(slot)
|
||||
end
|
||||
|
||||
local currentItem = player:GetEquippedItemBySlot(equipmentSlot)
|
||||
local equippedItemType = nil
|
||||
local equippedItemSubType = nil
|
||||
|
||||
if currentItem then
|
||||
equippedItemType = currentItem:GetClass()
|
||||
equippedItemSubType = currentItem:GetSubClass()
|
||||
end
|
||||
|
||||
-- Calculate page offset
|
||||
local pageOffset = (page > 1) and (SLOTS * (page - 1)) or 0
|
||||
|
||||
local queryConditions = "account_id = " .. player:GetAccountId() .. " AND inventory_type " .. inventoryTypes .. " AND (display_id LIKE '%" .. search .. "%' OR item_name LIKE '%" .. search .. "%')"
|
||||
|
||||
if equippedItemSubType then
|
||||
if (RESTRICT_ARMOR_TRANSMOG_TO_SIMILAR_MATERIALS and equippedItemType == 4) then
|
||||
if slot == PLAYER_VISIBLE_ITEM_5_ENTRYID then -- Special check for chestpiece/robes.
|
||||
queryConditions = queryConditions .. " AND inventory_subtype = " .. equippedItemSubType
|
||||
else
|
||||
queryConditions = queryConditions .. " AND inventory_subtype = " .. equippedItemSubType
|
||||
end
|
||||
elseif (RESTRICT_WEAPON_TRANSMOG_TO_SIMILAR_WEAPONS and equippedItemType == 2) then
|
||||
queryConditions = queryConditions .. " AND inventory_subtype = " .. equippedItemSubType
|
||||
end
|
||||
end
|
||||
|
||||
-- Query to count matching transmogs
|
||||
local countQuery = string.format(
|
||||
"SELECT COUNT(unlocked_item_id) FROM account_transmog WHERE %s;",
|
||||
queryConditions
|
||||
)
|
||||
local countResult = AuthDBQuery(countQuery)
|
||||
if not countResult then
|
||||
AIO.Handle(player, "TransmogrificationServer", "InitTab", {}, page, false)
|
||||
return
|
||||
end
|
||||
|
||||
local totalTransmogs = countResult:GetUInt32(0)
|
||||
local hasMorePages = (totalTransmogs > SLOTS * page)
|
||||
|
||||
-- Query to get transmogs
|
||||
local transmogQuery = string.format(
|
||||
"SELECT unlocked_item_id FROM account_transmog WHERE %s LIMIT %d OFFSET %d;",
|
||||
queryConditions, SLOTS, pageOffset
|
||||
)
|
||||
local transmogs = AuthDBQuery(transmogQuery)
|
||||
if not transmogs then
|
||||
AIO.Handle(player, "TransmogrificationServer", "InitTab", {}, page, false)
|
||||
return
|
||||
end
|
||||
|
||||
-- Collect the unlocked item IDs
|
||||
local currentSlotItemIDs = {}
|
||||
for i = 1, transmogs:GetRowCount() do
|
||||
local currentRow = transmogs:GetRow()
|
||||
local item = currentRow["unlocked_item_id"]
|
||||
table.insert(currentSlotItemIDs, item)
|
||||
transmogs:NextRow()
|
||||
end
|
||||
|
||||
-- Return the result
|
||||
AIO.Handle(player, "TransmogrificationServer", "InitTab", currentSlotItemIDs, page, hasMorePages)
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.SetEquipmentTransmogInfo(player, slot, currentSlotTooltip)
|
||||
local playerGUID = player:GetGUIDLow()
|
||||
|
||||
local transmog = CharDBQuery("SELECT COUNT(item) FROM character_transmog WHERE player_guid = "..playerGUID.." AND slot = '"..slot.."';")
|
||||
if (transmog == nil) then
|
||||
return;
|
||||
end
|
||||
|
||||
if (transmog:GetUInt32(0) ~= 0) then
|
||||
AIO.Handle(player, "TransmogrificationServer", "SetEquipmentTransmogInfoClient", currentSlotTooltip)
|
||||
end
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.GetItemsWithSameAppearance(player, itemID)
|
||||
-- Query the server for the display ID of the new item
|
||||
local displayIDQuery = "SELECT displayid FROM item_template WHERE entry = " .. itemID .. ";"
|
||||
local displayIDResult = WorldDBQuery(displayIDQuery)
|
||||
|
||||
if not displayIDResult then
|
||||
return
|
||||
end
|
||||
|
||||
local displayID = displayIDResult:GetUInt32(0)
|
||||
|
||||
-- Find all items with the same display ID
|
||||
local matchingItemsQuery = "SELECT entry FROM item_template WHERE displayid = " .. displayID .. ";"
|
||||
local matchingItemsResult = WorldDBQuery(matchingItemsQuery)
|
||||
|
||||
if not matchingItemsResult then
|
||||
return
|
||||
end
|
||||
|
||||
-- Collect the matching item IDs into a table
|
||||
local matchingItems = {}
|
||||
for i = 1, matchingItemsResult:GetRowCount() do
|
||||
local currentRow = matchingItemsResult:GetRow()
|
||||
local matchingItemID = currentRow["entry"]
|
||||
table.insert(matchingItems, matchingItemID)
|
||||
matchingItemsResult:NextRow()
|
||||
end
|
||||
|
||||
-- Send the matching transmogs to the client
|
||||
AIO.Handle(player, "TransmogrificationServer", "ReceiveMatchingAppearances", itemID, matchingItems)
|
||||
end
|
||||
|
||||
function TransmogrificationHandler.SendCollectedTransmogItemIDs(player)
|
||||
local accountGUID = player:GetAccountId()
|
||||
|
||||
-- Query to retrieve collected transmog display IDs
|
||||
local collectedDisplayIDsQuery = "SELECT DISTINCT display_id FROM account_transmog WHERE account_id = " .. accountGUID .. ";"
|
||||
local displayIDsResult = AuthDBQuery(collectedDisplayIDsQuery)
|
||||
|
||||
if not displayIDsResult then
|
||||
AIO.Handle(player, "TransmogrificationServer", "ReceiveCollectedAppearances", {}, 0)
|
||||
return
|
||||
end
|
||||
|
||||
-- Count the unique appearances.
|
||||
local uniqueAppearancesCount = displayIDsResult:GetRowCount()
|
||||
|
||||
-- Collect the display IDs into a table
|
||||
local collectedDisplayIDs = {}
|
||||
for i = 1, displayIDsResult:GetRowCount() do
|
||||
local currentRow = displayIDsResult:GetRow()
|
||||
local displayID = currentRow["display_id"]
|
||||
table.insert(collectedDisplayIDs, displayID)
|
||||
displayIDsResult:NextRow()
|
||||
end
|
||||
|
||||
local collectedAppearances = {}
|
||||
|
||||
-- For each display ID, find all items that share the appearance
|
||||
for _, displayID in ipairs(collectedDisplayIDs) do
|
||||
local itemsWithDisplayQuery = "SELECT entry FROM item_template WHERE displayid = " .. displayID .. ";"
|
||||
local itemsResult = WorldDBQuery(itemsWithDisplayQuery)
|
||||
|
||||
if itemsResult then
|
||||
for j = 1, itemsResult:GetRowCount() do
|
||||
local itemRow = itemsResult:GetRow()
|
||||
local itemID = itemRow["entry"]
|
||||
table.insert(collectedAppearances, itemID)
|
||||
itemsResult:NextRow()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Send the collected transmogs to the client
|
||||
AIO.Handle(player, "TransmogrificationServer", "ReceiveCollectedAppearances", collectedAppearances, uniqueAppearancesCount)
|
||||
end
|
||||
|
||||
RegisterPlayerEvent(1, Transmog_OnCharacterCreate)
|
||||
RegisterPlayerEvent(2, Transmog_OnCharacterDelete)
|
||||
RegisterPlayerEvent(3, Transmog_OnCharacterLogin)
|
||||
|
||||
RegisterPlayerEvent(29, Transmog_OnEquipItem)
|
||||
|
||||
RegisterPlayerEvent(30, function(event, player, bag, slot)
|
||||
if bag == 255 then
|
||||
TransmogrificationHandler.OnUnequipItem(player)
|
||||
end
|
||||
end)
|
||||
|
||||
if ADD_NEWLY_LOOTED_ITEMS_TO_THE_TRANSMOG_LIST then
|
||||
RegisterPlayerEvent(32, Transmog_OnLootItem)
|
||||
RegisterPlayerEvent(51, Transmog_OnLootItem)
|
||||
RegisterPlayerEvent(52, Transmog_OnLootItem)
|
||||
RegisterPlayerEvent(53, Transmog_OnLootItem)
|
||||
RegisterPlayerEvent(56, Transmog_OnLootItem)
|
||||
end
|
||||
|
||||
if ADD_QUEST_REWARD_ITEMS_TO_THE_TRANSMOG_LIST then
|
||||
RegisterPlayerEvent(54, Transmog_OnQuestComplete)
|
||||
end
|
||||
|
||||
RegisterPlayerEvent(42, function(event, player, command)
|
||||
if command:lower() == "transmog sync" then
|
||||
TransmogrificationHandler.SendCollectedTransmogItemIDs(player)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
||||
print("[Eluna] Transmog System loaded successfully.")
|
||||
@@ -61,9 +61,9 @@
|
||||
# false - (disabled)
|
||||
|
||||
Eluna.Enabled = true
|
||||
Eluna.TraceBack = false
|
||||
Eluna.TraceBack = true
|
||||
Eluna.ScriptPath = "lua_scripts"
|
||||
Eluna.PlayerAnnounceReload = false
|
||||
Eluna.PlayerAnnounceReload = true
|
||||
Eluna.RequirePaths = ""
|
||||
Eluna.RequireCPaths = ""
|
||||
Eluna.AutoReload = false
|
||||
|
||||
+27
-18
@@ -23,35 +23,37 @@ FORCE_PLAYERBOTS="${FORCE_PLAYERBOTS:-${ACORE_PLAYERBOTS_FORCE:-0}}"
|
||||
: "${ACORE_WORLD_CONSOLE_ENABLE:=0}"
|
||||
: "${ACORE_WORLD_DBC_ENFORCE_ITEM_ATTRIBUTES:=0}"
|
||||
: "${ACORE_WORLD_INSTANCE_IGNORE_RAID:=1}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_DAMAGE:=0.80}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RARE_DAMAGE:=0.80}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RAREELITE_DAMAGE:=0.75}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_DAMAGE:=1.00}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RARE_DAMAGE:=1.00}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RAREELITE_DAMAGE:=1.00}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_WORLDBOSS_DAMAGE:=1}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_SPELL_DAMAGE:=0.80}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RARE_SPELL_DAMAGE:=0.80}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RAREELITE_SPELL_DAMAGE:=0.75}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_SPELL_DAMAGE:=1.00}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RARE_SPELL_DAMAGE:=1.00}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RAREELITE_SPELL_DAMAGE:=1.00}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_WORLDBOSS_SPELL_DAMAGE:=1}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_ELITE_ELITE_HP:=0.75}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RARE_HP:=0.70}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_RAREELITE_HP:=0.65}"
|
||||
: "${ACORE_WORLD_RATE_CREATURE_WORLDBOSS_HP:=1}"
|
||||
|
||||
: "${ACORE_AUTOBALANCE_MIN_PLAYERS:=1}"
|
||||
: "${ACORE_AUTOBALANCE_MIN_PLAYERS_HEROIC:=1}"
|
||||
: "${ACORE_AUTOBALANCE_MIN_PLAYERS:=2}"
|
||||
: "${ACORE_AUTOBALANCE_MIN_PLAYERS_HEROIC:=2}"
|
||||
: "${ACORE_AUTOBALANCE_MIN_PLAYERS_RAID:=1}"
|
||||
: "${ACORE_AUTOBALANCE_MIN_PLAYERS_RAID_HEROIC:=1}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEALTH:=1.30}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_DAMAGE:=1.10}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_HEALTH:=1.40}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_HEALTH:=1.25}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_DAMAGE:=1.05}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_HEALTH:=1.35}"
|
||||
: "${ACORE_AUTOBALANCE_LEVEL_SCALING_FLOOR_DUNGEONS:=1}"
|
||||
: "${ACORE_AUTOBALANCE_LEVEL_SCALING_FLOOR_HEROIC_DUNGEONS:=1}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEALTH:=1.55}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_DAMAGE:=2.00}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_HEALTH:=2.00}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_HEALTH:=1.65}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_DAMAGE:=2.20}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_HEALTH:=2.20}"
|
||||
: "${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID:=0.75}"
|
||||
: "${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_BOSS_MODIFIER:=1.35}"
|
||||
: "${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_HEROIC:=0.80}"
|
||||
: "${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_HEROIC_BOSS_MODIFIER:=1.45}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_DAMAGE:=1.00}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_DAMAGE:=0.90}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_DAMAGE:=2.50}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_HEROIC_BOSS_DAMAGE:=2.80}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_RAID_GLOBAL:=0.85}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_RAID_DAMAGE:=0.75}"
|
||||
: "${ACORE_AUTOBALANCE_STAT_MODIFIER_RAID_BOSS_HEALTH:=0.70}"
|
||||
@@ -401,14 +403,21 @@ AutoBalance.MinPlayers.Heroic = ${ACORE_AUTOBALANCE_MIN_PLAYERS_HEROIC}
|
||||
AutoBalance.MinPlayers.Raid = ${ACORE_AUTOBALANCE_MIN_PLAYERS_RAID}
|
||||
AutoBalance.MinPlayers.RaidHeroic = ${ACORE_AUTOBALANCE_MIN_PLAYERS_RAID_HEROIC}
|
||||
|
||||
# Do not downscale dungeon creatures far below the highest player. The module
|
||||
# default of 5 made level 38 Scarlet Monastery mobs become level 29 for a
|
||||
# level 32 player, reducing their damage a second time after player scaling.
|
||||
AutoBalance.LevelScaling.DynamicLevel.Floor.Dungeons = ${ACORE_AUTOBALANCE_LEVEL_SCALING_FLOOR_DUNGEONS}
|
||||
AutoBalance.LevelScaling.DynamicLevel.Floor.HeroicDungeons = ${ACORE_AUTOBALANCE_LEVEL_SCALING_FLOOR_HEROIC_DUNGEONS}
|
||||
|
||||
# So raids scale down harder at low player counts.
|
||||
AutoBalance.InflectionPointRaid = ${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID}
|
||||
AutoBalance.InflectionPointRaid.BossModifier = ${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_BOSS_MODIFIER}
|
||||
AutoBalance.InflectionPointRaidHeroic = ${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_HEROIC}
|
||||
AutoBalance.InflectionPointRaidHeroic.BossModifier = ${ACORE_AUTOBALANCE_INFLECTION_POINT_RAID_HEROIC_BOSS_MODIFIER}
|
||||
|
||||
# Moderate solo profile for 5-man dungeons: longer fights with a controlled
|
||||
# damage increase, while keeping one-player scaling enabled.
|
||||
# Medium solo profile for 5-man dungeons. A solo player is scaled against a
|
||||
# two-player floor so large trash pulls are dangerous, while bosses receive
|
||||
# extra health and damage to remain meaningful without requiring a full group.
|
||||
AutoBalance.StatModifier.Health = ${ACORE_AUTOBALANCE_STAT_MODIFIER_HEALTH}
|
||||
AutoBalance.StatModifier.Damage = ${ACORE_AUTOBALANCE_STAT_MODIFIER_DAMAGE}
|
||||
AutoBalance.StatModifier.Boss.Health = ${ACORE_AUTOBALANCE_STAT_MODIFIER_BOSS_HEALTH}
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
-- Create Squire NPC
|
||||
INSERT
|
||||
INTO
|
||||
acore_world.creature_template (entry,
|
||||
difficulty_entry_1,
|
||||
difficulty_entry_2,
|
||||
difficulty_entry_3,
|
||||
KillCredit1,
|
||||
KillCredit2,
|
||||
name,
|
||||
subname,
|
||||
IconName,
|
||||
gossip_menu_id,
|
||||
minlevel,
|
||||
maxlevel,
|
||||
`exp`,
|
||||
faction,
|
||||
npcflag,
|
||||
speed_walk,
|
||||
speed_run,
|
||||
speed_swim,
|
||||
speed_flight,
|
||||
detection_range,
|
||||
`rank`,
|
||||
dmgschool,
|
||||
DamageModifier,
|
||||
BaseAttackTime,
|
||||
RangeAttackTime,
|
||||
BaseVariance,
|
||||
RangeVariance,
|
||||
unit_class,
|
||||
unit_flags,
|
||||
unit_flags2,
|
||||
dynamicflags,
|
||||
family,
|
||||
`type`,
|
||||
type_flags,
|
||||
lootid,
|
||||
pickpocketloot,
|
||||
skinloot,
|
||||
PetSpellDataId,
|
||||
VehicleId,
|
||||
mingold,
|
||||
maxgold,
|
||||
AIName,
|
||||
MovementType,
|
||||
HoverHeight,
|
||||
HealthModifier,
|
||||
ManaModifier,
|
||||
ArmorModifier,
|
||||
ExperienceModifier,
|
||||
RacialLeader,
|
||||
movementId,
|
||||
RegenHealth,
|
||||
mechanic_immune_mask,
|
||||
spell_school_immune_mask,
|
||||
flags_extra,
|
||||
ScriptName,
|
||||
VerifiedBuild)
|
||||
VALUES
|
||||
(9000001,
|
||||
29831,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'Eluna Squire',
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
81,
|
||||
81,
|
||||
2,
|
||||
21,
|
||||
1,
|
||||
1.0,
|
||||
1.42857,
|
||||
1.0,
|
||||
1.0,
|
||||
20.0,
|
||||
1,
|
||||
0,
|
||||
7.5,
|
||||
2000,
|
||||
2000,
|
||||
1.0,
|
||||
1.0,
|
||||
1,
|
||||
64,
|
||||
2048,
|
||||
8,
|
||||
0,
|
||||
6,
|
||||
72,
|
||||
100003,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1163,
|
||||
1524,
|
||||
'SmartAI',
|
||||
0,
|
||||
1.0,
|
||||
4.0,
|
||||
1.0,
|
||||
1.0,
|
||||
2.5,
|
||||
0,
|
||||
144,
|
||||
1,
|
||||
1007366674,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
12340) ON DUPLICATE KEY UPDATE entry = entry;
|
||||
|
||||
|
||||
-- Add Squire localization
|
||||
INSERT INTO
|
||||
acore_world.creature_template_locale (entry,
|
||||
locale,
|
||||
Name,
|
||||
Title,
|
||||
VerifiedBuild)
|
||||
VALUES
|
||||
(9000001,
|
||||
'ruRU',
|
||||
'Оруженосец',
|
||||
'',
|
||||
12340) ON DUPLICATE KEY UPDATE entry = entry;
|
||||
|
||||
|
||||
-- Add Squire model
|
||||
INSERT
|
||||
INTO
|
||||
acore_world.creature_template_model (CreatureID,
|
||||
Idx,
|
||||
CreatureDisplayID,
|
||||
DisplayScale,
|
||||
Probability,
|
||||
VerifiedBuild)
|
||||
VALUES
|
||||
(9000001,
|
||||
0,
|
||||
16927,
|
||||
1.0,
|
||||
1.0,
|
||||
12340) ON
|
||||
DUPLICATE KEY
|
||||
UPDATE
|
||||
CreatureID = CreatureID;
|
||||
|
||||
-- Add Squire dialogue text
|
||||
INSERT
|
||||
INTO
|
||||
acore_world.npc_text (ID,
|
||||
text0_0,
|
||||
text0_1,
|
||||
BroadcastTextID0,
|
||||
lang0,
|
||||
Probability0,
|
||||
em0_0,
|
||||
em0_1,
|
||||
em0_2,
|
||||
em0_3,
|
||||
em0_4,
|
||||
em0_5,
|
||||
text1_0,
|
||||
text1_1,
|
||||
BroadcastTextID1,
|
||||
lang1,
|
||||
Probability1,
|
||||
em1_0,
|
||||
em1_1,
|
||||
em1_2,
|
||||
em1_3,
|
||||
em1_4,
|
||||
em1_5,
|
||||
text2_0,
|
||||
text2_1,
|
||||
BroadcastTextID2,
|
||||
lang2,
|
||||
Probability2,
|
||||
em2_0,
|
||||
em2_1,
|
||||
em2_2,
|
||||
em2_3,
|
||||
em2_4,
|
||||
em2_5,
|
||||
text3_0,
|
||||
text3_1,
|
||||
BroadcastTextID3,
|
||||
lang3,
|
||||
Probability3,
|
||||
em3_0,
|
||||
em3_1,
|
||||
em3_2,
|
||||
em3_3,
|
||||
em3_4,
|
||||
em3_5,
|
||||
text4_0,
|
||||
text4_1,
|
||||
BroadcastTextID4,
|
||||
lang4,
|
||||
Probability4,
|
||||
em4_0,
|
||||
em4_1,
|
||||
em4_2,
|
||||
em4_3,
|
||||
em4_4,
|
||||
em4_5,
|
||||
text5_0,
|
||||
text5_1,
|
||||
BroadcastTextID5,
|
||||
lang5,
|
||||
Probability5,
|
||||
em5_0,
|
||||
em5_1,
|
||||
em5_2,
|
||||
em5_3,
|
||||
em5_4,
|
||||
em5_5,
|
||||
text6_0,
|
||||
text6_1,
|
||||
BroadcastTextID6,
|
||||
lang6,
|
||||
Probability6,
|
||||
em6_0,
|
||||
em6_1,
|
||||
em6_2,
|
||||
em6_3,
|
||||
em6_4,
|
||||
em6_5,
|
||||
text7_0,
|
||||
text7_1,
|
||||
BroadcastTextID7,
|
||||
lang7,
|
||||
Probability7,
|
||||
em7_0,
|
||||
em7_1,
|
||||
em7_2,
|
||||
em7_3,
|
||||
em7_4,
|
||||
em7_5,
|
||||
VerifiedBuild)
|
||||
VALUES
|
||||
(10000000,
|
||||
'',
|
||||
'By the grace of the stars, I have been bound to your side, $n. This ancient pile of bones is ready to serve you.',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0) ON DUPLICATE KEY UPDATE ID = ID;
|
||||
|
||||
-- Add squire dialogue text locale
|
||||
INSERT
|
||||
INTO
|
||||
acore_world.npc_text_locale (ID,
|
||||
Locale,
|
||||
Text0_0,
|
||||
Text0_1,
|
||||
Text1_0,
|
||||
Text1_1,
|
||||
Text2_0,
|
||||
Text2_1,
|
||||
Text3_0,
|
||||
Text3_1,
|
||||
Text4_0,
|
||||
Text4_1,
|
||||
Text5_0,
|
||||
Text5_1,
|
||||
Text6_0,
|
||||
Text6_1,
|
||||
Text7_0,
|
||||
Text7_1)
|
||||
VALUES
|
||||
(10000000,
|
||||
'ruRU',
|
||||
'',
|
||||
'Милостью высших сил я был приставлен к тебе, $n. Эти древние кости готовы служить. Чего желаешь?',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'') ON DUPLICATE KEY UPDATE ID = ID;
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
-- --------------------------------------------------------
|
||||
-- Host: 192.168.0.167
|
||||
-- Server-Version: 8.3.0 - MySQL Community Server - GPL
|
||||
-- Server-Betriebssystem: Linux
|
||||
-- HeidiSQL Version: 12.8.0.6908
|
||||
-- --------------------------------------------------------
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
-- Exportiere Struktur von Tabelle acore_auth.account_transmog
|
||||
CREATE TABLE IF NOT EXISTS `account_transmog` (
|
||||
`account_id` int unsigned NOT NULL,
|
||||
`unlocked_item_id` int unsigned NOT NULL,
|
||||
`inventory_type` int unsigned DEFAULT NULL,
|
||||
`inventory_subtype` int unsigned DEFAULT NULL,
|
||||
`display_id` int unsigned NOT NULL,
|
||||
`item_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
UNIQUE KEY `account_item_id` (`account_id`,`unlocked_item_id`) USING BTREE,
|
||||
UNIQUE KEY `account_display_id` (`account_id`,`display_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- Daten-Export vom Benutzer nicht ausgewählt
|
||||
|
||||
/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;
|
||||
@@ -0,0 +1,33 @@
|
||||
-- --------------------------------------------------------
|
||||
-- Host: 192.168.0.167
|
||||
-- Server-Version: 8.3.0 - MySQL Community Server - GPL
|
||||
-- Server-Betriebssystem: Linux
|
||||
-- HeidiSQL Version: 12.8.0.6908
|
||||
-- --------------------------------------------------------
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
-- Exportiere Struktur von Tabelle acore_characters.character_transmog
|
||||
CREATE TABLE IF NOT EXISTS `character_transmog` (
|
||||
`player_guid` int unsigned DEFAULT NULL,
|
||||
`slot` varchar(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||
`item` int unsigned DEFAULT NULL,
|
||||
`real_item` int unsigned DEFAULT NULL,
|
||||
UNIQUE KEY `player_and_slot` (`player_guid`,`slot`) USING BTREE,
|
||||
KEY `player_and_slot_key` (`player_guid`,`slot`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
-- Daten-Export vom Benutzer nicht ausgewählt
|
||||
|
||||
/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;
|
||||
Reference in New Issue
Block a user