diff --git a/modules/client/client.otmod b/modules/client/client.otmod index 48124cd..2824a66 100644 --- a/modules/client/client.otmod +++ b/modules/client/client.otmod @@ -17,7 +17,6 @@ Module - client_textedit - client_options - client_entergame - - client_entergamev2 - client_terminal - client_stats - client_feedback diff --git a/modules/client_entergamev2/entergamev2.lua b/modules/client_entergamev2/entergamev2.lua deleted file mode 100644 index 59a93b5..0000000 --- a/modules/client_entergamev2/entergamev2.lua +++ /dev/null @@ -1,484 +0,0 @@ -local entergameWindow -local characterGroup -local outfitGroup -local protocol -local infoBox -local loadingBox - -function init() - if not USE_NEW_ENERGAME then return end - entergameWindow = g_ui.displayUI('entergamev2') - - entergameWindow.news:hide() - entergameWindow.quick:hide() - entergameWindow.registration:hide() - entergameWindow.characters:hide() - entergameWindow.createcharacter:hide() - entergameWindow.settings:hide() - - -- entergame - entergameWindow.entergame.register.onClick = function() - entergameWindow.registration:show() - entergameWindow.entergame:hide() - end - entergameWindow.entergame.mainPanel.button.onClick = login - - -- registration - entergameWindow.registration.back.onClick = function() - entergameWindow.registration:hide() - entergameWindow.entergame:show() - end - - -- characters - --- outfits - entergameWindow.characters.mainPanel.showOutfits.onClick = function() - local status = not (entergameWindow.characters.mainPanel.showOutfits:isOn()) - g_settings.set('showOutfits', status) - entergameWindow.characters.mainPanel.showOutfits:setOn(status) - if status then - entergameWindow.characters.mainPanel.outfitsPanel:show() - entergameWindow.characters.mainPanel.outfitsScroll:show() - entergameWindow.characters.mainPanel.charactersPanel:hide() - entergameWindow.characters.mainPanel.charactersScroll:hide() - else - entergameWindow.characters.mainPanel.outfitsPanel:hide() - entergameWindow.characters.mainPanel.outfitsScroll:hide() - entergameWindow.characters.mainPanel.charactersPanel:show() - entergameWindow.characters.mainPanel.charactersScroll:show() - end - end - - local showOutfits = g_settings.getBoolean("showOutfits", false) - entergameWindow.characters.mainPanel.showOutfits:setOn(showOutfits) - if showOutfits then - entergameWindow.characters.mainPanel.charactersPanel:hide() - entergameWindow.characters.mainPanel.charactersScroll:hide() - else - entergameWindow.characters.mainPanel.outfitsPanel:hide() - entergameWindow.characters.mainPanel.outfitsScroll:hide() - end - - --- auto reconnect - entergameWindow.characters.mainPanel.autoReconnect.onClick = function() - local status = (not entergameWindow.characters.mainPanel.autoReconnect:isOn()) - g_settings.set('autoReconnect', status) - entergameWindow.characters.mainPanel.autoReconnect:setOn(status) - end - local autoReconnect = g_settings.getBoolean("autoReconnect", true) - entergameWindow.characters.mainPanel.autoReconnect:setOn(autoReconnect) - - --- buttons - entergameWindow.characters.logout.onClick = function() - protocol:logout() - entergameWindow.characters:hide() - entergameWindow.entergame:show() - entergameWindow.entergame.mainPanel.account:setText("") - entergameWindow.entergame.mainPanel.password:setText("") - end - entergameWindow.characters.createcharacter.onClick = function() - entergameWindow.characters:hide() - entergameWindow.createcharacter:show() - entergameWindow.createcharacter.mainPanel.name:setText("") - end - entergameWindow.characters.settings.onClick = function() - entergameWindow.characters:hide() - entergameWindow.settings:show() - end - - -- create character - entergameWindow.createcharacter.back.onClick = function() - entergameWindow.createcharacter:hide() - entergameWindow.characters:show() - end - entergameWindow.createcharacter.mainPanel.createButton.onClick = createcharacter - - entergameWindow.settings.back.onClick = function() - entergameWindow.settings:hide() - entergameWindow.characters:show() - end - entergameWindow.settings.mainPanel.updateButton.onClick = updateSettings - - -- pick server - local server = nil - if type(Servers) == "table" then - for name, url in pairs(Servers) do - server = url - end - elseif type(Servers) == "string" then - server = Servers - elseif type(Server) == "string" then - server = Server - end - - if not server then - message("Configuration error", "You must set server url in init.lua!\nExample:\nServer = \"ws://otclient.ovh:8000\"") - return - end - - -- init protocol - -- token is random string - local session = g_crypt.sha1Encode("" .. math.random() .. g_clock.realMicros() .. tostring(G.UUID) .. g_platform.getCPUName() .. g_platform.getProcessId()) - protocol = EnterGameV2Protocol.new(session) - if not protocol:setUrl(server) then - return message("Configuration error", "Invalid url for entergamev2:\n" .. server) - end - - protocol.onLogin = onLogin - protocol.onLogout = logout - protocol.onMessage = serverMessage - protocol.onLoading = showLoading - protocol.onQAuth = updateQAuth - protocol.onCharacters = updateCharacters - protocol.onNews = updateNews - protocol.onMotd = updateMotd - protocol.onCharacterCreate = onCharacterCreate - - -- game stuff - connect(g_game, { onLoginError = onLoginError, - onLoginToken = onLoginToken , - onUpdateNeeded = onUpdateNeeded, - onConnectionError = onConnectionError, - onGameStart = onGameStart, - onGameEnd = onGameEnd, - onLoginWait = onLoginWait, - onLogout = onLogout - }) - - if g_game.isOnline() then - onGameStart() - end -end - -function terminate() - if not USE_NEW_ENERGAME then return end - if protocol then - protocol:destroy() - protocol = nil - end - if infoBox then - infoBox:destroy() - infoBox = nil - end - if loadingBox then - loadingBox:destroy() - loadingBox = nil - end - if characterGroup then - characterGroup:destroy() - characterGroup = nil - end - if outfitGroup then - outfitGroup:destroy() - outfitGroup = nil - end - entergameWindow:destroy() - entergameWindow = nil - - disconnect(g_game, { onLoginError = onLoginError, - onLoginToken = onLoginToken , - onUpdateNeeded = onUpdateNeeded, - onConnectionError = onConnectionError, - onGameStart = onGameStart, - onGameEnd = onGameEnd, - onLoginWait = onLoginWait, - onLogout = onLogout - }) -end - -function show() - -end - -function hide() - -end - -function message(title, text) - if infoBox then - infoBox:destroy() - end - - infoBox = displayInfoBox(title, text) - infoBox.onDestroy = function(widget) - if widget == infoBox then - infoBox = nil - end - end - infoBox:show() - infoBox:raise() - infoBox:focus() -end - -function showLoading(titie, text) - if loadingBox then - loadingBox:destroy() - end - - local callback = function() end -- do nothing - loadingBox = displayGeneralBox(titie, text, {}, callback, callback) - loadingBox.onDestroy = function(widget) - if widget == loadingBox then - loadingBox = nil - end - end - loadingBox:show() - loadingBox:raise() - loadingBox:focus() -end - -function serverMessage(title, text) - return message(title, text) -end - -function updateCharacters(characters) - if outfitGroup then - outfitGroup:destroy() - end - if characterGroup then - characterGroup:destroy() - end - entergameWindow.characters.mainPanel.charactersPanel:destroyChildren() - entergameWindow.characters.mainPanel.outfitsPanel:destroyChildren() - - outfitGroup = UIRadioGroup.create() - characterGroup = UIRadioGroup.create() - for i, character in ipairs(characters) do - local characterWidget = g_ui.createWidget('EntergameCharacter', entergameWindow.characters.mainPanel.charactersPanel) - characterGroup:addWidget(characterWidget) - local outfitWidget = g_ui.createWidget('EntergameBigCharacter', entergameWindow.characters.mainPanel.outfitsPanel) - outfitGroup:addWidget(outfitWidget) - for i, widget in ipairs({characterWidget, outfitWidget}) do - widget.character = character - widget.outfit:setOutfit(character["outfit"]) - widget.line1:setText(character["line1"]) - widget.line2:setText(character["line2"]) - widget.line3:setText(character["line3"]) - end - end - if #characters > 1 then - characterGroup:selectWidget(entergameWindow.characters.mainPanel.charactersPanel:getFirstChild()) - outfitGroup:selectWidget(entergameWindow.characters.mainPanel.outfitsPanel:getFirstChild()) - end -end - -function updateQAuth(token) - if not token or token:len() == 0 then - return entergameWindow.quick:hide() - end - entergameWindow.quick:show() - entergameWindow.quick.qrcode:setQRCode(token, 1) - entergameWindow.quick.qrcode.onClick = function() - g_platform.openUrl(token) - end - entergameWindow.quick.quathlogo.onClick = entergameWindow.quick.qrcode.onClick -end - -function updateNews(news) - if not news or #news == 0 then - return entergameWindow.news:hide() - end - entergameWindow.news:show() - entergameWindow.news.content:destroyChildren() - for i, entry in ipairs(news) do - local title = entry["title"] - local text = entry["text"] - local image = entry["image"] - if title then - local newsLabel = g_ui.createWidget('NewsLabel', entergameWindow.news.content) - newsLabel:setText(title) - end - if text ~= nil then - local newsText = g_ui.createWidget('NewsText', entergameWindow.news.content) - newsText:setText(text) - end - end -end - -function updateMotd(text) - if not text or text:len() == 0 then - return entergameWindow.characters.mainPanel.motd:hide() - end - entergameWindow.characters.mainPanel.motd:show() - entergameWindow.characters.mainPanel.motd:setText(text) -end - -function login() - local account = entergameWindow.entergame.mainPanel.account:getText() - local password = entergameWindow.entergame.mainPanel.password:getText() - entergameWindow.entergame:hide() - showLoading("Login", "Connecting to server...") - protocol:login(account, password, "") -end - -function onLogin(data) - if loadingBox then - loadingBox:destroy() - loadingBox = nil - end - - if data["error"] and data["error"]:len() > 0 then - entergameWindow.entergame:show() - return message("Login error", data["error"]) - end - - local incorrectThings = validateThings(data["things"]) - if incorrectThings:len() > 0 then - entergameWindow.entergame:show() - return message("Login error - missing things", incorrectThings) - end - - if infoBox then - infoBox:destroy() - end - - local version = data["version"] - G.clientVersion = version - g_game.setClientVersion(version) - g_game.setProtocolVersion(g_game.getClientProtocolVersion(version)) - g_game.setCustomOs(-1) -- disable custom os - - local customProtocol = data["customProtocol"] - g_game.setCustomProtocolVersion(0) - if type(customProtocol) == 'number' then - g_game.setCustomProtocolVersion(customProtocol) - end - - local email = data["email"] - local security = data["security"] - entergameWindow.settings.mainPanel.email:setText(email) - entergameWindow.settings.mainPanel.security:setCurrentIndex(math.max(1, security)) - - entergameWindow.characters:show() - entergameWindow.entergame:hide() -end - -function logout() - if not entergameWindow.characters:isVisible() and not entergameWindow.createcharacter:isVisible() then - return - end - entergameWindow.characters:hide() - entergameWindow.createcharacter:hide() - entergameWindow.entergame:show() - message("Information", "Session expired, you has been logged out.") -end - -function validateThings(things) - local incorrectThings = "" - local missingFiles = false - local versionForMissingFiles = 0 - if things ~= nil then - local thingsNode = {} - for thingtype, thingdata in pairs(things) do - thingsNode[thingtype] = thingdata[1] - if not g_resources.fileExists("/things/" .. thingdata[1]) then - incorrectThings = incorrectThings .. "Missing file: " .. thingdata[1] .. "\n" - missingFiles = true - versionForMissingFiles = thingdata[1]:split("/")[1] - else - local localChecksum = g_resources.fileChecksum("/things/" .. thingdata[1]):lower() - if localChecksum ~= thingdata[2]:lower() and #thingdata[2] > 1 then - if g_resources.isLoadedFromArchive() then -- ignore checksum if it's test/debug version - incorrectThings = incorrectThings .. "Invalid checksum of file: " .. thingdata[1] .. " (is " .. localChecksum .. ", should be " .. thingdata[2]:lower() .. ")\n" - end - end - end - end - g_settings.setNode("things", thingsNode) - else - g_settings.setNode("things", {}) - end - if missingFiles then - incorrectThings = incorrectThings .. "\nYou should open data/things and create directory " .. versionForMissingFiles .. - ".\nIn this directory (data/things/" .. versionForMissingFiles .. ") you should put missing\nfiles (Tibia.dat and Tibia.spr) " .. - "from correct Tibia version." - end - return incorrectThings -end - -function doGameLogin() - local selected = nil - if entergameWindow.characters.mainPanel.charactersPanel:isVisible() then - selected = characterGroup:getSelectedWidget() - else - selected = outfitGroup:getSelectedWidget() - end - if not selected then - return message("Entergame error", "Please select character") - end - local character = selected.character - if not g_game.getFeature(GameSessionKey) then - g_game.enableFeature(GameSessionKey) - end - g_game.loginWorld("", "", character.worldName, character.worldHost, character.worldPort, character.name, "", protocol.session) -end - -function onLoginError(err) - message("Login error", err) -end - -function onLoginToken() - -end - -function onUpdateNeeded(signature) - -end - -function onConnectionError(message, code) - -end - -function onGameStart() - entergameWindow:hide() -end - -function onGameEnd() - entergameWindow:show() -end - -function onLoginWait(message, time) - -end - -function onLogout() - -end - -function createcharacter() - local name = entergameWindow.createcharacter.mainPanel.name:getText() - local gender = entergameWindow.createcharacter.mainPanel.gender:getCurrentOption().text - local vocation = entergameWindow.createcharacter.mainPanel.vocation:getCurrentOption().text - local town = entergameWindow.createcharacter.mainPanel.town:getCurrentOption().text - if name:len() < 3 or name:len() > 20 then - return message("Error", "Invalid character name") - end - protocol:createCharacter(name, gender, vocation, town) - showLoading("Creating character", "Creating new character...") -end - -function onCharacterCreate(err, msg) - if loadingBox then - loadingBox:destroy() - loadingBox = nil - end - - if err then - return message("Error", err) - end - message("Success", msg) - entergameWindow.createcharacter:hide() - entergameWindow.characters:show() -end - -function updateSettings() - local email = entergameWindow.settings.mainPanel.email:getText() - local security = entergameWindow.settings.mainPanel.security.currentIndex - - protocol:updateSettings({ - email=email, - security=security - }) - - entergameWindow.settings:hide() - entergameWindow.characters:show() -end \ No newline at end of file diff --git a/modules/client_entergamev2/entergamev2.otmod b/modules/client_entergamev2/entergamev2.otmod deleted file mode 100644 index 2fd817e..0000000 --- a/modules/client_entergamev2/entergamev2.otmod +++ /dev/null @@ -1,10 +0,0 @@ -Module - name: client_entergamev2 - description: Manages enter game and character list windows - author: otclient.ovh - website: http://otclient.ovh - sandboxed: true - scripts: [ protocol, entergamev2 ] - @onLoad: init() - @onUnload: terminate() - \ No newline at end of file diff --git a/modules/client_entergamev2/entergamev2.otui b/modules/client_entergamev2/entergamev2.otui deleted file mode 100644 index b4b381a..0000000 --- a/modules/client_entergamev2/entergamev2.otui +++ /dev/null @@ -1,796 +0,0 @@ -EnterGamePanel < Panel - font: verdana-11px-antialised - color: #dfdfdf - text-offset: 0 6 - text-align: top - image-source: /images/ui/window - image-border: 6 - image-border-top: 27 - padding-top: 28 - padding-left: 8 - padding-right: 8 - padding-bottom: 8 - -News < EnterGamePanel - id: news - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - width: 230 - !text: tr("News") - - ScrollablePanel - id: content - anchors.fill: parent - margin-right: 8 - margin-left: 1 - margin-bottom: 5 - vertical-scrollbar: newsPanelScroll - layout: - type: verticalBox - - SmallScrollBar - id: newsPanelScroll - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.right: parent.right - -NewsLabel < Label - text-wrap: true - text-auto-resize: true - text-align: center - font: terminus-14px-bold - -NewsText < Label - text-wrap: true - text-auto-resize: true - text-align: left - margin-bottom: 10 - -NewsImage < Label - text-wrap: true - margin-bottom: 5 - text-align: center - -EnterGame < Panel - anchors.fill: parent - id: entergame - - EnterGamePanel - id: mainPanel - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - size: 230 210 - !text: tr("Enter Game") - padding-top: 36 - padding-left: 16 - padding-right: 16 - padding-bottom: 16 - - MenuLabel - !text: tr('Account name') - anchors.left: parent.left - anchors.top: parent.top - text-auto-resize: true - - TextEdit - id: account - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - MenuLabel - !text: tr('Password') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - PasswordTextEdit - id: password - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - HorizontalSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 10 - - CheckBox - id: rememberPasswordBox - !text: tr('Remember password') - !tooltip: tr('Remember account and password when starts client') - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 9 - - HorizontalSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 9 - - Button - id: button - !text: tr('Login') - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 10 - margin-left: 50 - margin-right: 50 - - EnterGamePanel - id: buttons - anchors.horizontalCenter: prev.horizontalCenter - anchors.top: prev.bottom - margin-top: 20 - size: 290 50 - image-source: /images/ui/window_headless - image-border: 6 - padding-top: 8 - - Button - id: register - anchors.verticalCenter: buttons.verticalCenter - anchors.left: buttons.left - margin-left: 10 - !text: tr("Create account") - size: 130 30 - - Button - id: register - anchors.verticalCenter: buttons.verticalCenter - anchors.right: buttons.right - margin-right: 10 - !text: tr("Casts") - size: 130 30 - -Registration < Panel - anchors.fill: parent - id: registration - - EnterGamePanel - id: mainPanel - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - size: 250 262 - !text: tr("Create Acoount") - padding-top: 36 - padding-left: 16 - padding-right: 16 - padding-bottom: 16 - - MenuLabel - !text: tr('Account name') - anchors.left: parent.left - anchors.top: parent.top - text-auto-resize: true - - TextEdit - id: accountNameTextEdit - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - MenuLabel - !text: tr('Email') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - TextEdit - id: emailTextEdit - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - MenuLabel - !text: tr('Password') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - PasswordTextEdit - id: accountPasswordTextEdit - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - MenuLabel - !text: tr('Password confirmation') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - PasswordTextEdit - id: accountPasswordTextEdit - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - HorizontalSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 9 - - Button - !text: tr('Create account') - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 10 - margin-left: 50 - margin-right: 50 - - EnterGamePanel - id: buttons - anchors.horizontalCenter: prev.horizontalCenter - anchors.top: prev.bottom - margin-top: 20 - size: 200 50 - image-source: /images/ui/window_headless - image-border: 6 - padding-top: 8 - - Button - id: back - anchors.verticalCenter: buttons.verticalCenter - anchors.horizontalCenter: buttons.horizontalCenter - !text: tr("Back") - size: 160 30 - -QuickLogin < EnterGamePanel - id: quick - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - size: 230 312 - !text: tr("Quick Login & Registration") - - UIButton - id: qrcode - width: 200 - height: 200 - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - image-fixed-ratio: true - image-smooth: false - margin-top: 5 - - UIButton - id: quathlogo - width: 66 - height: 40 - anchors.verticalCenter: prev.verticalCenter - anchors.horizontalCenter: prev.horizontalCenter - image-fixed-ratio: true - image-smooth: false - image-source: /images/ui/qauth - - Label - anchors.top: qrcode.bottom - anchors.left: qrcode.left - anchors.right: qrcode.right - text-align: center - text-auto-resize: true - !text: tr("Scan or click QR code\nto register or login") - height: 40 - margin-top: 10 - margin-bottom: 5 - - Button - anchors.top: prev.bottom - anchors.left: parent.left - anchors.right: parent.right - text-align: center - !text: tr("Click to get PC/Android/iOS app") - height: 23 - margin-top: 10 - margin-left: 5 - margin-right: 5 - color: #FFFFFF - @onClick: g_platform.openUrl("http://qauth.co") - -Characters < Panel - id: characters - anchors.fill: parent - - EnterGamePanel - id: mainPanel - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - size: 550 350 - !text: tr("Characters") - padding-top: 36 - padding-left: 16 - padding-right: 16 - padding-bottom: 16 - - Label - id: motd - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - text-auto-resize: true - text-wrap: true - text-align: center - - HorizontalSeparator - id: motdSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 5 - - ScrollablePanel - id: outfitsPanel - layout: - type: grid - cell-size: 125 125 - cell-spacing: 1 - flow: true - vertical-scrollbar: outfitsScroll - background-color: #444444 - anchors.top: prev.bottom - anchors.bottom: bottomSeparator.top - anchors.left: parent.left - anchors.right: parent.right - margin-right: 12 - margin-bottom: 5 - margin-top: 5 - - VerticalScrollBar - id: outfitsScroll - anchors.top: outfitsPanel.top - anchors.bottom: outfitsPanel.bottom - anchors.left: outfitsPanel.right - step: 14 - pixels-scroll: true - - ScrollablePanel - id: charactersPanel - layout: - type: verticalBox - vertical-scrollbar: charactersScroll - background-color: #444444 - anchors.top: motdSeparator.bottom - anchors.bottom: bottomSeparator.top - anchors.left: parent.left - anchors.right: parent.right - margin-right: 12 - margin-bottom: 5 - margin-top: 5 - - VerticalScrollBar - id: charactersScroll - anchors.top: charactersPanel.top - anchors.bottom: charactersPanel.bottom - anchors.left: charactersPanel.right - step: 14 - pixels-scroll: true - - HorizontalSeparator - id: bottomSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - margin-bottom: 30 - - Button - id: autoReconnect - !text: tr('Auto reconnect: On') - width: 140 - anchors.left: parent.left - anchors.bottom: parent.bottom - image-color: green - $!on: - image-color: red - !text: tr('Auto reconnect: Off') - - Button - id: showOutfits - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - width: 140 - - $on: - !text: tr("Hide big outfits") - - $!on: - !text: tr("Show big outfits") - - Button - id: connect - anchors.right: parent.right - anchors.bottom: parent.bottom - !text: tr("Connect") - width: 140 - @onClick: modules.client_entergamev2.doGameLogin() - - EnterGamePanel - id: buttons - anchors.horizontalCenter: prev.horizontalCenter - anchors.top: prev.bottom - margin-top: 20 - size: 450 50 - image-source: /images/ui/window_headless - image-border: 6 - padding-top: 8 - - Button - id: createcharacter - anchors.verticalCenter: buttons.verticalCenter - anchors.left: buttons.left - !text: tr("Create character") - margin-left: 10 - size: 140 30 - - Button - id: settings - anchors.verticalCenter: buttons.verticalCenter - anchors.horizontalCenter: buttons.horizontalCenter - !text: tr("Account settings") - size: 140 30 - - Button - id: logout - anchors.verticalCenter: buttons.verticalCenter - anchors.right: buttons.right - margin-right: 10 - !text: tr("Logout") - size: 140 30 - -EntergameBigCharacter < UIButton - border-width: 1 - padding: 1 1 1 1 - @onClick: self:setChecked(true) - @onDoubleClick: modules.client_entergamev2.doGameLogin() - - $checked: - border-color: #ffffff - - $!checked: - border-color: black - - UICreature - id: outfit - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - size: 70 70 - margin-bottom: 3 - phantom: true - - Label - id: line1 - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - text-align: center - text-wrap: false - height: 16 - font: terminus-10px - border-width-bottom: 1 - border-color: #00000077 - phantom: true - - Label - id: line2 - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - text-align: center - text-wrap: false - height: 16 - font: terminus-10px - border-width-bottom: 1 - border-color: #00000077 - phantom: true - - Label - id: line3 - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - text-align: center - text-wrap: false - height: 16 - font: terminus-10px - border-width-bottom: 1 - border-color: #00000077 - phantom: true - -EntergameCharacter < UIButton - padding: 3 3 3 3 - @onClick: self:setChecked(true) - @onDoubleClick: modules.client_entergamev2.doGameLogin() - height: 34 - - $checked: - background-color: #333333 - - $!checked: - background-color: #555555 - - UICreature - id: outfit - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - size: 32 32 - margin-top: -2 - margin-bottom: -2 - phantom: true - - UILabel - id: line1 - anchors.left: prev.right - anchors.top: parent.top - anchors.bottom: parent.bottom - margin-left: 6 - width: 150 - text-align: left - phantom: true - - VerticalSeparator - anchors.left: prev.right - anchors.top: parent.top - anchors.bottom: parent.bottom - - UILabel - id: line2 - anchors.left: prev.right - anchors.top: parent.top - anchors.bottom: parent.bottom - width: 150 - text-align: center - phantom: true - - VerticalSeparator - anchors.left: prev.right - anchors.top: parent.top - anchors.bottom: parent.bottom - - UILabel - id: line3 - anchors.left: prev.right - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - text-align: center - phantom: true - -CreateCharacter < Panel - anchors.fill: parent - id: createcharacter - - EnterGamePanel - id: mainPanel - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - size: 250 262 - !text: tr("Create Character") - padding-top: 36 - padding-left: 16 - padding-right: 16 - padding-bottom: 16 - - MenuLabel - !text: tr('Name') - anchors.left: parent.left - anchors.top: parent.top - text-auto-resize: true - - TextEdit - id: name - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - MenuLabel - !text: tr('Gender') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - ComboBox - id: gender - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - menu-scroll: true - menu-height: 125 - menu-scroll-step: 25 - margin-right: 3 - @onSetup: | - self:addOption("Male") - self:addOption("Female") - - MenuLabel - !text: tr('Vocation') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - ComboBox - id: vocation - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - menu-scroll: true - menu-height: 125 - menu-scroll-step: 25 - margin-right: 3 - @onSetup: | - self:addOption("Sorcerer") - self:addOption("Druid") - self:addOption("Paladin") - self:addOption("Knight") - - MenuLabel - !text: tr('Town') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - ComboBox - id: town - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - menu-scroll: true - menu-height: 125 - menu-scroll-step: 25 - margin-right: 3 - @onSetup: | - self:addOption("Carlin") - self:addOption("Edron") - self:addOption("Thais") - self:addOption("Venore") - - HorizontalSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 9 - - Button - id: createButton - !text: tr('Create character') - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 10 - margin-left: 50 - margin-right: 50 - - EnterGamePanel - id: buttons - anchors.horizontalCenter: prev.horizontalCenter - anchors.top: prev.bottom - margin-top: 20 - size: 200 50 - image-source: /images/ui/window_headless - image-border: 6 - padding-top: 8 - - Button - id: back - anchors.verticalCenter: buttons.verticalCenter - anchors.horizontalCenter: buttons.horizontalCenter - !text: tr("Back") - size: 160 30 - - -AccountSettings < Panel - anchors.fill: parent - id: settings - - EnterGamePanel - id: mainPanel - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - size: 250 173 - !text: tr("Account settings") - padding-top: 36 - padding-left: 16 - padding-right: 16 - padding-bottom: 16 - - MenuLabel - !text: tr('Email') - anchors.left: parent.left - anchors.top: parent.top - text-auto-resize: true - - TextEdit - id: email - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 2 - - MenuLabel - !text: tr('Security level') - anchors.left: prev.left - anchors.top: prev.bottom - margin-top: 8 - text-auto-resize: true - - ComboBox - id: security - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - menu-scroll: true - menu-height: 125 - menu-scroll-step: 25 - margin-right: 3 - @onSetup: | - self:addOption("Low") - self:addOption("Medium") - self:addOption("High") - - HorizontalSeparator - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 9 - - Button - id: updateButton - !text: tr('Update settings') - anchors.left: parent.left - anchors.right: parent.right - anchors.top: prev.bottom - margin-top: 10 - margin-left: 50 - margin-right: 50 - - EnterGamePanel - id: buttons - anchors.horizontalCenter: prev.horizontalCenter - anchors.top: prev.bottom - margin-top: 20 - size: 200 50 - image-source: /images/ui/window_headless - image-border: 6 - padding-top: 8 - - Button - id: back - anchors.verticalCenter: buttons.verticalCenter - anchors.horizontalCenter: buttons.horizontalCenter - !text: tr("Back") - size: 160 30 - -Panel - anchors.top: topMenu.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - margin: 10 10 10 10 - - News - QuickLogin - EnterGame - Registration - Characters - CreateCharacter - AccountSettings diff --git a/modules/client_entergamev2/protocol.lua b/modules/client_entergamev2/protocol.lua deleted file mode 100644 index bd18607..0000000 --- a/modules/client_entergamev2/protocol.lua +++ /dev/null @@ -1,228 +0,0 @@ -EnterGameV2Protocol = {} -EnterGameV2Protocol.__index = EnterGameV2Protocol - -EnterGameV2Protocol.new = function(session) - if type(session) ~= 'string' then - return error("You need to specify string session for EnterGameV2Protocol") - end - local data = {} - data.socket = nil - data.terminated = false - data.reconnectEvent = nil - data.connected = false - data.session = session - data.sendQueue = {} - data.sendQueueMsgId = 1 - data.loginTimeoutEvent = nil - setmetatable(data, EnterGameV2Protocol) - return data -end - -function EnterGameV2Protocol:destroy() - self.terminated = true - self.sendQueue = {} - - if self.loginTimeoutEvent then - removeEvent(self.loginTimeoutEvent) - self.loginTimeoutEvent = nil - end - - self:reset() -end - -function EnterGameV2Protocol:reset() - self.connected = false - if self.reconnectEvent then - removeEvent(self.reconnectEvent) - self.reconnectEvent = nil - end - if self.socket then - self.socket.close() - self.socket = nil - end -end - -function EnterGameV2Protocol:setUrl(url) - if self.terminated then - return false - end - self:reset() - if self.url ~= url then - self.sendQueue = {} - self.sendQueueMsgId = 1 - if self.loginTimeoutEvent then - removeEvent(self.loginTimeoutEvent) - self.loginTimeoutEvent = nil - end - end - if type(url) ~= 'string' or not url:lower():find("ws") then - g_logger.error("Invalid url for EnterGameV2Protocol:\n" .. url) - return false - end - self.url = url - self.socket = HTTP.WebSocketJSON(url, { - onOpen = function(message, websocketId) - if self.terminated or not self.socket or self.socket.id ~= websocketId then return end - self.connected = true - self:sendFirstMessage() - end, - onMessage = function(message, websocketId) - if self.terminated or not self.socket or self.socket.id ~= websocketId then return end - self:onSocketMessage(message) - end, - onClose = function(message, websocketId) - if self.terminated or not self.socket or self.socket.id ~= websocketId then return end - self.connected = false - self:scheduleReconnect() - end, - onError = function(message, websocketId) - if self.terminated or not self.socket or self.socket.id ~= websocketId then return end - self.connected = false - self:scheduleReconnect() - end - }) - return true -end - -function EnterGameV2Protocol:isConnected() - return self.socket and self.connected -end - -function EnterGameV2Protocol:scheduleReconnect() - if self.socket then - self.connected = false - self.socket.close() - self.socket = nil - end - if self.terminated then return end - if self.reconnectEvent then return end - self.reconnectEvent = scheduleEvent(function() self:reconnect() end, 500) -end - -function EnterGameV2Protocol:login(account, password, token, callback) - self:send({ - type="login", - account=account, - password=password, - token=token, - }) - if self.loginTimeoutEvent then - removeEvent(self.loginTimeoutEvent) - end - self.loginTimeoutEvent = scheduleEvent(function() - self.loginTimeoutEvent = nil - self.onLogin({error="Connection timeout"}) - end, 10000) -end - -function EnterGameV2Protocol:logout() - self:send({ - type="logout" - }) -end - -function EnterGameV2Protocol:register(name, email, password, callback) - -end - -function EnterGameV2Protocol:createCharacter(name, gender, vocation, town) - self:send({ - type="createcharacter", - name=name, - gender=gender, - vocation=vocation, - town=town - }) -end - -function EnterGameV2Protocol:updateSettings(settings) - self:send({ - type="settings", - settings=settings - }) -end - --- private functions -function EnterGameV2Protocol:reconnect() - if #self.sendQueue > 1 then - self.sendQueue = {} -- TEMPORARY - end - self.reconnectEvent = nil - if self.terminated then return end - self:setUrl(self.url) -end - -function EnterGameV2Protocol:send(data) - if type(data) ~= "table" then - return error("data should be table") - end - data["id"] = self.sendQueueMsgId - table.insert(self.sendQueue, {id=self.sendQueueMsgId, msg=json.encode(data)}) - self.sendQueueMsgId = self.sendQueueMsgId + 1 - if self.socket then - self.socket.send(self.sendQueue[#self.sendQueue].msg) - end -end - -function EnterGameV2Protocol:sendFirstMessage() - self.socket.send({type="init", session=self.session}) - for i, msg in ipairs(self.sendQueue) do - self.socket.send(msg.msg) - end -end - -function EnterGameV2Protocol:onSocketMessage(message) - local lastId = message["lastId"] - if type(lastId) == 'number' then -- clear send queue - while #self.sendQueue > 0 do - local id = self.sendQueue[1].id - if id < lastId then - break - end - table.remove(self.sendQueue, 1) - end - end - if message["type"] == "ping" then - self.socket.send({type="ping"}) - elseif message["type"] == "login" then - if self.loginTimeoutEvent then - removeEvent(self.loginTimeoutEvent) - self.loginTimeoutEvent = nil - end - if self.onLogin then - self.onLogin(message) - end - elseif message["type"] == "logout" then - if self.onLogout then - self.onLogout() - end - elseif message["type"] == "qauth" then - if self.onQAuth then - self.onQAuth(message["token"]) - end - elseif message["type"] == "characters" then - if self.onCharacters then - self.onCharacters(message["characters"]) - end - elseif message["type"] == "message" then - if self.onMessage then - self.onMessage(message["title"], message["text"]) - end - elseif message["type"] == "loading" then - if self.onMessage then - self.onLoading(message["title"], message["text"]) - end - elseif message["type"] == "news" then - if self.onNews then - self.onNews(message["news"]) - end - elseif message["type"] == "motd" then - if self.onMotd then - self.onMotd(message["text"]) - end - elseif message["type"] == "createcharacter" then - if self.onMessage then - self.onCharacterCreate(message["error"], message["message"]) - end - end -end diff --git a/modules/game_battle/battle.lua b/modules/game_battle/battle.lua index 6c66f7f..bc2e03c 100644 --- a/modules/game_battle/battle.lua +++ b/modules/game_battle/battle.lua @@ -47,7 +47,8 @@ function init() sortTypeBox:addOption('Name', 'name') sortTypeBox:addOption('Distance', 'distance') - sortTypeBox:addOption('Age', 'age') + sortTypeBox:addOption('Total age', 'age') + sortTypeBox:addOption('Screen age', 'screenage') sortTypeBox:addOption('Health', 'health') sortTypeBox:setCurrentOptionByData(getSortType()) sortTypeBox.onOptionChange = onChangeSortType @@ -207,13 +208,13 @@ function toggleFilterPanel() end end -function onChangeSortType(comboBox, option) - setSortType(option:lower()) +function onChangeSortType(comboBox, option, value) + setSortType(value:lower()) end -function onChangeSortOrder(comboBox, option) +function onChangeSortOrder(comboBox, option, value) -- Replace dot in option name - setSortOrder(option:lower():gsub('[.]', '')) + setSortOrder(value:lower():gsub('[.]', '')) end -- functions @@ -238,10 +239,16 @@ function checkCreatures() local maxCreatures = battlePanel:getChildCount() local creatures = {} + local now = g_clock.millis() + local resetAgePoint = now - 250 for _, creature in ipairs(spectators) do if doCreatureFitFilters(creature) and #creatures < maxCreatures then + if not creature.lastSeen or creature.lastSeen < resetAgePoint then + creature.screenAge = now + end + creature.lastSeen = now if not ages[creature:getId()] then - if ageNumber > 10000 then + if ageNumber > 1000 then ageNumber = 1 ages = {} end @@ -342,6 +349,8 @@ function sortCreatures(creatures) end) elseif getSortType() == 'age' then table.sort(creatures, function(a, b) return ages[a:getId()] > ages[b:getId()] end) + elseif getSortType() == 'screenage' then + table.sort(creatures, function(a, b) return a.screenAge > b.screenAge end) else -- name table.sort(creatures, function(a, b) if a:getName():lower() == b:getName():lower() then diff --git a/modules/game_bot/executor.lua b/modules/game_bot/executor.lua index 8be9f83..ee55fba 100644 --- a/modules/game_bot/executor.lua +++ b/modules/game_bot/executor.lua @@ -10,7 +10,7 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo end if ext[#ext]:lower() == "ui" or ext[#ext]:lower() == "otui" then table.insert(uiFiles, file) - end + end end if #luaFiles == 0 then @@ -74,6 +74,13 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo context.tonumber = tonumber context.type = type context.pcall = pcall + context.os = { + time = os.time, + date = os.date, + difftime = os.difftime, + date = os.date, + clock = os.clock + } context.load = function(str) return assert(load(str, nil, nil, context)) end context.loadstring = context.load context.assert = assert diff --git a/modules/game_bot/functions/server.lua b/modules/game_bot/functions/server.lua index 5fc733f..6495e8b 100644 --- a/modules/game_bot/functions/server.lua +++ b/modules/game_bot/functions/server.lua @@ -58,6 +58,7 @@ context.BotServer.init = function(name, channel) end context.BotServer._wasConnected = false context.BotServer._websocket = nil + context.BotServer.ping = 0 context.BotServer.init(name, channel) end }, context.BotServer.timeout) diff --git a/modules/game_outfit/outfit.lua b/modules/game_outfit/outfit.lua index d7eea90..d19da8b 100644 --- a/modules/game_outfit/outfit.lua +++ b/modules/game_outfit/outfit.lua @@ -53,9 +53,12 @@ end function setupSelector(widget, id, outfit, list) widget:setId(id) + widget.title:setText(id:gsub("^%l", string.upper)) + table.insert(list, 1, {0, "-"}) + local pos = 1 for i, o in pairs(list) do - if outfit[id] == o[1] then + if (id == "shader" and outfit[id] == o[2]) or outfit[id] == o[1] then pos = i end end @@ -63,7 +66,7 @@ function setupSelector(widget, id, outfit, list) widget.outfit = list[pos] if id == "shader" then widget.creature:setOutfit({ - shader = list[pos][1] + shader = list[pos][2] }) else widget.creature:setOutfit({ @@ -80,7 +83,7 @@ function setupSelector(widget, id, outfit, list) end local outfit = widget.creature:getOutfit() if id == "shader" then - outfit.shader = list[pos][1] + outfit.shader = list[pos][2] else outfit.type = list[pos][1] end @@ -97,7 +100,7 @@ function setupSelector(widget, id, outfit, list) end local outfit = widget.creature:getOutfit() if id == "shader" then - outfit.shader = list[pos][1] + outfit.shader = list[pos][2] else outfit.type = list[pos][1] end @@ -312,6 +315,15 @@ function updateOutfit() outfit.addons = 0 outfitWindow.type.creature:setOutfit(outfit) + local shader = outfitWindow.extensions:getChildById("shader") + if shader then + outfit.shader = shader.creature:getOutfit().shader + if outfit.shader == "-" then + outfit.shader = "" + end + shader.creature:setOutfit(outfit) + end + if availableAddons > 0 then for _, i in pairs(ADDON_SETS[availableAddons]) do addons[i].widget:setEnabled(true) diff --git a/modules/game_outfit/outfitwindow.otui b/modules/game_outfit/outfitwindow.otui index 9834e23..47ce5a0 100644 --- a/modules/game_outfit/outfitwindow.otui +++ b/modules/game_outfit/outfitwindow.otui @@ -5,11 +5,18 @@ PrevMountButton < PreviousButton OutfitSelectorPanel < Panel size: 125 120 + + Label + id: title + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + text-align: center UICreature id: creature - size: 96 96 - anchors.top: parent.top + size: 100 80 + anchors.top: prev.bottom anchors.horizontalCenter: parent.horizontalCenter margin-top: 1 @@ -39,7 +46,7 @@ OutfitSelectorPanel < Panel MainWindow !text: tr('Select Outfit') - size: 540 335 + size: 540 330 @onEnter: modules.game_outfit.accept() @onEscape: modules.game_outfit.destroy() diff --git a/modules/gamelib/const.lua b/modules/gamelib/const.lua index 033a3a8..198983b 100644 --- a/modules/gamelib/const.lua +++ b/modules/gamelib/const.lua @@ -188,6 +188,7 @@ GameSendIdentifiers = 103 GameWingsAndAura = 104 GamePlayerStateU32 = 105 GameOutfitShaders = 106 +GameForceAllowItemHotkeys = 107 GamePacketSizeU32 = 110 GamePacketCompression = 111 diff --git a/modules/gamelib/ui/uiitem.lua b/modules/gamelib/ui/uiitem.lua index 1c6b1c8..05ab126 100644 --- a/modules/gamelib/ui/uiitem.lua +++ b/modules/gamelib/ui/uiitem.lua @@ -60,7 +60,7 @@ end function UIItem:onHoverChange(hovered) UIWidget.onHoverChange(self, hovered) - + if self:isVirtual() or not self:isDraggable() then return end local draggingWidget = g_ui.getDraggingWidget() @@ -126,4 +126,12 @@ function UIItem:onClick(mousePos) if modules.game_itemselector then modules.game_itemselector.show(self) end +end + +function UIItem:onItemChange() + local tooltip = nil + if self:getItem() and self:getItem():getTooltip():len() > 0 then + tooltip = self:getItem():getTooltip() + end + self:setTooltip(tooltip) end \ No newline at end of file diff --git a/otclient_dx.exe b/otclient_dx.exe index 059dd57..e7506ae 100644 Binary files a/otclient_dx.exe and b/otclient_dx.exe differ diff --git a/otclient_gl.exe b/otclient_gl.exe index 0f379be..9df5d41 100644 Binary files a/otclient_gl.exe and b/otclient_gl.exe differ diff --git a/otclient_linux b/otclient_linux index c7f1f8d..e1c0be9 100644 Binary files a/otclient_linux and b/otclient_linux differ diff --git a/otclientv8.apk b/otclientv8.apk index 2590db2..448e4c3 100644 Binary files a/otclientv8.apk and b/otclientv8.apk differ diff --git a/src/client/game.cpp b/src/client/game.cpp index 45bb0bf..410dba0 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1384,7 +1384,14 @@ void Game::mount(bool mount) { if(!canPerformGameAction()) return; - m_protocolGame->sendMountStatus(mount); + m_protocolGame->sendOutfitExtensionStatus(mount ? 1 : 0); +} + +void Game::setOutfitExtensions(int mount, int wings, int aura, int shader) +{ + if (!canPerformGameAction()) + return; + m_protocolGame->sendOutfitExtensionStatus(mount, wings, aura, shader); } void Game::requestItemInfo(const ItemPtr& item, int index) diff --git a/src/client/game.h b/src/client/game.h index acda7d3..b1863ab 100644 --- a/src/client/game.h +++ b/src/client/game.h @@ -282,6 +282,7 @@ public: // 870 only void equipItem(const ItemPtr& item); void mount(bool mount); + void setOutfitExtensions(int mount, int wings, int aura, int shader); // 910 only void requestItemInfo(const ItemPtr& item, int index); diff --git a/src/client/luafunctions_client.cpp b/src/client/luafunctions_client.cpp index 86dcab9..982fb94 100644 --- a/src/client/luafunctions_client.cpp +++ b/src/client/luafunctions_client.cpp @@ -279,6 +279,7 @@ void Client::registerLuaFunctions() g_lua.bindSingletonFunction("g_game", "requestQuestLine", &Game::requestQuestLine, &g_game); g_lua.bindSingletonFunction("g_game", "equipItem", &Game::equipItem, &g_game); g_lua.bindSingletonFunction("g_game", "mount", &Game::mount, &g_game); + g_lua.bindSingletonFunction("g_game", "setOutfitExtensions", &Game::setOutfitExtensions, &g_game); g_lua.bindSingletonFunction("g_game", "requestItemInfo", &Game::requestItemInfo, &g_game); g_lua.bindSingletonFunction("g_game", "ping", &Game::ping, &g_game); g_lua.bindSingletonFunction("g_game", "setPingDelay", &Game::setPingDelay, &g_game); @@ -488,8 +489,10 @@ void Client::registerLuaFunctions() g_lua.bindClassStaticFunction("create", []{ return CreaturePtr(new Creature); }); g_lua.bindClassMemberFunction("getId", &Creature::getId); g_lua.bindClassMemberFunction("getName", &Creature::getName); + g_lua.bindClassMemberFunction("setName", &Creature::setName); g_lua.bindClassMemberFunction("setManaPercent", &LocalPlayer::setManaPercent); g_lua.bindClassMemberFunction("getManaPercent", &LocalPlayer::getManaPercent); + g_lua.bindClassMemberFunction("setHealthPercent", &Creature::setHealthPercent); g_lua.bindClassMemberFunction("getHealthPercent", &Creature::getHealthPercent); g_lua.bindClassMemberFunction("getSpeed", &Creature::getSpeed); g_lua.bindClassMemberFunction("setSpeed", &Creature::setSpeed); diff --git a/src/client/luavaluecasts_client.cpp b/src/client/luavaluecasts_client.cpp index 3be4321..41c5573 100644 --- a/src/client/luavaluecasts_client.cpp +++ b/src/client/luavaluecasts_client.cpp @@ -84,9 +84,9 @@ bool luavalue_cast(int index, Outfit& outfit) } if (g_game.getFeature(Otc::GameWingsAndAura)) { g_lua.getField("wings", index); - outfit.setMount(g_lua.popInteger()); + outfit.setWings(g_lua.popInteger()); g_lua.getField("aura", index); - outfit.setMount(g_lua.popInteger()); + outfit.setAura(g_lua.popInteger()); } //if (g_game.getFeature(Otc::GameOutfitShaders)) { g_lua.getField("shader", index); diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp index c01fd11..1ed5c9d 100644 --- a/src/client/protocolgamesend.cpp +++ b/src/client/protocolgamesend.cpp @@ -828,15 +828,24 @@ void ProtocolGame::sendChangeOutfit(const Outfit& outfit) send(msg); } -void ProtocolGame::sendMountStatus(bool mount) +void ProtocolGame::sendOutfitExtensionStatus(int mount, int wings, int aura, int shader) { - if(g_game.getFeature(Otc::GamePlayerMounts)) { + if(g_game.getFeature(Otc::GamePlayerMounts) || g_game.getFeature(Otc::GameWingsAndAura) || g_game.getFeature(Otc::GameWingsAndAura)) { OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientMount); - msg->addU8(mount); + if (g_game.getFeature(Otc::GamePlayerMounts)) { + msg->addU8(mount); + } + if (g_game.getFeature(Otc::GameWingsAndAura)) { + msg->addU8(wings); + msg->addU8(aura); + } + if (g_game.getFeature(Otc::GameOutfitShaders)) { + msg->addU8(shader); + } send(msg); } else { - g_logger.error("ProtocolGame::sendMountStatus does not support the current protocol."); + g_logger.error("ProtocolGame::sendOutfitExtensionStatus does not support the current protocol."); } }