mirror of
https://github.com/edubart/otclient.git
synced 2025-10-15 20:14:54 +02:00
Added Market/MarketProtocol module to begin the construction of the Market! Fixed some Minor Issues, and Some Cosmetics
* Added new protocol lib. * Added missing Game Features to game/const.lua * Added new Market module that will handle the market/market protocols too. * Finished Market protocol and begun on the market structure (MarketOffer etc). * Removed any traces of market protocol in the core (I think). * Moved minimap images to /images. * Removed old zoom images for minimap. * Fixed a bug with randomize outfit.
This commit is contained in:
61
modules/game_market/market.lua
Normal file
61
modules/game_market/market.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
Market = {}
|
||||
|
||||
local marketWindow
|
||||
|
||||
function Market.init()
|
||||
g_ui.importStyle('market.otui')
|
||||
|
||||
end
|
||||
|
||||
function Market.terminate()
|
||||
marketWindow = nil
|
||||
Market = nil
|
||||
end
|
||||
|
||||
function Market.onMarketEnter(depotItems, offers, balance)
|
||||
-- open market window
|
||||
-- populate market?
|
||||
print('onMarketEnter')
|
||||
print(offers)
|
||||
print(balance)
|
||||
print('depotItems:')
|
||||
for k, item in pairs(depotItems) do
|
||||
print('id- '..item[1])
|
||||
print('count- '..item[2])
|
||||
end
|
||||
end
|
||||
|
||||
function Market.onMarketLeave()
|
||||
-- close market window?
|
||||
print('onMarketLeave')
|
||||
end
|
||||
|
||||
function Market.onMarketDetail(itemId, descriptions, purchaseStats, saleStats)
|
||||
-- populate market widget
|
||||
print('onMarketDetail')
|
||||
print(itemId)
|
||||
print('descriptions:')
|
||||
for k, desc in pairs(descriptions) do
|
||||
print('type- '..desc[1])
|
||||
print('description- '..desc[2])
|
||||
end
|
||||
print('purchaseStats:')
|
||||
for k, stat in pairs(purchaseStats) do
|
||||
print('transactions- '..stat[1])
|
||||
print('total price- '..stat[2])
|
||||
print('highest price- '..stat[3])
|
||||
print('lowest price- '..stat[4])
|
||||
end
|
||||
print('saleStats:')
|
||||
for k, stat in pairs(saleStats) do
|
||||
print('transactions- '..stat[1])
|
||||
print('total price- '..stat[2])
|
||||
print('highest price- '..stat[3])
|
||||
print('lowest price- '..stat[4])
|
||||
end
|
||||
end
|
||||
|
||||
function Market.onMarketBrowse(offers)
|
||||
-- populate market widget
|
||||
print('onMarketBrowse')
|
||||
end
|
19
modules/game_market/market.otmod
Normal file
19
modules/game_market/market.otmod
Normal file
@@ -0,0 +1,19 @@
|
||||
Module
|
||||
name: game_market
|
||||
description: Manage the Players Market system
|
||||
author: BeniS
|
||||
website: www.otclient.info
|
||||
|
||||
dependencies:
|
||||
- game
|
||||
|
||||
@onLoad: |
|
||||
dofile 'marketoffer'
|
||||
dofile 'marketprotocol'
|
||||
dofile 'market'
|
||||
MarketProtocol.init()
|
||||
Market.init()
|
||||
|
||||
@onUnload: |
|
||||
MarketProtocol.terminate()
|
||||
Market.terminate()
|
29
modules/game_market/market.otui
Normal file
29
modules/game_market/market.otui
Normal file
@@ -0,0 +1,29 @@
|
||||
MarketWindow < MainWindow
|
||||
id: marketWindow
|
||||
!text: tr('Market')
|
||||
size: 350 155
|
||||
|
||||
Label
|
||||
!text: tr('Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!')
|
||||
width: 550
|
||||
height: 140
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
margin-left: 10
|
||||
margin-top: 2
|
||||
|
||||
Button
|
||||
id: buttonOk
|
||||
!text: tr('Ok')
|
||||
width: 64
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
margin-left: 160
|
||||
|
||||
Button
|
||||
id: buttonCancel
|
||||
!text: tr('Cancel')
|
||||
width: 64
|
||||
anchors.left: prev.right
|
||||
anchors.bottom: parent.bottom
|
||||
margin-left: 5
|
137
modules/game_market/marketoffer.lua
Normal file
137
modules/game_market/marketoffer.lua
Normal file
@@ -0,0 +1,137 @@
|
||||
MarketOffer = {}
|
||||
MarketOffer.__index = MarketOffer
|
||||
|
||||
local OFFER_TIMESTAMP = 1
|
||||
local OFFER_COUNTER = 2
|
||||
|
||||
MarketOffer.new = function(offerId, action, itemId, amount, price, playerName, state)
|
||||
local offer = {
|
||||
id = {},
|
||||
action = nil,
|
||||
item = 0,
|
||||
amount = 0,
|
||||
price = 0,
|
||||
player = '',
|
||||
state = 0
|
||||
}
|
||||
|
||||
if not offerId or type(offerId) ~= 'table' then
|
||||
g_logger.error('MarketOffer.new - invalid offer id provided.')
|
||||
end
|
||||
offer.id = offerId
|
||||
|
||||
action = tonumber(action)
|
||||
if action ~= MarketAction.Buy and action ~= MarketAction.Sell then
|
||||
g_logger.error('MarketOffer.new - invalid action provided.')
|
||||
end
|
||||
offer.action = action
|
||||
|
||||
offer.item = itemId
|
||||
offer.amount = amount
|
||||
offer.price = price
|
||||
offer.player = playerName
|
||||
|
||||
state = tonumber(state)
|
||||
if state ~= MarketOfferState.Active and state ~= MarketOfferState.Cancelled
|
||||
and state ~= MarketOfferState.Expired and state ~= MarketOfferState.Accepted then
|
||||
g_logger.error('MarketOffer.new - invalid state provided.')
|
||||
end
|
||||
offer.state = state
|
||||
|
||||
setmetatable(offer, MarketOffer)
|
||||
return offer
|
||||
end
|
||||
|
||||
function MarketOffer:isEqual(offer)
|
||||
return self.offer[OFFER_TIMESTAMP] == offer[OFFER_TIMESTAMP] and self.offer[OFFER_COUNTER] == offer[OFFER_COUNTER]
|
||||
end
|
||||
|
||||
function MarketOffer:isLessThan(offer)
|
||||
return self.offer[OFFER_TIMESTAMP] <= offer[OFFER_TIMESTAMP] and self.offer[OFFER_COUNTER] < offer[OFFER_COUNTER]
|
||||
end
|
||||
|
||||
function MarketOffer:isNull(offer)
|
||||
return table.empty(self.id)
|
||||
end
|
||||
|
||||
-- Sets/Gets
|
||||
|
||||
function MarketOffer:setId(id)
|
||||
if not id or type(id) ~= 'table' then
|
||||
g_logger.error('MarketOffer.setId - invalid id provided.')
|
||||
end
|
||||
self.id = id
|
||||
end
|
||||
|
||||
function MarketOffer:getId()
|
||||
return self.id
|
||||
end
|
||||
|
||||
function MarketOffer:setItem(item)
|
||||
if not item or type(item) ~= 'number' then
|
||||
g_logger.error('MarketOffer.setItem - invalid item id provided.')
|
||||
end
|
||||
self.item = item
|
||||
end
|
||||
|
||||
function MarketOffer:getItem()
|
||||
return self.item
|
||||
end
|
||||
|
||||
function MarketOffer:setAmount(amount)
|
||||
if not amount or type(amount) ~= 'number' then
|
||||
g_logger.error('MarketOffer.setAmount - invalid amount provided.')
|
||||
end
|
||||
self.amount = amount
|
||||
end
|
||||
|
||||
function MarketOffer:getAmount()
|
||||
return self.amount
|
||||
end
|
||||
|
||||
function MarketOffer:setPrice(price)
|
||||
if not price or type(price) ~= 'number' then
|
||||
g_logger.error('MarketOffer.setPrice - invalid price provided.')
|
||||
end
|
||||
self.price = price
|
||||
end
|
||||
|
||||
function MarketOffer:getPrice()
|
||||
return self.price
|
||||
end
|
||||
|
||||
function MarketOffer:setPlayer(player)
|
||||
if not player or type(player) ~= 'number' then
|
||||
g_logger.error('MarketOffer.setPlayer - invalid player provided.')
|
||||
end
|
||||
self.player = player
|
||||
end
|
||||
|
||||
function MarketOffer:getPlayer()
|
||||
return self.player
|
||||
end
|
||||
|
||||
function MarketOffer:setState(state)
|
||||
if not state or type(state) ~= 'number' then
|
||||
g_logger.error('MarketOffer.setState - invalid state provided.')
|
||||
end
|
||||
self.state = state
|
||||
end
|
||||
|
||||
function MarketOffer:getState()
|
||||
return self.state
|
||||
end
|
||||
|
||||
function MarketOffer:getTimeStamp()
|
||||
if table.empty(self.id) or #self.id < OFFER_TIMESTAMP then
|
||||
return
|
||||
end
|
||||
return self.id[OFFER_TIMESTAMP]
|
||||
end
|
||||
|
||||
function MarketOffer:getCounter()
|
||||
if table.empty(self.id) or #self.id < OFFER_COUNTER then
|
||||
return
|
||||
end
|
||||
return self.id[OFFER_COUNTER]
|
||||
end
|
204
modules/game_market/marketprotocol.lua
Normal file
204
modules/game_market/marketprotocol.lua
Normal file
@@ -0,0 +1,204 @@
|
||||
MarketProtocol = {}
|
||||
|
||||
local market
|
||||
|
||||
-- private functions
|
||||
|
||||
function parseOpcode(protocol, opcode, msg)
|
||||
if not g_game.getFeature(GamePlayerMarket) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- process msg
|
||||
if opcode == GameServerOpcodes.GameServerMarketEnter then
|
||||
parseMarketEnter(msg)
|
||||
elseif opcode == GameServerOpcodes.GameServerMarketLeave then
|
||||
parseMarketLeave(msg)
|
||||
elseif opcode == GameServerOpcodes.GameServerMarketDetail then
|
||||
parseMarketDetail(msg)
|
||||
elseif opcode == GameServerOpcodes.GameServerMarketBrowse then
|
||||
parseMarketBrowse(msg)
|
||||
else
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function send(msg)
|
||||
print(msg:getMessageSize())
|
||||
g_game.getProtocolGame():safeSend(msg)
|
||||
end
|
||||
|
||||
function readMarketOffer(msg, action, var)
|
||||
local timestamp = msg:getU32()
|
||||
local counter = msg:getU16()
|
||||
|
||||
local itemId = 0
|
||||
if var == MarketRequest.MyOffers or var == MarketRequest.MyHistory then
|
||||
itemId = msg:getU16()
|
||||
else
|
||||
itemId = var
|
||||
end
|
||||
|
||||
local amount = msg:getU16()
|
||||
local price = msg:getU32()
|
||||
local playerName
|
||||
local state = MarketOfferState.Active
|
||||
if var == MarketRequest.MyHistory then
|
||||
state = msg:getU8()
|
||||
else
|
||||
playerName = msg:getString()
|
||||
end
|
||||
|
||||
return MarketOffer.new({timestamp, counter}, action, itemId, amount, price, playerName, state)
|
||||
end
|
||||
|
||||
-- parsing protocols
|
||||
|
||||
function parseMarketEnter(msg)
|
||||
local balance = msg:getU32()
|
||||
local offers = msg:getU8()
|
||||
local depotItems = {}
|
||||
|
||||
local depotCount = (msg:getU16() - 1)
|
||||
for i = 0, depotCount do
|
||||
local itemId = msg:getU16() -- item id
|
||||
local itemCount = msg:getU16() -- item count
|
||||
|
||||
table.insert(depotItems, {itemId, itemCount})
|
||||
end
|
||||
|
||||
Market.onMarketEnter(depotItems, offers, balance)
|
||||
end
|
||||
|
||||
function parseMarketLeave(msg)
|
||||
Market.onMarketLeave()
|
||||
end
|
||||
|
||||
function parseMarketDetail(msg)
|
||||
local itemId = msg:getU16()
|
||||
|
||||
local descriptions = {}
|
||||
for i = MarketItemDescription.First, MarketItemDescription.Last do
|
||||
if msg:peekU16() ~= 0x00 then
|
||||
table.insert(descriptions, {i, msg:getString()})
|
||||
else
|
||||
msg:getU16()
|
||||
end
|
||||
end
|
||||
|
||||
local purchaseStats = {}
|
||||
if msg:getU8() == 0x01 then
|
||||
local transactions = msg:getU32() -- transaction count
|
||||
local totalPrice = msg:getU32() -- total price
|
||||
local highestPrice = msg:getU32() -- highest price
|
||||
local lowestPrice = msg: getU32() -- lowest price
|
||||
|
||||
table.insert(purchaseStats, {transaction, totalPrice, highestPrice, lowestPrice})
|
||||
end
|
||||
|
||||
local saleStats = {}
|
||||
if msg:getU8() == 0x01 then
|
||||
local transactions = msg:getU32() -- transaction count
|
||||
local totalPrice = msg:getU32() -- total price
|
||||
local highestPrice = msg:getU32() -- highest price
|
||||
local lowestPrice = msg: getU32() -- lowest price
|
||||
|
||||
table.insert(saleStats, {transaction, totalPrice, highestPrice, lowestPrice})
|
||||
end
|
||||
|
||||
Market.onMarketDetail(itemId, descriptions, purchaseStats, saleStats)
|
||||
end
|
||||
|
||||
function parseMarketBrowse(msg)
|
||||
local var = msg:getU16()
|
||||
local offers = {}
|
||||
|
||||
local buyOfferCount = (msg:getU32() - 1)
|
||||
for i = 0, buyOfferCount do
|
||||
table.insert(offers, readMarketOffer(msg, MarketAction.Buy, var))
|
||||
end
|
||||
|
||||
local sellOfferCount = (msg:getU32() - 1)
|
||||
for i = 0, sellOfferCount do
|
||||
table.insert(offers, readMarketOffer(msg, MarketAction.Sell, var))
|
||||
end
|
||||
|
||||
Market.onMarketBrowse(offers)
|
||||
end
|
||||
|
||||
-- public functions
|
||||
|
||||
function MarketProtocol.init()
|
||||
connect(ProtocolGame, { onOpcode = parseOpcode } )
|
||||
|
||||
end
|
||||
|
||||
function MarketProtocol.terminate()
|
||||
disconnect(ProtocolGame, { onOpcode = parseOpcode } )
|
||||
|
||||
market = nil
|
||||
MarketProtocol = nil
|
||||
end
|
||||
|
||||
-- sending protocols
|
||||
|
||||
function MarketProtocol.sendMarketLeave()
|
||||
if g_game.getFeature(GamePlayerMarket) then
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientMarketLeave)
|
||||
send(msg)
|
||||
else
|
||||
g_logger.error('MarketProtocol.sendMarketLeave does not support the current protocol.')
|
||||
end
|
||||
end
|
||||
|
||||
function MarketProtocol.sendMarketBrowse(browseId)
|
||||
if g_game.getFeature(GamePlayerMarket) then
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientMarketBrowse)
|
||||
msg:addU16(browseId)
|
||||
send(msg)
|
||||
else
|
||||
g_logger.error('MarketProtocol.sendMarketBrowse does not support the current protocol.')
|
||||
end
|
||||
end
|
||||
|
||||
function MarketProtocol.sendMarketCreateOffer(type, spriteId, amount, price, anonymous)
|
||||
if g_game.getFeature(GamePlayerMarket) then
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientMarketCreate)
|
||||
msg:addU8(type)
|
||||
msg:addU16(spriteId)
|
||||
msg:addU16(amount)
|
||||
msg:addU32(price)
|
||||
msg:addU8(anonymous)
|
||||
send(msg)
|
||||
else
|
||||
g_logger.error('MarketProtocol.sendMarketCreateOffer does not support the current protocol.')
|
||||
end
|
||||
end
|
||||
|
||||
function MarketProtocol.sendMarketCancelOffer(counter)
|
||||
if g_game.getFeature(GamePlayerMarket) then
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientMarketCancel)
|
||||
msg:addU32(os.time())
|
||||
msg:addU16(counter)
|
||||
send(msg)
|
||||
else
|
||||
g_logger.error('MarketProtocol.sendMarketCancelOffer does not support the current protocol.')
|
||||
end
|
||||
end
|
||||
|
||||
function MarketProtocol.sendMarketAcceptOffer(counter)
|
||||
if g_game.getFeature(GamePlayerMarket) then
|
||||
local msg = OutputMessage.create()
|
||||
msg:addU8(ClientOpcodes.ClientMarketAccept)
|
||||
msg:addU32(os.time())
|
||||
msg:addU16(counter)
|
||||
send(msg)
|
||||
else
|
||||
g_logger.error('MarketProtocol.sendMarketAcceptOffer does not support the current protocol.')
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user