Version 2.2.1 - updated market, text editor, bot

This commit is contained in:
OTCv8 2020-04-02 06:47:02 +02:00
parent 932165111d
commit ed8162a9d5
20 changed files with 263 additions and 163 deletions

View File

@ -23,7 +23,7 @@ ComboBoxPopupMenuButton < UIButton
height: 23
font: verdana-11px-antialised
text-align: left
text-offset: 4 0
text-offset: 5 2
color: #dfdfdf
background-color: alpha
margin: 1
@ -44,7 +44,7 @@ ComboBox < UIComboBox
font: verdana-11px-antialised
color: #dfdfdf
size: 91 23
text-offset: 3 0
text-offset: 5 2
text-align: left
image-source: /images/ui/combobox_square
image-border: 3
@ -65,7 +65,7 @@ ComboBoxRoundedPopupScrollMenuButton < UIButton
height: 23
font: verdana-11px-antialised
text-align: left
text-offset: 4 0
text-offset: 5 2
color: #dfdfdf
background-color: alpha
@ -85,7 +85,7 @@ ComboBoxRoundedPopupMenuButton < UIButton
height: 23
font: verdana-11px-antialised
text-align: left
text-offset: 4 0
text-offset: 5 2
color: #dfdfdf
background-color: alpha

View File

@ -2,7 +2,7 @@ Window < UIWindow
font: verdana-11px-antialised
size: 236 207
opacity: 1
color: #8F8F8F
color: #AFAFAF
text-offset: 0 2
text-align: top
image-source: /images/ui/window

View File

@ -2,7 +2,7 @@ MiniWindow < UIMiniWindow
font: verdana-11px-antialised
icon-rect: 4 2 13 13
icon-clip: 0 0 20 20
color: #8F8F8F
color: #9F9F9F
width: 190
height: 200
text-offset: 24 2

View File

@ -392,6 +392,7 @@ function EnterGame.doLogin()
g_game.setClientVersion(G.clientVersion)
g_game.setProtocolVersion(g_game.getClientProtocolVersion(G.clientVersion))
g_game.setCustomProtocolVersion(0)
g_game.setCustomOs(-1) -- disable
g_game.chooseRsa(G.host)
if #server_params <= 3 and not g_game.getFeature(GameExtendedOpcode) then
g_game.setCustomOs(2) -- set os to windows if opcodes are disabled

View File

@ -1,2 +1,3 @@
BattleButton < CreatureButton
&isBattleButton: true
&isBattleButton: true
optimized: true

View File

@ -366,7 +366,8 @@ function initCallbacks()
onAppear = botCreatureAppear,
onDisappear = botCreatureDisappear,
onPositionChange = botCreaturePositionChange,
onHealthPercentChange = botCraetureHealthPercentChange
onHealthPercentChange = botCraetureHealthPercentChange,
onTurn = botCreatureTurn
})
connect(LocalPlayer, {
@ -414,7 +415,8 @@ function terminateCallbacks()
onAppear = botCreatureAppear,
onDisappear = botCreatureDisappear,
onPositionChange = botCreaturePositionChange,
onHealthPercentChange = botCraetureHealthPercentChange
onHealthPercentChange = botCraetureHealthPercentChange,
onTurn = botCreatureTurn
})
disconnect(LocalPlayer, {
@ -559,3 +561,8 @@ function botChannelEvent(channelId, name, event)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onChannelEvent(channelId, name, event) end)
end
function botCreatureTurn(creature, direction)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onTurn(creature, direction) end)
end

View File

@ -59,7 +59,8 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo
onChannelList = {},
onOpenChannel = {},
onCloseChannel = {},
onChannelEvent = {}
onChannelEvent = {},
onTurn = {}
}
-- basic functions & classes
@ -311,6 +312,11 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo
callback(channelId, name, event)
end
end,
onTurn = function(creature, direction)
for i, callback in ipairs(context._callbacks.onTurn) do
callback(creature, direction)
end
end,
}
}
end

View File

@ -146,6 +146,10 @@ context.onChannelEvent = function(callback)
return context.callback("onChannelEvent", callback)
end
-- onTurn -- callback = function(creature, direction)
context.onTurn = function(callback)
return context.callback("onTurn", callback)
end
-- CUSTOM CALLBACKS

View File

@ -166,7 +166,7 @@ Config.setup = function(dir, widget, configExtension, callback)
end
widget.add.onClick = function()
context.UI.SinglelineEditorWindow("config_name", function(name)
context.UI.SinglelineEditorWindow("config_name", {title="Enter config name"}, function(name)
name = name:gsub("%s+", "_")
if name:len() == 0 or name:len() >= 30 or name:find("/") or name:find("\\") then
return context.error("Invalid config name")
@ -185,8 +185,7 @@ Config.setup = function(dir, widget, configExtension, callback)
widget.edit.onClick = function()
local name = context.storage._configs[dir].selected
if not name then return end
context.UI.MultilineEditorWindow("Config editor - " .. name .. " in " .. dir,
Config.loadRaw(dir, name), function(newValue)
context.UI.MultilineEditorWindow(Config.loadRaw(dir, name), {title="Config editor - " .. name .. " in " .. dir}, function(newValue)
local data = Config.parse(newValue)
Config.save(dir, name, data, configExtension)
refresh()

View File

@ -4,12 +4,31 @@ if type(context.UI) ~= "table" then
end
local UI = context.UI
UI.SinglelineEditorWindow = function(text, callback)
return modules.game_textedit.singlelineEditor(text, callback)
UI.EditorWindow = function(text, options, callback)
--[[
Available options:
title = text
description = text
multiline = true / false
width = number
validation = text (regex)
examples = {{name, text}, {name, text}}
]]--
local window = modules.game_textedit.edit(text, options, callback)
window.botWidget = true
return window
end
UI.MultilineEditorWindow = function(description, test, callback)
return modules.game_textedit.multilineEditor(description, test, callback)
UI.SinglelineEditorWindow = function(text, options, callback)
options = options or {}
options.multiline = false
return UI.EditorWindow(text, options, callback)
end
UI.MultilineEditorWindow = function(text, options, callback)
options = options or {}
options.multiline = true
return UI.EditorWindow(text, options, callback)
end
UI.ConfirmationWindow = function(title, question, callback)

View File

@ -29,7 +29,7 @@ BotConfig < Panel
anchors.top: prev.bottom
anchors.left: parent.left
text: Add
width: 59
width: 56
height: 20
Button
@ -37,7 +37,7 @@ BotConfig < Panel
anchors.top: prev.top
anchors.horizontalCenter: parent.horizontalCenter
text: Edit
width: 59
width: 56
height: 20
Button
@ -45,5 +45,5 @@ BotConfig < Panel
anchors.top: prev.top
anchors.right: parent.right
text: Remove
width: 59
width: 56
height: 20

View File

@ -22,6 +22,7 @@ BotIcon < UIWidget
margin-top: 0
size: 48 48
phantom: true
optimized: true
UIWidget
id: status

View File

@ -78,6 +78,7 @@ currentItems = {}
lastCreatedOffer = 0
fee = 0
averagePrice = 0
tibiaCoins = 0
loaded = false
@ -198,8 +199,8 @@ local function addOffer(offer, offerType)
if offer.var == MarketRequest.MyOffers then
row = buyMyOfferTable:addRow({
{text = itemName},
{text = price*amount},
{text = price},
{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}
})
@ -207,8 +208,8 @@ local function addOffer(offer, offerType)
row = buyOfferTable:addRow({
{text = player},
{text = amount},
{text = price*amount},
{text = price},
{text = comma_value(price*amount), sortvalue = price*amount},
{text = comma_value(price), sortvalue = price},
{text = string.gsub(os.date('%c', timestamp), " ", " ")}
})
end
@ -227,8 +228,8 @@ local function addOffer(offer, offerType)
if offer.var == MarketRequest.MyOffers then
row = sellMyOfferTable:addRow({
{text = itemName},
{text = price*amount},
{text = price},
{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}
})
@ -236,8 +237,8 @@ local function addOffer(offer, offerType)
row = sellOfferTable:addRow({
{text = player},
{text = amount},
{text = price*amount},
{text = price},
{text = comma_value(price*amount), sortvalue = price*amount},
{text = comma_value(price), sortvalue = price},
{text = string.gsub(os.date('%c', timestamp), " ", " "), sortvalue = timestamp}
})
end
@ -462,7 +463,7 @@ local function updateBalance(balance)
if balance < 0 then balance = 0 end
information.balance = balance
balanceLabel:setText('Balance: '..balance..' gold')
balanceLabel:setText('Balance: '.. comma_value(balance) ..' gold')
balanceLabel:resizeToText()
end
@ -473,7 +474,7 @@ local function updateFee(price, amount)
elseif fee > 1000 then
fee = 1000
end
feeLabel:setText('Fee: '..fee)
feeLabel:setText('Fee: '.. comma_value(fee))
feeLabel:resizeToText()
end
@ -521,11 +522,11 @@ local function openAmountWindow(callback, actionType, actionText)
itembox:setItemId(item:getId())
local scrollbar = amountWindow:getChildById('amountScrollBar')
scrollbar:setText(offer:getPrice()..'gp')
scrollbar:setText(comma_value(offer:getPrice()) ..'gp')
scrollbar.onValueChange = function(widget, value)
widget:setText((value*offer:getPrice())..'gp')
itembox:setText(value)
widget:setText(comma_value(value*offer:getPrice())..'gp')
itembox:setText(comma_value(value))
end
scrollbar:setRange(1, maximum)
scrollbar:setValue(1)
@ -743,7 +744,7 @@ local function initInterface()
-- setup 'Market Offer' section tabs
marketOffersPanel = g_ui.loadUI('ui/marketoffers')
mainTabBar:addTab(tr('Market Offers'), marketOffersPanel)
selectionTabBar = marketOffersPanel:getChildById('leftTabBar')
selectionTabBar:setContentWidget(marketOffersPanel:getChildById('leftTabContent'))
@ -770,7 +771,7 @@ local function initInterface()
-- setup 'My Offer' section tabs
myOffersPanel = g_ui.loadUI('ui/myoffers')
mainTabBar:addTab(tr('My Offers'), myOffersPanel)
local myOffersTab = mainTabBar:addTab(tr('My Offers'), myOffersPanel)
offersTabBar = myOffersPanel:getChildById('offersTabBar')
offersTabBar:setContentWidget(myOffersPanel:getChildById('offersTabContent'))
@ -783,6 +784,12 @@ local function initInterface()
balanceLabel = marketWindow:getChildById('balanceLabel')
mainTabBar.onTabChange = function(widget, tab)
if tab == myOffersTab then
Market.refreshMyOffers()
end
end
-- setup offers
buyButton = itemOffersPanel:getChildById('buyButton')
buyButton.onClick = function() openAmountWindow(Market.acceptMarketOffer, MarketAction.Buy, 'Buy') end
@ -889,6 +896,8 @@ function init()
connect(g_game, { onGameEnd = Market.reset })
connect(g_game, { onGameEnd = Market.close })
connect(g_game, { onGameStart = Market.updateCategories })
connect(g_game, { onCoinBalance = Market.onCoinBalance })
marketWindow = g_ui.createWidget('MarketWindow', rootWidget)
marketWindow:hide()
@ -904,6 +913,7 @@ function terminate()
disconnect(g_game, { onGameEnd = Market.reset })
disconnect(g_game, { onGameEnd = Market.close })
disconnect(g_game, { onGameStart = Market.updateCategories })
disconnect(g_game, { onCoinBalance = Market.onCoinBalance })
destroyAmountWindow()
marketWindow:destroy()
@ -1076,7 +1086,7 @@ function Market.refreshItemsWidget(selectItem)
local amount = Market.getDepotCount(item.marketData.tradeAs)
if amount > 0 then
itemWidget:setText(amount)
itemWidget:setText(comma_value(amount))
itemBox:setTooltip('You have '.. amount ..' in your depot.')
end
@ -1116,7 +1126,7 @@ function Market.loadMarketItems(category)
end
end
if not marketItems[category] then
if not marketItems[category] and category ~= MarketCategory.All then
return
end
@ -1253,6 +1263,11 @@ function Market.onMarketEnter(depotItems, offers, balance, vocation)
-- set list of depot items
information.depotItems = depotItems
for i = 1, #marketItems[MarketCategory.TibiaCoins] do
local item = marketItems[MarketCategory.TibiaCoins][i].displayItem
depotItems[item:getId()] = tibiaCoins
end
-- update the items widget to match depot items
if Market.isItemSelected() then
local spriteId = selectedItem.item.marketData.tradeAs
@ -1284,3 +1299,12 @@ end
function Market.onMarketBrowse(offers)
updateOffers(offers)
end
function Market.onCoinBalance(coins, transferableCoins)
tibiaCoins = coins
if not marketItems[MarketCategory.TibiaCoins] then return end
for i = 1, #marketItems[MarketCategory.TibiaCoins] do
local item = marketItems[MarketCategory.TibiaCoins][i].displayItem
depotItems[item:getId()] = tibiaCoins
end
end

View File

@ -19,96 +19,135 @@ function destroyWindow()
end
end
function show(widget)
if not widget then
return
-- also works as show(text, callback)
function show(text, options, callback) -- callback = function(newText)
--[[
Available options:
title = text
description = text
multiline = true / false
width = number
validation = text (regex)
examples = {{name, text}, {name, text}}
]]--
if type(text) == 'userdata' then
local widget = text
callback = function(newText)
widget:setText(newText)
end
text = widget:getText()
elseif type(text) == 'number' then
text = tostring(text)
elseif type(text) == 'nil' then
text = ''
elseif type(text) ~= 'string' then
return error("Invalid text type for game_textedit: " .. type(text))
end
if type(options) == 'function' then
local tmp = callback
callback = options
options = callback
end
options = options or {}
if activeWindow then
destroyWindow()
end
local window = g_ui.createWidget('TextEditWindow', rootWidget)
local window
if options.multiline then
window = g_ui.createWidget('MultilineTextEditWindow', rootWidget)
window.text = window.textPanel.text
else
window = g_ui.createWidget('SinglelineTextEditWindow', rootWidget)
end
-- functions
local validate = function(text)
if type(options.validation) ~= 'string' or options.validation:len() == 0 then
return true
end
return #regexMatch(text, options.validation) == 1
end
local destroy = function()
window:destroy()
if window == activeWindow then
activeWindow = nil
end
end
local doneFunc = function()
widget:setText(window.text:getText())
local text = window.text:getText()
if not validate(text) then return end
destroy()
if callback then
callback(text)
end
end
window.buttons.ok.onClick = doneFunc
window.buttons.cancel.onClick = destroy
if not options.multiline then
window.onEnter = doneFunc
end
window.okButton.onClick = doneFunc
window.cancelButton.onClick = destroy
window.onEnter = doneFunc
window.onEscape = destroy
window.text:setText(widget:getText())
activeWindow = window
activeWindow:raise()
activeWindow:focus()
end
function singlelineEditor(text, callback)
if activeWindow then
destroyWindow()
end
local window = g_ui.createWidget('TextEditWindow', rootWidget)
local destroy = function()
window:destroy()
window.onDestroy = function()
if window == activeWindow then
activeWindow = nil
end
end
window.okButton.onClick = function()
local text = window.text:getText()
destroy()
callback(text)
end
window.cancelButton.onClick = destroy
window.onEscape = destroy
window.onEnter = window.okButton.onClick
window.text:setText(text)
activeWindow = window
activeWindow:raise()
activeWindow:focus()
end
function multilineEditor(description, text, callback)
if activeWindow then
destroyWindow()
end
local window = g_ui.createWidget('TextEditMultilineWindow', rootWidget)
local destroy = function()
window:destroy()
if window == activeWindow then
activeWindow = nil
if options.title then
window:setText(options.title)
end
if options.description then
window.description:show()
window.description:setText(options.description)
end
if type(options.examples) == 'table' and #options.examples > 0 then
window.examples:show()
for i, title_text in ipairs(options.examples) do
window.examples:addOption(title_text[1], title_text[2])
end
window.examples.onOptionChange = function(widget, option, data)
window.text:setText(data)
window.text:setCursorPos(-1)
end
end
if type(options.validation) == 'string' and options.validation:len() > 0 then
window.buttons.ok:disable()
window.text.onTextChange = function(widget, text)
if validate(text) then
window.buttons.ok:enable()
else
window.buttons.ok:disable()
end
end
end
window.okButton.onClick = function()
local text = window.text:getText()
destroy()
callback(text)
end
window.cancelButton.onClick = destroy
window.onEscape = destroy
window.description:setText(description)
window.text:setText(text)
window.text:setCursorPos(-1)
if type(options.width) == 'number' then
window:setWidth(options.width)
end
activeWindow = window
activeWindow:raise()
activeWindow:focus()
return activeWindow
end
function hide()
destroyWindow()
end
function edit(...)
return show(...)
end
-- legacy
function singlelineEditor(text, callback)
return show(text, {}, callback)
end
-- legacy
function multilineEditor(description, text, callback)
return show(text, {description=description, multiline=true}, callback)
end

View File

@ -1,73 +1,72 @@
TextEditButtons < Panel
id: buttons
height: 30
Button
id: ok
!text: tr('Ok')
anchors.bottom: parent.bottom
anchors.right: next.left
margin-right: 10
width: 60
Button
id: cancel
!text: tr('Cancel')
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 60
TextEditWindow < MainWindow
id: textedit
size: 260 105
!text: tr("Edit text")
TextEdit
id: text
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
Button
id: okButton
!text: tr('Ok')
anchors.bottom: parent.bottom
anchors.right: next.left
margin-right: 10
width: 60
Button
id: cancelButton
!text: tr('Cancel')
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 60
TextEditMultilineWindow < MainWindow
id: texteditmultiline
size: 650 497
!text: tr("Edit text")
layout:
type: verticalBox
fit-children: true
Label
id: description
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
text-auto-resize: true
text-align: center
text: description
margin-bottom: 5
visible: false
text-wrap: true
text-auto-resize: true
ComboBox
id: examples
margin-bottom: 5
visible: false
MultilineTextEdit
SinglelineTextEditWindow < TextEditWindow
width: 250
TextEdit
id: text
anchors.top: textScroll.top
anchors.left: parent.left
anchors.right: textScroll.left
anchors.bottom: textScroll.bottom
vertical-scrollbar: textScroll
text-wrap: true
VerticalScrollBar
id: textScroll
anchors.top: description.bottom
anchors.bottom: okButton.top
anchors.right: parent.right
margin-bottom: 10
step: 16
pixels-scroll: true
TextEditButtons
Button
id: okButton
!text: tr('Ok')
anchors.bottom: parent.bottom
anchors.right: next.left
margin-right: 10
width: 60
MultilineTextEditWindow < TextEditWindow
width: 600
Button
id: cancelButton
!text: tr('Cancel')
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 60
Panel
id: textPanel
height: 400
MultilineTextEdit
id: text
anchors.fill: parent
margin-right: 12
text-wrap: true
vertical-scrollbar: textScroll
VerticalScrollBar
id: textScroll
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
pixels-scroll: true
step: 10
TextEditButtons

View File

@ -350,7 +350,7 @@ function walk(dir, ticks)
return
end
if dash and lastWalkDir == dir and lastWalk + 30 > g_clock.millis() then
if dash and lastWalkDir == dir and lastWalk + 50 > g_clock.millis() then
return
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.