diff --git a/modules/game_market/market.lua b/modules/game_market/market.lua index ad42efa..5e55f76 100644 --- a/modules/game_market/market.lua +++ b/modules/game_market/market.lua @@ -35,6 +35,8 @@ itemDetailsPanel = nil itemStatsPanel = nil myOffersPanel = nil currentOffersPanel = nil +myCurrentOffersTab = nil +myOfferHistoryTab = nil offerHistoryPanel = nil itemsPanel = nil selectedOffer = {} @@ -69,10 +71,12 @@ buyCancelButton = nil sellCancelButton = nil buyMyOfferTable = nil sellMyOfferTable = nil +myOfferHistoryTabel = nil offerExhaust = {} marketOffers = {} marketItems = {} +marketItemNames = {} information = {} currentItems = {} lastCreatedOffer = 0 @@ -114,7 +118,7 @@ local function isItemValid(item, category, searchFilter) if filterLevel and marketData.requiredLevel and player:getLevel() < marketData.requiredLevel then return false end - if filterVocation and marketData.restrictVocation > 0 then + if filterVocation and marketData.restrictVocation and marketData.restrictVocation > 0 then local voc = Bit.bit(information.vocation) if not Bit.hasBit(marketData.restrictVocation, voc) then return false @@ -146,6 +150,7 @@ local function clearMyOffers() marketOffers[MarketAction.Sell] = {} buyMyOfferTable:clearData() sellMyOfferTable:clearData() + myOfferHistoryTabel:clearData() end local function clearFilters() @@ -181,14 +186,17 @@ local function addOffer(offer, offerType) local amount = offer:getAmount() local price = offer:getPrice() local timestamp = offer:getTimeStamp() - local itemName = offer:getItem():getMarketData().name + local itemName = marketItemNames[offer:getItem():getId()] + if not itemName then + itemName = offer:getItem():getMarketData().name + end buyOfferTable:toggleSorting(false) sellOfferTable:toggleSorting(false) buyMyOfferTable:toggleSorting(false) sellMyOfferTable:toggleSorting(false) - + if amount < 1 then return false end if offerType == MarketAction.Buy then if offer.warn then @@ -202,7 +210,7 @@ local function addOffer(offer, offerType) {text = comma_value(price*amount), sortvalue = price*amount}, {text = comma_value(price), sortvalue = price}, {text = amount}, - {text = string.gsub(os.date('%c', timestamp), " ", " "), sortvalue = timestamp} + {text = string.gsub(os.date('%H:%M %d/%m/%y', timestamp), " ", " "), sortvalue = timestamp} }) else row = buyOfferTable:addRow({ @@ -210,7 +218,7 @@ local function addOffer(offer, offerType) {text = amount}, {text = comma_value(price*amount), sortvalue = price*amount}, {text = comma_value(price), sortvalue = price}, - {text = string.gsub(os.date('%c', timestamp), " ", " ")} + {text = string.gsub(os.date('%H:%M %d/%m/%y', timestamp), " ", " ")} }) end row.ref = id @@ -231,7 +239,7 @@ local function addOffer(offer, offerType) {text = comma_value(price*amount), sortvalue = price*amount}, {text = comma_value(price), sortvalue = price}, {text = amount}, - {text = string.gsub(os.date('%c', timestamp), " ", " "), sortvalue = timestamp} + {text = string.gsub(os.date('%H:%M %d/%m/%y', timestamp), " ", " "), sortvalue = timestamp} }) else row = sellOfferTable:addRow({ @@ -239,7 +247,7 @@ local function addOffer(offer, offerType) {text = amount}, {text = comma_value(price*amount), sortvalue = price*amount}, {text = comma_value(price), sortvalue = price}, - {text = string.gsub(os.date('%c', timestamp), " ", " "), sortvalue = timestamp} + {text = string.gsub(os.date('%H:%M %d/%m/%y', timestamp), " ", " "), sortvalue = timestamp} }) end row.ref = id @@ -343,6 +351,40 @@ local function updateOffers(offers) end end +local function updateHistoryOffers(offers) + myOfferHistoryTabel:toggleSorting(false) + for _, offer in ipairs(offers) do + local offerType = offer:getType() + local id = offer:getId() + local player = offer:getPlayer() + local amount = offer:getAmount() + local price = offer:getPrice() + local timestamp = offer:getTimeStamp() + local itemName = marketItemNames[offer:getItem():getId()] + if not itemName then + itemName = offer:getItem():getMarketData().name + end + + local offerTypeName = "?" + if offerType == MarketAction.Buy then + offerTypeName = "Buy" + elseif offerType == MarketAction.Sell then + offerTypeName = "Sell" + end + + local row = myOfferHistoryTabel:addRow({ + {text = offerTypeName}, + {text = itemName}, + {text = comma_value(price*amount), sortvalue = price*amount}, + {text = comma_value(price), sortvalue = price}, + {text = amount}, + {text = string.gsub(os.date('%H:%M %d/%m/%y', timestamp), " ", " "), sortvalue = timestamp} + }) + end + myOfferHistoryTabel:toggleSorting(false) + myOfferHistoryTabel:sort() +end + local function updateDetails(itemId, descriptions, purchaseStats, saleStats) if not selectedItem then return @@ -698,13 +740,45 @@ local function onMarketMessage(messageMode, message) Market.displayMessage(message) end -local function initMarketItems() +local function initMarketItems(items) for c = MarketCategory.First, MarketCategory.Last do marketItems[c] = {} end - + marketItemNames = {} + -- save a list of items which are already added local itemSet = {} + + -- parse items send by server + if items then + for _, entry in ipairs(items) do + local item = Item.create(entry.id) + local thingType = g_things.getThingType(entry.id, ThingCategoryItem) + if item and thingType and not marketItemNames[entry.id] then + -- create new marketItem block + local marketItem = { + displayItem = item, + thingType = thingType, + marketData = { + name = entry.name, + category = entry.category, + requiredLevel = 0, + restrictVocation = 0, + showAs = entry.id, + tradeAs = entry.id + } + } + + -- add new market item + if marketItems[entry.category] ~= nil then + table.insert(marketItems[entry.category], marketItem) + marketItemNames[entry.id] = entry.name + end + end + end + Market.updateCategories() + return + end -- populate all market items local types = g_things.findThingTypeByAttr(ThingAttrMarket, 0) @@ -777,16 +851,31 @@ local function initInterface() offersTabBar:setContentWidget(myOffersPanel:getChildById('offersTabContent')) currentOffersPanel = g_ui.loadUI('ui/myoffers/currentoffers') - offersTabBar:addTab(tr('Current Offers'), currentOffersPanel) + myCurrentOffersTab = offersTabBar:addTab(tr('Current Offers'), currentOffersPanel) offerHistoryPanel = g_ui.loadUI('ui/myoffers/offerhistory') - offersTabBar:addTab(tr('Offer History'), offerHistoryPanel) + myOfferHistoryTab = offersTabBar:addTab(tr('Offer History'), offerHistoryPanel) balanceLabel = marketWindow:getChildById('balanceLabel') mainTabBar.onTabChange = function(widget, tab) if tab == myOffersTab then - Market.refreshMyOffers() + local ctab = offersTabBar:getCurrentTab() + if ctab == myCurrentOffersTab then + Market.refreshMyOffers() + elseif ctab == myOfferHistoryTab then + Market.refreshMyOffersHistory() + end + else + Market.refreshOffers() + end + end + + offersTabBar.onTabChange = function(widget, tab) + if tab == myCurrentOffersTab then + Market.refreshMyOffers() + elseif tab == myOfferHistoryTab then + Market.refreshMyOffersHistory() end end @@ -859,6 +948,8 @@ local function initInterface() -- setup my offers buyMyOfferTable = currentOffersPanel:recursiveGetChildById('myBuyingTable') sellMyOfferTable = currentOffersPanel:recursiveGetChildById('mySellingTable') + myOfferHistoryTabel = offerHistoryPanel:recursiveGetChildById('myHistoryTable') + buyMyOfferTable.onSelectionChange = onSelectMyBuyOffer sellMyOfferTable.onSelectionChange = onSelectMySellOffer @@ -878,6 +969,7 @@ local function initInterface() buyMyOfferTable:setSorting(3, TABLE_SORTING_DESC) sellMyOfferTable:setSorting(3, TABLE_SORTING_DESC) + myOfferHistoryTabel:setSorting(6, TABLE_SORTING_DESC) end function init() @@ -937,9 +1029,18 @@ function Market.updateCategories() subCategoryList:clearOptions() local categories = {} + local addedCategories = {} for _, c in ipairs(g_things.getMarketCategories()) do table.insert(categories, getMarketCategoryName(c) or "Unknown") + addedCategories[c] = true end + for c, items in ipairs(marketItems) do + if #items > 0 and not addedCategories[c] then + table.insert(categories, getMarketCategoryName(c) or "Unknown") + addedCategories[c] = true + end + end + table.sort(categories) for _, c in ipairs(categories) do categoryList:addOption(c) @@ -993,6 +1094,9 @@ function Market.isOfferSelected(type) end function Market.getDepotCount(itemId) + if not information.depotItems then + return 0 + end return information.depotItems[itemId] or 0 end @@ -1108,7 +1212,12 @@ function Market.refreshOffers() if Market.isItemSelected() then Market.onItemBoxChecked(selectedItem.ref) else - Market.refreshMyOffers() + local ctab = offersTabBar:getCurrentTab() + if ctab == myCurrentOffersTab then + Market.refreshMyOffers() + elseif ctab == myOfferHistoryTab then + Market.refreshMyOffersHistory() + end end end @@ -1117,6 +1226,11 @@ function Market.refreshMyOffers() MarketProtocol.sendMarketBrowseMyOffers() end +function Market.refreshMyOffersHistory() + clearMyOffers() + MarketProtocol.sendMarketBrowseMyHistory() +end + function Market.loadMarketItems(category) clearItems() @@ -1242,9 +1356,9 @@ end -- protocol callback functions -function Market.onMarketEnter(depotItems, offers, balance, vocation) - if not loaded then - initMarketItems() +function Market.onMarketEnter(depotItems, offers, balance, vocation, items) + if not loaded or (items and #items > 0) then + initMarketItems(items) loaded = true end @@ -1301,8 +1415,12 @@ function Market.onMarketDetail(itemId, descriptions, purchaseStats, saleStats) updateDetails(itemId, descriptions, purchaseStats, saleStats) end -function Market.onMarketBrowse(offers) - updateOffers(offers) +function Market.onMarketBrowse(offers, offersType) + if offersType == MarketRequest.MyHistory then + updateHistoryOffers(offers) + else + updateOffers(offers) + end end function Market.onCoinBalance(coins, transferableCoins) diff --git a/modules/game_market/marketprotocol.lua b/modules/game_market/marketprotocol.lua index 0df40e9..a7573c4 100644 --- a/modules/game_market/marketprotocol.lua +++ b/modules/game_market/marketprotocol.lua @@ -39,15 +39,31 @@ end -- parsing protocols local function parseMarketEnter(protocol, msg) + local items + if g_game.getClientVersion() < 944 then + items = {} + local itemsCount = msg:getU16() + for i = 1, itemsCount do + local itemId = msg:getU16() + local category = msg:getU8() + local name = msg:getString() + table.insert(items, { + id = itemId, + category = category, + name = name + }) + end + end + local balance - if g_game.getClientVersion() >= 981 then + if g_game.getClientVersion() >= 981 or g_game.getClientVersion() < 944 then balance = msg:getU64() else balance = msg:getU32() end local vocation = -1 - if g_game.getClientVersion() < 950 then + if g_game.getClientVersion() >= 944 and g_game.getClientVersion() < 950 then vocation = msg:getU8() -- get vocation id end local offers = msg:getU8() @@ -61,7 +77,7 @@ local function parseMarketEnter(protocol, msg) depotItems[itemId] = itemCount end - signalcall(Market.onMarketEnter, depotItems, offers, balance, vocation) + signalcall(Market.onMarketEnter, depotItems, offers, balance, vocation, items) return true end @@ -134,7 +150,7 @@ local function parseMarketBrowse(protocol, msg) table.insert(offers, readMarketOffer(msg, MarketAction.Sell, var)) end - signalcall(Market.onMarketBrowse, offers) + signalcall(Market.onMarketBrowse, offers, var) return true end @@ -215,6 +231,10 @@ function MarketProtocol.sendMarketBrowseMyOffers() MarketProtocol.sendMarketBrowse(MarketRequest.MyOffers) end +function MarketProtocol.sendMarketBrowseMyHistory() + MarketProtocol.sendMarketBrowse(MarketRequest.MyHistory) +end + function MarketProtocol.sendMarketCreateOffer(type, spriteId, amount, price, anonymous) if g_game.getFeature(GamePlayerMarket) then local msg = OutputMessage.create() diff --git a/modules/game_market/ui/myoffers/currentoffers.otui b/modules/game_market/ui/myoffers/currentoffers.otui index 420ec4c..6c53dac 100644 --- a/modules/game_market/ui/myoffers/currentoffers.otui +++ b/modules/game_market/ui/myoffers/currentoffers.otui @@ -46,17 +46,18 @@ Panel text-offset: 0 2 anchors.top: parent.top anchors.left: parent.left - margin-top: 44 + margin-top: 20 margin-left: 6 Table id: mySellingTable anchors.top: prev.bottom - anchors.left: prev.left + anchors.left: parent.left anchors.right: parent.right - height: 150 + height: 160 margin-top: 5 margin-bottom: 5 + margin-left: 6 margin-right: 6 padding: 1 focusable: false @@ -82,10 +83,10 @@ Panel width: 125 OfferTableHeaderColumn !text: tr('Amount') - width: 110 + width: 100 OfferTableHeaderColumn !text: tr('Auction End') - width: 110 + width: 120 TableData id: mySellingTableData @@ -103,34 +104,35 @@ Panel step: 28 pixels-scroll: true + Label + !text: tr('Buy Offers') + font: verdana-11px-rounded + text-offset: 0 2 + anchors.top: prev.bottom + anchors.left: parent.left + margin-top: 20 + margin-left: 6 + Button id: buyCancelButton !text: tr('Cancel') anchors.right: parent.right - anchors.top: prev.bottom + anchors.bottom: prev.bottom margin-top: 5 margin-right: 6 width: 80 enabled: false - Label - !text: tr('Buy Offers') - font: verdana-11px-rounded - text-offset: 0 2 - anchors.top: prev.top - anchors.left: parent.left - margin-top: 9 - margin-left: 6 - Table id: myBuyingTable anchors.top: prev.bottom - anchors.left: prev.left + anchors.left: parent.left anchors.right: parent.right margin-top: 5 margin-bottom: 5 + margin-left: 6 margin-right: 6 - height: 150 + height: 160 padding: 1 focusable: false background-color: #222833 @@ -155,10 +157,10 @@ Panel width: 125 OfferTableHeaderColumn !text: tr('Amount') - width: 110 + width: 100 OfferTableHeaderColumn !text: tr('Auction End') - width: 110 + width: 120 TableData id: myBuyingTableData diff --git a/modules/game_market/ui/myoffers/offerhistory.otui b/modules/game_market/ui/myoffers/offerhistory.otui index d9c9fa3..3f8380d 100644 --- a/modules/game_market/ui/myoffers/offerhistory.otui +++ b/modules/game_market/ui/myoffers/offerhistory.otui @@ -2,8 +2,60 @@ Panel background-color: #22283399 margin: 1 - Label - !text: tr('Offer History') + Table + id: myHistoryTable anchors.top: parent.top anchors.left: parent.left - margin-left: 10 + anchors.right: parent.right + height: 390 + margin-top: 5 + margin-bottom: 5 + margin-left: 8 + margin-right: 8 + padding: 1 + focusable: false + background-color: #222833 + border-width: 1 + border-color: #191f27 + table-data: myHistoryTableData + row-style: OfferTableRow + column-style: OfferTableColumn + header-column-style: false + header-row-style: false + + OfferTableHeaderRow + id: header + OfferTableHeaderColumn + !text: tr('Action') + width: 60 + OfferTableHeaderColumn + !text: tr('Item Name') + width: 140 + OfferTableHeaderColumn + !text: tr('Total Price') + width: 115 + OfferTableHeaderColumn + !text: tr('Piece Price') + width: 115 + OfferTableHeaderColumn + !text: tr('Amount') + width: 75 + OfferTableHeaderColumn + !text: tr('Auction End') + width: 120 + + TableData + id: myHistoryTableData + anchors.bottom: myHistoryTable.bottom + anchors.left: myHistoryTable.left + anchors.right: myHistoryTable.right + margin-top: 2 + vertical-scrollbar: myHistoryTableScrollBar + + VerticalScrollBar + id: myHistoryTableScrollBar + anchors.top: myHistoryTable.top + anchors.bottom: myHistoryTable.bottom + anchors.right: myHistoryTable.right + step: 28 + pixels-scroll: true \ No newline at end of file diff --git a/modules/game_outfit/outfit.lua b/modules/game_outfit/outfit.lua index d19da8b..c1c04e5 100644 --- a/modules/game_outfit/outfit.lua +++ b/modules/game_outfit/outfit.lua @@ -54,7 +54,9 @@ end function setupSelector(widget, id, outfit, list) widget:setId(id) widget.title:setText(id:gsub("^%l", string.upper)) - table.insert(list, 1, {0, "-"}) + if id ~= "type" or #list == 0 then + table.insert(list, 1, {0, "-"}) + end local pos = 1 for i, o in pairs(list) do diff --git a/modules/game_outfit/outfitwindow.otui b/modules/game_outfit/outfitwindow.otui index 47ce5a0..426e071 100644 --- a/modules/game_outfit/outfitwindow.otui +++ b/modules/game_outfit/outfitwindow.otui @@ -46,7 +46,7 @@ OutfitSelectorPanel < Panel MainWindow !text: tr('Select Outfit') - size: 540 330 + size: 560 330 @onEnter: modules.game_outfit.accept() @onEscape: modules.game_outfit.destroy() @@ -162,7 +162,7 @@ MainWindow layout: type: horizontalBox fit-children: true - spacing: 3 + spacing: 8 Button id: outfitOkButton diff --git a/modules/game_protocol/protocol.lua b/modules/game_protocol/protocol.lua new file mode 100644 index 0000000..8ee0b89 --- /dev/null +++ b/modules/game_protocol/protocol.lua @@ -0,0 +1,7 @@ +function init() +end + +function terminate() +end + + diff --git a/modules/game_protocol/protocol.otmod b/modules/game_protocol/protocol.otmod new file mode 100644 index 0000000..81238ac --- /dev/null +++ b/modules/game_protocol/protocol.otmod @@ -0,0 +1,11 @@ +Module + name: game_protocol + description: Game protocol + author: otclientv8 + website: http://otclient.ovh + scripts: [ protocol ] + sandboxed: true + autoload: true + autoload-priority: 500 + @onLoad: init() + @onUnload: terminate() diff --git a/modules/game_skills/skills.otui b/modules/game_skills/skills.otui index 9a7f29a..c51e893 100644 --- a/modules/game_skills/skills.otui +++ b/modules/game_skills/skills.otui @@ -202,11 +202,11 @@ MiniWindow SmallSkillButton id: skillId11 SkillNameLabel - !text: tr('Life Leech Chance') + !text: tr('Mana Leech Chance') SkillValueLabel SmallSkillButton id: skillId12 SkillNameLabel - !text: tr('Life Leech Amount') + !text: tr('Mana Leech Amount') SkillValueLabel diff --git a/modules/game_walking/walking.lua b/modules/game_walking/walking.lua index 95d7506..88af196 100644 --- a/modules/game_walking/walking.lua +++ b/modules/game_walking/walking.lua @@ -377,7 +377,6 @@ function walk(dir, ticks) return elseif not toTile then player:lockWalk(100) -- bug fix for missing stairs down on map - return else if g_app.isMobile() and dir <= Directions.West then turn(dir, ticks > 0) diff --git a/modules/gamelib/const.lua b/modules/gamelib/const.lua index 198983b..dd8e245 100644 --- a/modules/gamelib/const.lua +++ b/modules/gamelib/const.lua @@ -189,6 +189,7 @@ GameWingsAndAura = 104 GamePlayerStateU32 = 105 GameOutfitShaders = 106 GameForceAllowItemHotkeys = 107 +GameCountU16 = 108 GamePacketSizeU32 = 110 GamePacketCompression = 111 diff --git a/otclient_dx.exe b/otclient_dx.exe index e7506ae..b86eca4 100644 Binary files a/otclient_dx.exe and b/otclient_dx.exe differ diff --git a/otclient_gl.exe b/otclient_gl.exe index 9df5d41..7a188e3 100644 Binary files a/otclient_gl.exe and b/otclient_gl.exe differ diff --git a/otclient_linux b/otclient_linux index e1c0be9..6c49e44 100644 Binary files a/otclient_linux and b/otclient_linux differ diff --git a/otclientv8.apk b/otclientv8.apk index 448e4c3..55adb9c 100644 Binary files a/otclientv8.apk and b/otclientv8.apk differ diff --git a/pdb/pdb.7z b/pdb/pdb.7z deleted file mode 100644 index 1d1fa3d..0000000 Binary files a/pdb/pdb.7z and /dev/null differ diff --git a/src/client/protocolgame.h b/src/client/protocolgame.h index 9ef076a..b48e8f5 100644 --- a/src/client/protocolgame.h +++ b/src/client/protocolgame.h @@ -102,7 +102,7 @@ public: void sendRefreshContainer(int containerId); void sendRequestOutfit(); void sendChangeOutfit(const Outfit& outfit); - void sendMountStatus(bool mount); + void sendOutfitExtensionStatus(int mount = -1, int wings = -1, int aura = -1, int shader = -1); void sendApplyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm); void sendClearImbuement(uint8_t slot); void sendCloseImbuingWindow(); diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp index 389a6e2..ee09524 100644 --- a/src/client/protocolgameparse.cpp +++ b/src/client/protocolgameparse.cpp @@ -1337,7 +1337,7 @@ void ProtocolGame::parseOpenNpcTrade(const InputMessagePtr& msg) for (int i = 0; i < listCount; ++i) { uint16 itemId = msg->getU16(); - uint8 count = msg->getU8(); + uint16 count = g_game.getFeature(Otc::GameCountU16) ? msg->getU16() : msg->getU8(); ItemPtr item = Item::create(itemId); item->setCountOrSubType(count); @@ -2653,7 +2653,7 @@ void ProtocolGame::parseItemInfo(const InputMessagePtr& msg) for (int i = 0; i < size; ++i) { ItemPtr item(new Item); item->setId(msg->getU16()); - item->setCountOrSubType(msg->getU8()); + item->setCountOrSubType(g_game.getFeature(Otc::GameCountU16) ? msg->getU16() : msg->getU8()); std::string desc = msg->getString(); list.push_back(std::make_tuple(item, desc)); @@ -3267,9 +3267,13 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type) g_logger.traceError("server said that a creature is known, but it's not"); } else { uint removeId = msg->getU32(); - g_map.removeCreatureById(removeId); - uint id = msg->getU32(); + if (id == removeId) { + creature = g_map.getCreatureById(id); + } else { + g_map.removeCreatureById(removeId); + } + int creatureType; if (g_game.getClientVersion() >= 910) @@ -3288,28 +3292,32 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type) std::string name = g_game.formatCreatureName(msg->getString()); - if (id == m_localPlayer->getId()) - creature = m_localPlayer; - else if (creatureType == Proto::CreatureTypePlayer) { - // fixes a bug server side bug where GameInit is not sent and local player id is unknown - if (m_localPlayer->getId() == 0 && name == m_localPlayer->getName()) - creature = m_localPlayer; - else - creature = PlayerPtr(new Player); - } else if (creatureType == Proto::CreatureTypeMonster) - creature = MonsterPtr(new Monster); - else if (creatureType == Proto::CreatureTypeNpc) - creature = NpcPtr(new Npc); - else if (creatureType == Proto::CreatureTypeSummonOwn) { - creature = MonsterPtr(new Monster); - } else - g_logger.traceError("creature type is invalid"); - if (creature) { - creature->setId(id); creature->setName(name); + } else { + if (id == m_localPlayer->getId()) + creature = m_localPlayer; + else if (creatureType == Proto::CreatureTypePlayer) { + // fixes a bug server side bug where GameInit is not sent and local player id is unknown + if (m_localPlayer->getId() == 0 && name == m_localPlayer->getName()) + creature = m_localPlayer; + else + creature = PlayerPtr(new Player); + } else if (creatureType == Proto::CreatureTypeMonster) + creature = MonsterPtr(new Monster); + else if (creatureType == Proto::CreatureTypeNpc) + creature = NpcPtr(new Npc); + else if (creatureType == Proto::CreatureTypeSummonOwn) { + creature = MonsterPtr(new Monster); + } else + g_logger.traceError("creature type is invalid"); - g_map.addCreature(creature); + if (creature) { + creature->setId(id); + creature->setName(name); + + g_map.addCreature(creature); + } } } @@ -3431,7 +3439,7 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id, bool hasDescri } if (item->isStackable() || item->isFluidContainer() || item->isSplash() || item->isChargeable()) - item->setCountOrSubType(msg->getU8()); + item->setCountOrSubType(g_game.getFeature(Otc::GameCountU16) ? msg->getU16() : msg->getU8()); else if (item->rawGetThingType()->isContainer() && g_game.getFeature(Otc::GameTibia12Protocol)) { // not sure about this part uint8_t hasQuickLootFlags = msg->getU8(); diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp index 1ed5c9d..ff34e4d 100644 --- a/src/client/protocolgamesend.cpp +++ b/src/client/protocolgamesend.cpp @@ -348,7 +348,10 @@ void ProtocolGame::sendEquipItem(int itemId, int countOrSubType) OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientEquipItem); msg->addU16(itemId); - msg->addU8(countOrSubType); + if (g_game.getFeature(Otc::GameCountU16)) + msg->addU16(countOrSubType); + else + msg->addU8(countOrSubType); send(msg); } @@ -360,7 +363,10 @@ void ProtocolGame::sendMove(const Position& fromPos, int thingId, int stackpos, msg->addU16(thingId); msg->addU8(stackpos); addPosition(msg, toPos); - msg->addU8(count); + if(g_game.getFeature(Otc::GameCountU16)) + msg->addU16(count); + else + msg->addU8(count); send(msg); } @@ -369,7 +375,10 @@ void ProtocolGame::sendInspectNpcTrade(int itemId, int count) OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientInspectNpcTrade); msg->addU16(itemId); - msg->addU8(count); + if (g_game.getFeature(Otc::GameCountU16)) + msg->addU16(count); + else + msg->addU8(count); send(msg); } @@ -830,7 +839,7 @@ void ProtocolGame::sendChangeOutfit(const Outfit& outfit) void ProtocolGame::sendOutfitExtensionStatus(int mount, int wings, int aura, int shader) { - if(g_game.getFeature(Otc::GamePlayerMounts) || g_game.getFeature(Otc::GameWingsAndAura) || g_game.getFeature(Otc::GameWingsAndAura)) { + if(g_game.getFeature(Otc::GamePlayerMounts) || g_game.getFeature(Otc::GameWingsAndAura) || g_game.getFeature(Otc::GameOutfitShaders)) { OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientMount); if (g_game.getFeature(Otc::GamePlayerMounts)) {