Use new coding style in game modules

Lots of refactoring and changes
Remove docs folder
master
Eduardo Bart 12 years ago
parent 1c3e630237
commit c54cd1fdf1

3
doc/.gitignore vendored

@ -1,3 +0,0 @@
*.yardoc
doc
!.gitignore

@ -1,222 +0,0 @@
# Style Tags Overview
## Style Overview
This document describes how style tags can be specified, how they affect your
widgets, and how to use specific built-in style tags in otclient, as well
as how to define new custom style tags.
## Style Value Types
{valhead:Integer}
Integer number, used by most of style proprieties
**Examples:**
* 1
* 9
* 5
{valhead:Float}
Float number
**Examples:**
* 1.0
* 9
* 1.5
{valhead:String}
String containing a text
**Examples:**
* this is a string
* it doesn't need quotes or escaping
{valhead:Boolean}
Value with two states, **true** or **false**
**Examples:**
* true
* false
{valhead:Size}
Size type, defined by 2 integers, width followed by height
size: width height
**Examples:**
* 10 20
* 30 10
{valhead:Rect}
Rect type, defined by 4 integers
rect: x y width height
**Examples:**
* 0 0 32 32
* 10 20 30 40
{valhead:Color}
{valhead:Image}
{valhead:Font}
## UIWidget
{taghead:rect Rect}
Defines widget's rect
**Examples:**
!!!plain
rect: 32 32 32 32
**See also:** {tag:pos}, {tag:size}
{taghead:size Size}
Defines size of a widget in pixels
**Examples:**
!!!plain
size: 32 32
{taghead:width Integer}
Defines width of a widget
{taghead:height Integer}
Defines height of a widget
{taghead:pos Point}
Defines absolute position of the widget relative to the window top left, this is generialy not used,
if you want to position relative to parent widget, use anchors and margins
**Examples:**
!!!plain
pos: 32 32
{taghead:x Integer}
Defines x absolute position
**See also:** {tag:pos}
{taghead:y Integer}
Defines y absolute position
**See also:** {tag:pos}
{taghead:color Color}
Foreground color, mostly used for coloring texts
**Examples:**
!!!plain
color: red
color: #ff0000
color: #ff000080
{taghead:background Color}
Same as {tag:background-color}
{taghead:background-color Color}
Defines background color
{taghead:background-rect Rect}
{taghead:background-offset Point}
{taghead:background-offset-x Integer}
{taghead:background-offset-y Integer}
{taghead:background-size Size}
{taghead:background-width Integer}
{taghead:background-height Integer}
{taghead:icon Image}
{taghead:icon-source Image}
{taghead:icon-color Color}
{taghead:icon-offset-x Integer}
{taghead:icon-offset-y Integer}
{taghead:icon-offset Point}
{taghead:icon-width Integer}
{taghead:icon-height Integer}
{taghead:icon-size Size}
{taghead:icon-rect Rect}
{taghead:opacity Float}
{taghead:enabled Boolean}
{taghead:visible Boolean}
{taghead:checked Boolean}
{taghead:dragable Boolean}
{taghead:on Boolean}
{taghead:focusable Boolean}
{taghead:phantom Boolean}
{taghead:fixed-size Boolean}
{taghead:clipping Boolean}
{taghead:border Integer}
{taghead:border-width Integer}
{taghead:border-width-top Integer}
{taghead:border-width-right Integer}
{taghead:border-width-bottom Integer}
{taghead:border-width-left Integer}
{taghead:border-color Color}
{taghead:border-color-top Color}
{taghead:border-color-right Color}
{taghead:border-color-bottom Color}
{taghead:border-color-left Color}
{taghead:margin-top Integer}
{taghead:margin-right Integer}
{taghead:margin-bottom Integer}
{taghead:margin-left Integer}
{taghead:margin Integer}
{taghead:padding-top Integer}
{taghead:padding-right Integer}
{taghead:padding-bottom Integer}
{taghead:padding-left Integer}
{taghead:padding Integer}
{taghead:layout Layout}
{taghead:image-source}
{taghead:image-offset-x Integer}
{taghead:image-offset-y Integer}
{taghead:image-offset Point}
{taghead:image-width Integer}
{taghead:image-height Integer}
{taghead:image-size Size}
{taghead:image-rect Rect}
{taghead:image-clip Rect}
{taghead:image-fixed-ratio Boolean}
{taghead:image-repeated Boolean}
{taghead:image-smooth Boolean}
{taghead:image-color Color}
{taghead:image-border-top Integer}
{taghead:image-border-right Integer}
{taghead:image-border-bottom Integer}
{taghead:image-border-left Integer}
{taghead:image-border Integer}
{taghead:text}
{taghead:text-align Align}
{taghead:text-offset Point}
{taghead:text-wrap Boolean}
{taghead:text-auto-resize Boolean}
{taghead:font Font}
## UITextEdit
{taghead:text-margin}
{taghead:always-active}
{taghead:shift-navigation}
{taghead:multiline}
{taghead:max-length}

@ -1,477 +0,0 @@
# @group Global functions
# Converts rect to string
# @return [Rect]
def torect(str); end
# Converts point to string
# @return [Point]
def topoint(str); end
# Converts color to string
# @return [Color]
def tocolor(str); end
# @return [Size]
def tosize(str); end
# @return [String]
def recttostring(rect); end
# @return [String]
def pointtostring(point); end
# @return [String]
def colortostring(color); end
# @return [String]
def sizetostring(size); end
# @endgroup
# All classes used by the engine is derived from this class
class LuaObject
# Return the number of references that this object have
# @return [Integer]
def getUseCount(); end
# Get the derived class name
# @return [String]
def getClassName(); end
# Return that hold all fields for this object
# @return [Table]
def getFieldsTable(); end
end
# Class that holds dispatcher events
class Event < LuaObject
# Cancel the event execution
# @return [Void]
def cancel(); end
# Force event execution, as an event can only be executed once,
# it will not be executed again in the next poll
# @return [Void]
def execute(); end
# Checks if the event is canceled
# @return [Boolean]
def isCanceled(); end
# Check if the event is executed
# @return [Boolean]
def isExecuted(); end
end
# Class that holds dispatcher scheduled events
class ScheduledEvent < Event
# Return ticks in milliseconds remaining to the event execution
# @return [Integer]
def reamaningTicks(); end
# Return ticks when this event will be executed
# @return [Integer]
def ticks(); end
end
# This is the base class for all UI elements
class UIWidget < LuaObject
# Creates a new UIWidget
# @return [UIWidget]
def self.create(); end
def addChild(); end
def insertChild(); end
def removeChild(); end
def focusChild(); end
def focusNextChild(); end
def focusPreviousChild(); end
def lowerChild(); end
def raiseChild(); end
def moveChildToIndex(); end
def lockChild(); end
def unlockChild(); end
def mergeStyle(); end
def applyStyle(); end
def addAnchor(); end
def removeAnchor(); end
def fill(); end
def centerIn(); end
def breakAnchors(); end
def updateParentLayout(); end
def updateLayout(); end
def lock(); end
def unlock(); end
def focus(); end
def lower(); end
def raise(); end
def grabMouse(); end
def ungrabMouse(); end
def grabKeyboard(); end
def ungrabKeyboard(); end
def bindRectToParent(); end
def destroy(); end
def destroyChildren(); end
def setId(); end
def setParent(); end
def setLayout(); end
def setRect(); end
def setStyle(); end
def setStyleFromNode(); end
def setEnabled(); end
def setVisible(); end
def setOn(); end
def setChecked(); end
def setFocusable(); end
def setPhantom(); end
def setDragable(); end
def setFixedSize(); end
def setClipping(); end
def setLastFocusReason(); end
def setAutoRepeatDelay(); end
def setVirtualOffset(); end
def isVisible(); end
def isChildLocked(); end
def hasChild(); end
def getChildIndex(); end
def getMarginRect(); end
def getClippingRect(); end
def getChildrenRect(); end
def getAnchoredLayout(); end
def getRootParent(); end
def getChildAfter(); end
def getChildBefore(); end
def getChildById(); end
def getChildByPos(); end
def getChildByIndex(); end
def recursiveGetChildById(); end
def recursiveGetChildByPos(); end
def recursiveGetChildrenByPos(); end
def backwardsGetWidgetById(); end
def asUIWidget(); end
def resize(); end
def move(); end
def hide(); end
def show(); end
def disable(); end
def enable(); end
def isActive(); end
def isEnabled(); end
def isDisabled(); end
def isFocused(); end
def isHovered(); end
def isPressed(); end
def isFirst(); end
def isMiddle(); end
def isLast(); end
def isAlternate(); end
def isChecked(); end
def isOn(); end
def isDragging(); end
def isHidden(); end
def isExplicitlyEnabled(); end
def isExplicitlyVisible(); end
def isFocusable(); end
def isPhantom(); end
def isDragable(); end
def isFixedSize(); end
def isClipping(); end
def isDestroyed(); end
def hasChildren(); end
def containsPoint(); end
def getId(); end
def getParent(); end
def getFocusedChild(); end
def getChildren(); end
def getFirstChild(); end
def getLastChild(); end
def getLayout(); end
def getStyle(); end
def getChildCount(); end
def getLastFocusReason(); end
def getAutoRepeatDelay(); end
def getVirtualOffset(); end
def getStyleName(); end
def getLastClickPosition(); end
def setX(); end
def setY(); end
def setWidth(); end
def setHeight(); end
def setSize(); end
def setPosition(); end
def setColor(); end
def setBackgroundColor(); end
def setBackgroundOffsetX(); end
def setBackgroundOffsetY(); end
def setBackgroundOffset(); end
def setBackgroundWidth(); end
def setBackgroundHeight(); end
def setBackgroundSize(); end
def setBackgroundRect(); end
def setIcon(); end
def setIconColor(); end
def setIconOffsetX(); end
def setIconOffsetY(); end
def setIconOffset(); end
def setIconWidth(); end
def setIconHeight(); end
def setIconSize(); end
def setIconRect(); end
def setBorderWidth(); end
def setBorderWidthTop(); end
def setBorderWidthRight(); end
def setBorderWidthBottom(); end
def setBorderWidthLeft(); end
def setBorderColor(); end
def setBorderColorTop(); end
def setBorderColorRight(); end
def setBorderColorBottom(); end
def setBorderColorLeft(); end
def setMargin(); end
def setMarginHorizontal(); end
def setMarginVertical(); end
def setMarginTop(); end
def setMarginRight(); end
def setMarginBottom(); end
def setMarginLeft(); end
def setPadding(); end
def setPaddingHorizontal(); end
def setPaddingVertical(); end
def setPaddingTop(); end
def setPaddingRight(); end
def setPaddingBottom(); end
def setPaddingLeft(); end
def setOpacity(); end
def getX(); end
def getY(); end
def getPosition(); end
def getWidth(); end
def getHeight(); end
def getSize(); end
def getRect(); end
def getColor(); end
def getBackgroundColor(); end
def getBackgroundOffsetX(); end
def getBackgroundOffsetY(); end
def getBackgroundOffset(); end
def getBackgroundWidth(); end
def getBackgroundHeight(); end
def getBackgroundSize(); end
def getBackgroundRect(); end
def getIconColor(); end
def getIconOffsetX(); end
def getIconOffsetY(); end
def getIconOffset(); end
def getIconWidth(); end
def getIconHeight(); end
def getIconSize(); end
def getIconRect(); end
def getBorderTopColor(); end
def getBorderRightColor(); end
def getBorderBottomColor(); end
def getBorderLeftColor(); end
def getBorderTopWidth(); end
def getBorderRightWidth(); end
def getBorderBottomWidth(); end
def getBorderLeftWidth(); end
def getMarginTop(); end
def getMarginRight(); end
def getMarginBottom(); end
def getMarginLeft(); end
def getPaddingTop(); end
def getPaddingRight(); end
def getPaddingBottom(); end
def getPaddingLeft(); end
def getOpacity(); end
def setImageSource(); end
def setImageClip(); end
def setImageOffsetX(); end
def setImageOffsetY(); end
def setImageOffset(); end
def setImageWidth(); end
def setImageHeight(); end
def setImageSize(); end
def setImageRect(); end
def setImageColor(); end
def setImageFixedRatio(); end
def setImageRepeated(); end
def setImageSmooth(); end
def setImageBorderTop(); end
def setImageBorderRight(); end
def setImageBorderBottom(); end
def setImageBorderLeft(); end
def setImageBorder(); end
def getImageClip(); end
def getImageOffsetX(); end
def getImageOffsetY(); end
def getImageOffset(); end
def getImageWidth(); end
def getImageHeight(); end
def getImageSize(); end
def getImageRect(); end
def getImageColor(); end
def isImageFixedRatio(); end
def isImageSmooth(); end
def getImageBorderTop(); end
def getImageBorderRight(); end
def getImageBorderBottom(); end
def getImageBorderLeft(); end
def resizeToText(); end
def clearText(); end
def setText(); end
def setTextAlign(); end
def setTextOffset(); end
def setTextWrap(); end
def setTextAutoResize(); end
def setFont(); end
def getText(); end
def getDrawText(); end
def getTextAlign(); end
def getTextOffset(); end
def getTextWrap(); end
def getFont(); end
def getTextSize(); end
# @group Class Events
# Triggered when a style is applied to the widget
# @param styleName Name of the style
# @param styleNode Table containing all style tags and values
# @return [Void]
def onStyleApply(styleName, styleNode); end
# Triggered when widget size or position has changed
# @param oldRect Table containing the old geometry rect
# @param newRect Table containing the new geometry rect
# @return [Void]
def onGeometryChange(oldRect, newRect); end
# Triggered when widget's layout updates its contents
# @return [Void]
def onLayoutUpdate(); end
# Triggered when widget focus state changes
# @param focused Boolean representing the focus state
# @param reason One of the constants: *ActiveFocusReason* *MouseFocusReason* *KeyboardFocusReason*
# @return [Void]
def onFocusChange(focused, reason); end
# Triggered when child focus changes
# @return [Void]
def onChildFocusChange(focusedChild, unfocusedChild, reason); end
# Triggered when mouse enter or leaves widget area
# @return [Void]
def onHoverChange(hovered); end
# Triggered when this widget dragging begin
# @return [Boolean]
def onDragEnter(mousePos); end
# Triggered when this widget dragging end
# @return [Boolean]
def onDragLeave(droppedWidget, mousePos); end
# Triggered when moving mouse while in dragging state
# @return [Boolean]
def onDragMove(mousePos, mouseMoved); end
# Triggered when leaving other widget dragging state while the mouse is over this widget
# @return [Boolean]
def onDrop(draggedWidget, mousePos); end
# @return [Boolean]
def onKeyText(keyText); end
# @return [Boolean]
def onKeyDown(keyCode, keyboardModifiers); end
# @return [Boolean]
def onKeyPress(keyCode, keyboardModifiers, autoRepeatTicks); end
# @return [Boolean]
def onKeyUp(keyCode, keyboardModifiers); end
# @return [Boolean]
def onMousePress(mousePos, utton); end
# @return [Boolean]
def onMouseRelease(mousePos, button); end
# @return [Boolean]
def onMouseMove(mousePos, mouseMoved); end
# @return [Boolean]
def onMouseWheel(mousePos, direction); end
# Triggered when clicking and releasing the mouse left button inside widget area
# @return [Boolean]
def onClick(mousePos); end
# Triggered when pressing mouse left button two times inside widget area
# @return [Boolean]
def onDoubleClick(mousePos); end
# @endgroup
end
class g_game
def self.login(); end
def self.logout(); end
def self.loginWorld(); end
def self.cancelLogin(); end
def self.forceLogout(); end
def self.safeLogout(); end
def self.walk(); end
def self.autoWalk(); end
def self.forceWalk(); end
def self.turn(); end
def self.stop(); end
def self.look(); end
def self.move(); end
def self.moveToParentContainer(); end
def self.rotate(); end
def self.use(); end
def self.useWith(); end
def self.useInventoryItem(); end
def self.useInventoryItemWith(); end
def self.open(); end
def self.openParent(); end
def self.close(); end
def self.refreshContainer(); end
def self.attack(); end
def self.cancelAttack(); end
def self.follow(); end
def self.cancelFollow(); end
def self.cancelAttackAndFollow(); end
def self.talk(); end
def self.talkChannel(); end
def self.talkPrivate(); end
def self.openPrivateChannel(); end
def self.requestChannels(); end
def self.joinChannel(); end
def self.leaveChannel(); end
def self.closeNpcChannel(); end
def self.openOwnChannel(); end
def self.inviteToOwnChannel(); end
def self.excludeFromOwnChannel(); end
def self.partyInvite(); end
def self.partyJoin(); end
def self.partyRevokeInvitation(); end
def self.partyPassLeadership(); end
def self.partyLeave(); end
def self.partyShareExperience(); end
def self.requestOutfit(); end
def self.changeOutfit(); end
def self.addVip(); end
def self.removeVip(); end
def self.setChaseMode(); end
def self.setFightMode(); end
def self.setSafeFight(); end
def self.getChaseMode(); end
def self.getFightMode(); end
def self.isSafeFight(); end
def self.inspectNpcTrade(); end
def self.buyItem(); end
def self.sellItem(); end
def self.closeNpcTrade(); end
def self.requestTrade(); end
def self.inspectTrade(); end
def self.acceptTrade(); end
def self.rejectTrade(); end
def self.reportBug(); end
def self.reportRuleVilation(); end
def self.debugReport(); end
def self.editText(); end
def self.editList(); end
def self.requestQuestLog(); end
def self.requestQuestLine(); end
def self.canPerformGameAction(); end
def self.canReportBugs(); end
def self.checkBotProtection(); end
def self.isOnline(); end
def self.isDead(); end
def self.isAttacking(); end
def self.isFollowing(); end
def self.getContainer(); end
def self.getContainers(); end
def self.getVips(); end
def self.getAttackingCreature(); end
def self.getFollowingCreature(); end
def self.getServerBeat(); end
def self.getLocalPlayer(); end
def self.getProtocolGame(); end
def self.getProtocolVersion(); end
def self.getWorldName(); end
def self.getGMActions(); end
end

@ -1,27 +0,0 @@
include YARD
include Templates
module MyTemplateHelper
def linkify(*args)
if args.first.is_a?(String)
case args.first
when /^taghead:(\S+)/
tag_name = $1
params = args[1]
return "<h3 class=\"note\" id=\"#{tag_name}\" toc-title=\"#{tag_name}\"><strong>#{tag_name}:</strong> #{params}</h3>"
when /^valhead:(\S+)/
tag_name = $1
return "<h3 class=\"note private\" id=\"#{tag_name}\" toc-title=\"#{tag_name}\"><strong>#{tag_name}</strong></h3>"
when /^tag:(\S+)/
tag_name = $1
return "<a href=\"##{tag_name}\">#{tag_name}</a>"
else
super
end
end
super
end
end
Template.extra_includes << MyTemplateHelper
Engine.register_template_path(File.dirname(__FILE__))

@ -4,7 +4,8 @@ function Client.reloadScripts()
g_modules.reloadModules()
dofile '/otclientrc'
local message = tr('All modules and scripts were reloaded.')
TextMessage.displayEventAdvance(message)
modules.game_textmessage.displayEventAdvance(message)
print(message)
end

@ -137,7 +137,7 @@ function Options.setOption(key, value)
g_sounds.enableMusic(value)
elseif key == 'showLeftPanel' then
addEvent(function()
GameInterface.getLeftPanel():setOn(value)
modules.game_interface.getLeftPanel():setOn(value)
end)
elseif key == 'backgroundFrameRate' then
local text = value

@ -2,6 +2,7 @@
-- root widget
rootWidget = g_ui.getRootWidget()
modules = package.loaded
-- G is used as a global table to save variables in memory between reloads
G = G or {}

@ -36,7 +36,17 @@ function quit()
g_app.quit()
end
function connect(object, signalsAndSlots, pushFront)
function connect(object, arg1, arg2, arg3)
local signalsAndSlots
local pushFront
if type(arg1) == 'string' then
signalsAndSlots = { [arg1] = arg2 }
pushFront = arg3
else
signalsAndSlots = arg1
pushFront = arg2
end
for signal,slot in pairs(signalsAndSlots) do
if not object[signal] then
local mt = getmetatable(object)
@ -150,6 +160,14 @@ local function module_loader(modname)
end
table.insert(package.loaders, 1, module_loader)
function import(table)
assert(type(table) == 'table')
local env = getfenv(2)
for k,v in pairs(table) do
env[k] = v
end
end
function export(what, key)
if key ~= nil then
_G[key] = what

@ -1,45 +1,41 @@
Battle = {}
--TODO
--onCreatureAppears onCreatureHealthChange onCreatureDisappears
--reloadable/disconnects
-- private variables
local battleWindow
local battleButton
local battlePanel
local lastBattleButtonSwitched
local checkCreaturesEvent
local battleButtonsByCreaturesList = {}
battleWindow = nil
battleButton = nil
battlePanel = nil
lastBattleButtonSwitched = nil
checkCreaturesEvent = nil
battleButtonsByCreaturesList = {}
local mouseWidget
mouseWidget = nil
local hidePlayersButton
local hideNPCsButton
local hideMonstersButton
local hideSkullsButton
local hidePartyButton
hidePlayersButton = nil
hideNPCsButton = nil
hideMonstersButton = nil
hideSkullsButton = nil
hidePartyButton = nil
local battleButtonColors = {
BattleButtonColors = {
onIdle = {notHovered = '#888888', hovered = '#FFFFFF' },
onTargeted = {notHovered = '#FF0000', hovered = '#FF8888' },
onFollowed = {notHovered = '#00FF00', hovered = '#88FF88' }
}
local lifeBarColors = {} --Must be sorted by percentAbose
table.insert(lifeBarColors, {percentAbove = 92, color = '#00BC00' } )
table.insert(lifeBarColors, {percentAbove = 60, color = '#50A150' } )
table.insert(lifeBarColors, {percentAbove = 30, color = '#A1A100' } )
table.insert(lifeBarColors, {percentAbove = 8, color = '#3C2727' } )
table.insert(lifeBarColors, {percentAbove = 3, color = '#3C0000' } )
table.insert(lifeBarColors, {percentAbove = -1, color = '#4F0000' } )
-- public functions
function Battle.init()
battleWindow = g_ui.loadUI('battle.otui', GameInterface.getRightPanel())
battleButton = TopMenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', Battle.toggle)
LifeBarColors = {} --Must be sorted by percentAbose
table.insert(LifeBarColors, {percentAbove = 92, color = '#00BC00' } )
table.insert(LifeBarColors, {percentAbove = 60, color = '#50A150' } )
table.insert(LifeBarColors, {percentAbove = 30, color = '#A1A100' } )
table.insert(LifeBarColors, {percentAbove = 8, color = '#3C2727' } )
table.insert(LifeBarColors, {percentAbove = 3, color = '#3C0000' } )
table.insert(LifeBarColors, {percentAbove = -1, color = '#4F0000' } )
function init()
battleWindow = g_ui.loadUI('battle.otui', modules.game_interface.getRightPanel())
battleButton = TopMenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', toggle)
battleButton:setOn(true)
g_keyboard.bindKeyDown('Ctrl+B', Battle.toggle)
g_keyboard.bindKeyDown('Ctrl+B', toggle)
battlePanel = battleWindow:recursiveGetChildById('battlePanel')
@ -53,46 +49,32 @@ function Battle.init()
mouseWidget:setVisible(false)
mouseWidget:setFocusable(false)
connect(Creature, { onSkullChange = Battle.checkCreatureSkull,
onEmblemChange = Battle.checkCreatureEmblem } )
connect(Creature, { onSkullChange = checkCreatureSkull,
onEmblemChange = checkCreatureEmblem } )
connect(g_game, { onAttackingCreatureChange = Battle.onAttack,
onFollowingCreatureChange = Battle.onFollow,
onGameEnd = Battle.removeAllCreatures } )
connect(g_game, { onAttackingCreatureChange = onAttack,
onFollowingCreatureChange = onFollow,
onGameEnd = removeAllCreatures } )
addEvent(Battle.addAllCreatures)
checkCreaturesEvent = scheduleEvent(Battle.checkCreatures, 200)
addEvent(addAllCreatures)
checkCreaturesEvent = scheduleEvent(checkCreatures, 200)
end
function Battle.terminate()
function terminate()
g_keyboard.unbindKeyDown('Ctrl+B')
battlePanel = nil
lastBattleButtonTargeted = nil
lastBattleButtonFollowed = nil
battleButtonsByCreaturesList = {}
removeEvent(checkCreaturesEvent)
hidePlayersButton = nil
hideNPCsButton = nil
hideMonstersButton = nil
hideSkullsButton = nil
hidePartyButton = nil
checkCreaturesEvent = nil
battleButton:destroy()
battleButton = nil
battleWindow:destroy()
battleWindow = nil
mouseWidget:destroy()
mouseWidget = nil
disconnect(Creature, { onSkullChange = Battle.checkCreatureSkull,
onEmblemChange = Battle.checkCreatureEmblem } )
disconnect(g_game, { onAttackingCreatureChange = Battle.onAttack } )
disconnect(Creature, { onSkullChange = checkCreatureSkull,
onEmblemChange = checkCreatureEmblem } )
Battle = nil
disconnect(g_game, { onAttackingCreatureChange = onAttack } )
end
function Battle.toggle()
function toggle()
if battleButton:isOn() then
battleWindow:close()
battleButton:setOn(false)
@ -102,28 +84,28 @@ function Battle.toggle()
end
end
function Battle.onMiniWindowClose()
function onMiniWindowClose()
battleButton:setOn(false)
end
function Battle.addAllCreatures()
function addAllCreatures()
local spectators = {}
local player = g_game.getLocalPlayer()
if player then
creatures = g_map.getSpectators(player:getPosition(), false)
for i, creature in ipairs(creatures) do
if creature ~= player and Battle.doCreatureFitFilters(creature) then
if creature ~= player and doCreatureFitFilters(creature) then
table.insert(spectators, creature)
end
end
end
for i, v in pairs(spectators) do
Battle.addCreature(v)
addCreature(v)
end
end
function Battle.doCreatureFitFilters(creature)
function doCreatureFitFilters(creature)
local hidePlayers = hidePlayersButton:isChecked()
local hideNPCs = hideNPCsButton:isChecked()
local hideMonsters = hideMonstersButton:isChecked()
@ -145,7 +127,7 @@ function Battle.doCreatureFitFilters(creature)
return true
end
function Battle.checkCreatures(forceRecheck)
function checkCreatures(forceRecheck)
local player = g_game.getLocalPlayer()
if player then
local spectators = {}
@ -154,20 +136,20 @@ function Battle.checkCreatures(forceRecheck)
local creaturesAppeared = {}
creatures = g_map.getSpectators(player:getPosition(), false)
for i, creature in ipairs(creatures) do
if creature ~= player and Battle.doCreatureFitFilters(creature) then
if creature ~= player and doCreatureFitFilters(creature) then
-- searching for creatures that appeared on battle list
local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton == nil then
table.insert(creaturesAppeared, creature)
else
Battle.setLifeBarPercent(battleButton, creature:getHealthPercent())
setLifeBarPercent(battleButton, creature:getHealthPercent())
end
spectators[creature:getId()] = creature
end
end
for i, v in pairs(creaturesAppeared) do
Battle.addCreature(v)
addCreature(v)
end
-- searching for creatures that disappeared from battle list
@ -179,15 +161,15 @@ function Battle.checkCreatures(forceRecheck)
end
for i, v in pairs(creaturesDisappeared) do
Battle.removeCreature(v)
removeCreature(v)
end
end
if not forceRecheck then
checkCreaturesEvent = scheduleEvent(Battle.checkCreatures, 500)
checkCreaturesEvent = scheduleEvent(checkCreatures, 500)
end
end
function Battle.addCreature(creature)
function addCreature(creature)
local creatureId = creature:getId()
if battleButtonsByCreaturesList[creatureId] == nil then
@ -205,16 +187,16 @@ function Battle.addCreature(creature)
labelWidget:setText(creature:getName())
creatureWidget:setCreature(creature)
Battle.setLifeBarPercent(battleButton, creature:getHealthPercent())
setLifeBarPercent(battleButton, creature:getHealthPercent())
battleButtonsByCreaturesList[creatureId] = battleButton
Battle.checkCreatureSkull(battleButton.creature)
Battle.checkCreatureEmblem(battleButton.creature)
checkCreatureSkull(battleButton.creature)
checkCreatureEmblem(battleButton.creature)
end
end
function Battle.checkCreatureSkull(creature, skullId)
function checkCreatureSkull(creature, skullId)
local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton then
local skullWidget = battleButton:getChildById('skull')
@ -235,7 +217,7 @@ function Battle.checkCreatureSkull(creature, skullId)
end
end
function Battle.checkCreatureEmblem(creature, emblemId)
function checkCreatureEmblem(creature, emblemId)
local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton then
local emblemId = emblemId or creature:getEmblem()
@ -259,9 +241,9 @@ function Battle.checkCreatureEmblem(creature, emblemId)
end
end
function Battle.onMouseRelease(self, mousePosition, mouseButton)
function onMouseRelease(self, mousePosition, mouseButton)
if mouseButton == MouseRightButton then
GameInterface.createThingMenu(mousePosition, nil, nil, self.creature)
modules.game_interface.createThingMenu(mousePosition, nil, nil, self.creature)
return true
elseif mouseButton == MouseLeftButton then
if g_keyboard.isShiftPressed() then
@ -277,13 +259,13 @@ function Battle.onMouseRelease(self, mousePosition, mouseButton)
end
end
function Battle.removeAllCreatures()
function removeAllCreatures()
for i, v in pairs(battleButtonsByCreaturesList) do
Battle.removeCreature(v.creature)
removeCreature(v.creature)
end
end
function Battle.removeCreature(creature)
function removeCreature(creature)
local creatureId = creature:getId()
if battleButtonsByCreaturesList[creatureId] ~= nil then
@ -297,12 +279,12 @@ function Battle.removeCreature(creature)
end
end
function Battle.setLifeBarPercent(battleButton, percent)
function setLifeBarPercent(battleButton, percent)
local lifeBarWidget = battleButton:getChildById('lifeBar')
lifeBarWidget:setPercent(percent)
local color
for i, v in pairs(lifeBarColors) do
for i, v in pairs(LifeBarColors) do
if percent > v.percentAbove then
color = v.color
break
@ -312,37 +294,37 @@ function Battle.setLifeBarPercent(battleButton, percent)
lifeBarWidget:setBackgroundColor(color)
end
function Battle.onbattleButtonHoverChange(widget, hovered)
function onbattleButtonHoverChange(widget, hovered)
if widget.isBattleButton then
widget.isHovered = hovered
Battle.checkBattleButton(widget)
checkBattleButton(widget)
end
end
function Battle.onAttack(creature)
Battle.checkCreatures(true) --Force recheck
function onAttack(creature)
checkCreatures(true) --Force recheck
local battleButton = creature and battleButtonsByCreaturesList[creature:getId()] or lastBattleButtonSwitched
if battleButton then
battleButton.isTarget = creature and true or false
Battle.checkBattleButton(battleButton)
checkBattleButton(battleButton)
end
end
function Battle.onFollow(creature)
Battle.checkCreatures(true) --Force recheck
function onFollow(creature)
checkCreatures(true) --Force recheck
local battleButton = creature and battleButtonsByCreaturesList[creature:getId()] or lastBattleButtonSwitched
if battleButton then
battleButton.isFollowed = creature and true or false
Battle.checkBattleButton(battleButton)
checkBattleButton(battleButton)
end
end
function Battle.checkBattleButton(battleButton)
local color = battleButtonColors.onIdle
function checkBattleButton(battleButton)
local color = BattleButtonColors.onIdle
if battleButton.isTarget then
color = battleButtonColors.onTargeted
color = BattleButtonColors.onTargeted
elseif battleButton.isFollowed then
color = battleButtonColors.onFollowed
color = BattleButtonColors.onFollowed
end
color = battleButton.isHovered and color.hovered or color.notHovered
@ -363,7 +345,7 @@ function Battle.checkBattleButton(battleButton)
if lastBattleButtonSwitched and lastBattleButtonSwitched ~= battleButton then
lastBattleButtonSwitched.isTarget = false
lastBattleButtonSwitched.isFollowed = false
Battle.checkBattleButton(lastBattleButtonSwitched)
checkBattleButton(lastBattleButtonSwitched)
end
lastBattleButtonSwitched = battleButton
end

@ -3,15 +3,7 @@ Module
description: Manage battle window
author: andrefaramir, BeniS
website: www.otclient.info
icon: battle.png
dependencies:
- game_interface
@onLoad: |
dofile 'battle'
Battle.init()
@onUnload: |
Battle.terminate()
sandboxed: true
scripts: [ battle.lua ]
@onLoad: init()
@onUnload: terminate()

@ -41,7 +41,7 @@ MiniWindow
!text: tr('Battle')
height: 166
icon: battle.png
@onClose: Battle.onMiniWindowClose()
@onClose: onMiniWindowClose()
&save: true
MiniWindowContents

@ -4,8 +4,8 @@ BattleButton
height: 20
margin-top: 5
fixed-size: true
&onHoverChange: Battle.onbattleButtonHoverChange
&onMouseRelease: Battle.onMouseRelease
&onHoverChange: onbattleButtonHoverChange
&onMouseRelease: onMouseRelease
&isBattleButton: true
UICreature

@ -1,10 +1,9 @@
BugReport = {}
HOTKEY = 'Ctrl+Z'
local bugReportWindow
local bugTextEdit
local HOTKEY = 'Ctrl+Z'
bugReportWindow = nil
bugTextEdit = nil
function BugReport.init()
function init()
g_ui.importStyle('bugreport.otui')
bugReportWindow = g_ui.createWidget('BugReportWindow', rootWidget)
@ -12,23 +11,21 @@ function BugReport.init()
bugTextEdit = bugReportWindow:getChildById('bugTextEdit')
g_keyboard.bindKeyDown(HOTKEY, BugReport.show)
g_keyboard.bindKeyDown(HOTKEY, show)
end
function BugReport.terminate()
function terminate()
g_keyboard.unbindKeyDown(HOTKEY)
bugReportWindow:destroy()
bugReportWindow = nil
bugTextEdit = nil
end
function BugReport.doReport()
function doReport()
g_game.reportBug(bugTextEdit:getText())
bugReportWindow:hide()
TextMessage.displayEventAdvance(tr('Bug report sent.'))
modules.game_textmessage.displayEventAdvance(tr('Bug report sent.'))
end
function BugReport.show()
function show()
bugTextEdit:setText('')
bugReportWindow:show()
bugReportWindow:raise()

@ -3,13 +3,7 @@ Module
description: Bug report interface (Ctrl+Z)
author: edubart
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'bugreport'
BugReport.init()
@onUnload: |
BugReport.terminate()
scripts: [ bugreport.lua ]
sandboxed: true
@onLoad: init()
@onUnload: terminate()

@ -28,7 +28,7 @@ BugReportWindow < MainWindow
anchors.right: cancelButton.left
margin-right: 10
width: 80
&onClick: BugReport.doReport
&onClick: doReport
Button
id: cancelButton

@ -1,49 +1,16 @@
CombatControls = {}
-- private variables
local combatControlsButton
local combatControlsWindow
local fightOffensiveBox
local fightBalancedBox
local fightDefensiveBox
local chaseModeButton
local safeFightButton
local fightModeRadioGroup
-- private functions
local function onSetFightMode(self, selectedFightButton)
if selectedFightButton == nil then return end
local buttonId = selectedFightButton:getId()
local fightMode
if buttonId == 'fightOffensiveBox' then
fightMode = FightOffensive
elseif buttonId == 'fightBalancedBox' then
fightMode = FightBalanced
else
fightMode = FightDefensive
end
g_game.setFightMode(fightMode)
end
local function onSetChaseMode(self, checked)
local chaseMode
if checked then
chaseMode = ChaseOpponent
else
chaseMode = DontChase
end
g_game.setChaseMode(chaseMode)
end
local function onSetSafeFight(self, checked)
g_game.setSafeFight(not checked)
end
-- public functions
function CombatControls.init()
combatControlsButton = TopMenu.addRightGameToggleButton('combatControlsButton', tr('Combat Controls'), 'combatcontrols.png', CombatControls.toggle)
combatControlsButton = nil
combatControlsWindow = nil
fightOffensiveBox = nil
fightBalancedBox = nil
fightDefensiveBox = nil
chaseModeButton = nil
safeFightButton = nil
fightModeRadioGroup = nil
function init()
combatControlsButton = TopMenu.addRightGameToggleButton('combatControlsButton', tr('Combat Controls'), 'combatcontrols.png', toggle)
combatControlsButton:setOn(true)
combatControlsWindow = g_ui.loadUI('combatcontrols.otui', GameInterface.getRightPanel())
combatControlsWindow = g_ui.loadUI('combatcontrols.otui', modules.game_interface.getRightPanel())
combatControlsWindow:disableResize()
fightOffensiveBox = combatControlsWindow:recursiveGetChildById('fightOffensiveBox')
@ -61,52 +28,39 @@ function CombatControls.init()
connect(chaseModeButton, { onCheckChange = onSetChaseMode })
connect(safeFightButton, { onCheckChange = onSetSafeFight })
connect(g_game, {
onGameStart = CombatControls.online,
onGameEnd = CombatControls.offline,
onFightModeChange = CombatControls.update,
onChaseModeChange = CombatControls.update,
onSafeFightChange = CombatControls.update,
onWalk = CombatControls.check
onGameStart = online,
onGameEnd = offline,
onFightModeChange = update,
onChaseModeChange = update,
onSafeFightChange = update,
onWalk = check
})
if g_game.isOnline() then
CombatControls.online()
online()
end
end
function CombatControls.terminate()
function terminate()
if g_game.isOnline() then
CombatControls.offline()
offline()
end
fightModeRadioGroup:destroy()
fightModeRadioGroup = nil
fightOffensiveBox = nil
fightBalancedBox = nil
fightDefensiveBox = nil
chaseModeButton = nil
safeFightButton = nil
combatControlsButton:destroy()
combatControlsButton = nil
combatControlsWindow:destroy()
combatControlsWindow = nil
disconnect(g_game, {
onGameStart = CombatControls.online,
onGameEnd = CombatControls.offline,
onFightModeChange = CombatControls.update,
onChaseModeChange = CombatControls.update,
onSafeFightChange = CombatControls.update,
onWalk = CombatControls.check
onGameStart = online,
onGameEnd = offline,
onFightModeChange = update,
onChaseModeChange = update,
onSafeFightChange = update,
onWalk = check
})
CombatControls = nil
end
function CombatControls.update()
function update()
local fightMode = g_game.getFightMode()
if fightMode == FightOffensive then
fightModeRadioGroup:selectWidget(fightOffensiveBox)
@ -123,7 +77,7 @@ function CombatControls.update()
safeFightButton:setChecked(not safeFight)
end
function CombatControls.check()
function check()
if(Options.getOption('autoChaseOverride')) then
if(g_game.isAttacking() and g_game.getChaseMode() == ChaseOpponent) then
g_game.setChaseMode(DontChase)
@ -131,7 +85,7 @@ function CombatControls.check()
end
end
function CombatControls.online()
function online()
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
@ -148,10 +102,10 @@ function CombatControls.online()
end
combatControlsWindow:setVisible(combatControlsButton:isOn())
CombatControls.update()
update()
end
function CombatControls.offline()
function offline()
local lastCombatControls = g_settings.getNode('LastCombatControls')
if(not lastCombatControls) then
lastCombatControls = {}
@ -171,7 +125,7 @@ function CombatControls.offline()
end
end
function CombatControls.toggle()
function toggle()
if combatControlsButton:isOn() then
combatControlsWindow:close()
combatControlsButton:setOn(false)
@ -181,6 +135,34 @@ function CombatControls.toggle()
end
end
function CombatControls.onMiniWindowClose()
function onMiniWindowClose()
combatControlsButton:setOn(false)
end
function onSetFightMode(self, selectedFightButton)
if selectedFightButton == nil then return end
local buttonId = selectedFightButton:getId()
local fightMode
if buttonId == 'fightOffensiveBox' then
fightMode = FightOffensive
elseif buttonId == 'fightBalancedBox' then
fightMode = FightBalanced
else
fightMode = FightDefensive
end
g_game.setFightMode(fightMode)
end
function onSetChaseMode(self, checked)
local chaseMode
if checked then
chaseMode = ChaseOpponent
else
chaseMode = DontChase
end
g_game.setChaseMode(chaseMode)
end
function onSetSafeFight(self, checked)
g_game.setSafeFight(not checked)
end

@ -3,13 +3,7 @@ Module
description: Combat controls window
author: edubart, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'combatcontrols'
CombatControls.init()
@onUnload: |
CombatControls.terminate()
sandboxed: true
scripts: [ combatcontrols.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,7 +1,4 @@
Console = {}
-- private variables
local SpeakTypesSettings = {
SpeakTypesSettings = {
say = { speakType = SpeakSay, color = '#FFFF00' },
whisper = { speakType = SpeakWhisper, color = '#FFFF00' },
yell = { speakType = SpeakYell, color = '#FFFF00' },
@ -19,7 +16,7 @@ local SpeakTypesSettings = {
monsterYell = { speakType = SpeakMonsterYell, color = '#FE6500', hideInConsole = true},
}
local SpeakTypes = {
SpeakTypes = {
[SpeakSay] = SpeakTypesSettings.say,
[SpeakWhisper] = SpeakTypesSettings.whisper,
[SpeakYell] = SpeakTypesSettings.yell,
@ -36,235 +33,29 @@ local SpeakTypes = {
[SpeakMonsterYell] = SpeakTypesSettings.monsterYell,
}
local SayModes = {
SayModes = {
[1] = { speakTypeDesc = 'whisper', icon = 'icons/whisper.png' },
[2] = { speakTypeDesc = 'say', icon = 'icons/say.png' },
[3] = { speakTypeDesc = 'yell', icon = 'icons/yell.png' }
}
local MAX_HISTORY = 1000
local MAX_LINES = 100
local HELP_CHANNEL = 9
local consolePanel
local consoleContentPanel
local consoleTabBar
local consoleTextEdit
local channels
local channelsWindow
local ownPrivateName
local messageHistory = {}
local currentMessageIndex = 0
local ignoreNpcMessages = false
-- private functions
local function navigateMessageHistory(step)
local numCommands = #messageHistory
if numCommands > 0 then
currentMessageIndex = math.min(math.max(currentMessageIndex + step, 0), numCommands)
if currentMessageIndex > 0 then
local command = messageHistory[numCommands - currentMessageIndex + 1]
consoleTextEdit:setText(command)
else
consoleTextEdit:clearText()
end
end
end
function applyMessagePrefixies(name, level, message)
if name then
if Options.getOption('showLevelsInConsole') and level > 0 then
message = name .. ' [' .. level .. ']: ' .. message
else
message = name .. ': ' .. message
end
end
return message
end
-- hooked events
local function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos)
if ignoreNpcMessages and speaktype == SpeakPrivateNpcToPlayer then return end
local defaultMessage = speaktype < 3 and true or false
speaktype = SpeakTypes[speaktype]
if speaktype.hideInConsole then return end
local composedMessage = applyMessagePrefixies(name, level, message)
if speaktype.private then
Console.addPrivateText(composedMessage, speaktype, name, false, name)
if Options.getOption('showPrivateMessagesOnScreen') then
if(speaktype.speakType ~= SpeakPrivateNpcToPlayer) then
TextMessage.displayPrivate(name .. ':\n' .. message)
end
end
else
local channel = tr('Default')
if not defaultMessage then
channel = channels[channelId]
end
if channel then
Console.addText(composedMessage, speaktype, channel, name)
elseif channelId ~= 0 then
-- server sent a message on a channel that is not open
pwarning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel')
end
end
end
local function onOpenChannel(channelId, channelName)
Console.addChannel(channelName, channelId)
end
local function onOpenPrivateChannel(receiver)
Console.addPrivateChannel(receiver)
end
local function onOpenOwnPrivateChannel(channelId, channelName)
local privateTab = Console.getTab(channelName)
if privateTab == nil then
Console.addChannel(channelName, channelId)
end
ownPrivateName = channelName
end
local function onCloseChannel(channelId)
local channel = channels[channelId]
if channel then
local tab = Console.getTab(channel)
if tab then
consoleTabBar:removeTab(tab)
end
for k, v in pairs(channels) do
if (k == tab.channelId) then channels[k] = nil end
end
end
end
MAX_HISTORY = 1000
MAX_LINES = 100
HELP_CHANNEL = 9
local function doChannelListSubmit()
local channelListPanel = channelsWindow:getChildById('channelList')
local openPrivateChannelWith = channelsWindow:getChildById('openPrivateChannelWith'):getText()
if openPrivateChannelWith ~= '' then
g_game.openPrivateChannel(openPrivateChannelWith)
else
local selectedChannelLabel = channelListPanel:getFocusedChild()
if not selectedChannelLabel then return end
if selectedChannelLabel.channelId == 0xFFFF then
g_game.openOwnChannel()
else
g_game.joinChannel(selectedChannelLabel.channelId)
end
end
consolePanel = nil
consoleContentPanel = nil
consoleTabBar = nil
consoleTextEdit = nil
channels = nil
channelsWindow = nil
ownPrivateName = nil
messageHistory = {}
currentMessageIndex = 0
ignoreNpcMessages = false
channelsWindow:destroy()
end
local function onChannelList(channelList)
if channelsWindow then channelsWindow:destroy() end
channelsWindow = g_ui.displayUI('channelswindow.otui')
local channelListPanel = channelsWindow:getChildById('channelList')
channelsWindow.onEnter = doChannelListSubmit
channelsWindow.onDestroy = function() channelsWindow = nil end
g_keyboard.bindKeyPress('Down', function() channelListPanel:focusNextChild(KeyboardFocusReason) end, channelsWindow)
g_keyboard.bindKeyPress('Up', function() channelListPanel:focusPreviousChild(KeyboardFocusReason) end, channelsWindow)
for k,v in pairs(channelList) do
local channelId = v[1]
local channelName = v[2]
if #channelName > 0 then
local label = g_ui.createWidget('ChannelListLabel', channelListPanel)
label.channelId = channelId
label:setText(channelName)
label:setPhantom(false)
label.onDoubleClick = doChannelListSubmit
end
end
end
local function onGameStart()
-- open last channels
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
local lastChannelsOpen = g_settings.getNode('LastChannelsOpen')
if(not table.empty(lastChannelsOpen) and lastChannelsOpen[char]) then
for channelName, channelId in ipairs(lastChannelsOpen[char]) do
channelId = tonumber(channelId)
if channelId ~= 0 then
if not table.find(channels, channelId) then
g_game.joinChannel(channelId)
end
end
end
end
end
local tab = Console.getTab(tr('Default'))
if tab then
--[[
Known Issue: The server is calling to open channels after
onGameStart is executed causing it to focus the last tab opened.
Fix: Don't save channels to the settings that are opened by the server.
]]
addEvent(function() consoleTabBar:selectTab(tab) end, true)
end
end
function Console.onTabChange(tabBar, tab)
if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then
consolePanel:getChildById('closeChannelButton'):disable()
else
consolePanel:getChildById('closeChannelButton'):enable()
end
end
function Console.clear()
local lastChannelsOpen = {}
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
lastChannelsOpen[char] = {}
for channelId, channelName in pairs(channels) do
table.insert(lastChannelsOpen[char], channelId)
end
end
-- save last open channels
g_settings.setNode('LastChannelsOpen', lastChannelsOpen)
for _, channelName in pairs(channels) do
local tab = consoleTabBar:getTab(channelName)
consoleTabBar:removeTab(tab)
end
channels = {}
consoleTabBar:getTab(tr('Default')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
consoleTabBar:getTab(tr('Server Log')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
local npcTab = consoleTabBar:getTab('NPCs')
if npcTab then
consoleTabBar:removeTab(npcTab)
end
consoleTextEdit:clearText()
if channelsWindow then
channelsWindow:destroy()
channelsWindow = nil
end
end
-- public functions
function Console.init()
function init()
connect(g_game, { onCreatureSpeak = onCreatureSpeak,
onChannelList = onChannelList,
onOpenChannel = onOpenChannel,
@ -272,37 +63,37 @@ function Console.init()
onOpenOwnPrivateChannel = onOpenOwnPrivateChannel,
onCloseChannel = onCloseChannel,
onGameStart = onGameStart,
onGameEnd = Console.clear })
onGameEnd = clear })
consolePanel = g_ui.loadUI('console.otui', GameInterface.getBottomPanel())
consolePanel = g_ui.loadUI('console.otui', modules.game_interface.getBottomPanel())
consoleTextEdit = consolePanel:getChildById('consoleTextEdit')
consoleContentPanel = consolePanel:getChildById('consoleContentPanel')
consoleTabBar = consolePanel:getChildById('consoleTabBar')
consoleTabBar:setContentWidget(consoleContentPanel)
channels = {}
Console.addTab(tr('Default'), true)
Console.addTab(tr('Server Log'), false)
addTab(tr('Default'), true)
addTab(tr('Server Log'), false)
g_keyboard.bindKeyPress('Shift+Up', function() navigateMessageHistory(1) end, consolePanel)
g_keyboard.bindKeyPress('Shift+Down', function() navigateMessageHistory(-1) end, consolePanel)
g_keyboard.bindKeyPress('Tab', function() consoleTabBar:selectNextTab() end, consolePanel)
g_keyboard.bindKeyPress('Shift+Tab', function() consoleTabBar:selectPrevTab() end, consolePanel)
g_keyboard.bindKeyDown('Enter', Console.sendCurrentMessage, consolePanel)
g_keyboard.bindKeyDown('Enter', sendCurrentMessage, consolePanel)
g_keyboard.bindKeyPress('Ctrl+A', function() consoleTextEdit:clearText() end, consolePanel)
-- apply buttom functions after loaded
consolePanel:getChildById('nextChannelButton').onClick = function() consoleTabBar:selectNextTab() end
consolePanel:getChildById('prevChannelButton').onClick = function() consoleTabBar:selectPrevTab() end
consoleTabBar.onTabChange = Console.onTabChange
consoleTabBar.onTabChange = onTabChange
-- tibia like hotkeys
g_keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels)
g_keyboard.bindKeyDown('Ctrl+E', Console.removeCurrentTab)
g_keyboard.bindKeyDown('Ctrl+H', Console.openHelp)
g_keyboard.bindKeyDown('Ctrl+E', removeCurrentTab)
g_keyboard.bindKeyDown('Ctrl+H', openHelp)
end
function Console.terminate()
function terminate()
disconnect(g_game, { onCreatureSpeak = onCreatureSpeak,
onChannelList = onChannelList,
onOpenChannel = onOpenChannel,
@ -310,7 +101,7 @@ function Console.terminate()
onOpenOwnPrivateChannel = onOpenPrivateChannel,
onCloseChannel = onCloseChannel,
onGameStart = onGameStart,
onGameEnd = Console.clear })
onGameEnd = clear })
for channelid, channelname in pairs(channels) do
if tonumber(channelid) and tonumber(channelid) ~= 0 then
@ -339,16 +130,63 @@ function Console.terminate()
Console = nil
end
function Console.setTextEditText(text)
function onTabChange(tabBar, tab)
if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then
consolePanel:getChildById('closeChannelButton'):disable()
else
consolePanel:getChildById('closeChannelButton'):enable()
end
end
function clear()
local lastChannelsOpen = {}
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
lastChannelsOpen[char] = {}
for channelId, channelName in pairs(channels) do
table.insert(lastChannelsOpen[char], channelId)
end
end
-- save last open channels
g_settings.setNode('LastChannelsOpen', lastChannelsOpen)
for _, channelName in pairs(channels) do
local tab = consoleTabBar:getTab(channelName)
consoleTabBar:removeTab(tab)
end
channels = {}
consoleTabBar:getTab(tr('Default')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
consoleTabBar:getTab(tr('Server Log')).tabPanel:getChildById('consoleBuffer'):destroyChildren()
local npcTab = consoleTabBar:getTab('NPCs')
if npcTab then
consoleTabBar:removeTab(npcTab)
end
consoleTextEdit:clearText()
if channelsWindow then
channelsWindow:destroy()
channelsWindow = nil
end
end
function setTextEditText(text)
consoleTextEdit:setText(text)
end
function Console.openHelp()
function openHelp()
g_game.joinChannel(HELP_CHANNEL)
end
function Console.addTab(name, focus)
local tab = Console.getTab(name)
function addTab(name, focus)
local tab = getTab(name)
if(tab) then -- is channel already open
if(not focus) then focus = true end
else
@ -362,7 +200,7 @@ function Console.addTab(name, focus)
return tab
end
function Console.removeCurrentTab()
function removeCurrentTab()
local tab = consoleTabBar:getCurrentTab()
if tab:getText() == tr('Default') or tab:getText() == tr('Server Log') then return end
@ -379,56 +217,56 @@ function Console.removeCurrentTab()
consoleTabBar:removeTab(tab)
end
function Console.getTab(name)
function getTab(name)
return consoleTabBar:getTab(name)
end
function Console.getCurrentTab()
function getCurrentTab()
return consoleTabBar:getCurrentTab()
end
function Console.addChannel(name, id)
function addChannel(name, id)
channels[id] = name
local tab = Console.addTab(name, true)
local tab = addTab(name, true)
tab.channelId = id
return tab
end
function Console.addPrivateChannel(receiver)
function addPrivateChannel(receiver)
channels[receiver] = receiver
return Console.addTab(receiver, true)
return addTab(receiver, true)
end
function Console.addPrivateText(text, speaktype, name, isPrivateCommand, creatureName)
function addPrivateText(text, speaktype, name, isPrivateCommand, creatureName)
local focus = false
if speaktype.speakType == SpeakPrivateNpcToPlayer then
name = 'NPCs'
focus = true
end
local privateTab = Console.getTab(name)
local privateTab = getTab(name)
if privateTab == nil then
if (Options.getOption('showPrivateMessagesInConsole') and not focus) or (isPrivateCommand and not privateTab) then
privateTab = Console.getTab(tr('Default'))
privateTab = getTab(tr('Default'))
else
privateTab = Console.addTab(name, focus)
privateTab = addTab(name, focus)
channels[name] = name
end
privateTab.npcChat = speaktype.npcChat
elseif focus then
consoleTabBar:selectTab(privateTab)
end
Console.addTabText(text, speaktype, privateTab, creatureName)
addTabText(text, speaktype, privateTab, creatureName)
end
function Console.addText(text, speaktype, tabName, creatureName)
local tab = Console.getTab(tabName)
function addText(text, speaktype, tabName, creatureName)
local tab = getTab(tabName)
if tab ~= nil then
Console.addTabText(text, speaktype, tab, creatureName)
addTabText(text, speaktype, tab, creatureName)
end
end
function Console.addTabText(text, speaktype, tab, creatureName)
function addTabText(text, speaktype, tab, creatureName)
if Options.getOption('showTimestampsInConsole') then
text = os.date('%H:%M') .. ' ' .. text
end
@ -441,14 +279,14 @@ function Console.addTabText(text, speaktype, tab, creatureName)
label:setColor(speaktype.color)
consoleTabBar:blinkTab(tab)
label.onMouseRelease = function (self, mousePos, mouseButton) Console.popupMenu(mousePos, mouseButton, creatureName, text) end
label.onMouseRelease = function (self, mousePos, mouseButton) popupMenu(mousePos, mouseButton, creatureName, text) end
if consoleBuffer:getChildCount() > MAX_LINES then
consoleBuffer:getFirstChild():destroy()
end
end
function Console.popupMenu(mousePos, mouseButton, creatureName, text)
function popupMenu(mousePos, mouseButton, creatureName, text)
if mouseButton == MouseRightButton then
local menu = g_ui.createWidget('PopupMenu')
if creatureName then
@ -478,13 +316,13 @@ function Console.popupMenu(mousePos, mouseButton, creatureName, text)
end
end
function Console.sendCurrentMessage()
function sendCurrentMessage()
local message = consoleTextEdit:getText()
if #message == 0 then return end
consoleTextEdit:clearText()
-- get current channel
local tab = Console.getCurrentTab()
local tab = getCurrentTab()
-- handling chat commands
local originalMessage = message
@ -527,7 +365,7 @@ function Console.sendCurrentMessage()
-- when talking on server log, the message goes to default channel
local name = tab:getText()
if name == tr('Server Log') then
tab = Console.getTab(tr('Default'))
tab = getTab(tr('Default'))
name = tr('Default')
end
@ -535,7 +373,7 @@ function Console.sendCurrentMessage()
if (tab.channelId or name == tr('Default')) and not chatCommandPrivateReady then
if name == tr('Default') then
speaktypedesc = chatCommandSayMode or SayModes[consolePanel:getChildById('sayModeButton').sayMode].speakTypeDesc
if speaktypedesc ~= 'say' then Console.sayModeChange(2) end -- head back to say mode
if speaktypedesc ~= 'say' then sayModeChange(2) end -- head back to say mode
else
speaktypedesc = 'channelYellow'
end
@ -560,11 +398,11 @@ function Console.sendCurrentMessage()
g_game.talkPrivate(speaktype.speakType, name, message)
message = applyMessagePrefixies(player:getName(), player:getLevel(), message)
Console.addPrivateText(message, speaktype, name, isPrivateCommand, g_game.getCharacterName())
addPrivateText(message, speaktype, name, isPrivateCommand, g_game.getCharacterName())
end
end
function Console.sayModeChange(sayMode)
function sayModeChange(sayMode)
local buttom = consolePanel:getChildById('sayModeButton')
if sayMode == nil then
sayMode = buttom.sayMode + 1
@ -576,11 +414,170 @@ function Console.sayModeChange(sayMode)
buttom.sayMode = sayMode
end
function Console.getOwnPrivateTab()
function getOwnPrivateTab()
if not ownPrivateName then return end
return Console.getTab(ownPrivateName)
return getTab(ownPrivateName)
end
function Console.ignoreNpcMessages(ignore)
function ignoreNpcMessages(ignore)
ignoreNpcMessages = ignore
end
function navigateMessageHistory(step)
local numCommands = #messageHistory
if numCommands > 0 then
currentMessageIndex = math.min(math.max(currentMessageIndex + step, 0), numCommands)
if currentMessageIndex > 0 then
local command = messageHistory[numCommands - currentMessageIndex + 1]
consoleTextEdit:setText(command)
else
consoleTextEdit:clearText()
end
end
end
function applyMessagePrefixies(name, level, message)
if name then
if Options.getOption('showLevelsInConsole') and level > 0 then
message = name .. ' [' .. level .. ']: ' .. message
else
message = name .. ': ' .. message
end
end
return message
end
function onCreatureSpeak(name, level, speaktype, message, channelId, creaturePos)
if ignoreNpcMessages and speaktype == SpeakPrivateNpcToPlayer then return end
local defaultMessage = speaktype < 3 and true or false
speaktype = SpeakTypes[speaktype]
if speaktype.hideInConsole then return end
local composedMessage = applyMessagePrefixies(name, level, message)
if speaktype.private then
addPrivateText(composedMessage, speaktype, name, false, name)
if Options.getOption('showPrivateMessagesOnScreen') then
if(speaktype.speakType ~= SpeakPrivateNpcToPlayer) then
TextMessage.displayPrivate(name .. ':\n' .. message)
end
end
else
local channel = tr('Default')
if not defaultMessage then
channel = channels[channelId]
end
if channel then
addText(composedMessage, speaktype, channel, name)
elseif channelId ~= 0 then
-- server sent a message on a channel that is not open
pwarning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel')
end
end
end
local function onOpenChannel(channelId, channelName)
addChannel(channelName, channelId)
end
local function onOpenPrivateChannel(receiver)
addPrivateChannel(receiver)
end
local function onOpenOwnPrivateChannel(channelId, channelName)
local privateTab = getTab(channelName)
if privateTab == nil then
addChannel(channelName, channelId)
end
ownPrivateName = channelName
end
local function onCloseChannel(channelId)
local channel = channels[channelId]
if channel then
local tab = getTab(channel)
if tab then
consoleTabBar:removeTab(tab)
end
for k, v in pairs(channels) do
if (k == tab.channelId) then channels[k] = nil end
end
end
end
local function doChannelListSubmit()
local channelListPanel = channelsWindow:getChildById('channelList')
local openPrivateChannelWith = channelsWindow:getChildById('openPrivateChannelWith'):getText()
if openPrivateChannelWith ~= '' then
g_game.openPrivateChannel(openPrivateChannelWith)
else
local selectedChannelLabel = channelListPanel:getFocusedChild()
if not selectedChannelLabel then return end
if selectedChannelLabel.channelId == 0xFFFF then
g_game.openOwnChannel()
else
g_game.joinChannel(selectedChannelLabel.channelId)
end
end
channelsWindow:destroy()
end
local function onChannelList(channelList)
if channelsWindow then channelsWindow:destroy() end
channelsWindow = g_ui.displayUI('channelswindow.otui')
local channelListPanel = channelsWindow:getChildById('channelList')
channelsWindow.onEnter = doChannelListSubmit
channelsWindow.onDestroy = function() channelsWindow = nil end
g_keyboard.bindKeyPress('Down', function() channelListPanel:focusNextChild(KeyboardFocusReason) end, channelsWindow)
g_keyboard.bindKeyPress('Up', function() channelListPanel:focusPreviousChild(KeyboardFocusReason) end, channelsWindow)
for k,v in pairs(channelList) do
local channelId = v[1]
local channelName = v[2]
if #channelName > 0 then
local label = g_ui.createWidget('ChannelListLabel', channelListPanel)
label.channelId = channelId
label:setText(channelName)
label:setPhantom(false)
label.onDoubleClick = doChannelListSubmit
end
end
end
local function onGameStart()
-- open last channels
local player = g_game.getLocalPlayer()
if(player) then
local char = player:getName()
local lastChannelsOpen = g_settings.getNode('LastChannelsOpen')
if(not table.empty(lastChannelsOpen) and lastChannelsOpen[char]) then
for channelName, channelId in ipairs(lastChannelsOpen[char]) do
channelId = tonumber(channelId)
if channelId ~= 0 then
if not table.find(channels, channelId) then
g_game.joinChannel(channelId)
end
end
end
end
end
local tab = getTab(tr('Default'))
if tab then
--[[
Known Issue: The server is calling to open channels after
onGameStart is executed causing it to focus the last tab opened.
Fix: Don't save channels to the settings that are opened by the server.
]]
addEvent(function() consoleTabBar:selectTab(tab) end, true)
end
end

@ -3,13 +3,7 @@ Module
description: Manage chat window
author: edubart, andrefaramir, baxnie, sn4ake, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'console'
Console.init()
@onUnload: |
Console.terminate()
sandboxed: true
scripts: [ console.lua ]
@onLoad: init()
@onUnload: terminate()

@ -71,7 +71,7 @@ Panel
enabled: false
margin-right: 5
margin-top: 6
@onClick: Console.removeCurrentTab()
@onClick: removeCurrentTab()
TabButton
id: clearChannelButton
@ -118,7 +118,7 @@ Panel
anchors.bottom: parent.bottom
margin-left: 6
margin-bottom: 6
@onClick: Console.sayModeChange()
@onClick: sayModeChange()
TextEdit
id: consoleTextEdit

@ -1,4 +1,41 @@
Containers = {}
function init()
g_ui.importStyle('container.otui')
connect(Container, { onOpen = onContainerOpen,
onClose = onContainerClose,
onAddItem = onContainerAddItem,
onUpdateItem = onContainerUpdateItem,
onRemoveItem = onContainerRemoveItem })
connect(Game, { onGameEnd = clean() })
reloadContainers()
end
function terminate()
disconnect(Container, { onOpen = onContainerOpen,
onClose = onContainerClose,
onAddItem = onContainerAddItem,
onUpdateItem = onContainerUpdateItem,
onRemoveItem = onContainerRemoveItem })
disconnect(Game, { onGameEnd = clean() })
end
function reloadContainers()
clean()
for containerid,container in pairs(g_game.getContainers()) do
onContainerOpen(container)
end
end
function clean()
for containerid,container in pairs(g_game.getContainers()) do
if container.window then
container.window:destroy()
container.window = nil
container.itemsPanel = nil
end
end
end
local function refreshContainerItems(container)
for slot=0,container:getCapacity()-1 do
@ -14,7 +51,7 @@ local function onContainerOpen(container, previousContainer)
previousContainer.window = nil
previousContainer.itemsPanel = nil
else
containerWindow = g_ui.createWidget('ContainerWindow', GameInterface.getRightPanel())
containerWindow = g_ui.createWidget('ContainerWindow', modules.game_interface.getRightPanel())
end
containerWindow:setId('container' .. container:getId())
local containerPanel = containerWindow:getChildById('contentsPanel')
@ -72,43 +109,3 @@ local function onContainerRemoveItem(container, slot, item)
if not container.window then return end
refreshContainerItems(container)
end
function Containers.init()
g_ui.importStyle('container.otui')
connect(Container, { onOpen = onContainerOpen,
onClose = onContainerClose,
onAddItem = onContainerAddItem,
onUpdateItem = onContainerUpdateItem,
onRemoveItem = onContainerRemoveItem })
connect(Game, { onGameEnd = Containers.clean() })
Containers.reloadContainers()
end
function Containers.terminate()
disconnect(Container, { onOpen = onContainerOpen,
onClose = onContainerClose,
onAddItem = onContainerAddItem,
onUpdateItem = onContainerUpdateItem,
onRemoveItem = onContainerRemoveItem })
disconnect(Game, { onGameEnd = Containers.clean() })
Containers = nil
end
function Containers.reloadContainers()
Containers.clean()
for containerid,container in pairs(g_game.getContainers()) do
onContainerOpen(container)
end
end
function Containers.clean()
for containerid,container in pairs(g_game.getContainers()) do
if container.window then
container.window:destroy()
container.window = nil
container.itemsPanel = nil
end
end
end

@ -3,13 +3,7 @@ Module
description: Manage containers
author: edubart, baxnie
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'containers'
Containers.init()
@onUnload: |
Containers.terminate()
sandboxed: true
scripts: [containers.lua]
@onLoad: init()
@onUnload: terminate()

@ -1,7 +1,4 @@
HealthInfo = {}
-- constants
local Icons = {}
Icons = {}
Icons[1] = { tooltip = tr('You are poisoned'), path = '/game_healthinfo/icons/poisoned.png', id = 'condition_poisoned' }
Icons[2] = { tooltip = tr('You are burning'), path = '/game_healthinfo/icons/burning.png', id = 'condition_burning' }
Icons[4] = { tooltip = tr('You are electrified'), path = '/game_healthinfo/icons/electrified.png', id = 'condition_electrified' }
@ -20,28 +17,26 @@ Icons[16384] = { tooltip = tr('You are within a protection zone'), path = '/game
Icons[32768] = { tooltip = tr('You are bleeding'), path = '/game_healthinfo/icons/bleeding.png', id = 'condition_bleeding' }
Icons[65536] = { tooltip = tr('You are hungry'), path = '/game_healthinfo/icons/hungry.png', id = 'condition_hungry' }
-- private variables
local healthInfoWindow
local healthBar
local manaBar
local soulBar
local healthLabel
local manaLabel
local soulLabel
local capLabel
-- public functions
function HealthInfo.init()
connect(LocalPlayer, { onHealthChange = HealthInfo.onHealthChange,
onManaChange = HealthInfo.onManaChange,
onStatesChange = HealthInfo.onStatesChange,
onSoulChange = HealthInfo.onSoulChange,
onFreeCapacityChange = HealthInfo.onFreeCapacityChange })
connect(g_game, { onGameEnd = HealthInfo.offline })
healthInfoWindow = g_ui.loadUI('healthinfo.otui', GameInterface.getRightPanel())
healthInfoButton = TopMenu.addRightGameToggleButton('healthInfoButton', tr('Health Information'), 'healthinfo.png', HealthInfo.toggle)
healthInfoWindow = nil
healthBar = nil
manaBar = nil
soulBar = nil
healthLabel = nil
manaLabel = nil
soulLabel = nil
capLabel = nil
function init()
connect(LocalPlayer, { onHealthChange = onHealthChange,
onManaChange = onManaChange,
onStatesChange = onStatesChange,
onSoulChange = onSoulChange,
onFreeCapacityChange = onFreeCapacityChange })
connect(g_game, { onGameEnd = offline })
healthInfoWindow = g_ui.loadUI('healthinfo.otui', modules.game_interface.getRightPanel())
healthInfoButton = TopMenu.addRightGameToggleButton('healthInfoButton', tr('Health Information'), 'healthinfo.png', toggle)
healthInfoWindow:disableResize()
healthInfoButton:setOn(true)
healthBar = healthInfoWindow:recursiveGetChildById('healthBar')
@ -54,22 +49,22 @@ function HealthInfo.init()
if g_game.isOnline() then
local localPlayer = g_game.getLocalPlayer()
HealthInfo.onHealthChange(localPlayer, localPlayer:getHealth(), localPlayer:getMaxHealth())
HealthInfo.onManaChange(localPlayer, localPlayer:getMana(), localPlayer:getMaxMana())
HealthInfo.onStatesChange(localPlayer, localPlayer:getStates(), 0)
HealthInfo.onSoulChange(localPlayer, localPlayer:getSoul())
HealthInfo.onFreeCapacityChange(localPlayer, localPlayer:getFreeCapacity())
onHealthChange(localPlayer, localPlayer:getHealth(), localPlayer:getMaxHealth())
onManaChange(localPlayer, localPlayer:getMana(), localPlayer:getMaxMana())
onStatesChange(localPlayer, localPlayer:getStates(), 0)
onSoulChange(localPlayer, localPlayer:getSoul())
onFreeCapacityChange(localPlayer, localPlayer:getFreeCapacity())
end
end
function HealthInfo.terminate()
disconnect(LocalPlayer, { onHealthChange = HealthInfo.onHealthChange,
onManaChange = HealthInfo.onManaChange,
onStatesChange = HealthInfo.onStatesChange,
onSoulChange = HealthInfo.onSoulChange,
onFreeCapacityChange = HealthInfo.onFreeCapacityChange })
function terminate()
disconnect(LocalPlayer, { onHealthChange = onHealthChange,
onManaChange = onManaChange,
onStatesChange = onStatesChange,
onSoulChange = onSoulChange,
onFreeCapacityChange = onFreeCapacityChange })
disconnect(g_game, { onGameEnd = HealthInfo.offline })
disconnect(g_game, { onGameEnd = offline })
healthInfoWindow:destroy()
healthInfoButton:destroy()
@ -88,7 +83,7 @@ function HealthInfo.terminate()
HealthInfo = nil
end
function HealthInfo.toggle()
function toggle()
if healthInfoButton:isOn() then
healthInfoWindow:close()
healthInfoButton:setOn(false)
@ -98,21 +93,21 @@ function HealthInfo.toggle()
end
end
function HealthInfo.onMiniWindowClose()
function onMiniWindowClose()
healthInfoButton:setOn(false)
end
function HealthInfo.offline()
function offline()
healthInfoWindow:recursiveGetChildById('conditionPanel'):destroyChildren()
end
-- hooked events
function HealthInfo.onHealthChange(localPlayer, health, maxHealth)
function onHealthChange(localPlayer, health, maxHealth)
healthLabel:setText(health .. ' / ' .. maxHealth)
healthBar:setPercent(health / maxHealth * 100)
end
function HealthInfo.onManaChange(localPlayer, mana, maxMana)
function onManaChange(localPlayer, mana, maxMana)
manaLabel:setText(mana .. ' / ' .. maxMana)
local percent
@ -124,16 +119,16 @@ function HealthInfo.onManaChange(localPlayer, mana, maxMana)
manaBar:setPercent(percent)
end
function HealthInfo.onSoulChange(localPlayer, soul)
function onSoulChange(localPlayer, soul)
soulLabel:setText(tr('Soul') .. ': ' .. soul)
end
function HealthInfo.onFreeCapacityChange(player, freeCapacity)
function onFreeCapacityChange(player, freeCapacity)
capLabel:setText(tr('Cap') .. ': ' .. freeCapacity)
end
function HealthInfo.onStatesChange(localPlayer, now, old)
function onStatesChange(localPlayer, now, old)
if now == old then return end
local bitsChanged = bit32.bxor(now, old)
@ -142,12 +137,12 @@ function HealthInfo.onStatesChange(localPlayer, now, old)
if pow > bitsChanged then break end
local bitChanged = bit32.band(bitsChanged, pow)
if bitChanged ~= 0 then
HealthInfo.toggleIcon(bitChanged)
toggleIcon(bitChanged)
end
end
end
function HealthInfo.toggleIcon(bitChanged)
function toggleIcon(bitChanged)
local content = healthInfoWindow:recursiveGetChildById('conditionPanel')
local icon = content:getChildById(Icons[bitChanged].id)

@ -3,13 +3,7 @@ Module
description: Displays health, mana points, soul points, and conditions
author: edubart, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'healthinfo'
HealthInfo.init()
@onUnload: |
HealthInfo.terminate()
sandboxed: true
scripts: [ healthinfo.lua ]
@onLoad: init()
@onUnload: terminate()

@ -65,7 +65,7 @@ MiniWindow
id: healthInfoWindow
!text: tr('Health Info')
height: 102
@onClose: HealthInfo.onMiniWindowClose()
@onClose: onMiniWindowClose()
&save: true
MiniWindowContents

@ -1,29 +1,8 @@
HotkeysManager = {}
local hotkeysManagerLoaded = false
local hotkeysWindow
local hotkeysButton
local currentHotkeysList
local hotkeyLabelSelectedOnList
local currentItemPreview
local itemWidget
local addHotkey
local removeHotkey
local hotkeyText
local hotKeyTextLabel
local sendAutomatically
local selectObjectButton
local clearObjectButton
local useOnSelf
local useOnTarget
local useWith
local hotkeyList = {}
HOTKEY_MANAGER_USEONSELF = 1
HOTKEY_MANAGER_USEONTARGET = 2
HOTKEY_MANAGER_USEWITH = 3
local hotkeyColors = {
HotkeyColors = {
text = '#888888',
textAutoSend = '#FFFFFF',
itemUse = '#8888FF',
@ -32,14 +11,33 @@ local hotkeyColors = {
itemUseWith = '#CC0000',
}
hotkeysManagerLoaded = false
hotkeysWindow = nil
hotkeysButton = nil
currentHotkeysList = nil
hotkeyLabelSelectedOnList = nil
currentItemPreview = nil
itemWidget = nil
addHotkey = nil
removeHotkey = nil
hotkeyText = nil
hotKeyTextLabel = nil
sendAutomatically = nil
selectObjectButton = nil
clearObjectButton = nil
useOnSelf = nil
useOnTarget = nil
useWith = nil
hotkeyList = {}
-- public functions
function HotkeysManager.init()
function init()
hotkeysWindow = g_ui.displayUI('hotkeys_manager.otui')
local hotkeyListPanel = hotkeysWindow:getChildById('currentHotkeys')
hotkeysWindow:setVisible(false)
hotkeysButton = TopMenu.addLeftGameButton('hotkeysButton', tr('Hotkeys') .. ' (Ctrl+K)', '/game_hotkeys/icon.png', HotkeysManager.toggle)
g_keyboard.bindKeyDown('Ctrl+K', HotkeysManager.toggle)
hotkeysButton = TopMenu.addLeftGameButton('hotkeysButton', tr('Hotkeys') .. ' (Ctrl+K)', '/game_hotkeys/icon.png', toggle)
g_keyboard.bindKeyDown('Ctrl+K', toggle)
g_keyboard.bindKeyPress('Down', function() hotkeyListPanel:focusNextChild(KeyboardFocusReason) end, hotkeysWindow)
g_keyboard.bindKeyPress('Up', function() hotkeyListPanel:focusPreviousChild(KeyboardFocusReason) end, hotkeysWindow)
@ -61,21 +59,39 @@ function HotkeysManager.init()
itemWidget:setVisible(false)
itemWidget:setFocusable(false)
connect(g_game, { onGameEnd = HotkeysManager.hide })
connect(currentHotkeysList, { onChildFocusChange = function (self, focusedChild) HotkeysManager.checkSelectedHotkey(focusedChild) end } )
connect(g_game, { onGameEnd = hide })
connect(currentHotkeysList, { onChildFocusChange = function (self, focusedChild) checkSelectedHotkey(focusedChild) end } )
hotkeysManagerLoaded = true
HotkeysManager.load()
load()
end
function terminate()
hotkeysManagerLoaded = false
disconnect(g_game, { onGameEnd = hide })
g_keyboard.unbindKeyDown('Ctrl+K')
save()
for keyCombo,v in pairs(hotkeyList) do
g_keyboard.unbindKeyPress(keyCombo)
end
hotkeyList = {}
itemWidget:destroy()
hotkeysWindow:destroy()
hotkeysButton:destroy()
end
function HotkeysManager.load()
function load()
local hotkeySettings = g_settings.getNode('HotkeysManager')
local hasCombos = false
if hotkeySettings ~= nil then
for i, v in pairs(hotkeySettings) do
HotkeysManager.addKeyCombo(nil, v.keyCombo, v)
addKeyCombo(nil, v.keyCombo, v)
hasCombos = true
end
end
@ -83,12 +99,12 @@ function HotkeysManager.load()
-- add default F keys combos
if not hasCombos then
for i=1,12 do
HotkeysManager.addKeyCombo(nil, 'F' .. i)
addKeyCombo(nil, 'F' .. i)
end
end
end
function HotkeysManager.save()
function save()
local hotkeySettings = {}
for i=1, currentHotkeysList:getChildCount() do
local child = currentHotkeysList:getChildByIndex(i)
@ -102,49 +118,15 @@ function HotkeysManager.save()
g_settings.setNode('HotkeysManager', hotkeySettings)
end
function HotkeysManager.terminate()
hotkeysManagerLoaded = false
disconnect(g_game, { onGameEnd = HotkeysManager.hide })
g_keyboard.unbindKeyDown('Ctrl+K')
HotkeysManager.save()
currentHotkeysList = nil
hotkeyLabelSelectedOnList = nil
currentItemPreview = nil
hotkeyList = {}
addHotkey = nil
removeHotkey = nil
hotkeyText = nil
hotKeyTextLabel = nil
sendAutomatically = nil
selectObjectButton = nil
clearObjectButton = nil
useOnSelf = nil
useOnTarget = nil
useWith = nil
itemWidget:destroy()
itemWidget = nil
hotkeysWindow:destroy()
hotkeysWindow = nil
hotkeysButton:destroy()
hotkeysButton = nil
HotkeysManager = nil
end
function HotkeysManager.toggle()
function toggle()
if hotkeysWindow:isVisible() then
HotkeysManager.hide()
hide()
else
HotkeysManager.show()
show()
end
end
function HotkeysManager.show()
function show()
if g_game.isOnline() then
hotkeysWindow:grabKeyboard()
hotkeysWindow:show()
@ -152,16 +134,16 @@ function HotkeysManager.show()
end
end
function HotkeysManager.hide()
function hide()
hotkeysWindow:ungrabKeyboard()
hotkeysWindow:hide()
end
-- private functions
function HotkeysManager.onChooseItemMouseRelease(self, mousePosition, mouseButton)
function onChooseItemMouseRelease(self, mousePosition, mouseButton)
local item = nil
if mouseButton == MouseLeftButton then
local clickedWidget = GameInterface.getRootPanel():recursiveGetChildByPos(mousePosition, false)
local clickedWidget = modules.game_interface.getRootPanel():recursiveGetChildByPos(mousePosition, false)
if clickedWidget then
if clickedWidget:getClassName() == 'UIMap' then
local tile = clickedWidget:getTile(mousePosition)
@ -180,8 +162,8 @@ function HotkeysManager.onChooseItemMouseRelease(self, mousePosition, mouseButto
if item then
currentItemPreview:setItemId(item:getId())
hotkeyLabelSelectedOnList.itemId = item:getId()
HotkeysManager.changeUseType(HOTKEY_MANAGER_USEONSELF)
HotkeysManager.checkSelectedHotkey(hotkeyLabelSelectedOnList)
changeUseType(HOTKEY_MANAGER_USEONSELF)
checkSelectedHotkey(hotkeyLabelSelectedOnList)
HotkeysManager:show()
end
@ -190,12 +172,12 @@ function HotkeysManager.onChooseItemMouseRelease(self, mousePosition, mouseButto
self:destroy()
end
function HotkeysManager.startChooseItem()
function startChooseItem()
local mouseGrabberWidget = g_ui.createWidget('UIWidget')
mouseGrabberWidget:setVisible(false)
mouseGrabberWidget:setFocusable(false)
connect(mouseGrabberWidget, { onMouseRelease = HotkeysManager.onChooseItemMouseRelease })
connect(mouseGrabberWidget, { onMouseRelease = onChooseItemMouseRelease })
mouseGrabberWidget:grabMouse()
g_mouse.setTargetCursor()
@ -203,17 +185,17 @@ function HotkeysManager.startChooseItem()
HotkeysManager:hide()
end
function HotkeysManager.clearObject()
function clearObject()
hotkeyLabelSelectedOnList.itemId = nil
currentItemPreview:clearItem()
HotkeysManager.changeUseType(HOTKEY_MANAGER_USEONSELF)
HotkeysManager.sendAutomatically(false)
changeUseType(HOTKEY_MANAGER_USEONSELF)
setSendAutomatically(false)
hotkeyLabelSelectedOnList:setText(hotkeyLabelSelectedOnList.keyCombo .. ': ')
HotkeysManager.checkSelectedHotkey(hotkeyLabelSelectedOnList)
checkSelectedHotkey(hotkeyLabelSelectedOnList)
end
function HotkeysManager.addHotkey()
function addHotkey()
local widget
messageBox = g_ui.createWidget('MainWindow', rootWidget)
@ -260,26 +242,26 @@ function HotkeysManager.addHotkey()
widget:setMarginRight(10)
widget.onClick = function (self)
messageBox = nil
HotkeysManager.addKeyCombo(self:getParent(), self:getParent():getChildById('comboPreview').keyCombo)
addKeyCombo(self:getParent(), self:getParent():getChildById('comboPreview').keyCombo)
end
connect(messageBox, { onKeyDown = HotkeysManager.hotkeyCapture }, true)
connect(messageBox, { onKeyDown = hotkeyCapture }, true)
end
function HotkeysManager.addKeyCombo(messageBox, keyCombo, keySettings)
function addKeyCombo(messageBox, keyCombo, keySettings)
local label = nil
if currentHotkeysList:getChildById(keyCombo) == nil then
local label = g_ui.createWidget('HotkeyListLabel', currentHotkeysList)
label:setId(keyCombo)
label:setColor(hotkeyColors.text)
label:setColor(HotkeyColors.text)
label:setText(keyCombo..': ')
if keySettings then
hotkeyLabelSelectedOnList = label
label.keyCombo = keyCombo
HotkeysManager.sendAutomatically(keySettings.autoSend)
setSendAutomatically(keySettings.autoSend)
label.itemId = keySettings.itemId
currentItemPreview:setItemId(keySettings.itemId)
HotkeysManager.changeUseType(tonumber(keySettings.useType))
changeUseType(tonumber(keySettings.useType))
label.value = keySettings.value
else
label.keyCombo = keyCombo
@ -289,10 +271,10 @@ function HotkeysManager.addKeyCombo(messageBox, keyCombo, keySettings)
label.value = ''
end
HotkeysManager.checkSelectedHotkey(label)
checkSelectedHotkey(label)
hotkeyList[keyCombo] = label
g_keyboard.bindKeyPress(keyCombo, function () HotkeysManager.call(keyCombo) end, nil, 350)
g_keyboard.bindKeyPress(keyCombo, function () call(keyCombo) end, nil, 350)
end
if messageBox then
@ -301,14 +283,14 @@ function HotkeysManager.addKeyCombo(messageBox, keyCombo, keySettings)
end
end
function HotkeysManager.call(keyCombo)
function call(keyCombo)
if g_game.isOnline() then
local hotKey = hotkeyList[keyCombo]
if hotKey ~= nil and hotKey.itemId == nil and hotKey.value ~= '' then
if hotKey.autoSend then
g_game.talk(hotKey.value)
else
Console.setTextEditText(hotKey.value)
modules.game_console.setTextEditText(hotKey.value)
end
elseif hotKey.itemId ~= nil then
if hotKey.useType == HOTKEY_MANAGER_USEONSELF then
@ -320,13 +302,13 @@ function HotkeysManager.call(keyCombo)
end
elseif hotKey.useType == HOTKEY_MANAGER_USEWITH then
itemWidget:setItemId(hotKey.itemId)
GameInterface.startUseWith(itemWidget:getItem())
modules.game_interface.startUseWith(itemWidget:getItem())
end
end
end
end
function HotkeysManager.checkSelectedHotkey(focused)
function checkSelectedHotkey(focused)
if not focused then return end
if hotkeysManagerLoaded then
hotkeyLabelSelectedOnList = focused
@ -362,7 +344,7 @@ function HotkeysManager.checkSelectedHotkey(focused)
currentItemPreview:setItemId(hotkeyLabelSelectedOnList.itemId)
end
HotkeysManager.changeUseType(hotkeyLabelSelectedOnList.useType)
changeUseType(hotkeyLabelSelectedOnList.useType)
else
hotkeyText:clearText()
removeHotkey:disable()
@ -383,7 +365,7 @@ function HotkeysManager.checkSelectedHotkey(focused)
end
end
function HotkeysManager.changeUseType(useType, checked)
function changeUseType(useType, checked)
if checked == nil or checked then
hotkeyLabelSelectedOnList.useType = useType
if hotkeyLabelSelectedOnList.itemId ~= nil and currentItemPreview:getItem():isMultiUse() then
@ -393,19 +375,19 @@ function HotkeysManager.changeUseType(useType, checked)
if useType == HOTKEY_MANAGER_USEONSELF then
hotkeyLabelSelectedOnList:setText(tr('%s: (use object on yourself)', hotkeyLabelSelectedOnList.keyCombo))
hotkeyLabelSelectedOnList:setColor(hotkeyColors.itemUseSelf)
hotkeyLabelSelectedOnList:setColor(HotkeyColors.itemUseSelf)
useOnSelf:setChecked(true)
useOnTarget:setChecked(false)
useWith:setChecked(false)
elseif useType == HOTKEY_MANAGER_USEONTARGET then
hotkeyLabelSelectedOnList:setText(tr('%s: (use object on target)', hotkeyLabelSelectedOnList.keyCombo))
hotkeyLabelSelectedOnList:setColor(hotkeyColors.itemUseTarget)
hotkeyLabelSelectedOnList:setColor(HotkeyColors.itemUseTarget)
useOnSelf:setChecked(false)
useOnTarget:setChecked(true)
useWith:setChecked(false)
elseif useType == HOTKEY_MANAGER_USEWITH then
hotkeyLabelSelectedOnList:setText(tr('%s: (use object with crosshair)', hotkeyLabelSelectedOnList.keyCombo))
hotkeyLabelSelectedOnList:setColor(hotkeyColors.itemUseWith)
hotkeyLabelSelectedOnList:setColor(HotkeyColors.itemUseWith)
useOnSelf:setChecked(false)
useOnTarget:setChecked(false)
@ -417,7 +399,7 @@ function HotkeysManager.changeUseType(useType, checked)
useWith:disable()
hotkeyLabelSelectedOnList:setText(tr('%s: (use object)', hotkeyLabelSelectedOnList.keyCombo))
hotkeyLabelSelectedOnList:setColor(hotkeyColors.itemUse)
hotkeyLabelSelectedOnList:setColor(HotkeyColors.itemUse)
useOnSelf:setChecked(false)
useOnTarget:setChecked(false)
@ -434,7 +416,7 @@ function HotkeysManager.changeUseType(useType, checked)
end
end
function HotkeysManager.removeHotkey()
function removeHotkey()
if hotkeyLabelSelectedOnList ~= nil then
hotkeyList[hotkeyLabelSelectedOnList.keyCombo] = nil
g_keyboard.unbindKeyPress(hotkeyLabelSelectedOnList.keyCombo)
@ -442,7 +424,7 @@ function HotkeysManager.removeHotkey()
end
end
function HotkeysManager.onHotkeyTextChange(id, value)
function onHotkeyTextChange(id, value)
if hotkeyLabelSelectedOnList ~= nil and hotkeyLabelSelectedOnList.keyCombo ~= nil then
hotkeyLabelSelectedOnList:setText(hotkeyLabelSelectedOnList.keyCombo .. ': ' .. value)
hotkeyLabelSelectedOnList.value = value
@ -456,16 +438,16 @@ function HotkeysManager.onHotkeyTextChange(id, value)
end
end
function HotkeysManager.sendAutomatically(value)
function setSendAutomatically(value)
hotkeyLabelSelectedOnList.autoSend = value
if value then
hotkeyLabelSelectedOnList:setColor(hotkeyColors.autoSend)
hotkeyLabelSelectedOnList:setColor(HotkeyColors.autoSend)
else
hotkeyLabelSelectedOnList:setColor(hotkeyColors.text)
hotkeyLabelSelectedOnList:setColor(HotkeyColors.text)
end
end
function HotkeysManager.hotkeyCapture(widget, keyCode, keyboardModifiers)
function hotkeyCapture(widget, keyCode, keyboardModifiers)
local keyCombo = determineKeyComboDesc(keyCode, keyboardModifiers)
local comboPreview = rootWidget:getChildById('assignWindow'):getChildById('comboPreview')
comboPreview:setText(tr('Current hotkey to add: %s', keyCombo))

@ -3,13 +3,7 @@ Module
description: Manage client hotkeys
author: andrefaramir, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'hotkeys_manager'
HotkeysManager.init()
@onUnload: |
HotkeysManager.terminate()
sandboxed: true
scripts: [ hotkeys_manager.lua ]
@onLoad: init()
@onUnload: terminate()

@ -13,8 +13,8 @@ MainWindow
!text: tr('Hotkeys')
size: 340 460
@onEnter: HotkeysManager.hide()
@onEscape: HotkeysManager.hide()
@onEnter: hide()
@onEscape: hide()
Label
id: currentHotkeysLabel
@ -33,7 +33,7 @@ MainWindow
TextList
id: currentHotkeys
vertical-scrollbar: currentHotkeysScrollBar
vertical-scrollbar: currentHotkeysScrollBar
anchors.left: parent.left
anchors.right: prev.left
anchors.top: prev.top
@ -56,7 +56,7 @@ MainWindow
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 2
@onClick: HotkeysManager.addHotkey()
@onClick: addHotkey()
Button
id: removeHotkey
@ -66,7 +66,7 @@ MainWindow
anchors.left: prev.right
anchors.top: prev.top
margin-left: 10
@onClick: HotkeysManager.removeHotkey()
@onClick: removeHotkey()
Label
id: hotKeyTextLabel
@ -84,7 +84,7 @@ MainWindow
anchors.right: parent.right
anchors.top: prev.bottom
margin-bottom: 2
@onTextChange: HotkeysManager.onHotkeyTextChange(self:getId(), self:getText())
@onTextChange: onHotkeyTextChange(self:getId(), self:getText())
CheckBox
id: sendAutomatically
@ -94,7 +94,7 @@ MainWindow
anchors.top: prev.bottom
enabled:false
margin-top: 10
@onCheckChange: HotkeysManager.sendAutomatically(self:isChecked())
@onCheckChange: setSendAutomatically(self:isChecked())
Item
id: itemPreview
@ -111,7 +111,7 @@ MainWindow
anchors.left: prev.right
anchors.top: prev.top
margin-left: 10
@onClick: HotkeysManager.startChooseItem()
@onClick: startChooseItem()
Button
id: clearObjectButton
@ -122,7 +122,7 @@ MainWindow
anchors.right: prev.right
anchors.top: prev.bottom
margin-top: 2
@onClick: HotkeysManager.clearObject()
@onClick: clearObject()
ButtonBox
id: useOnSelf
@ -134,7 +134,7 @@ MainWindow
anchors.top: selectObjectButton.top
checked: false
margin-left: 10
@onCheckChange: HotkeysManager.changeUseType(HOTKEY_MANAGER_USEONSELF, self:isChecked())
@onCheckChange: changeUseType(HOTKEY_MANAGER_USEONSELF, self:isChecked())
ButtonBox
id: useOnTarget
@ -146,7 +146,7 @@ MainWindow
anchors.top: prev.bottom
checked: false
margin-top: 2
@onCheckChange: HotkeysManager.changeUseType(HOTKEY_MANAGER_USEONTARGET, self:isChecked())
@onCheckChange: changeUseType(HOTKEY_MANAGER_USEONTARGET, self:isChecked())
ButtonBox
id: useWith
@ -158,11 +158,11 @@ MainWindow
anchors.top: prev.bottom
checked: false
margin-top: 2
@onCheckChange: HotkeysManager.changeUseType(HOTKEY_MANAGER_USEWITH, self:isChecked())
@onCheckChange: changeUseType(HOTKEY_MANAGER_USEWITH, self:isChecked())
Button
!text: tr('Close')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: HotkeysManager.hide()
@onClick: hide()

@ -1,41 +1,30 @@
GameInterface = {}
local WALK_AUTO_REPEAT_DELAY = 90
local gameRootPanel
local gameMapPanel
local gameRightPanel
local gameLeftPanel
local gameBottomPanel
local logoutButton
local mouseGrabberWidget
local countWindow
local logoutWindow
local exitWindow
local function onLeftPanelVisibilityChange(leftPanel, visible)
if not visible then
local children = leftPanel:getChildren()
for i=1,#children do
children[i]:setParent(gameRightPanel)
end
end
end
function GameInterface.init()
WALK_AUTO_REPEAT_DELAY = 90
gameRootPanel = nil
gameMapPanel = nil
gameRightPanel = nil
gameLeftPanel = nil
gameBottomPanel = nil
logoutButton = nil
mouseGrabberWidget = nil
countWindow = nil
logoutWindow = nil
exitWindow = nil
function init()
g_ui.importStyle('styles/countwindow.otui')
g_ui.importStyle('styles/logoutwindow.otui')
g_ui.importStyle('styles/exitwindow.otui')
connect(g_game, { onGameStart = GameInterface.show,
onGameEnd = GameInterface.hide }, true)
connect(g_game, { onGameStart = show,
onGameEnd = hide }, true)
gameRootPanel = g_ui.displayUI('gameinterface.otui')
gameRootPanel:hide()
gameRootPanel:lower()
mouseGrabberWidget = gameRootPanel:getChildById('mouseGrabber')
mouseGrabberWidget.onMouseRelease = GameInterface.onMouseGrabberRelease
mouseGrabberWidget.onMouseRelease = onMouseGrabberRelease
gameMapPanel = gameRootPanel:getChildById('gameMapPanel')
gameRightPanel = gameRootPanel:getChildById('gameRightPanel')
@ -43,7 +32,7 @@ function GameInterface.init()
gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel')
connect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange })
logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', '/images/logout.png', GameInterface.tryLogout)
logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', '/images/logout.png', tryLogout)
logoutButton:hide()
g_keyboard.bindKeyPress('Up', function() g_game.walk(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
@ -69,9 +58,9 @@ function GameInterface.init()
g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel, 250)
g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel, 250)
g_keyboard.bindKeyDown('Ctrl+Q', GameInterface.logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+L', GameInterface.logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() TextMessage.clearMessages() end, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+Q', logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+L', logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() modules.game_textmessage.clearMessages() end, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+.', function()
if gameMapPanel:isKeepAspectRatioEnabled() then
@ -80,35 +69,24 @@ function GameInterface.init()
gameMapPanel:setKeepAspectRatio(true)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 })
end
end)
end, gameRootPanel)
if g_game.isOnline() then
GameInterface.show()
show()
end
end
function GameInterface.terminate()
disconnect(g_game, { onGameStart = GameInterface.show,
onGameEnd = GameInterface.hide })
function terminate()
disconnect(g_game, { onGameStart = show,
onGameEnd = hide })
disconnect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange })
logoutButton:destroy()
logoutButton = nil
gameRootPanel:destroy()
gameRootPanel = nil
gameMapPanel = nil
gameRightPanel = nil
gameLeftPanel = nil
gameBottomPanel = nil
mouseGrabberWidget = nil
countWindow = nil
logoutWindow = nil
exitWindow = nil
GameInterface = nil
end
function GameInterface.show()
connect(g_app, { onClose = GameInterface.tryExit })
function show()
connect(g_app, { onClose = tryExit })
logoutButton:show()
Background.hide()
gameRootPanel:show()
@ -116,8 +94,8 @@ function GameInterface.show()
gameMapPanel:followCreature(g_game.getLocalPlayer())
end
function GameInterface.hide()
disconnect(g_app, { onClose = GameInterface.tryExit })
function hide()
disconnect(g_app, { onClose = tryExit })
if logoutWindow then
logoutWindow:destroy()
logoutWindow = nil
@ -135,7 +113,7 @@ function GameInterface.hide()
Background.show()
end
function GameInterface.exit()
function exit()
if g_game.isOnline() then
g_game.forceLogout()
scheduleEvent(exit, 10)
@ -143,7 +121,7 @@ function GameInterface.exit()
end
end
function GameInterface.tryExit()
function tryExit()
if exitWindow then
return true
end
@ -153,10 +131,10 @@ function GameInterface.tryExit()
local cancelButton = exitWindow:getChildById('buttonCancel')
local exitFunc = function()
GameInterface.exit()
exit()
end
local logoutFunc = function()
GameInterface.logout()
logout()
logButton:getParent():destroy()
exitWindow = nil
end
@ -174,14 +152,14 @@ function GameInterface.tryExit()
return true -- signal closing
end
function GameInterface.logout()
function logout()
if g_game.isOnline() then
g_game.safeLogout()
return true
end
end
function GameInterface.tryLogout()
function tryLogout()
if logoutWindow then
return
end
@ -190,7 +168,7 @@ function GameInterface.tryLogout()
local noButton = logoutWindow:getChildById('buttonNo')
local logoutFunc = function()
GameInterface.logout()
logout()
yesButton:getParent():destroy()
logoutWindow = nil
end
@ -206,60 +184,60 @@ function GameInterface.tryLogout()
noButton.onClick = cancelFunc
end
function GameInterface.onMouseGrabberRelease(self, mousePosition, mouseButton)
if GameInterface.selectedThing == nil then return false end
function onMouseGrabberRelease(self, mousePosition, mouseButton)
if selectedThing == nil then return false end
if mouseButton == MouseLeftButton then
local clickedWidget = gameRootPanel:recursiveGetChildByPos(mousePosition, false)
if clickedWidget then
if GameInterface.selectedType == 'use' then
GameInterface.onUseWith(clickedWidget, mousePosition)
elseif GameInterface.selectedType == 'trade' then
GameInterface.onTradeWith(clickedWidget, mousePosition)
if selectedType == 'use' then
onUseWith(clickedWidget, mousePosition)
elseif selectedType == 'trade' then
onTradeWith(clickedWidget, mousePosition)
end
end
end
GameInterface.selectedThing = nil
selectedThing = nil
g_mouse.restoreCursor()
self:ungrabMouse()
return true
end
function GameInterface.onUseWith(clickedWidget, mousePosition)
function onUseWith(clickedWidget, mousePosition)
if clickedWidget:getClassName() == 'UIMap' then
local tile = clickedWidget:getTile(mousePosition)
if tile then
g_game.useWith(GameInterface.selectedThing, tile:getTopMultiUseThing())
g_game.useWith(selectedThing, tile:getTopMultiUseThing())
elseif clickedWidget:getClassName() == 'UIItem' and not clickedWidget:isVirtual() then
g_game.useWith(GameInterface.selectedThing, clickedWidget:getItem())
g_game.useWith(selectedThing, clickedWidget:getItem())
end
end
end
function GameInterface.onTradeWith(clickedWidget, mousePosition)
function onTradeWith(clickedWidget, mousePosition)
if clickedWidget:getClassName() == 'UIMap' then
local tile = clickedWidget:getTile(mousePosition)
if tile then
g_game.requestTrade(GameInterface.selectedThing, tile:getTopCreature())
g_game.requestTrade(selectedThing, tile:getTopCreature())
end
end
end
function GameInterface.startUseWith(thing)
GameInterface.selectedType = 'use'
GameInterface.selectedThing = thing
function startUseWith(thing)
selectedType = 'use'
selectedThing = thing
mouseGrabberWidget:grabMouse()
g_mouse.setTargetCursor()
end
function GameInterface.startTradeWith(thing)
GameInterface.selectedType = 'trade'
GameInterface.selectedThing = thing
function startTradeWith(thing)
selectedType = 'trade'
selectedThing = thing
mouseGrabberWidget:grabMouse()
g_mouse.setTargetCursor()
end
function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
local menu = g_ui.createWidget('PopupMenu')
if lookThing then
@ -276,7 +254,7 @@ function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatu
end
else
if useThing:isMultiUse() then
menu:addOption(tr('Use with ...'), function() GameInterface.startUseWith(useThing) end)
menu:addOption(tr('Use with ...'), function() startUseWith(useThing) end)
else
menu:addOption(tr('Use'), function() g_game.use(useThing) end)
end
@ -290,7 +268,7 @@ function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatu
if lookThing and not lookThing:asCreature() and not lookThing:isNotMoveable() and lookThing:isPickupable() then
menu:addSeparator()
menu:addOption(tr('Trade with ...'), function() GameInterface.startTradeWith(lookThing) end)
menu:addOption(tr('Trade with ...'), function() startTradeWith(lookThing) end)
end
if lookThing then
@ -336,7 +314,7 @@ function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatu
menu:addSeparator()
local creatureName = creatureThing:getName()
menu:addOption(tr('Message to %s', creatureName), function() g_game.openPrivateChannel(creatureName) end)
if Console.getOwnPrivateTab() then
if modules.game_console.getOwnPrivateTab() then
menu:addOption(tr('Invite to private chat'), function() g_game.inviteToOwnChannel(creatureName) end)
menu:addOption(tr('Exclude from private chat'), function() g_game.excludeFromOwnChannel(creatureName) end) -- [TODO] must be removed after message's popup labels been implemented
end
@ -383,12 +361,12 @@ function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatu
menu:display(menuPosition)
end
function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing, multiUseThing)
function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing, multiUseThing)
local keyboardModifiers = g_keyboard.getModifiers()
if not Options.getOption('classicControl') then
if keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton then
GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
createThingMenu(menuPosition, lookThing, useThing, creatureThing)
return true
elseif lookThing and keyboardModifiers == KeyboardShiftModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
g_game.look(lookThing)
@ -403,7 +381,7 @@ function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalkPos
return true
end
elseif useThing:isMultiUse() then
GameInterface.startUseWith(useThing)
startUseWith(useThing)
return true
else
g_game.use(useThing)
@ -429,7 +407,7 @@ function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalkPos
return true
end
elseif multiUseThing:isMultiUse() then
GameInterface.startUseWith(useThing)
startUseWith(useThing)
return true
else
g_game.use(multiUseThing)
@ -442,7 +420,7 @@ function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalkPos
g_game.look(lookThing)
return true
elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
createThingMenu(menuPosition, lookThing, useThing, creatureThing)
return true
elseif creatureThing and keyboardModifiers == KeyboardAltModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
g_game.attack(creatureThing)
@ -453,7 +431,7 @@ function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalkPos
if autoWalkPos and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseLeftButton then
local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), autoWalkPos, 127)
if #dirs == 0 then
TextMessage.displayStatus(tr('There is no way.'))
modules.game_textmessage.displayStatus(tr('There is no way.'))
return true
end
g_game.autoWalk(dirs)
@ -463,7 +441,7 @@ function GameInterface.processMouseAction(menuPosition, mouseButton, autoWalkPos
return false
end
function GameInterface.moveStackableItem(item, toPos)
function moveStackableItem(item, toPos)
if(countWindow) then
return
end
@ -507,22 +485,32 @@ function GameInterface.moveStackableItem(item, toPos)
cancelButton.onClick = cancelFunc
end
function GameInterface.getRootPanel()
function getRootPanel()
return gameRootPanel
end
function GameInterface.getMapPanel()
function getMapPanel()
return gameMapPanel
end
function GameInterface.getRightPanel()
function getRightPanel()
return gameRightPanel
end
function GameInterface.getLeftPanel()
function getLeftPanel()
return gameLeftPanel
end
function GameInterface.getBottomPanel()
function getBottomPanel()
return gameBottomPanel
end
local function onLeftPanelVisibilityChange(leftPanel, visible)
if not visible then
local children = leftPanel:getChildren()
for i=1,#children do
children[i]:setParent(gameRightPanel)
end
end
end

@ -3,7 +3,8 @@ Module
description: Create the game interface, where the ingame stuff starts
author: OTClient team
website: www.otclient.info
sandboxed: true
scripts: [ widgets/uigamemap.lua, widgets/uiitem.lua, gameinterface.lua ]
load-later:
- game_hotkeys
- game_questlog
@ -27,14 +28,5 @@ Module
- game_playerdeath
- game_playermount
- game_market
@onLoad: |
dofile 'widgets/uigamemap'
dofile 'widgets/uiitem'
dofile 'gameinterface'
GameInterface.init()
@onUnload: |
GameInterface.terminate()
@onLoad: init()
@onUnload: terminate()

@ -39,7 +39,7 @@ function UIGameMap:onDrop(widget, mousePos)
if thingPos.x == toPos.x and thingPos.y == toPos.y and thingPos.z == toPos.z then return false end
if thing:asItem() and thing:getCount() > 1 then
GameInterface.moveStackableItem(thing, toPos)
modules.game_interface.moveStackableItem(thing, toPos)
else
g_game.move(thing, toPos, 1)
end
@ -74,7 +74,7 @@ function UIGameMap:onMouseRelease(mousePosition, mouseButton)
local creatureThing = tile:getTopCreature()
local multiUseThing = tile:getTopMultiUseThing()
local ret = GameInterface.processMouseAction(mousePosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing, multiUseThing)
local ret = modules.game_interface.processMouseAction(mousePosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing, multiUseThing)
if ret then
self.cancelNextRelease = true
end

@ -30,7 +30,7 @@ function UIItem:onDrop(widget, mousePos)
if itemPos.x == toPos.x and itemPos.y == toPos.y and itemPos.z == toPos.z then return false end
if item:getCount() > 1 then
GameInterface.moveStackableItem(item, toPos)
modules.game_interface.moveStackableItem(item, toPos)
else
g_game.move(item, toPos, 1)
end
@ -73,7 +73,7 @@ function UIItem:onMouseRelease(mousePosition, mouseButton)
g_game.look(item)
self.cancelNextRelease = true
return true
elseif GameInterface.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, item) then
elseif modules.game_interface.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, item) then
return true
end
return false

@ -1,6 +1,3 @@
Inventory = {}
-- public variables
InventorySlotStyles = {
[InventorySlotHead] = "HeadSlot",
[InventorySlotNeck] = "NeckSlot",
@ -14,54 +11,47 @@ InventorySlotStyles = {
[InventorySlotAmmo] = "AmmoSlot"
}
-- private variables
local inventoryWindow
local inventoryPanel
local inventoryButton
inventoryWindow = nil
inventoryPanel = nil
inventoryButton = nil
-- public functions
function Inventory.init()
connect(LocalPlayer, { onInventoryChange = Inventory.onInventoryChange })
connect(g_game, { onGameStart = Inventory.refresh })
function init()
connect(LocalPlayer, { onInventoryChange = onInventoryChange })
connect(g_game, { onGameStart = refresh })
g_keyboard.bindKeyDown('Ctrl+I', Inventory.toggle)
g_keyboard.bindKeyDown('Ctrl+I', toggle)
inventoryWindow = g_ui.loadUI('inventory.otui', GameInterface.getRightPanel())
inventoryWindow = g_ui.loadUI('inventory.otui', modules.game_interface.getRightPanel())
inventoryWindow:disableResize()
inventoryPanel = inventoryWindow:getChildById('contentsPanel')
inventoryButton = TopMenu.addRightGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', 'inventory.png', Inventory.toggle)
inventoryButton = TopMenu.addRightGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', 'inventory.png', toggle)
inventoryButton:setOn(true)
Inventory.refresh()
refresh()
end
function Inventory.terminate()
disconnect(LocalPlayer, { onInventoryChange = Inventory.onInventoryChange })
disconnect(g_game, { onGameStart = Inventory.refresh })
function terminate()
disconnect(LocalPlayer, { onInventoryChange = onInventoryChange })
disconnect(g_game, { onGameStart = refresh })
g_keyboard.unbindKeyDown('Ctrl+I')
inventoryWindow:destroy()
inventoryButton:destroy()
inventoryWindow = nil
inventoryButton = nil
inventoryPanel = nil
Inventory = nil
end
function Inventory.refresh()
function refresh()
local player = g_game.getLocalPlayer()
for i=InventorySlotFirst,InventorySlotLast do
if player then
Inventory.onInventoryChange(player, i, player:getInventoryItem(i))
onInventoryChange(player, i, player:getInventoryItem(i))
else
Inventory.onInventoryChange(player, i, nil)
onInventoryChange(player, i, nil)
end
end
end
function Inventory.toggle()
function toggle()
if inventoryButton:isOn() then
inventoryWindow:close()
inventoryButton:setOn(false)
@ -71,12 +61,12 @@ function Inventory.toggle()
end
end
function Inventory.onMiniWindowClose()
function onMiniWindowClose()
inventoryButton:setOn(false)
end
-- hooked events
function Inventory.onInventoryChange(player, slot, item, oldItem)
function onInventoryChange(player, slot, item, oldItem)
local itemWidget = inventoryPanel:getChildById('slot' .. slot)
if(item) then
itemWidget:setStyle('Item')

@ -3,14 +3,7 @@ Module
description: View local player equipments window
author: baxnie, edubart, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'inventory'
Inventory.init()
@onUnload: |
Inventory.terminate()
sandboxed: true
scripts: [ inventory.lua ]
@onLoad: init()
@onUnload: terminate()

@ -56,7 +56,7 @@ MiniWindow
!text: tr('Inventory')
icon: inventory.png
height: 95
@onClose: Inventory.onMiniWindowClose()
@onClose: onMiniWindowClose()
&save: true
MiniWindowContents

@ -1,64 +1,33 @@
Minimap = {}
DEFAULT_ZOOM = 60
MAX_FLOOR_UP = 0
MAX_FLOOR_DOWN = 15
-- public variables
minimapFirstLoad = true
G.minimapFirstLoad = true
-- private variables
local minimapWidget
local minimapButton
local minimapWindow
local DEFAULT_ZOOM = 60
local MAX_FLOOR_UP = 0
local MAX_FLOOR_DOWN = 15
local navigating = false
-- private functions
function onMinimapMouseRelease(self, mousePosition, mouseButton)
if navigating then
navigating = false
return
end
local tile = self:getTile(mousePosition)
if tile and mouseButton == MouseLeftButton and self:isPressed() then
local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), tile:getPosition(), 127)
if #dirs == 0 then
TextMessage.displayStatus(tr('There is no way.'))
return true
end
g_game.autoWalk(dirs)
return true
end
return false
end
function onMinimapMouseWheel(self, mousePos, direction)
if direction == MouseWheelUp then
self:zoomIn()
else
self:zoomOut()
end
end
navigating = false
minimapWidget = nil
minimapButton = nil
minimapWindow = nil
--[[
Known Issue (TODO):
If you move the minimap compass directions and
you change floor it will not update the minimap.
]]
-- public functions
function Minimap.init()
connect(g_game, { onGameStart = Minimap.reset,
onForceWalk = Minimap.center })
function init()
connect(g_game, { onGameStart = reset,
onForceWalk = center })
g_keyboard.bindKeyDown('Ctrl+M', Minimap.toggle)
g_keyboard.bindKeyDown('Ctrl+M', toggle)
minimapButton = TopMenu.addRightGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', 'minimap.png', Minimap.toggle)
minimapButton = TopMenu.addRightGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', 'minimap.png', toggle)
minimapButton:setOn(true)
minimapWindow = g_ui.loadUI('minimap.otui', GameInterface.getRightPanel())
minimapWindow = g_ui.loadUI('minimap.otui', modules.game_interface.getRightPanel())
minimapWidget = minimapWindow:recursiveGetChildById('minimap')
g_mouse.bindAutoPress(minimapWidget, Minimap.compassClick, nil, MouseRightButton)
g_mouse.bindAutoPress(minimapWidget, Minimap.compassClick, nil, MouseLeftButton)
g_mouse.bindAutoPress(minimapWidget, compassClick, nil, MouseRightButton)
g_mouse.bindAutoPress(minimapWidget, compassClick, nil, MouseLeftButton)
minimapWidget:setAutoViewMode(false)
minimapWidget:setViewMode(1) -- mid view
minimapWidget:setDrawMinimapColors(true)
@ -67,11 +36,11 @@ function Minimap.init()
minimapWidget.onMouseRelease = onMinimapMouseRelease
minimapWidget.onMouseWheel = onMinimapMouseWheel
Minimap.reset()
reset()
-- load only the first time (avoid load/save between reloads)
if minimapFirstLoad then
minimapFirstLoad = false
if G.minimapFirstLoad then
G.minimapFirstLoad = false
if g_resources.fileExists('/minimap.otcm') then
if g_game.isOnline() then
perror('cannot load minimap while online')
@ -87,21 +56,17 @@ function Minimap.init()
end
end
function Minimap.terminate()
disconnect(g_game, { onGameStart = Minimap.reset,
onForceWalk = Minimap.center })
function terminate()
disconnect(g_game, { onGameStart = reset,
onForceWalk = center })
g_keyboard.unbindKeyDown('Ctrl+M')
minimapButton:destroy()
minimapWindow:destroy()
minimapWindow = nil
minimapWidget = nil
minimapButton = nil
Minimap = nil
end
function Minimap.toggle()
function toggle()
if minimapButton:isOn() then
minimapWindow:close()
minimapButton:setOn(false)
@ -111,16 +76,24 @@ function Minimap.toggle()
end
end
function Minimap.onMiniWindowClose()
minimapButton:setOn(false)
function isClickInRange(position, fromPosition, toPosition)
return (position.x >= fromPosition.x and position.y >= fromPosition.y and position.x <= toPosition.x and position.y <= toPosition.y)
end
function Minimap.isClickInRange(position, fromPosition, toPosition)
return (position.x >= fromPosition.x and position.y >= fromPosition.y and position.x <= toPosition.x and position.y <= toPosition.y)
function reset()
local player = g_game.getLocalPlayer()
if not player then return end
minimapWidget:followCreature(player)
minimapWidget:setZoom(DEFAULT_ZOOM)
end
-- hooked functions
function Minimap.compassClick(self, mousePos, mouseButton, elapsed)
function center()
local player = g_game.getLocalPlayer()
if not player then return end
minimapWidget:followCreature(player)
end
function compassClick(self, mousePos, mouseButton, elapsed)
if elapsed < 300 then return end
navigating = true
@ -144,7 +117,7 @@ function Minimap.compassClick(self, mousePos, mouseButton, elapsed)
minimapWidget:setCameraPosition(pos)
end
function Minimap.onButtonClick(id)
function onButtonClick(id)
if id == "zoomIn" then
minimapWidget:setZoom(math.max(minimapWidget:getMaxZoomIn(), minimapWidget:getZoom()-15))
elseif id == "zoomOut" then
@ -164,16 +137,32 @@ function Minimap.onButtonClick(id)
end
end
-- hooked events
function Minimap.reset()
local player = g_game.getLocalPlayer()
if not player then return end
minimapWidget:followCreature(player)
minimapWidget:setZoom(DEFAULT_ZOOM)
function onMinimapMouseRelease(self, mousePosition, mouseButton)
if navigating then
navigating = false
return
end
local tile = self:getTile(mousePosition)
if tile and mouseButton == MouseLeftButton and self:isPressed() then
local dirs = g_map.findPath(g_game.getLocalPlayer():getPosition(), tile:getPosition(), 127)
if #dirs == 0 then
modules.game_textmessage.displayStatus(tr('There is no way.'))
return true
end
g_game.autoWalk(dirs)
return true
end
return false
end
function Minimap.center()
local player = g_game.getLocalPlayer()
if not player then return end
minimapWidget:followCreature(player)
end
function onMinimapMouseWheel(self, mousePos, direction)
if direction == MouseWheelUp then
self:zoomIn()
else
self:zoomOut()
end
end
function onMiniWindowClose()
minimapButton:setOn(false)
end

@ -3,13 +3,7 @@ Module
description: Manage minimap
author: edubart, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'minimap'
Minimap.init()
@onUnload: |
Minimap.terminate()
sandboxed: true
scripts: [minimap.lua]
@onLoad: init()
@onUnload: terminate()

@ -25,7 +25,7 @@ MiniWindow
!text: tr('Minimap')
height: 150
icon: minimap.png
@onClose: Minimap.onMiniWindowClose()
@onClose: onMiniWindowClose()
&save: true
Label
@ -51,7 +51,7 @@ MiniWindow
margin-right: 28
margin-bottom: 28
enabled: true
@onClick: Minimap.onButtonClick(self:getId())
@onClick: onButtonClick(self:getId())
FloorDownControl
id: floorDown
@ -60,7 +60,7 @@ MiniWindow
margin-right: 28
margin-bottom: 4
enabled: true
@onClick: Minimap.onButtonClick(self:getId())
@onClick: onButtonClick(self:getId())
ZoomInControl
id: zoomIn
@ -70,7 +70,7 @@ MiniWindow
margin-right: 4
margin-bottom: 28
enabled: true
@onClick: Minimap.onButtonClick(self:getId())
@onClick: onButtonClick(self:getId())
ZoomOutControl
id: zoomOut
@ -81,7 +81,7 @@ MiniWindow
margin-right: 4
margin-bottom: 4
enabled: true
@onClick: Minimap.onButtonClick(self:getId())
@onClick: onButtonClick(self:getId())
Button
id: reset
@ -90,5 +90,5 @@ MiniWindow
anchors.left: parent.left
anchors.top: parent.top
margin: 4
@onClick: Minimap.center()
@onClick: center()

@ -1,44 +1,193 @@
NPCTrade = {}
-- private variables
local BUY = 1
local SELL = 2
local CURRENCY = 'gold'
local WEIGHT_UNIT = 'oz'
local LAST_INVENTORY = 10
local npcWindow
local itemsPanel
local radioTabs
local radioItems
local searchText
local setupPanel
local quantity
local quantityScroll
local nameLabel
local priceLabel
local moneyLabel
local weightLabel
local capacityLabel
local tradeButton
local buyTab
local sellTab
local showCapacity = true
local buyWithBackpack
local ignoreCapacity
local ignoreEquipped
local showAllItems
local playerFreeCapacity
local playerMoney
local tradeItems = {}
local playerItems
local selectedItem
-- private functions
local function clearSelectedItem()
BUY = 1
SELL = 2
CURRENCY = 'gold'
WEIGHT_UNIT = 'oz'
LAST_INVENTORY = 10
npcWindow = nil
itemsPanel = nil
radioTabs = nil
radioItems = nil
searchText = nil
setupPanel = nil
quantity = nil
quantityScroll = nil
nameLabel = nil
priceLabel = nil
moneyLabel = nil
weightLabel = nil
capacityLabel = nil
tradeButton = nil
buyTab = nil
sellTab = nil
showCapacity = true
buyWithBackpack = nil
ignoreCapacity = nil
ignoreEquipped = nil
showAllItems = nil
playerFreeCapacity = nil
playerMoney = nil
tradeItems = {}
playerItems = nil
selectedItem = nil
function init()
npcWindow = g_ui.displayUI('npctrade.otui')
npcWindow:setVisible(false)
itemsPanel = npcWindow:recursiveGetChildById('itemsPanel')
searchText = npcWindow:recursiveGetChildById('searchText')
setupPanel = npcWindow:recursiveGetChildById('setupPanel')
quantityLabel = setupPanel:getChildById('quantity')
quantityScroll = setupPanel:getChildById('quantityScroll')
nameLabel = setupPanel:getChildById('name')
priceLabel = setupPanel:getChildById('price')
moneyLabel = setupPanel:getChildById('money')
weightLabel = setupPanel:getChildById('weight')
capacityLabel = setupPanel:getChildById('capacity')
tradeButton = npcWindow:recursiveGetChildById('tradeButton')
buyWithBackpack = npcWindow:recursiveGetChildById('buyWithBackpack')
ignoreCapacity = npcWindow:recursiveGetChildById('ignoreCapacity')
ignoreEquipped = npcWindow:recursiveGetChildById('ignoreEquipped')
showAllItems = npcWindow:recursiveGetChildById('showAllItems')
buyTab = npcWindow:getChildById('buyTab')
sellTab = npcWindow:getChildById('sellTab')
radioTabs = UIRadioGroup.create()
radioTabs:addWidget(buyTab)
radioTabs:addWidget(sellTab)
radioTabs:selectWidget(buyTab)
radioTabs.onSelectionChange = onTradeTypeChange
if g_game.isOnline() then
playerFreeCapacity = g_game.getLocalPlayer():getFreeCapacity()
end
connect(g_game, { onGameEnd = hide,
onOpenNpcTrade = onOpenNpcTrade,
onCloseNpcTrade = onCloseNpcTrade,
onPlayerGoods = onPlayerGoods } )
connect(LocalPlayer, { onFreeCapacityChange = onFreeCapacityChange,
onInventoryChange = onInventoryChange } )
end
function terminate()
npcWindow:destroy()
disconnect(g_game, { onGameEnd = hide,
onOpenNpcTrade = onOpenNpcTrade,
onCloseNpcTrade = onCloseNpcTrade,
onPlayerGoods = onPlayerGoods } )
disconnect(LocalPlayer, { onFreeCapacityChange = onFreeCapacityChange,
onInventoryChange = onInventoryChange } )
end
function show()
if g_game.isOnline() then
if #tradeItems[BUY] > 0 then
radioTabs:selectWidget(buyTab)
else
radioTabs:selectWidget(sellTab)
end
npcWindow:show()
npcWindow:raise()
npcWindow:focus()
end
end
function hide()
npcWindow:hide()
end
function onItemBoxChecked(widget)
if widget:isChecked() then
local item = widget.item
selectedItem = item
refreshItem(item)
tradeButton:enable()
end
end
function onQuantityValueChange(quantity)
if quantityLabel and selectedItem then
quantityLabel:setText(quantity)
weightLabel:setText(string.format('%.2f', selectedItem.weight*quantity) .. ' ' .. WEIGHT_UNIT)
priceLabel:setText(getItemPrice(selectedItem) .. ' ' .. CURRENCY)
end
end
function onTradeTypeChange(radioTabs, selected, deselected)
tradeButton:setText(selected:getText())
selected:setOn(true)
deselected:setOn(false)
local currentTradeType = getCurrentTradeType()
buyWithBackpack:setVisible(currentTradeType == BUY)
ignoreCapacity:setVisible(currentTradeType == BUY)
ignoreEquipped:setVisible(currentTradeType == SELL)
showAllItems:setVisible(currentTradeType == SELL)
refreshTradeItems()
refreshPlayerGoods()
end
function onTradeClick()
if getCurrentTradeType() == BUY then
g_game.buyItem(selectedItem.ptr, quantityScroll:getValue(), ignoreCapacity:isChecked(), buyWithBackpack:isChecked())
else
g_game.sellItem(selectedItem.ptr, quantityScroll:getValue(), ignoreEquipped:isChecked())
end
end
function onSearchTextChange()
refreshPlayerGoods()
end
function itemPopup(self, mousePosition, mouseButton)
if mouseButton == MouseRightButton then
local menu = g_ui.createWidget('PopupMenu')
menu:addOption(tr('Look'), function() return g_game.inspectNpcTrade(self:getItem()) end)
menu:display(mousePosition)
return true
end
return false
end
function onBuyWithBackpackChange()
if selectedItem then
refreshItem(selectedItem)
end
end
function onIgnoreCapacityChange()
refreshPlayerGoods()
end
function onIgnoreEquippedChange()
refreshPlayerGoods()
end
function onShowAllItemsChange()
refreshPlayerGoods()
end
function setCurrency(currency)
CURRENCY = currency
end
function showCapacity(state)
showCapacity = state
end
function clearSelectedItem()
nameLabel:clearText()
weightLabel:clearText()
priceLabel:clearText()
@ -51,7 +200,7 @@ local function clearSelectedItem()
end
end
local function getCurrentTradeType()
function getCurrentTradeType()
if tradeButton:getText() == tr('Buy') then
return BUY
else
@ -59,7 +208,7 @@ local function getCurrentTradeType()
end
end
local function getItemPrice(item)
function getItemPrice(item)
if getCurrentTradeType() == BUY then
if buyWithBackpack:isChecked() then
if item.ptr:isStackable() then
@ -72,7 +221,7 @@ local function getItemPrice(item)
return item.price*quantityScroll:getValue()
end
local function getSellQuantity(item)
function getSellQuantity(item)
if not playerItems[item.ptr:getId()] then
return 0
end
@ -90,7 +239,7 @@ local function getSellQuantity(item)
return playerItems[item.ptr:getId()] - removeAmount
end
local function canTradeItem(item)
function canTradeItem(item)
if getCurrentTradeType() == BUY then
return (ignoreCapacity:isChecked() or (not ignoreCapacity:isChecked() and playerFreeCapacity >= item.weight)) and playerMoney >= getItemPrice(item)
else
@ -98,7 +247,7 @@ local function canTradeItem(item)
end
end
local function refreshItem(item)
function refreshItem(item)
nameLabel:setText(item.name)
weightLabel:setText(string.format('%.2f', item.weight) .. ' ' .. WEIGHT_UNIT)
priceLabel:setText(getItemPrice(item) .. ' ' .. CURRENCY)
@ -130,7 +279,7 @@ local function refreshItem(item)
setupPanel:enable()
end
local function refreshTradeItems()
function refreshTradeItems()
local layout = itemsPanel:getLayout()
layout:disableUpdates()
@ -163,7 +312,7 @@ local function refreshTradeItems()
local itemWidget = itemBox:getChildById('item')
itemWidget:setItem(item.ptr)
itemWidget.onMouseRelease = NPCTrade.itemPopup
itemWidget.onMouseRelease = itemPopup
radioItems:addWidget(itemBox)
end
@ -172,7 +321,7 @@ local function refreshTradeItems()
layout:update()
end
local function refreshPlayerGoods()
function refreshPlayerGoods()
moneyLabel:setText(playerMoney .. ' ' .. CURRENCY)
capacityLabel:setText(string.format('%.2f', playerFreeCapacity) .. ' ' .. WEIGHT_UNIT)
@ -206,8 +355,7 @@ local function refreshPlayerGoods()
end
end
-- hooked functions
local function onOpenNpcTrade(items)
function onOpenNpcTrade(items)
tradeItems[BUY] = {}
tradeItems[SELL] = {}
@ -229,14 +377,14 @@ local function onOpenNpcTrade(items)
end
refreshTradeItems()
addEvent(NPCTrade.show) -- player goods has not been parsed yet
addEvent(show) -- player goods has not been parsed yet
end
local function onCloseNpcTrade()
NPCTrade.hide()
function onCloseNpcTrade()
hide()
end
local function onPlayerGoods(money, items)
function onPlayerGoods(money, items)
playerMoney = money
playerItems = {}
@ -252,7 +400,7 @@ local function onPlayerGoods(money, items)
refreshPlayerGoods()
end
local function onFreeCapacityChange(localPlayer, freeCapacity, oldFreeCapacity)
function onFreeCapacityChange(localPlayer, freeCapacity, oldFreeCapacity)
playerFreeCapacity = freeCapacity
if npcWindow:isVisible() then
@ -260,186 +408,9 @@ local function onFreeCapacityChange(localPlayer, freeCapacity, oldFreeCapacity)
end
end
local function onInventoryChange(inventory, item, oldeItem)
function onInventoryChange(inventory, item, oldeItem)
if selectedItem then
refreshItem(selectedItem)
end
end
-- public functions
function NPCTrade.init()
npcWindow = g_ui.displayUI('npctrade.otui')
npcWindow:setVisible(false)
itemsPanel = npcWindow:recursiveGetChildById('itemsPanel')
searchText = npcWindow:recursiveGetChildById('searchText')
setupPanel = npcWindow:recursiveGetChildById('setupPanel')
quantityLabel = setupPanel:getChildById('quantity')
quantityScroll = setupPanel:getChildById('quantityScroll')
nameLabel = setupPanel:getChildById('name')
priceLabel = setupPanel:getChildById('price')
moneyLabel = setupPanel:getChildById('money')
weightLabel = setupPanel:getChildById('weight')
capacityLabel = setupPanel:getChildById('capacity')
tradeButton = npcWindow:recursiveGetChildById('tradeButton')
buyWithBackpack = npcWindow:recursiveGetChildById('buyWithBackpack')
ignoreCapacity = npcWindow:recursiveGetChildById('ignoreCapacity')
ignoreEquipped = npcWindow:recursiveGetChildById('ignoreEquipped')
showAllItems = npcWindow:recursiveGetChildById('showAllItems')
buyTab = npcWindow:getChildById('buyTab')
sellTab = npcWindow:getChildById('sellTab')
radioTabs = UIRadioGroup.create()
radioTabs:addWidget(buyTab)
radioTabs:addWidget(sellTab)
radioTabs:selectWidget(buyTab)
radioTabs.onSelectionChange = NPCTrade.onTradeTypeChange
if g_game.isOnline() then -- event wont be sent again when reloading modules
playerFreeCapacity = g_game.getLocalPlayer():getFreeCapacity()
end
connect(g_game, { onGameEnd = NPCTrade.hide,
onOpenNpcTrade = onOpenNpcTrade,
onCloseNpcTrade = onCloseNpcTrade,
onPlayerGoods = onPlayerGoods } )
connect(LocalPlayer, { onFreeCapacityChange = onFreeCapacityChange,
onInventoryChange = onInventoryChange } )
end
function NPCTrade.terminate()
--radioTabs:destroy()
radioTabs = nil
npcWindow:destroy()
npcWindow = nil
itemsPanel = nil
buyButton = nil
sellButton = nil
searchText = nil
buyTab = nil
sellTab = nil
setupPanel = nil
quantityLabel = nil
quantityScroll = nil
nameLabel = nil
priceLabel = nil
moneyLabel = nil
weightLabel = nil
capacityLabel = nil
offerSelected = nil
tradeButton = nil
disconnect(g_game, { onGameEnd = NPCTrade.hide,
onOpenNpcTrade = onOpenNpcTrade,
onCloseNpcTrade = onCloseNpcTrade,
onPlayerGoods = onPlayerGoods } )
disconnect(LocalPlayer, { onFreeCapacityChange = onFreeCapacityChange,
onInventoryChange = onInventoryChange } )
NPCTrade = nil
end
function NPCTrade.show()
if g_game.isOnline() then
if #tradeItems[BUY] > 0 then
radioTabs:selectWidget(buyTab)
else
radioTabs:selectWidget(sellTab)
end
npcWindow:show()
npcWindow:raise()
npcWindow:focus()
end
end
function NPCTrade.hide()
npcWindow:hide()
end
function NPCTrade.onItemBoxChecked(widget)
if widget:isChecked() then
local item = widget.item
selectedItem = item
refreshItem(item)
tradeButton:enable()
end
end
function NPCTrade.onQuantityValueChange(quantity)
if quantityLabel and selectedItem then
quantityLabel:setText(quantity)
weightLabel:setText(string.format('%.2f', selectedItem.weight*quantity) .. ' ' .. WEIGHT_UNIT)
priceLabel:setText(getItemPrice(selectedItem) .. ' ' .. CURRENCY)
end
end
function NPCTrade.onTradeTypeChange(radioTabs, selected, deselected)
tradeButton:setText(selected:getText())
selected:setOn(true)
deselected:setOn(false)
local currentTradeType = getCurrentTradeType()
buyWithBackpack:setVisible(currentTradeType == BUY)
ignoreCapacity:setVisible(currentTradeType == BUY)
ignoreEquipped:setVisible(currentTradeType == SELL)
showAllItems:setVisible(currentTradeType == SELL)
refreshTradeItems()
refreshPlayerGoods()
end
function NPCTrade.onTradeClick()
if getCurrentTradeType() == BUY then
g_game.buyItem(selectedItem.ptr, quantityScroll:getValue(), ignoreCapacity:isChecked(), buyWithBackpack:isChecked())
else
g_game.sellItem(selectedItem.ptr, quantityScroll:getValue(), ignoreEquipped:isChecked())
end
end
function NPCTrade.onSearchTextChange()
refreshPlayerGoods()
end
function NPCTrade.itemPopup(self, mousePosition, mouseButton)
if mouseButton == MouseRightButton then
local menu = g_ui.createWidget('PopupMenu')
menu:addOption(tr('Look'), function() return g_game.inspectNpcTrade(self:getItem()) end)
menu:display(mousePosition)
return true
end
return false
end
function NPCTrade.onBuyWithBackpackChange()
if selectedItem then
refreshItem(selectedItem)
end
end
function NPCTrade.onIgnoreCapacityChange()
refreshPlayerGoods()
end
function NPCTrade.onIgnoreEquippedChange()
refreshPlayerGoods()
end
function NPCTrade.onShowAllItemsChange()
refreshPlayerGoods()
end
function NPCTrade.setCurrency(currency)
CURRENCY = currency
end
function NPCTrade.showCapacity(state)
showCapacity = state
end

@ -3,13 +3,7 @@ Module
description: NPC trade interface
author: andrefaramir, baxnie
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'npctrade'
NPCTrade.init()
@onUnload: |
NPCTrade.terminate()
sandboxed: true
scripts: [ npctrade.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,7 +1,4 @@
Outfit = {}
-- private variables
local addonSets = {
ADDON_SETS = {
[1] = { 1 },
[2] = { 2 },
[3] = { 1, 2 },
@ -10,116 +7,32 @@ local addonSets = {
[6] = { 2, 3 },
[7] = { 1, 2, 3 }
}
local outfitWindow
local outfit
local outfits
local outfitCreature
local currentOutfit = 1
local addons
local currentColorBox
local currentClotheButtonBox
local colorBoxes = {}
local mount
local mounts
local mountCreature
local currentMount = 1
-- private functions
local function onAddonCheckChange(addon, value)
if addon:isChecked() then
outfit.addons = outfit.addons + value
else
outfit.addons = outfit.addons - value
end
outfitCreature:setOutfit(outfit)
end
local function onColorCheckChange(colorBox)
if colorBox == currentColorBox then
colorBox.onCheckChange = nil
colorBox:setChecked(true)
colorBox.onCheckChange = onColorCheckChange
else
currentColorBox.onCheckChange = nil
currentColorBox:setChecked(false)
currentColorBox.onCheckChange = onColorCheckChange
currentColorBox = colorBox
if currentClotheButtonBox:getId() == 'head' then
outfit.head = currentColorBox.colorId
elseif currentClotheButtonBox:getId() == 'primary' then
outfit.body = currentColorBox.colorId
elseif currentClotheButtonBox:getId() == 'secondary' then
outfit.legs = currentColorBox.colorId
elseif currentClotheButtonBox:getId() == 'detail' then
outfit.feet = currentColorBox.colorId
end
outfitCreature:setOutfit(outfit)
end
end
local function onClotheCheckChange(clotheButtonBox)
if clotheButtonBox == currentClotheButtonBox then
clotheButtonBox.onCheckChange = nil
clotheButtonBox:setChecked(true)
clotheButtonBox.onCheckChange = onClotheCheckChange
else
currentClotheButtonBox.onCheckChange = nil
currentClotheButtonBox:setChecked(false)
currentClotheButtonBox.onCheckChange = onClotheCheckChange
currentClotheButtonBox = clotheButtonBox
local colorId = 0
if currentClotheButtonBox:getId() == 'head' then
colorId = outfit.head
elseif currentClotheButtonBox:getId() == 'primary' then
colorId = outfit.body
elseif currentClotheButtonBox:getId() == 'secondary' then
colorId = outfit.legs
elseif currentClotheButtonBox:getId() == 'detail' then
colorId = outfit.feet
end
outfitWindow:recursiveGetChildById('colorBox' .. colorId):setChecked(true)
end
outfitWindow = nil
outfit = nil
outfits = nil
outfitCreature = nil
currentOutfit = 1
addons = nil
currentColorBox = nil
currentClotheButtonBox = nil
colorBoxes = {}
mount = nil
mounts = nil
mountCreature = nil
currentMount = 1
function init()
connect(g_game, { onOpenOutfitWindow = create,
onGameEnd = destroy })
end
local function updateOutfit()
if table.empty(outfits) or not outfit then
return
end
local nameWidget = outfitWindow:getChildById('outfitName')
nameWidget:setText(outfits[currentOutfit][2])
local availableAddons = outfits[currentOutfit][3]
local prevAddons = {}
for k, addon in pairs(addons) do
prevAddons[k] = addon.widget:isChecked()
addon.widget:setChecked(false)
addon.widget:setEnabled(false)
end
if availableAddons > 0 then
for _, i in pairs(addonSets[availableAddons]) do
addons[i].widget:setEnabled(true)
end
end
outfit.addons = 0
for i = 1, #prevAddons do
local addon = prevAddons[i]
if addon and addons[i].widget:isEnabled() then
addons[i].widget:setChecked(true)
end
end
outfit.type = outfits[currentOutfit][1]
outfitCreature:setOutfit(outfit)
function terminate()
disconnect(g_game, { onOpenOutfitWindow = create,
onGameEnd = destroy })
destroy()
end
function updateMount()
@ -128,30 +41,17 @@ function updateMount()
end
local nameMountWidget = outfitWindow:getChildById('mountName')
nameMountWidget:setText(mounts[currentMount][2])
mount.type = mounts[currentMount][1]
mountCreature:setOutfit(mount)
end
-- public functions
function Outfit.init()
connect(g_game, { onOpenOutfitWindow = Outfit.create,
onGameEnd = Outfit.destroy })
end
function Outfit.terminate()
disconnect(g_game, { onOpenOutfitWindow = Outfit.create,
onGameEnd = Outfit.destroy })
Outfit.destroy()
Outfit = nil
end
function Outfit.create(creatureOutfit, outfitList, creatureMount, mountList)
function create(creatureOutfit, outfitList, creatureMount, mountList)
outfitCreature = creatureOutfit
mountCreature = creatureMount
outfits = outfitList
mounts = mountList
Outfit.destroy()
destroy()
outfitWindow = g_ui.displayUI('outfitwindow.otui')
local colorBoxPanel = outfitWindow:getChildById('colorBoxPanel')
@ -178,24 +78,24 @@ function Outfit.create(creatureOutfit, outfitList, creatureMount, mountList)
outfitWindow:getChildById('mountNextButton'):hide()
outfitWindow:getChildById('mountPrevButton'):hide()
end
-- set addons
addons = {
[1] = {widget = outfitWindow:getChildById('addon1'), value = 1},
[2] = {widget = outfitWindow:getChildById('addon2'), value = 2},
[3] = {widget = outfitWindow:getChildById('addon3'), value = 4}
}
for _, addon in pairs(addons) do
addon.widget.onCheckChange = function(self) onAddonCheckChange(self, addon.value) end
end
if outfit.addons > 0 then
for _, i in pairs(addonSets[outfit.addons]) do
for _, i in pairs(ADDON_SETS[outfit.addons]) do
addons[i].widget:setChecked(true)
end
end
-- hook outfit sections
currentClotheButtonBox = outfitWindow:getChildById('head')
outfitWindow:getChildById('head').onCheckChange = onClotheCheckChange
@ -241,7 +141,7 @@ function Outfit.create(creatureOutfit, outfitList, creatureMount, mountList)
updateMount()
end
function Outfit.destroy()
function destroy()
if outfitWindow then
outfitWindow:destroy()
outfitWindow = nil
@ -253,14 +153,14 @@ function Outfit.destroy()
end
end
function Outfit.randomize()
function randomize()
local outfitTemplate = {
outfitWindow:getChildById('head'),
outfitWindow:getChildById('primary'),
outfitWindow:getChildById('secondary'),
outfitWindow:getChildById('detail')
}
for i = 1, #outfitTemplate do
outfitTemplate[i]:setChecked(true)
colorBoxes[math.random(1, #colorBoxes)]:setChecked(true)
@ -269,13 +169,13 @@ function Outfit.randomize()
outfitTemplate[1]:setChecked(true)
end
function Outfit.accept()
function accept()
if mount then outfit.mount = mount.type end
g_game.changeOutfit(outfit)
Outfit.destroy()
destroy()
end
function Outfit.nextOutfitType()
function nextOutfitType()
if not outfits then
return
end
@ -286,7 +186,7 @@ function Outfit.nextOutfitType()
updateOutfit()
end
function Outfit.previousOutfitType()
function previousOutfitType()
if not outfits then
return
end
@ -297,7 +197,7 @@ function Outfit.previousOutfitType()
updateOutfit()
end
function Outfit.nextMountType()
function nextMountType()
if not mounts then
return
end
@ -308,7 +208,7 @@ function Outfit.nextMountType()
updateMount()
end
function Outfit.previousMountType()
function previousMountType()
if not mounts then
return
end
@ -318,3 +218,99 @@ function Outfit.previousMountType()
end
updateMount()
end
function onAddonCheckChange(addon, value)
if addon:isChecked() then
outfit.addons = outfit.addons + value
else
outfit.addons = outfit.addons - value
end
outfitCreature:setOutfit(outfit)
end
function onColorCheckChange(colorBox)
if colorBox == currentColorBox then
colorBox.onCheckChange = nil
colorBox:setChecked(true)
colorBox.onCheckChange = onColorCheckChange
else
currentColorBox.onCheckChange = nil
currentColorBox:setChecked(false)
currentColorBox.onCheckChange = onColorCheckChange
currentColorBox = colorBox
if currentClotheButtonBox:getId() == 'head' then
outfit.head = currentColorBox.colorId
elseif currentClotheButtonBox:getId() == 'primary' then
outfit.body = currentColorBox.colorId
elseif currentClotheButtonBox:getId() == 'secondary' then
outfit.legs = currentColorBox.colorId
elseif currentClotheButtonBox:getId() == 'detail' then
outfit.feet = currentColorBox.colorId
end
outfitCreature:setOutfit(outfit)
end
end
function onClotheCheckChange(clotheButtonBox)
if clotheButtonBox == currentClotheButtonBox then
clotheButtonBox.onCheckChange = nil
clotheButtonBox:setChecked(true)
clotheButtonBox.onCheckChange = onClotheCheckChange
else
currentClotheButtonBox.onCheckChange = nil
currentClotheButtonBox:setChecked(false)
currentClotheButtonBox.onCheckChange = onClotheCheckChange
currentClotheButtonBox = clotheButtonBox
local colorId = 0
if currentClotheButtonBox:getId() == 'head' then
colorId = outfit.head
elseif currentClotheButtonBox:getId() == 'primary' then
colorId = outfit.body
elseif currentClotheButtonBox:getId() == 'secondary' then
colorId = outfit.legs
elseif currentClotheButtonBox:getId() == 'detail' then
colorId = outfit.feet
end
outfitWindow:recursiveGetChildById('colorBox' .. colorId):setChecked(true)
end
end
function updateOutfit()
if table.empty(outfits) or not outfit then
return
end
local nameWidget = outfitWindow:getChildById('outfitName')
nameWidget:setText(outfits[currentOutfit][2])
local availableAddons = outfits[currentOutfit][3]
local prevAddons = {}
for k, addon in pairs(addons) do
prevAddons[k] = addon.widget:isChecked()
addon.widget:setChecked(false)
addon.widget:setEnabled(false)
end
if availableAddons > 0 then
for _, i in pairs(ADDON_SETS[availableAddons]) do
addons[i].widget:setEnabled(true)
end
end
outfit.addons = 0
for i = 1, #prevAddons do
local addon = prevAddons[i]
if addon and addons[i].widget:isEnabled() then
addons[i].widget:setChecked(true)
end
end
outfit.type = outfits[currentOutfit][1]
outfitCreature:setOutfit(outfit)
end

@ -3,13 +3,7 @@ Module
description: Change local player outfit
author: baxnie, edubart
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'outfit'
Outfit.init()
@onUnload: |
Outfit.terminate()
sandboxed: true
scripts: [ outfit.lua ]
@onLoad: init()
@onUnload: terminate()

@ -31,8 +31,8 @@ Window
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
@onEnter: Outfit.accept()
@onEscape: Outfit.destroy()
@onEnter: accept()
@onEscape: destroy()
// Creature Boxes
@ -59,7 +59,7 @@ Window
anchors.verticalCenter: outfitCreatureBox.verticalCenter
margin-left: 3
enabled: true
@onClick: Outfit.nextOutfitType()
@onClick: nextOutfitType()
PrevOutfitButton
id: outfitPrevButton
@ -67,7 +67,7 @@ Window
anchors.verticalCenter: outfitCreatureBox.verticalCenter
margin-right: 3
enabled: true
@onClick: Outfit.previousOutfitType()
@onClick: previousOutfitType()
Creature
id: mountCreatureBox
@ -92,7 +92,7 @@ Window
anchors.verticalCenter: mountCreatureBox.verticalCenter
margin-left: 3
enabled: true
@onClick: Outfit.nextMountType()
@onClick: nextMountType()
PrevMountButton
id: mountPrevButton
@ -100,7 +100,7 @@ Window
anchors.verticalCenter: mountCreatureBox.verticalCenter
margin-right: 3
enabled: true
@onClick: Outfit.previousMountType()
@onClick: previousMountType()
// Addon Check Boxes
@ -189,7 +189,7 @@ Window
anchors.left: prev.left
anchors.top: prev.bottom
margin-right: 16
@onClick: Outfit.randomize()
@onClick: randomize()
HorizontalSeparator
anchors.left: parent.left
@ -208,7 +208,7 @@ Window
anchors.bottom: parent.bottom
margin-bottom: 16
margin-right: 16
@onClick: Outfit.accept()
@onClick: accept()
Button
id: outfitCancelButton
@ -218,4 +218,4 @@ Window
anchors.bottom: parent.bottom
margin-bottom: 16
margin-right: 16
@onClick: Outfit.destroy()
@onClick: destroy()

@ -1,51 +1,42 @@
PlayerDeath = {}
deathWindow = nil
-- private variables
local deathWindow
-- private functions
-- public functions
function PlayerDeath.init()
function init()
g_ui.importStyle('deathwindow.otui')
connect(g_game, { onDeath = PlayerDeath.display,
onGameEnd = PlayerDeath.reset })
connect(g_game, { onDeath = display,
onGameEnd = reset })
end
function PlayerDeath.terminate()
disconnect(g_game, { onDeath = PlayerDeath.display,
onGameEnd = PlayerDeath.reset })
function terminate()
disconnect(g_game, { onDeath = display,
onGameEnd = reset })
PlayerDeath.reset()
PlayerDeath = nil
reset()
end
function PlayerDeath.reset()
function reset()
if deathWindow then
deathWindow:destroy()
deathWindow = nil
end
end
function PlayerDeath.display()
PlayerDeath.displayDeadMessage()
PlayerDeath.openWindow()
function display()
displayDeadMessage()
openWindow()
end
function PlayerDeath.displayDeadMessage()
local advanceLabel = GameInterface.getMapPanel():recursiveGetChildById('centerAdvance')
function displayDeadMessage()
local advanceLabel = modules.game_interface.getMapPanel():recursiveGetChildById('centerAdvance')
if advanceLabel:isVisible() then
return
end
TextMessage.displayEventAdvance(tr('You are dead.'))
modules.game_textmessage.displayEventAdvance(tr('You are dead.'))
end
function PlayerDeath.openWindow()
if deathWindow then
return
end
function openWindow()
if deathWindow then return end
deathWindow = g_ui.createWidget('DeathWindow', rootWidget)
local okButton = deathWindow:getChildById('buttonOk')
local cancelButton = deathWindow:getChildById('buttonCancel')
@ -56,7 +47,7 @@ function PlayerDeath.openWindow()
deathWindow = nil
end
local cancelFunc = function()
GameInterface.logout()
modules.game_interface.logout()
cancelButton:getParent():destroy()
deathWindow = nil
end
@ -66,4 +57,4 @@ function PlayerDeath.openWindow()
okButton.onClick = okFunc
cancelButton.onClick = cancelFunc
end
end

@ -3,15 +3,7 @@ Module
description: Manage player deaths
author: BeniS, edubart
website: www.otclient.info
dependencies:
- game_interface
- game_textmessage
- client_entergame
@onLoad: |
dofile 'playerdeath'
PlayerDeath.init()
@onUnload: |
PlayerDeath.terminate()
sandboxed: true
scripts: [ playerdeath.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,23 +1,19 @@
PlayerMount = {}
function PlayerMount.init()
function init()
if g_game.getFeature(GamePlayerMount) then
g_keyboard.bindKeyDown('Ctrl+R', PlayerMount.toggleMount, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+R', toggleMount, gameRootPanel)
end
end
function PlayerMount.terminate()
function terminate()
if g_game.getFeature(GamePlayerMount) then
g_keyboard.unbindKeyDown('Ctrl+R', gameRootPanel)
end
PlayerMount = nil
end
function PlayerMount.toggleMount()
function toggleMount()
g_game.mount(not g_game.isMounted())
end
function PlayerMount.dismount()
function dismount()
g_game.mount(false)
end

@ -3,10 +3,7 @@ Module
description: Manage player mounts
author: BeniS
website: www.otclient.info
@onLoad: |
dofile 'playermount'
PlayerMount.init()
@onUnload: |
PlayerMount.terminate()
sandboxed: true
scripts: [playermount.lua]
@onLoad: init()
@onUnload: terminate()

@ -1,16 +1,34 @@
PlayerTrade = {}
tradeWindow = nil
local tradeWindow
function init()
g_ui.importStyle('tradewindow.otui')
connect(g_game, { onOwnTrade = onGameOwnTrade,
onCounterTrade = onGameCounterTrade,
onCloseTrade = onGameCloseTrade,
onGameEnd = onGameCloseTrade })
end
function terminate()
disconnect(g_game, { onOwnTrade = onGameOwnTrade,
onCounterTrade = onGameCounterTrade,
onCloseTrade = onGameCloseTrade,
onGameEnd = onGameCloseTrade })
local function createTrade()
tradeWindow = g_ui.createWidget('TradeWindow', GameInterface.getRightPanel())
if tradeWindow then
tradeWindow:destroy()
end
end
function createTrade()
tradeWindow = g_ui.createWidget('TradeWindow', modules.game_interface.getRightPanel())
tradeWindow.onClose = function()
g_game.rejectTrade()
tradeWindow:hide()
end
end
local function fillTrade(name, items, counter)
function fillTrade(name, items, counter)
if not tradeWindow then
createTrade()
end
@ -42,37 +60,16 @@ local function fillTrade(name, items, counter)
end
end
local function onGameOwnTrade(name, items)
function onGameOwnTrade(name, items)
fillTrade(name, items, false)
end
local function onGameCounterTrade(name, items)
function onGameCounterTrade(name, items)
fillTrade(name, items, true)
end
local function onGameCloseTrade()
function onGameCloseTrade()
if not tradeWindow then return end
tradeWindow:destroy()
tradeWindow = nil
end
function PlayerTrade.init()
g_ui.importStyle('tradewindow.otui')
connect(g_game, { onOwnTrade = onGameOwnTrade,
onCounterTrade = onGameCounterTrade,
onCloseTrade = onGameCloseTrade,
onGameEnd = onGameCloseTrade })
end
function PlayerTrade.terminate()
disconnect(g_game, { onOwnTrade = onGameOwnTrade,
onCounterTrade = onGameCounterTrade,
onCloseTrade = onGameCloseTrade,
onGameEnd = onGameCloseTrade })
if tradeWindow then
tradeWindow:destroy()
tradeWindow = nil
end
end

@ -3,13 +3,7 @@ Module
description: Allow to trade items with players
author: edubart
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'playertrade'
PlayerTrade.init()
@onUnload: |
PlayerTrade.terminate()
sandboxed: true
scripts: [ playertrade.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,11 +1,39 @@
QuestLog = {}
questLogButton = nil
questLineWindow = nil
local questLogButton
local questLogWindow
local questLineWindow
function init()
g_ui.importStyle('questlogwindow.otui')
g_ui.importStyle('questlinewindow.otui')
questLogButton = TopMenu.addLeftGameButton('questLogButton', tr('Quest Log'), 'questlog.png', function() g_game.requestQuestLog() end)
local function onGameQuestLog(quests)
QuestLog.destroyWindows()
connect(g_game, { onQuestLog = onGameQuestLog,
onQuestLine = onGameQuestLine,
onGameEnd = destroyWindows})
end
function terminate()
disconnect(g_game, { onQuestLog = onGameQuestLog,
onQuestLine = onGameQuestLine,
onGameEnd = destroyWindows})
destroyWindows()
end
function destroyWindows()
if questLogWindow then
questLogWindow:destroy()
questLogWindow = nil
end
if questLineWindow then
questLineWindow:destroy()
questLineWindow = nil
end
end
function onGameQuestLog(quests)
destroyWindows()
questLogWindow = g_ui.createWidget('QuestLogWindow', rootWidget)
local questList = questLogWindow:getChildById('questList')
@ -27,7 +55,7 @@ local function onGameQuestLog(quests)
end
end
local function onGameQuestLine(questId, questMissions)
function onGameQuestLine(questId, questMissions)
if questLogWindow then questLogWindow:hide() end
if questLineWindow then questLineWindow:destroy() end
@ -53,37 +81,3 @@ local function onGameQuestLine(questId, questMissions)
questLineWindow = nil
end
end
function QuestLog.init()
g_ui.importStyle('questlogwindow.otui')
g_ui.importStyle('questlinewindow.otui')
questLogButton = TopMenu.addLeftGameButton('questLogButton', tr('Quest Log'), 'questlog.png', function() g_game.requestQuestLog() end)
connect(g_game, { onQuestLog = onGameQuestLog,
onQuestLine = onGameQuestLine,
onGameEnd = QuestLog.destroyWindows})
end
function QuestLog.destroyWindows()
if questLogWindow then
questLogWindow:destroy()
questLogWindow = nil
end
if questLineWindow then
questLineWindow:destroy()
questLineWindow = nil
end
end
function QuestLog.terminate()
disconnect(g_game, { onQuestLog = onGameQuestLog,
onQuestLine = onGameQuestLine,
onGameEnd = QuestLog.destroyWindows})
QuestLog.destroyWindows()
questLogButton:destroy()
questLogButton = nil
end

@ -3,13 +3,7 @@ Module
description: View game quests status
author: edubart
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'questlog'
QuestLog.init()
@onUnload: |
QuestLog.terminate()
sandboxed: true
scripts: [ questlog.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,7 +1,4 @@
RuleViolation = {}
-- private variables
local rvreasons = {}
rvreasons = {}
rvreasons[1] = tr("1a) Offensive Name")
rvreasons[2] = tr("1b) Invalid Name Format")
rvreasons[3] = tr("1c) Unsuitable Name")
@ -24,7 +21,7 @@ rvreasons[19] = tr("4c) False Report to Gamemaster")
rvreasons[20] = tr("Destructive Behaviour")
rvreasons[21] = tr("Excessive Unjustified Player Killing")
local rvactions = {}
rvactions = {}
rvactions[0] = tr("Notation")
rvactions[1] = tr("Name Report")
rvactions[2] = tr("Banishment")
@ -33,31 +30,12 @@ rvactions[4] = tr("Banishment + Final Warning")
rvactions[5] = tr("Name Report + Banishment + Final Warning")
rvactions[6] = tr("Statement Report")
local ruleViolationWindow
local reasonsTextList
local actionsTextList
-- public functions
function RuleViolation.hasWindowAccess()
return reasonsTextList:getChildCount() > 0
end
function RuleViolation.loadReasons()
reasonsTextList:destroyChildren()
local actions = g_game.getGMActions()
for reason, actionFlags in pairs(actions) do
local label = g_ui.createWidget('RVListLabel', reasonsTextList)
label:setText(rvreasons[reason])
label.reasonId = reason
label.actionFlags = actionFlags
end
if not RuleViolation.hasWindowAccess() and ruleViolationWindow:isVisible() then RuleViolation.hide() end
end
ruleViolationWindow = nil
reasonsTextList = nil
actionsTextList = nil
function RuleViolation.init()
connect(g_game, { onGMActions = RuleViolation.loadReasons })
function init()
connect(g_game, { onGMActions = loadReasons })
ruleViolationWindow = g_ui.displayUI('ruleviolation.otui')
ruleViolationWindow:setVisible(false)
@ -65,25 +43,40 @@ function RuleViolation.init()
reasonsTextList = ruleViolationWindow:getChildById('reasonList')
actionsTextList = ruleViolationWindow:getChildById('actionList')
g_keyboard.bindKeyDown('Ctrl+Y', RuleViolation.show)
g_keyboard.bindKeyDown('Ctrl+Y', show)
if g_game.isOnline() then
RuleViolation.loadReasons()
loadReasons()
end
end
function RuleViolation.terminate()
disconnect(g_game, { onGMActions = RuleViolation.loadReasons })
function terminate()
disconnect(g_game, { onGMActions = loadReasons })
g_keyboard.unbindKeyDown('Ctrl+Y')
ruleViolationWindow:destroy()
ruleViolationWindow = nil
end
reasonsTextList = nil
actionsTextList = nil
function hasWindowAccess()
return reasonsTextList:getChildCount() > 0
end
function RuleViolation.show(target, statement)
if g_game.isOnline() and RuleViolation.hasWindowAccess() then
function loadReasons()
reasonsTextList:destroyChildren()
local actions = g_game.getGMActions()
for reason, actionFlags in pairs(actions) do
local label = g_ui.createWidget('RVListLabel', reasonsTextList)
label:setText(rvreasons[reason])
label.reasonId = reason
label.actionFlags = actionFlags
end
if not hasWindowAccess() and ruleViolationWindow:isVisible() then hide() end
end
function show(target, statement)
if g_game.isOnline() and hasWindowAccess() then
if target then
ruleViolationWindow:getChildById('nameText'):setText(target)
end
@ -97,12 +90,12 @@ function RuleViolation.show(target, statement)
end
end
function RuleViolation.hide()
function hide()
ruleViolationWindow:hide()
RuleViolation.clearForm()
clearForm()
end
function RuleViolation.onSelectReason(reasonLabel, focused)
function onSelectReason(reasonLabel, focused)
if reasonLabel.actionFlags and focused then
actionsTextList:destroyChildren()
for actionBaseFlag = 0, #rvactions do
@ -116,7 +109,7 @@ function RuleViolation.onSelectReason(reasonLabel, focused)
end
end
function RuleViolation.report()
function report()
local target = ruleViolationWindow:getChildById('nameText'):getText()
local reason = reasonsTextList:getFocusedChild().reasonId
local action = actionsTextList:getFocusedChild().actionId
@ -130,13 +123,13 @@ function RuleViolation.report()
displayErrorBox(tr("Error"), tr("You must enter a comment."))
else
g_game.reportRuleVilation(target, reason, action, comment, statement, statementId, ipBanishment)
RuleViolation.hide()
hide()
end
end
function RuleViolation.clearForm()
function clearForm()
ruleViolationWindow:getChildById('nameText'):clearText()
ruleViolationWindow:getChildById('commentText'):clearText()
ruleViolationWindow:getChildById('statementText'):clearText()
ruleViolationWindow:getChildById('ipBanCheckBox'):setChecked(false)
end
end

@ -3,13 +3,7 @@ Module
description: Rule violation interface (Ctrl+Y)
author: andrefaramir
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'ruleviolation'
RuleViolation.init()
@onUnload: |
RuleViolation.terminate()
sandboxed: true
scripts: [ ruleviolation.lua ]
@onLoad: init()
@onUnload: terminate()

@ -3,7 +3,7 @@ RVListLabel < Label
text-offset: 2 0
focusable: true
@onFocusChange: function (self, focused) RuleViolation.onSelectReason(self, focused) end
$focus:
background-color: #ffffff22
color: #ffffff
@ -11,10 +11,10 @@ RVListLabel < Label
RVLabel < Label
anchors.left: parent.left
anchors.right: parent.right
$first:
anchors.top: parent.top
$!first:
margin-top: 10
anchors.top: prev.bottom
@ -23,34 +23,34 @@ RVTextEdit < TextEdit
margin-top: 2
anchors.left: parent.left
anchors.right: parent.right
$first:
anchors.top: parent.top
$!first:
anchors.top: prev.bottom
MainWindow
id: ruleViolationWindow
size: 400 445
text: Rule Violation
text: Rule Violation
RVLabel
!text: tr('Name:')
RVTextEdit
id: nameText
RVLabel
!text: tr('Statement:')
RVTextEdit
id: statementText
enabled: false
RVLabel
!text: tr('Reason:')
TextList
id: reasonList
height: 100
@ -67,11 +67,11 @@ MainWindow
anchors.bottom: reasonList.bottom
anchors.right: reasonList.right
step: 14
pixels-scroll: true
pixels-scroll: true
RVLabel
!text: tr('Action:')
TextList
id: actionList
height: 60
@ -88,8 +88,8 @@ MainWindow
anchors.bottom: actionList.bottom
anchors.right: actionList.right
step: 14
pixels-scroll: true
pixels-scroll: true
CheckBox
id: ipBanCheckBox
!text: tr('IP Address Banishment')
@ -97,24 +97,24 @@ MainWindow
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: parent.right
RVLabel
!text: tr('Comment:')
RVTextEdit
id: commentText
Button
!text: tr('Cancel')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: RuleViolation.hide()
Button
!text: tr('Ok')
width: 64
margin-right: 5
anchors.right: prev.left
anchors.bottom: parent.bottom
anchors.bottom: parent.bottom
@onClick: RuleViolation.report()

@ -1,7 +1,5 @@
Shaders = {}
local HOTKEY = 'Ctrl+X'
local MAP_SHADERS = {
HOTKEY = 'Ctrl+X'
MAP_SHADERS = {
{ name = 'Default', frag = 'shaders/default.frag' },
{ name = 'Bloom', frag = 'shaders/bloom.frag'},
{ name = 'Sepia', frag ='shaders/sepia.frag' },
@ -16,23 +14,23 @@ local MAP_SHADERS = {
{ name = 'Noise', frag ='shaders/noise.frag' },
}
local ITEM_SHADERS = {
ITEM_SHADERS = {
{ name = 'Fake 3D', vert = 'shaders/fake3d.vert' }
}
local shadersPanel
shadersPanel = nil
function Shaders.init()
function init()
g_ui.importStyle('shaders.otui')
g_keyboard.bindKeyDown(HOTKEY, Shaders.toggle)
g_keyboard.bindKeyDown(HOTKEY, toggle)
shadersPanel = g_ui.createWidget('ShadersPanel', GameInterface.getMapPanel())
shadersPanel = g_ui.createWidget('ShadersPanel', modules.game_interface.getMapPanel())
shadersPanel:hide()
local mapComboBox = shadersPanel:getChildById('mapComboBox')
mapComboBox.onOptionChange = function(combobox, option)
local map = GameInterface.getMapPanel()
local map = modules.game_interface.getMapPanel()
map:setMapShader(g_shaders.getShader(option))
end
@ -51,16 +49,15 @@ function Shaders.init()
mapComboBox:addOption(opts.name)
end
local map = GameInterface.getMapPanel()
local map = modules.game_interface.getMapPanel()
map:setMapShader(g_shaders.getShader('Default'))
end
function Shaders.terminate()
function terminate()
g_keyboard.unbindKeyDown(HOTKEY)
shadersPanel:destroy()
shadersPanel = nil
end
function Shaders.toggle()
function toggle()
shadersPanel:setVisible(not shadersPanel:isVisible())
end

@ -3,13 +3,6 @@ Module
description: Manage game shaders
author: edubart
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'shaders'
Shaders.init()
@onUnload: |
Shaders.terminate()
scripts: [ shaders.lua ]
@onLoad: init()
@onUnload: terminate()

@ -14,7 +14,7 @@ function init()
onSkillChange = onSkillChange
})
skillsWindow = g_ui.loadUI('skills.otui', GameInterface.getRightPanel())
skillsWindow = g_ui.loadUI('skills.otui', modules.game_interface.getRightPanel())
skillsButton = TopMenu.addRightGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', toggle)
skillsButton:setOn(true)
g_keyboard.bindKeyDown('Ctrl+S', toggle)

@ -26,7 +26,7 @@ function init()
registerProtocol()
g_ui.importStyle('textmessage.otui')
centerTextMessagePanel = g_ui.createWidget('Panel', GameInterface.getMapPanel())
centerTextMessagePanel = g_ui.createWidget('Panel', modules.game_interface.getMapPanel())
centerTextMessagePanel:setId('centerTextMessagePanel')
local layout = UIVerticalLayout.create(centerTextMessagePanel)
@ -38,15 +38,8 @@ function init()
warningLabel = createTextMessageLabel('warningLabel', centerTextMessagePanel, 'CenterLabel')
advanceLabel = createTextMessageLabel('advanceLabel', centerTextMessagePanel, 'CenterLabel')
infoLabel = createTextMessageLabel('infoLabel', centerTextMessagePanel, 'CenterLabel')
privateLabel = createTextMessageLabel('privateLabel', GameInterface.getMapPanel(), 'TopCenterLabel')
statusLabel = createTextMessageLabel('statusLabel', GameInterface.getMapPanel(), 'BottomLabel')
export({
clearMessages = clearMessages,
displayStatus = function(msg, time) displayMessage('StatusSmall', msg) end,
displayEventAdvance = function(msg, time) displayMessage('EventAdvance', msg, time) end,
displayPrivate = function(msg, time) displayMessage('Private', time) end
}, 'TextMessage')
privateLabel = createTextMessageLabel('privateLabel', modules.game_interface.getMapPanel(), 'TopCenterLabel')
statusLabel = createTextMessageLabel('statusLabel', modules.game_interface.getMapPanel(), 'BottomLabel')
end
function terminate()
@ -65,8 +58,6 @@ function terminate()
centerTextMessagePanel:destroy()
statusLabel:destroy()
privateLabel:destroy()
unexport('TextMessage')
end
function clearMessages()
@ -90,12 +81,12 @@ function displayMessage(msgtype, msg, time)
if msgtype.consoleTab ~= nil then
if msgtype.consoleOption == nil or Options.getOption(msgtype.consoleOption) then
Console.addText(msg, msgtype, msgtype.consoleTab)
modules.game_console.addText(msg, msgtype, msgtype.consoleTab)
end
end
if msgtype.labelId then
local label = GameInterface.getMapPanel():recursiveGetChildById(msgtype.labelId)
local label = modules.game_interface.getMapPanel():recursiveGetChildById(msgtype.labelId)
label:setText(msg)
label:setColor(msgtype.color)
@ -110,3 +101,15 @@ function displayMessage(msgtype, msg, time)
label.hideEvent = scheduleEvent(function() label:setVisible(false) end, time)
end
end
function displayStatus(msg, time)
displayMessage('StatusSmall', msg)
end
function displayEventAdvance(msg, time)
displayMessage('EventAdvance', msg, time)
end
function displayPrivate(msg, time)
displayMessage('Private', time)
end

@ -1,13 +1,28 @@
TextWindow = {}
function init()
g_ui.importStyle('textwindow.otui')
connect(g_game, { onEditText = onGameEditText,
onEditList = onGameEditList,
onGameEnd = destroy })
end
function terminate()
disconnect(g_game, { onEditText = onGameEditText,
onEditList = onGameEditList,
onGameEnd = destroy })
-- private variables
local textWindow
destroy()
end
-- private functions
local function onGameEditText(id, itemId, maxLength, text, writter, time)
function destroy()
if textWindow then
return
textWindow:destroy()
textWindow = nil
end
end
function onGameEditText(id, itemId, maxLength, text, writter, time)
if textWindow then return end
textWindow = g_ui.createWidget('TextWindow', rootWidget)
local writeable = (maxLength ~= #text) and maxLength > 0
@ -52,18 +67,16 @@ local function onGameEditText(id, itemId, maxLength, text, writter, time)
if writeable then
g_game.editText(id, textEdit:getText())
end
TextWindow.destroy()
destroy()
end
okButton.onClick = doneFunc
textWindow.onEnter = doneFunc
textWindow.onEscape = TextWindow.destroy
textWindow.onEscape = destroy
end
local function onGameEditList(id, doorId, text)
if textWindow then
return
end
function onGameEditList(id, doorId, text)
if textWindow then return end
textWindow = g_ui.createWidget('TextWindow', rootWidget)
local textEdit = textWindow:getChildById('text')
@ -79,34 +92,10 @@ local function onGameEditList(id, doorId, text)
doneFunc = function()
g_game.editList(id, doorId, textEdit:getText())
TextWindow.destroy()
destroy()
end
okButton.onClick = doneFunc
textWindow.onEnter = doneFunc
textWindow.onEscape = TextWindow.destroy
end
-- public functions
function TextWindow.init()
g_ui.importStyle('textwindow.otui')
connect(g_game, { onEditText = onGameEditText,
onEditList = onGameEditList,
onGameEnd = TextWindow.destroy })
end
function TextWindow.terminate()
disconnect(g_game, { onEditText = onGameEditText,
onEditList = onGameEditList,
onGameEnd = TextWindow.destroy })
TextWindow.destroy()
textWindow.onEscape = destroy
end
function TextWindow.destroy()
if textWindow then
textWindow:destroy()
textWindow = nil
end
end

@ -3,13 +3,8 @@ Module
description: Allow to edit text books and lists
author: edubart, BeniS
website: www.otclient.info
dependencies:
- game_interface
@onLoad: |
dofile 'textwindow'
TextWindow.init()
@onUnload: |
TextWindow.terminate()
sandboxed: true
dependencies: [ game_interface ]
scripts: [ textwindow.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,6 +1,4 @@
TibiaFiles = {}
function TibiaFiles.init()
function init()
if not g_things.loadDat('/game_tibiafiles/Tibia.dat') then
fatal(tr("Unable to load dat file, please place a valid Tibia dat in modules/game_tibiafiles/Tibia.dat"))
end
@ -9,5 +7,5 @@ function TibiaFiles.init()
end
end
function TibiaFiles.terminate()
function terminate()
end

@ -2,10 +2,7 @@ Module
name: game_tibiafiles
description: Contains tibia spr and dat
reloadable: false
@onLoad: |
dofile 'tibiafiles'
TibiaFiles.init()
@onUnload: |
TibiaFiles.terminate()
sandboxed: true
scripts: [tibiafiles.lua]
@onLoad: init()
@onUnload: terminate()

@ -1,8 +1,8 @@
MainWindow
size: 256 128
!text: tr('Add to VIP list')
@onEnter: VipList.addVip()
@onEscape: VipList.destroyAddWindow()
@onEnter: addVip()
@onEscape: destroyAddWindow()
Label
!text: tr('Please enter a character name:')
@ -29,11 +29,11 @@ MainWindow
anchors.right: next.left
anchors.bottom: parent.bottom
margin-right: 10
@onClick: VipList.addVip()
@onClick: addVip()
Button
!text: tr('Cancel')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: VipList.destroyAddWindow()
@onClick: destroyAddWindow()

@ -1,53 +1,45 @@
VipList = {}
vipWindow = nil
vipButton = nil
addVipWindow = nil
-- private variables
local vipWindow
local vipButton
local addVipWindow
function init()
connect(g_game, { onGameEnd = clear,
onAddVip = onAddVip,
onVipStateChange = onVipStateChange })
-- public functions
function VipList.init()
connect(g_game, { onGameEnd = VipList.clear,
onAddVip = VipList.onAddVip,
onVipStateChange = VipList.onVipStateChange })
g_keyboard.bindKeyDown('Ctrl+P', toggle)
g_keyboard.bindKeyDown('Ctrl+P', VipList.toggle)
vipWindow = g_ui.loadUI('viplist.otui', GameInterface.getRightPanel())
vipButton = TopMenu.addRightGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', VipList.toggle)
vipWindow = g_ui.loadUI('viplist.otui', modules.game_interface.getRightPanel())
vipButton = TopMenu.addRightGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', toggle)
vipButton:setOn(true)
VipList.refresh()
refresh()
end
function VipList.terminate()
function terminate()
g_keyboard.unbindKeyDown('Ctrl+P')
disconnect(g_game, { onGameEnd = VipList.clear,
onAddVip = VipList.onAddVip,
onVipStateChange = VipList.onVipStateChange })
disconnect(g_game, { onGameEnd = clear,
onAddVip = onAddVip,
onVipStateChange = onVipStateChange })
vipWindow:destroy()
vipWindow = nil
vipButton:destroy()
vipButton = nil
VipList = nil
end
function VipList.refresh()
VipList.clear()
function refresh()
clear()
for id,vip in pairs(g_game.getVips()) do
VipList.onAddVip(id, unpack(vip))
onAddVip(id, unpack(vip))
end
end
function VipList.clear()
function clear()
local vipList = vipWindow:getChildById('contentsPanel')
vipList:destroyChildren()
end
function VipList.toggle()
function toggle()
if vipButton:isOn() then
vipWindow:close()
vipButton:setOn(false)
@ -57,26 +49,25 @@ function VipList.toggle()
end
end
function VipList.onMiniWindowClose()
function onMiniWindowClose()
vipButton:setOn(false)
end
function VipList.createAddWindow()
function createAddWindow()
addVipWindow = g_ui.displayUI('addvip.otui')
end
function VipList.destroyAddWindow()
function destroyAddWindow()
addVipWindow:destroy()
addVipWindow = nil
end
function VipList.addVip()
function addVip()
g_game.addVip(addVipWindow:getChildById('name'):getText())
VipList.destroyAddWindow()
destroyAddWindow()
end
-- hooked events
function VipList.onAddVip(id, name, online)
function onAddVip(id, name, online)
local vipList = vipWindow:getChildById('contentsPanel')
local label = g_ui.createWidget('VipListLabel')
@ -122,34 +113,34 @@ function VipList.onAddVip(id, name, online)
vipList:insertChild(childrenCount+1, label)
end
function VipList.onVipStateChange(id, online)
function onVipStateChange(id, online)
local vipList = vipWindow:getChildById('contentsPanel')
local label = vipList:getChildById('vip' .. id)
local text = label:getText()
label:destroy()
VipList.onAddVip(id, text, online)
onAddVip(id, text, online)
end
function VipList.onVipListMousePress(widget, mousePos, mouseButton)
function onVipListMousePress(widget, mousePos, mouseButton)
if mouseButton ~= MouseRightButton then return end
local vipList = vipWindow:getChildById('contentsPanel')
local menu = g_ui.createWidget('PopupMenu')
menu:addOption(tr('Add new VIP'), function() VipList.createAddWindow() end)
menu:addOption(tr('Add new VIP'), function() createAddWindow() end)
menu:display(mousePos)
return true
end
function VipList.onVipListLabelMousePress(widget, mousePos, mouseButton)
function onVipListLabelMousePress(widget, mousePos, mouseButton)
if mouseButton ~= MouseRightButton then return end
local vipList = vipWindow:getChildById('contentsPanel')
local menu = g_ui.createWidget('PopupMenu')
menu:addOption(tr('Add new VIP'), function() VipList.createAddWindow() end)
menu:addOption(tr('Add new VIP'), function() createAddWindow() end)
menu:addOption(tr('Remove %s', widget:getText()), function() if widget then g_game.removeVip(widget:getId():sub(4)) vipList:removeChild(widget) end end)
menu:addSeparator()
menu:addOption(tr('Copy Name'), function() g_window.setClipboardText(widget:getText()) end)

@ -3,10 +3,7 @@ Module
description: Manage vip list window
author: baxnie, edubart
website: www.otclient.info
@onLoad: |
dofile 'viplist'
VipList.init()
@onUnload: |
VipList.terminate()
sandboxed: true
scripts: [ viplist.lua ]
@onLoad: init()
@onUnload: terminate()

@ -1,17 +1,17 @@
VipListLabel < GameLabel
font: verdana-11px-monochrome
phantom: false
&onMousePress: VipList.onVipListLabelMousePress
&onMousePress: onVipListLabelMousePress
MiniWindow
id: vipWindow
!text: tr('VIP List')
height: 100
icon: viplist.png
@onClose: VipList.onMiniWindowClose()
@onClose: onMiniWindowClose()
&save: true
MiniWindowContents
layout: verticalBox
anchors.fill: parent
&onMousePress: VipList.onVipListMousePress
&onMousePress: onVipListMousePress

@ -70,6 +70,13 @@ bool Module::load()
if(m_sandboxed)
g_lua.resetGlobalEnvironment();
// add to package.loaded
g_lua.getGlobalField("package", "loaded");
g_lua.getRef(m_sandboxEnv);
g_lua.setField(m_name);
g_lua.pop();
m_loaded = true;
g_logger.debug(stdext::format("Loaded module '%s'", m_name));
} catch(stdext::exception& e) {
if(m_sandboxed)
@ -78,7 +85,6 @@ bool Module::load()
return false;
}
m_loaded = true;
g_modules.updateModuleLoadOrder(asModule());
for(const std::string& modName : m_loadLaterModules) {
@ -119,6 +125,12 @@ void Module::unload()
g_lua.clearTable();
g_lua.pop();
// remove from package.loaded
g_lua.getGlobalField("package", "loaded");
g_lua.pushNil();
g_lua.setField(m_name);
g_lua.pop();
m_loaded = false;
//g_logger.info(stdext::format("Unloaded module '%s'", m_name));
g_modules.updateModuleLoadOrder(asModule());

@ -930,18 +930,21 @@ void LuaInterface::setTable(int index)
void LuaInterface::clearTable(int index)
{
assert(hasIndex(index) && isTable(index));
pushNil();
pushNil(); // table, nil
bool stop = false;
while(!stop && next(index-1)) {
pop();
pushValue();
if(next(index-2))
pop();
else
stop = true;
insert(-2);
pushNil();
rawSet(index-3);
while(next(index-1)) { // table, key, value
pop(); // table, key
pushValue(); // table, key, key
if(next(index-2)) { // table, key, nextkey, value
pop(); // table, key, nextkey
insert(-2); // table, nextkey, key
pushNil(); // table, nextkey, key, nil
rawSet(index-3); // table, nextkey
} else { // table, key
pushNil(); // table, key, nil
rawSet(index-2); // table
break;
}
}
}

@ -191,10 +191,8 @@ void OTMLParser::parseNode(const std::string& data)
if(boost::starts_with(value, "[") && boost::ends_with(value, "]")) {
std::string tmp = value.substr(1, value.length()-2);
boost::tokenizer<boost::escaped_list_separator<char>> tokens(tmp);
for(std::string v : tokens) {
stdext::trim(v);
node->writeIn(v);
}
for(std::string v : tokens)
node->writeIn(stdext::trim(v));
} else
node->setValue(value);
}

Loading…
Cancel
Save