diff --git a/data/styles/40-outfitwindow.otui b/data/styles/40-outfitwindow.otui index ecb2779ff2..ae245e6708 100644 --- a/data/styles/40-outfitwindow.otui +++ b/data/styles/40-outfitwindow.otui @@ -195,6 +195,28 @@ OutfitWindow < MainWindow anchors.right: parent.right text: Show Mount + FlatPanel + id: showFamiliar + height: 22 + padding: 5 + @onSetup: | + if not g_game.getFeature(GamePlayerFamiliars) then + self:hide() + self:setHeight(0) + self:setPadding(0) + end + + CheckBox + id: check + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + text: Show Familiar + @onSetup: | + if not g_game.getFeature(GamePlayerFamiliars) then + self:hide() + end + FlatPanel id: showWings height: 22 @@ -288,6 +310,15 @@ OutfitWindow < MainWindow cell-size: 64 64 flow: true + UICreature + id: familiarui + anchors.centerIn: parent + size: 256 256 + @onSetup: | + if not g_game.getFeature(GamePlayerFamiliars) then + self:hide() + end + UICreature id: creature anchors.centerIn: parent @@ -499,7 +530,40 @@ OutfitWindow < MainWindow anchors.bottom: parent.bottom anchors.left: prev.right anchors.right: parent.right - + + Panel + id: familiar + height: 20 + @onSetup: | + if not g_game.getFeature(GamePlayerFamiliars) then + self:hide() + self:setHeight(0) + end + + CheckBox + id: check + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + image-source: /images/ui/outfits/checkbox_round + text-offset: 15 0 + text: familiar: + width: 84 + @onSetup: | + if not g_game.getFeature(GamePlayerFamiliars) then + self:hide() + end + + FlatPanel + id: name + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: prev.right + anchors.right: parent.right + @onSetup: | + if not g_game.getFeature(GamePlayerFamiliars) then + self:hide() + end + Panel id: wings height: 20 @@ -730,7 +794,7 @@ OutfitWindow < MainWindow anchors.bottom: separator.top margin-top: 5 margin-bottom: 5 - image-source: /images/ui/panel_flat + image-source: /images/ui/panel_side image-border: 1 padding: 4 padding-right: 15 diff --git a/modules/game_features/features.lua b/modules/game_features/features.lua index 6f690828da..ba6f2f9228 100644 --- a/modules/game_features/features.lua +++ b/modules/game_features/features.lua @@ -189,6 +189,7 @@ controller:registerEvents(g_game, { if version >= 1260 then g_game.enableFeature(GameThingQuiver); + g_game.enableFeature(GamePlayerFamiliars); end if version >= 1264 then diff --git a/modules/game_outfit/outfit.lua b/modules/game_outfit/outfit.lua index a4dc87a0fd..64bd0c3ba8 100644 --- a/modules/game_outfit/outfit.lua +++ b/modules/game_outfit/outfit.lua @@ -13,6 +13,7 @@ local movementCheck = nil local showFloorCheck = nil local showOutfitCheck = nil local showMountCheck = nil +local showFamiliarCheck = nil local showWingsCheck = nil local showAuraCheck = nil local showShaderCheck = nil @@ -33,6 +34,7 @@ local ServerData = { currentOutfit = {}, outfits = {}, mounts = {}, + familiars = {}, wings = {}, auras = {}, shaders = {}, @@ -104,6 +106,7 @@ local function showSelectionList(data, tempValue, tempField, onSelectCallback) focused = 0 end end + if data and #data > 0 then for _, itemData in ipairs(data) do @@ -143,7 +146,8 @@ local function showSelectionList(data, tempValue, tempField, onSelectCallback) window.listSearch:show() end -local AppearanceData = {"preset", "outfit", "mount", "wings", "aura", "effects", "shader", "healthBar", "title"} +local AppearanceData = {"preset", "outfit", "mount", "familiar", "wings", "aura", "effects", "shader", "healthBar", + "title"} function init() if opcodeSystem.enable then @@ -181,10 +185,18 @@ function terminate() end function onMovementChange(checkBox, checked) - if checked == true then - previewCreature:getCreature():setStaticWalking(1000) - else - previewCreature:getCreature():setStaticWalking(0) + local walkingSpeed = checked and 1000 or 0 + + local mainCreature = previewCreature:getCreature() + if mainCreature then + mainCreature:setStaticWalking(walkingSpeed) + end + + if g_game.getFeature(GamePlayerFamiliars) then + local familiarCreature = previewFamiliar:getCreature() + if familiarCreature then + familiarCreature:setStaticWalking(walkingSpeed) + end end settings.movement = checked @@ -248,9 +260,15 @@ function onShowMountChange(checkBox, checked) updatePreview() end +function onShowFamiliarChange(checkBox, checked) + settings.showFamiliar = checked + updatePreview() +end + function onShowOutfitChange(checkBox, checked) settings.showOutfit = checked showMountCheck:setEnabled(settings.showOutfit) + showFamiliarCheck:setEnabled(settings.showOutfit) showWingsCheck:setEnabled(settings.showOutfit) showAuraCheck:setEnabled(settings.showOutfit) showShaderCheck:setEnabled(settings.showOutfit) @@ -293,6 +311,7 @@ local PreviewOptions = { ["showFloor"] = onShowFloorChange, ["showOutfit"] = onShowOutfitChange, ["showMount"] = onShowMountChange, + ["showFamiliar"] = onShowFamiliarChange, ["showWings"] = onShowWingsChange, ["showAura"] = onShowAuraChange, ["showShader"] = onShowShaderChange, @@ -301,7 +320,9 @@ local PreviewOptions = { ["showEffects"] = onShowEffectsChange } -function create(player, outfitList, creatureMount, mountList, wingsList, auraList, effectsList, shaderList) +function create(player, outfitList, creatureMount, mountList, creatureFamiliar, familiarList, wingsList, auraList, + effectsList, shaderList) + if ignoreNextOutfitWindow and g_clock.millis() < ignoreNextOutfitWindow + 1000 then return end @@ -320,6 +341,7 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis currentOutfit = currentOutfit, outfits = outfitList, mounts = mountList, + familiars = familiarList, wings = wingsList, auras = auraList, effects = effectsList, @@ -368,6 +390,8 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis previewCreature = window.preview.panel.creature previewCreature:setCreatureSize(200) previewCreature:setCenter(true) + previewFamiliar = window.preview.panel.familiarui + -- previewCreature:setBorderColor('red') -- previewCreature:setBorderWidth(2) @@ -418,6 +442,7 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis showFloorCheck = window.preview.options.showFloor.check showOutfitCheck = window.preview.options.showOutfit.check showMountCheck = window.preview.options.showMount.check + showFamiliarCheck = window.preview.options.showFamiliar.check showWingsCheck = window.preview.options.showWings.check showAuraCheck = window.preview.options.showAura.check showShaderCheck = window.preview.options.showShader.check @@ -435,6 +460,7 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis if not settings.showOutfit then showMountCheck:setEnabled(false) + showFamiliarCheck:setEnabled(false) showWingsCheck:setEnabled(false) showAuraCheck:setEnabled(false) showShaderCheck:setEnabled(false) @@ -445,6 +471,7 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis showOutfitCheck:setChecked(settings.showOutfit) showMountCheck:setChecked(settings.showMount) + showFamiliarCheck:setChecked(settings.showFamiliar) showWingsCheck:setChecked(settings.showWings) showAuraCheck:setChecked(settings.showAura) showShaderCheck:setChecked(settings.showShader) @@ -475,6 +502,7 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis appearanceGroup:addWidget(window.appearance.settings.preset.check) appearanceGroup:addWidget(window.appearance.settings.outfit.check) appearanceGroup:addWidget(window.appearance.settings.mount.check) + appearanceGroup:addWidget(window.appearance.settings.familiar.check) appearanceGroup:addWidget(window.appearance.settings.aura.check) appearanceGroup:addWidget(window.appearance.settings.wings.check) appearanceGroup:addWidget(window.appearance.settings.shader.check) @@ -496,6 +524,10 @@ function create(player, outfitList, creatureMount, mountList, wingsList, auraLis window.preview.options.showMount:setVisible(g_game.getFeature(GamePlayerMounts)) window.configure.mount:setVisible(g_game.getFeature(GamePlayerMounts)) window.appearance.settings.mount:setVisible(g_game.getFeature(GamePlayerMounts)) + + window.preview.options.showFamiliar:setVisible(true) + window.appearance.settings.familiar:setVisible(true) + window.listSearch.search.onKeyPress = onFilterSearch previewCreature:getCreature():setDirection(2) end @@ -507,6 +539,7 @@ function destroy() showFloorCheck = nil showOutfitCheck = nil showMountCheck = nil + showFamiliarCheck = nil showWingsCheck = nil showAuraCheck = nil showShaderCheck = nil @@ -528,6 +561,7 @@ function destroy() currentOutfit = {}, outfits = {}, mounts = {}, + familiars = {}, wings = {}, auras = {}, shaders = {}, @@ -591,7 +625,8 @@ function newPreset() effects = "None", wings = "None", shader = "None", - mounted = window.configure.mount.check:isChecked() + mounted = "None", + familiar = "None" } presetWidget:focus() @@ -659,6 +694,7 @@ function savePreset() settings.presets[presetId].outfit = outfitCopy settings.presets[presetId].mounted = window.configure.mount.check:isChecked() + settings.presets[presetId].familiar = tempOutfit.familiar or 0 settings.presets[presetId].shader = "Outfit - Default" settings.presets[presetId].auras = lastSelectAura or "None" @@ -742,6 +778,8 @@ function onAppearanceChange(widget, selectedWidget) showOutfits() elseif id == "mount" then showMounts() + elseif id == "familiar" then + showFamiliars() -- numbers elseif id == "aura" then showSelectionList(ServerData.auras, tempOutfit.auras, "aura", onAuraSelect) @@ -837,6 +875,7 @@ function showOutfits() outfit.type = outfitData[1] outfit.addons = outfitData[3] outfit.mount = 0 + outfit.familiar = 0 outfit.auras = 0 outfit.wings = 0 outfit.shader = "Outfit - Default" @@ -902,7 +941,7 @@ function showMounts() window.configure.mount.check:setEnabled(focused) window.configure.mount.check:setChecked(g_game.getLocalPlayer():isMounted() and focused) - if focused ~= nil then + if focused then local w = window.selectionList[focused] w:focus() window.selectionList:ensureChildVisible(w, { @@ -917,6 +956,54 @@ function showMounts() window.listSearch:show() end +function showFamiliars() + window.presetsList:hide() + window.presetsScroll:hide() + window.presetButtons:hide() + + window.selectionList.onChildFocusChange = nil + window.selectionList:destroyChildren() + + local focused = nil + + local button = g_ui.createWidget("SelectionButton", window.selectionList) + button:setId(0) + button.name:setText("None") + focused = 0 + + for _, familiarData in ipairs(ServerData.familiars) do + local button = g_ui.createWidget("SelectionButton", window.selectionList) + button:setId(familiarData[1]) + + button.outfit:setOutfit({ + type = familiarData[1] + }) + + button.name:setText(familiarData[2]) + if tempOutfit.familiar == familiarData[1] then + focused = familiarData[1] + end + end + + if #ServerData.familiars == 1 then + window.selectionList:focusChild(nil) + end + + if focused then + local w = window.selectionList[focused] + w:focus() + window.selectionList:ensureChildVisible(w, { + x = 0, + y = 196 + }) + end + + window.selectionList.onChildFocusChange = onFamiliarSelect + window.selectionList:show() + window.selectionScroll:show() + window.listSearch:show() +end + function showShaders() window.presetsList:hide() window.presetsScroll:hide() @@ -961,7 +1048,8 @@ function showShaders() end end end - if focused ~= nil then + + if focused then local w = window.selectionList[focused] w:focus() window.selectionList:ensureChildVisible(w, { @@ -995,6 +1083,7 @@ function showHealthBars() focused = 0 end end + if ServerData.healthBars and #ServerData.healthBars > 0 then for _, barData in ipairs(ServerData.healthBars) do local button = g_ui.createWidget("SelectionButton", window.selectionList) @@ -1018,7 +1107,8 @@ function showHealthBars() end end end - if focused ~= nil then + + if focused then local w = window.selectionList[focused] w:focus() window.selectionList:ensureChildVisible(w, { @@ -1054,6 +1144,7 @@ function showTitle() focused = 0 end end + if ServerData.title and #ServerData.title > 0 then for _, titleData in ipairs(ServerData.title) do local button = g_ui.createWidget("SelectionButton", window.selectionList) @@ -1068,7 +1159,8 @@ function showTitle() end end end - if focused ~= nil then + + if focused then local w = window.selectionList[focused] w:focus() window.selectionList:ensureChildVisible(w, { @@ -1084,9 +1176,7 @@ function showTitle() end function onPresetSelect(list, focusedChild, unfocusedChild, reason) - if focusedChild then - local presetId = tonumber(focusedChild:getId()) local preset = settings.presets[presetId] tempOutfit = table.copy(preset.outfit) @@ -1182,6 +1272,34 @@ function onMountSelect(list, focusedChild, unfocusedChild, reason) end end +function onFamiliarSelect(list, focusedChild, unfocusedChild, reason) + if focusedChild then + local familiarType = tonumber(focusedChild:getId()) + + tempOutfit.familiar = familiarType + + deselectPreset() + + previewFamiliar:setOutfit({ + type = familiarType + }) + + updatePreview() + + if g_game.getFeature(GamePlayerFamiliars) and familiarType > 0 then + previewCreature:setMarginRight(50) + previewFamiliar:setCreatureSize(200) + previewFamiliar:setCenter(true) + previewFamiliar:setMarginLeft(70) + else + previewCreature:setMarginRight(0) + previewFamiliar:setMarginLeft(0) + end + + updateAppearanceText("familiar", focusedChild.name:getText()) + end +end + function onAuraSelect(list, focusedChild, unfocusedChild, reason) local auraName = window.appearance.settings["aura"].name:getText() if auraName ~= "None" then @@ -1414,7 +1532,7 @@ end function updatePreview() local direction = previewCreature:getDirection() - --[[ + --[[ --note : without c++ g_lua.bindClassMemberFunction("getDirection", &UICreature::getDirection); @@ -1436,6 +1554,14 @@ function updatePreview() previewOutfit.mount = 0 end + if not settings.showFamiliar then + previewOutfit.familiar = 0 + + previewFamiliar:setVisible(settings.showFamiliar) + else + previewFamiliar:setVisible(true) + end + if settings.showAura then attachOrDetachEffect(lastSelectAura, true) else @@ -1607,6 +1733,7 @@ function loadDefaultSettings() showFloor = true, showOutfit = true, showMount = true, + showFamiliar = true, showWings = true, showAura = true, showShader = true, @@ -1650,6 +1777,13 @@ function accept() end end + if g_game.getFeature(GamePlayerFamiliars) then + local player = g_game.getLocalPlayer() + if settings.currentPreset > 0 then + settings.presets[settings.currentPreset].mounted = window.configure.familiar.check:isChecked() + end + end + g_game.changeOutfit(tempOutfit) if opcodeSystem.enable then sendAction("changeOutfit", { diff --git a/modules/gamelib/const.lua b/modules/gamelib/const.lua index c2ba095d69..8859da390a 100644 --- a/modules/gamelib/const.lua +++ b/modules/gamelib/const.lua @@ -193,8 +193,9 @@ GameContainerFilter = 113 GameEnterGameShowAppearance = 114 GameSmoothWalkElevation = 115 GameNegativeOffset = 116 -GameItemTooltipV8 = 117 +GameItemTooltipV8 = 117 GameWingsAurasEffectsShader = 118 -- note: change to 117 if not approved GameItemTooltipV8 +GamePlayerFamiliars = 119 TextColors = { red = '#f55e5e', -- '#c83200' diff --git a/src/client/const.h b/src/client/const.h index cb966bc3ac..3362f0d829 100644 --- a/src/client/const.h +++ b/src/client/const.h @@ -545,8 +545,9 @@ namespace Otc GameSmoothWalkElevation = 115, GameNegativeOffset = 116, GameItemTooltipV8 = 117, - GameWingsAurasEffectsShader = 118, // note: change to 117 if not approved GameItemTooltipV8 - LastGameFeature = 119 + GameWingsAurasEffectsShader = 118, // note: change to 117 if not approved GameItemTooltipV8 + GamePlayerFamiliars = 119, + LastGameFeature = 120 }; enum MagicEffectsType_t : uint8_t diff --git a/src/client/game.cpp b/src/client/game.cpp index 46e15a9e0d..4e6cca3edf 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -404,6 +404,7 @@ void Game::processRemoveAutomapFlag(const Position& pos, int icon, const std::st void Game::processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector >& outfitList, const std::vector >& mountList, + const std::vector >& familiarList, const std::vector >& wingsList, const std::vector >& aurasList, const std::vector >& effectList, @@ -428,7 +429,19 @@ void Game::processOpenOutfitWindow(const Outfit& currentOutfit, const std::vecto virtualMountCreature->setOutfit(mountOutfit); } - g_lua.callGlobalField("g_game", "onOpenOutfitWindow", virtualOutfitCreature, outfitList, virtualMountCreature, mountList, wingsList, aurasList, effectList, shaderList); + // creature virtual familiar outfit + CreaturePtr virtualFamiliarCreature; + if (getFeature(Otc::GamePlayerFamiliars)) { + Outfit familiarOutfit; + familiarOutfit.setId(currentOutfit.getFamiliar()); + familiarOutfit.setCategory(ThingCategoryCreature); + + virtualFamiliarCreature = std::make_shared(); + virtualFamiliarCreature->setDirection(Otc::South); + virtualFamiliarCreature->setOutfit(familiarOutfit); + } + + g_lua.callGlobalField("g_game", "onOpenOutfitWindow", virtualOutfitCreature, outfitList, virtualMountCreature, mountList, virtualFamiliarCreature, familiarList, wingsList, aurasList, effectList, shaderList); } void Game::processOpenNpcTrade(const std::vector >& items) @@ -1700,4 +1713,4 @@ void Game::stashWithdraw(uint16_t itemId, uint32_t count, uint8_t stackpos) if (!canPerformGameAction()) return; m_protocolGame->sendStashWithdraw(itemId, count, stackpos); -} \ No newline at end of file +} diff --git a/src/client/game.h b/src/client/game.h index 2238e8cb5d..ff8eb85ded 100644 --- a/src/client/game.h +++ b/src/client/game.h @@ -128,6 +128,7 @@ class Game // outfit void processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector >& outfitList, const std::vector >& mountList, + const std::vector >& familiarList, const std::vector >& wingsList, const std::vector >& aurasList, const std::vector >& effectsList, diff --git a/src/client/outfit.cpp b/src/client/outfit.cpp index 5f190f941f..37b5b64694 100644 --- a/src/client/outfit.cpp +++ b/src/client/outfit.cpp @@ -118,11 +118,11 @@ void Outfit::resetClothes() setLegs(0); setFeet(0); setMount(0); + setFamiliar(0); setWing(0); setAura(0); setEffect(0); setShader("Outfit - Default"); - } void Outfit::setHead(uint8_t head) { @@ -132,6 +132,7 @@ void Outfit::setHead(uint8_t head) { m_head = head; m_headColor = getColor(head); } + void Outfit::setBody(uint8_t body) { if (m_body == body) return; @@ -139,6 +140,7 @@ void Outfit::setBody(uint8_t body) { m_body = body; m_bodyColor = getColor(body); } + void Outfit::setLegs(uint8_t legs) { if (m_legs == legs) return; @@ -146,10 +148,11 @@ void Outfit::setLegs(uint8_t legs) { m_legs = legs; m_legsColor = getColor(legs); } + void Outfit::setFeet(uint8_t feet) { if (m_feet == feet) return; m_feet = feet; m_feetColor = getColor(feet); -} \ No newline at end of file +} diff --git a/src/client/outfit.h b/src/client/outfit.h index ad7e6c1e29..81b647d2ee 100644 --- a/src/client/outfit.h +++ b/src/client/outfit.h @@ -39,6 +39,7 @@ class Outfit void setId(uint16_t id) { m_id = id; } void setAuxId(uint16_t id) { m_auxId = id; } void setMount(uint16_t mount) { m_mount = mount; } + void setFamiliar(uint16_t familiar) { m_familiar = familiar; } void setWing(uint16_t Wing) { m_wing = Wing; } void setAura(uint16_t Aura) { m_aura = Aura; } void setEffect(uint16_t Effect) { m_effect = Effect; } @@ -58,6 +59,7 @@ class Outfit uint16_t getId() const { return m_id; } uint16_t getAuxId() const { return m_auxId; } uint16_t getMount() const { return m_mount; } + uint16_t getFamiliar() const { return m_familiar; } uint16_t getWing() const { return m_wing; } uint16_t getAura() const { return m_aura; } uint16_t getEffect() const { return m_effect; } @@ -94,6 +96,7 @@ class Outfit m_feet == other.m_feet && m_addons == other.m_addons && m_mount == other.m_mount && + m_familiar == other.m_familiar && m_wing == other.m_wing && m_aura == other.m_aura && m_effect == other.m_effect && @@ -109,6 +112,7 @@ class Outfit uint16_t m_id{ 0 }; uint16_t m_auxId{ 0 }; uint16_t m_mount{ 0 }; + uint16_t m_familiar{ 0 }; uint16_t m_wing{ 0 }; uint16_t m_aura{ 0 }; uint16_t m_effect{ 0 }; diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp index b1d7535d13..a785f81b08 100644 --- a/src/client/protocolgameparse.cpp +++ b/src/client/protocolgameparse.cpp @@ -2258,7 +2258,7 @@ void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg) const if (g_game.getFeature(Otc::GameNewOutfitProtocol)) { const uint16_t outfitCount = g_game.getClientVersion() >= 1281 ? msg->getU16() : msg->getU8(); - for (int_fast32_t i = 0; i < outfitCount; ++i) { + for (uint_fast16_t i = 0; i < outfitCount; ++i) { uint16_t outfitId = msg->getU16(); const auto& outfitName = msg->getString(); uint8_t outfitAddons = msg->getU8(); @@ -2283,14 +2283,15 @@ void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg) const outfitEnd = msg->getU8(); } - for (int_fast32_t i = outfitStart; i <= outfitEnd; ++i) + for (uint_fast16_t i = outfitStart; i <= outfitEnd; ++i) outfitList.emplace_back(i, "", 0); } std::vector > mountList; + if (g_game.getFeature(Otc::GamePlayerMounts)) { const uint16_t mountCount = g_game.getClientVersion() >= 1281 ? msg->getU16() : msg->getU8(); - for (int_fast32_t i = 0; i < mountCount; ++i) { + for (uint_fast16_t i = 0; i < mountCount; ++i) { const uint16_t mountId = msg->getU16(); // mount type const auto& mountName = msg->getString(); // mount name @@ -2305,56 +2306,67 @@ void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg) const } } + std::vector > familiarList; + + if (g_game.getFeature(Otc::GamePlayerFamiliars)) { + const uint16_t familiarCount = msg->getU16(); + for (uint_fast16_t i = 0; i < familiarCount; ++i) { + const uint16_t familiarLookType = msg->getU16(); // familiar lookType + const auto& familiarName = msg->getString(); // familiar name + + if (g_game.getClientVersion() >= 1281) { + const uint8_t familiarMode = msg->getU8(); // mode: 0x00 - available, 0x01 store (requires U32 store offerId) + if (familiarMode == 1) { + msg->getU32(); + } + } + + familiarList.emplace_back(familiarLookType, familiarName); + } + } + + if (g_game.getClientVersion() >= 1281) { + msg->getU8(); //Try outfit mode (?) + msg->getU8(); // mounted + msg->getU8(); // randomize mount (bool) + } + std::vector > wingList; std::vector > auraList; std::vector > effectList; std::vector > shaderList; - if (g_game.getFeature(Otc::GameWingsAurasEffectsShader)) { - int wingCount = msg->getU8(); - for (int i = 0; i < wingCount; ++i) { - int wingId = msg->getU16(); - std::string wingName = msg->getString(); - wingList.push_back(std::make_tuple(wingId, wingName)); - } - int auraCount = msg->getU8(); - for (int i = 0; i < auraCount; ++i) { - int auraId = msg->getU16(); - std::string auraName = msg->getString(); - auraList.push_back(std::make_tuple(auraId, auraName)); - } - int effectCount = msg->getU8(); - for (int i = 0; i < effectCount; ++i) { - int effectId = msg->getU16(); - std::string effectName = msg->getString(); - effectList.push_back(std::make_tuple(effectId, effectName)); - } - int shaderCount = msg->getU8(); - for (int i = 0; i < shaderCount; ++i) { - int shaderId = msg->getU16(); - std::string shaderName = msg->getString(); - shaderList.push_back(std::make_tuple(shaderId, shaderName)); - } - } + if (g_game.getFeature(Otc::GameWingsAurasEffectsShader)) { + const uint8_t wingCount = msg->getU8(); + for (uint_fast8_t i = 0; i < wingCount; ++i) { + const uint16_t wingId = msg->getU16(); + const auto& wingName = msg->getString(); + wingList.emplace_back(wingId, wingName); + } + const uint8_t auraCount = msg->getU8(); + for (uint_fast8_t i = 0; i < auraCount; ++i) { + const uint16_t auraId = msg->getU16(); + const auto& auraName = msg->getString(); + auraList.emplace_back(auraId, auraName); + } - if (g_game.getClientVersion() >= 1281) { - const uint16_t familiarCount = msg->getU16(); - for (int_fast32_t i = 0; i < familiarCount; ++i) { - msg->getU16(); // familiar lookType - msg->getString(); // familiar name - const uint8_t familiarMode = msg->getU8(); // 0x00 // mode: 0x00 - available, 0x01 store (requires U32 store offerId) - if (familiarMode == 1) { - msg->getU32(); - } + const uint8_t effectCount = msg->getU8(); + for (uint_fast8_t i = 0; i < effectCount; ++i) { + const uint16_t effectId = msg->getU16(); + const auto& effectName = msg->getString(); + effectList.emplace_back(effectId, effectName); } - msg->getU8(); //Try outfit mode (?) - msg->getU8(); // mounted - msg->getU8(); // randomize mount (bool) + const uint8_t shaderCount = msg->getU8(); + for (uint_fast8_t i = 0; i < shaderCount; ++i) { + const uint16_t shaderId = msg->getU16(); + const auto& shaderName = msg->getString(); + shaderList.emplace_back(shaderId, shaderName); + } } - g_game.processOpenOutfitWindow(currentOutfit, outfitList, mountList, wingList, auraList, effectList, shaderList); + g_game.processOpenOutfitWindow(currentOutfit, outfitList, mountList, familiarList, wingList, auraList, effectList, shaderList); } void ProtocolGame::parseKillTracker(const InputMessagePtr& msg) @@ -4110,4 +4122,4 @@ void ProtocolGame::parseCreatureTyping(const InputMessagePtr& msg) creature->setTyping(typing); else g_logger.traceError("could not get creature"); -} \ No newline at end of file +} diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp index 76475fd2f2..6af6b66b4d 100644 --- a/src/client/protocolgamesend.cpp +++ b/src/client/protocolgamesend.cpp @@ -772,10 +772,14 @@ void ProtocolGame::sendChangeOutfit(const Outfit& outfit) } } + if (g_game.getFeature(Otc::GamePlayerFamiliars)) { + msg->addU16(outfit.getFamiliar()); //familiars + } + if (g_game.getClientVersion() >= 1281) { - msg->addU16(0x00); //familiars msg->addU8(0x00); //randomizeMount } + if (g_game.getFeature(Otc::GameWingsAurasEffectsShader)) { msg->addU16(outfit.getWing()); // wings msg->addU16(outfit.getAura()); // auras