OTCv8 3.0 rev 2

This commit is contained in:
OTCv8
2021-04-07 21:31:27 +00:00
parent e93bcdc9cf
commit d77991f60f
85 changed files with 8780 additions and 8200 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -0,0 +1,11 @@
varying vec2 v_TexCoord;
uniform vec4 u_Color;
uniform sampler2D u_Tex0;
void main()
{
gl_FragColor = texture2D(u_Tex0, v_TexCoord) * u_Color;
if(gl_FragColor.a < 0.01)
discard;
}

View File

@@ -0,0 +1,14 @@
attribute vec2 a_Vertex;
attribute vec2 a_TexCoord;
uniform mat3 u_TransformMatrix;
uniform mat3 u_ProjectionMatrix;
uniform mat3 u_TextureMatrix;
varying vec2 v_TexCoord;
void main()
{
gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, 1.0, 1.0);
v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;
}

View File

@@ -0,0 +1,15 @@
varying vec2 v_TexCoord;
varying vec2 v_TexCoord2;
uniform vec4 u_Color;
uniform sampler2D u_Tex0;
uniform sampler2D u_Tex1;
void main()
{
gl_FragColor = texture2D(u_Tex0, v_TexCoord) * u_Color;
gl_FragColor += texture2D(u_Tex1, v_TexCoord2);
if(gl_FragColor.a < 0.01)
discard;
}

View File

@@ -0,0 +1,33 @@
attribute vec2 a_TexCoord;
attribute vec2 a_Vertex;
varying vec2 v_TexCoord;
varying vec2 v_TexCoord2;
uniform mat3 u_TextureMatrix;
uniform mat3 u_TransformMatrix;
uniform mat3 u_ProjectionMatrix;
uniform vec2 u_Offset;
uniform vec2 u_Center;
uniform float u_Time;
vec2 effectTextureSize = vec2(466.0, 342.0);
vec2 direction = vec2(1.0,0.2);
float speed = 200.0;
vec2 rotate(vec2 v, float a) {
float s = sin(a);
float c = cos(a);
mat2 m = mat2(c, -s, s, c);
return m * v;
}
void main()
{
gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, 1.0, 1.0);
v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;
v_TexCoord2 = ((a_Vertex + direction * u_Time * speed) / effectTextureSize);
}

View File

@@ -0,0 +1,16 @@
uniform mat4 u_Color;
varying vec2 v_TexCoord;
varying vec2 v_TexCoord2;
varying vec2 v_TexCoord3;
uniform sampler2D u_Tex0;
uniform sampler2D u_Tex1;
void main()
{
gl_FragColor = texture2D(u_Tex0, v_TexCoord);
vec4 texcolor = texture2D(u_Tex0, v_TexCoord2);
vec4 effectColor = texture2D(u_Tex1, v_TexCoord3);
if(texcolor.a > 0.1) {
gl_FragColor *= effectColor;
}
if(gl_FragColor.a < 0.01) discard;
}

View File

@@ -0,0 +1,47 @@
attribute vec2 a_TexCoord;
uniform mat3 u_TextureMatrix;
varying vec2 v_TexCoord;
varying vec2 v_TexCoord2;
varying vec2 v_TexCoord3;
attribute vec2 a_Vertex;
uniform mat3 u_TransformMatrix;
uniform mat3 u_ProjectionMatrix;
uniform vec2 u_Offset;
uniform vec2 u_Center;
uniform float u_Time;
vec2 effectTextureSize = vec2(466.0, 342.0);
vec2 direction = vec2(1.0,0.2);
float speed = 200.0;
vec2 rotate(vec2 v, float a) {
float s = sin(a);
float c = cos(a);
mat2 m = mat2(c, -s, s, c);
return m * v;
}
void main()
{
vec2 offset = direction * speed * u_Time;
gl_Position = vec4((u_ProjectionMatrix * u_TransformMatrix * vec3(a_Vertex.xy, 1.0)).xy, 1.0, 1.0);
v_TexCoord = (u_TextureMatrix * vec3(a_TexCoord,1.0)).xy;
v_TexCoord2 = (u_TextureMatrix * vec3(a_TexCoord + u_Offset,1.0)).xy;
vec2 vertex = a_Vertex;
if(vertex.x < u_Center.x) {
vertex.x = effectTextureSize.x / 10.0;
}
if(vertex.x > u_Center.x) {
vertex.x = effectTextureSize.x - effectTextureSize.x / 10.0;
}
if(vertex.y < u_Center.y) {
vertex.y = effectTextureSize.y / 10.0;
}
if(vertex.y > u_Center.y) {
vertex.y = effectTextureSize.y - effectTextureSize.y / 10.0;
}
v_TexCoord3 = ((vertex + direction * u_Time * speed) / effectTextureSize);
}

View File

@@ -1,6 +1,6 @@
-- CONFIG
APP_NAME = "otclientv8" -- important, change it, it's name for config dir and files in appdata
APP_VERSION = 1343 -- client version for updater and login to identify outdated client
APP_VERSION = 1341 -- client version for updater and login to identify outdated client
DEFAULT_LAYOUT = "retro" -- on android it's forced to "mobile", check code bellow
-- If you don't use updater or other service, set it to updater = ""
@@ -16,11 +16,16 @@ Services = {
-- Servers accept http login url, websocket login url or ip:port:version
Servers = {
--[[ OTClientV8 = "http://otclient.ovh/api/login.php",
OTClientV8c = "otclient.ovh:7171",
OTClientV8proxy = "http://otclient.ovh/api/login.php?proxy=1",
OTClientV8c = "otclient.ovh:7171:1099:25:30:80:90",
OTClientV8Test = "http://otclient.ovh/api/login2.php",
Evoulinia = "evolunia.net:7171:1098",
GarneraTest = "garnera-global.net:7171:1100",
LocalTestServ = "127.0.0.1:7171:1098:110:30:93" ]]
}
--Server = "ws://otclient.ovh:3000/"
--Server = "ws://127.0.0.1:88/"
--USE_NEW_ENERGAME = true -- uses entergamev2 based on websockets instead of entergame
ALLOW_CUSTOM_SERVERS = true -- if true it shows option ANOTHER on server list
@@ -84,5 +89,4 @@ if type(Services.updater) == 'string' and Services.updater:len() > 4
g_modules.ensureModuleLoaded("updater")
return Updater.init(loadModules)
end
loadModules()

View File

@@ -8,7 +8,7 @@ function init()
background:lower()
clientVersionLabel = background:getChildById('clientVersionLabel')
clientVersionLabel:setText('OTClientV8 ' .. g_app.getVersion() .. '\nMade by:\n' .. g_app.getAuthor() .. "\notclient@otclient.ovh")
clientVersionLabel:setText('OTClientV8 ' .. g_app.getVersion() .. '\nrev ' .. g_app.getBuildRevision() .. '\nMade by:\n' .. g_app.getAuthor() .. "")
if not g_game.isOnline() then
addEvent(function() g_effects.fadeIn(clientVersionLabel, 1500) end)

View File

@@ -15,7 +15,7 @@ local serverSelector
local clientVersionSelector
local serverHostTextEdit
local rememberPasswordBox
local protos = {"740", "760", "772", "792", "800", "810", "854", "860", "870", "910", "961", "1000", "1077", "1090", "1096", "1098", "1099", "1100", "1200", "1220", "1230", "1240", "1250", "1252"}
local protos = {"740", "760", "772", "792", "800", "810", "854", "860", "870", "910", "961", "1000", "1077", "1090", "1096", "1098", "1099", "1100", "1200", "1220"}
local checkedByUpdater = {}
local waitingForHttpResults = 0

View File

@@ -31,4 +31,4 @@ Module
dofile 'base64'
dofile 'json'
dofile 'http'
dofile 'test'

62
modules/corelib/test.lua Normal file
View File

@@ -0,0 +1,62 @@
Test = {
tests = {},
activeTest = 0,
screenShot = 1
}
Test.Test = function(name, func)
local testId = #Test.tests + 1
Test.tests[testId] = {
name = name,
actions = {},
delay = 0,
start = 0
}
local test = function(testFunc)
table.insert(Test.tests[testId].actions, {type = "test", value = testFunc})
end
local wait = function(millis)
Test.tests[testId].delay = Test.tests[testId].delay + millis
table.insert(Test.tests[testId].actions, {type = "wait", value = Test.tests[testId].delay})
end
local ss = function()
table.insert(Test.tests[testId].actions, {type = "screenshot"})
end
local fail = function(message)
g_logger.fatal("Test " .. name .. " failed: " .. message)
end
func(test, wait, ss, fail)
end
Test.run = function()
if Test.activeTest > #Test.tests then
g_logger.info("[TEST] Finished tests. Exiting...")
return g_app.exit()
end
local test = Test.tests[Test.activeTest]
if not test or #test.actions == 0 then
Test.activeTest = Test.activeTest + 1
local nextTest = Test.tests[Test.activeTest]
if nextTest then
nextTest.start = g_clock.millis()
g_logger.info("[TEST] Starting test: " .. nextTest.name)
end
return scheduleEvent(Test.run, 500)
end
local action = test.actions[1]
if action.type == "test" then
table.remove(test.actions, 1)
action.value()
elseif action.type == "screenshot" then
table.remove(test.actions, 1)
g_app.doScreenshot(Test.screenShot .. ".png")
Test.screenShot = Test.screenShot + 1
elseif action.type == "wait" then
if action.value + test.start < g_clock.millis() then
table.remove(test.actions, 1)
end
end
scheduleEvent(Test.run, 100)
end

View File

@@ -194,11 +194,19 @@ function UIMiniWindowContainer:order()
if not children[i].miniLoaded then return end
end
table.sort(children, function(a, b)
local indexA = a.miniIndex or a.autoOpen or 999
local indexB = b.miniIndex or b.autoOpen or 999
return indexA < indexB
end)
self:reorderChildren(children)
local ignoreIndex = 0
for i=1,#children do
if children[i].miniIndex then
self:swapInsert(children[i], children[i].miniIndex)
elseif children[i].autoOpen then
self:swapInsert(children[i], children[i].autoOpen)
if children[i].save then
children[i].miniIndex = i - ignoreIndex
else
ignoreIndex = ignoreIndex + 1
end
end
end

View File

@@ -283,7 +283,7 @@ function checkCreatures()
for i=#creatures + 1,maxCreatures do
if battleButtons[i]:isHidden() then break end
battleButtons[i]:hide()
battleButtons[i]:setOn(false)
battleButton:setOn(false)
end
battlePanel:getLayout():enableUpdates()

View File

@@ -474,7 +474,9 @@ function initCallbacks()
onChannelList = botChannelList,
onOpenChannel = botOpenChannel,
onCloseChannel = botCloseChannel,
onChannelEvent = botChannelEvent
onChannelEvent = botChannelEvent,
onImbuementWindow = botOnImbuementWindow,
onModalDialog = botOnModalDialog,
})
connect(Tile, {
@@ -527,7 +529,9 @@ function terminateCallbacks()
onChannelList = botChannelList,
onOpenChannel = botOpenChannel,
onCloseChannel = botCloseChannel,
onChannelEvent = botChannelEvent
onChannelEvent = botChannelEvent,
onImbuementWindow = botOnImbuementWindow,
onModalDialog = botOnModalDialog,
})
disconnect(Tile, {
@@ -703,3 +707,13 @@ function botCreatureWalk(creature, oldPos, newPos)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onWalk(creature, oldPos, newPos) end)
end
function botOnImbuementWindow(itemId, slots, activeSlots, imbuements, needItems)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onImbuementWindow(itemId, slots, activeSlots, imbuements, needItems) end)
end
function botOnModalDialog(id, title, message, buttons, enterButton, escapeButton, choices, priority)
if botExecutor == nil then return false end
safeBotCall(function() botExecutor.callbacks.onModalDialog(id, title, message, buttons, enterButton, escapeButton, choices, priority) end)
end

View File

@@ -104,7 +104,7 @@ CaveBot.Editor.setup = function()
title="Go to position",
description="Go to position (x,y,z)",
multiline=false,
validation="^\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+),?\\s*([0-9]?)$"
validation="^\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*,\\s*([0-9]+)$"
})
registerAction("use", {
value=function() return posx() .. "," .. posy() .. "," .. posz() end,

View File

@@ -0,0 +1,23 @@
goto:1033,1044,7
goto:1031,1038,7
goto:1030,1038,7
goto:1157,985,7
goto:1161,981,7
goto:1033,1042,7
goto:1034,1038,7
goto:1169,985,7
goto:1175,985,7
goto:1176,983,7
goto:756,846,7
goto:756,846,7
config:{"walk":100,"walk2":false}
extensions:[[
{
"Depositer": [
],
"Supply": [
]
}
]]

View File

@@ -0,0 +1,13 @@
goto:84,112,6
goto:95,108,6
config:{"mapClickDelay":100,"walkDelay":10,"ping":250,"ignoreFields":false,"useDelay":400,"mapClick":false}
extensions:[[
{
"Depositer": [
],
"Supply": [
]
}
]]

View File

@@ -0,0 +1,104 @@
goto:93,129,7
goto:96,123,7
goto:96,117,7
goto:101,114,7
goto:95,111,6
goto:89,111,6
goto:83,108,6
goto:80,102,6
goto:80,96,6
goto:85,90,6
goto:88,92,6
goto:91,86,7
goto:97,85,7
goto:103,84,7
function:[[
TargetBot.enableLuring()
return true
]]
goto:109,79,7
goto:112,79,7
goto:112,79,8
function:[[
TargetBot.disableLuring()
return true
]]
goto:112,79,7
goto:106,84,8
goto:100,80,8
goto:100,74,8
goto:99,80,8
goto:105,83,8
function:[[
TargetBot.setOff()
return true
]]
goto:111,82,8
goto:112,79,8
goto:106,82,7
goto:100,85,7
goto:94,85,7
goto:91,91,7
goto:89,92,7
goto:83,90,6
function:[[
TargetBot.setOff()
return true
]]
goto:77,94,6
goto:75,95,6
goto:69,96,7
goto:63,100,7
goto:61,102,7
goto:62,96,8
use:61,102,8
goto:62,101,8
goto:68,99,7
goto:74,95,7
goto:75,95,7
goto:79,101,6
goto:81,107,6
goto:87,109,6
goto:93,112,6
function:[[
TargetBot.disableLuring()
return true
]]
goto:99,116,6
use:102,114,6
goto:101,115,6
use:100,116,5
goto:101,115,5
goto:100,116,4
goto:102,114,5
goto:101,114,6
goto:96,120,7
goto:95,126,7
function:[[
g_game.safeLogout()
delay(1000)
return "retry"
]]
config:{"useDelay":400,"mapClickDelay":100,"walkDelay":20,"ping":150,"ignoreFields":false,"skipBlocked":true,"mapClick":false}
extensions:[[
{
"Depositer": [
],
"Supply": [
]
}
]]

View File

@@ -0,0 +1,128 @@
{
"hpitem1": {
"max": 90,
"title": "HP%",
"subType": 0,
"item": 266,
"min": 51,
"on": false
},
"foodItems": [
{
"id": 3582,
"count": 1
},
{
"id": 3577,
"count": 1
}
],
"autoEquip": [
{
"item1": 3052,
"title": "Auto Equip",
"item2": 3089,
"on": false,
"slot": 9
},
{
"item1": 0,
"title": "Auto Equip",
"item2": 0,
"on": false,
"slot": 0
},
{
"item1": 0,
"title": "Auto Equip",
"item2": 0,
"on": false,
"slot": 0
},
{
"item1": 0,
"title": "Auto Equip",
"item2": 0,
"on": false,
"slot": 0
}
],
"ingame_hotkeys": "singlehotkey(\"f1\", function()\nlocal shaders = {\"stars\", \"gold\", \"rainbow\", \"sweden\", \"brazil\", \"line\", \"3line\", \"circle\", \"outline\"}\nlocal p = 0\nfor i, c in pairs(getSpectators()) do\n c:setOutfitShader(shaders[1 + p % 10])\n p = p + 1\nend\nend)\n\nsinglehotkey(\"1\", function()\n for _, s in ipairs(getSpectators()) do\n if s:canShoot(3) then\n info(s:getName())\n else\n warn(s:getName())\n end\n end\nend)",
"healing2": {
"max": 50,
"title": "HP%",
"on": false,
"min": 1,
"text": "exura vita"
},
"ingame_macros": "",
"hasteSpell": "utani hur",
"manaitem2": {
"max": 50,
"title": "MP%",
"subType": 0,
"item": 3157,
"min": 0,
"on": false
},
"_configs": {
"cavebot_configs": {
"selected": "test_src",
"enabled": false
},
"targetbot_configs": {
"enabled": false,
"selected": "config_name"
}
},
"healing1": {
"max": 100,
"title": "HP%",
"on": false,
"min": 51,
"text": "exura"
},
"dropItems": [
{
"id": 283,
"count": 1
},
{
"id": 284,
"count": 1
},
{
"id": 285,
"count": 1
}
],
"_macros": {
"": false
},
"manaitem1": {
"max": 90,
"title": "MP%",
"subType": 0,
"item": 268,
"min": 51,
"on": false
},
"hpitem2": {
"max": 50,
"title": "HP%",
"subType": 0,
"item": 3160,
"min": 0,
"on": false
},
"manaShield": "utamo vita",
"autoTradeMessage": "I'm using OTClientV8!",
"antiParalyze": "utani hur",
"manaTrain": {
"max": 100,
"title": "MP%",
"on": false,
"min": 80,
"text": "utevo lux"
}
}

View File

@@ -0,0 +1,53 @@
{
"looting": {
"items": [
],
"maxDanger": 10,
"minCapacity": 100,
"containers": [
{
"count": 1,
"id": 2853
}
],
"everyItem": true
},
"targeting": [
{
"useSpellAttack": false,
"useRuneAttack": false,
"minMana": 200,
"avoidAttacks": false,
"groupAttackTargets": 2,
"groupAttackSpell": "",
"danger": 1,
"runeAttackDelay": 2000,
"lureCavebot": true,
"dontLoot": false,
"useGroupAttackRune": false,
"groupRuneAttackRadius": 1,
"groupAttackIgnorePlayers": true,
"maxDistance": 10,
"groupAttackIgnoreParty": false,
"lureCount": 5,
"useGroupAttack": false,
"groupRuneAttackTargets": 2,
"attackSpell": "",
"groupAttackRune": 0,
"groupAttackRadius": 1,
"keepDistanceRange": 1,
"groupRuneAttackDelay": 5000,
"priority": 1,
"attackRune": 0,
"groupAttackDelay": 5000,
"minManaGroup": 1500,
"lure": true,
"keepDistance": false,
"attackSpellDelay": 2500,
"chase": true,
"name": "cat, w?lf, snake, troll",
"regex": "^cat$|^w.?lf$|^snake$|^troll$"
}
]
}

View File

@@ -2,7 +2,7 @@ if player:getBlessings() == 0 then
say("!bless")
schedule(2000, function()
if player:getBlessings() == 0 then
error("!! Blessings not bought !!")
warn("!! Blessings not bought !!")
end
end)
end

View File

@@ -62,7 +62,9 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo
onCloseChannel = {},
onChannelEvent = {},
onTurn = {},
onWalk = {}
onWalk = {},
onImbuementWindow = {},
onModalDialog = {}
}
-- basic functions & classes
@@ -233,6 +235,11 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo
callback(name, level, mode, text, channelId, pos)
end
end,
onImbuementWindow = function(itemId, slots, activeSlots, imbuements, needItems)
for i, callback in ipairs(context._callbacks.onImbuementWindow) do
callback(itemId, slots, activeSlots, imbuements, needItems)
end
end,
onTextMessage = function(mode, text)
for i, callback in ipairs(context._callbacks.onTextMessage) do
callback(mode, text)
@@ -343,6 +350,11 @@ function executeBot(config, storage, tabs, msgCallback, saveConfigCallback, relo
callback(creature, oldPos, newPos)
end
end,
onModalDialog = function(id, title, message, buttons, enterButton, escapeButton, choices, priority)
for i, callback in ipairs(context._callbacks.onModalDialog) do
callback(id, title, message, buttons, enterButton, escapeButton, choices, priority)
end
end,
}
}
end

View File

@@ -175,6 +175,16 @@ context.onWalk = function(callback)
return context.callback("onWalk", callback)
end
-- onImbuementWindow -- callback = function(itemId, slots, activeSlots, imbuements, needItems)
context.onImbuementWindow = function(callback)
return context.callback("onImbuementWindow", callback)
end
-- onModalDialog -- callback = function(id, title, message, buttons, enterButton, escapeButton, choices, priority) -- priority is unused, ignore it
context.onModalDialog = function(callback)
return context.callback("onModalDialog", callback)
end
-- CUSTOM CALLBACKS
-- listen(name, callback) -- callback = function(text, channelId, pos)

View File

@@ -161,6 +161,7 @@ function hide()
countWindow = nil
end
gameRootPanel:hide()
gameMapPanel:setShader("")
modules.client_background.show()
end

View File

@@ -1384,7 +1384,7 @@ function Market.onMarketEnter(depotItems, offers, balance, vocation, items)
for i = 1, #marketItems[MarketCategory.TibiaCoins] do
local item = marketItems[MarketCategory.TibiaCoins][i].displayItem
information.depotItems[item:getId()] = tibiaCoins
depotItems[item:getId()] = tibiaCoins
end
-- update the items widget to match depot items
@@ -1425,10 +1425,9 @@ end
function Market.onCoinBalance(coins, transferableCoins)
tibiaCoins = coins
if not information or type(information.depotItems) ~= "table" then return end
if not marketItems[MarketCategory.TibiaCoins] then return end
for i = 1, #marketItems[MarketCategory.TibiaCoins] do
local item = marketItems[MarketCategory.TibiaCoins][i].displayItem
information.depotItems[item:getId()] = tibiaCoins
depotItems[item:getId()] = tibiaCoins
end
end

View File

@@ -1,6 +1,22 @@
function init()
-- add manually your shaders from /data/shaders
g_shaders.createOutfitShader("default", "/shaders/outfit_default_vertex", "/shaders/outfit_default_fragment")
-- map shaders
g_shaders.createShader("map_default", "/shaders/map_default_vertex", "/shaders/map_default_fragment")
g_shaders.createShader("map_rainbow", "/shaders/map_rainbow_vertex", "/shaders/map_rainbow_fragment")
g_shaders.addTexture("map_rainbow", "/images/shaders/rainbow.png")
-- use modules.game_interface.gameMapPanel:setShader("map_rainbow") to set shader
-- outfit shaders
g_shaders.createOutfitShader("outfit_default", "/shaders/outfit_default_vertex", "/shaders/outfit_default_fragment")
g_shaders.createOutfitShader("outfit_rainbow", "/shaders/outfit_rainbow_vertex", "/shaders/outfit_rainbow_fragment")
g_shaders.addTexture("outfit_rainbow", "/images/shaders/rainbow.png")
-- you can use creature:setOutfitShader("outfit_rainbow") to set shader
end
function terminate()

View File

@@ -282,13 +282,24 @@ function onSkillButtonClick(button)
end
function onExperienceChange(localPlayer, value)
setSkillValue('experience', comma_value(value))
local postFix = ""
if value > 1e15 then
postFix = "B"
value = math.floor(value / 1e9)
elseif value > 1e12 then
postFix = "M"
value = math.floor(value / 1e6)
elseif value > 1e9 then
postFix = "K"
value = math.floor(value / 1e3)
end
setSkillValue('experience', comma_value(value) .. postFix)
end
function onLevelChange(localPlayer, value, percent)
setSkillValue('level', value)
local text = tr('You have %s percent to go', 100 - percent) .. '\n' ..
tr('%s of experience left', comma_value(expToAdvance(localPlayer:getLevel(), localPlayer:getExperience())))
tr('%s of experience left', expToAdvance(localPlayer:getLevel(), localPlayer:getExperience()))
if localPlayer.expSpeed ~= nil then
local expPerHour = math.floor(localPlayer.expSpeed * 3600)
@@ -297,7 +308,7 @@ function onLevelChange(localPlayer, value, percent)
local hoursLeft = (nextLevelExp - localPlayer:getExperience()) / expPerHour
local minutesLeft = math.floor((hoursLeft - math.floor(hoursLeft))*60)
hoursLeft = math.floor(hoursLeft)
text = text .. '\n' .. comma_value(expPerHour) .. tr(' of experience per hour')
text = text .. '\n' .. tr('%d of experience per hour', expPerHour)
text = text .. '\n' .. tr('Next level in %d hours and %d minutes', hoursLeft, minutesLeft)
end
end

View File

@@ -14,32 +14,16 @@ function load()
local things = g_settings.getNode('things')
local datPath, sprPath
if things["data"] ~= nil and things["sprites"] ~= nil then
if things and things["data"] ~= nil and things["sprites"] ~= nil then
datPath = '/things/' .. things["data"]
if G.hdSprites and things["sprites_hd"] then
sprPath = '/things/' .. things["sprites_hd"]
else
sprPath = '/things/' .. things["sprites"]
end
else
if filename then
datPath = resolvepath('/things/' .. filename)
sprPath = resolvepath('/things/' .. filename)
if G.hdSprites then
local hdsprPath = resolvepath('/things/' .. filename .. '_hd')
if g_resources.fileExists(hdsprPath) then
sprPath = hdsprPath
end
end
else
datPath = resolvepath('/things/' .. version .. '/Tibia')
sprPath = resolvepath('/things/' .. version .. '/Tibia')
if G.hdSprites then
local hdsprPath = resolvepath('/things/' .. version .. '/Tibia_hd')
if g_resources.fileExists(hdsprPath) then
sprPath = hdsprPath
end
end
end
end
@@ -54,7 +38,7 @@ function load()
errorMessage = errorMessage .. tr("Unable to load dat file, please place a valid dat in '%s'", datPath) .. '\n'
end
end
if not g_sprites.loadSpr(sprPath, G.hdSprites or false) then
if not g_sprites.loadSpr(sprPath, false) then
errorMessage = errorMessage .. tr("Unable to load spr file, please place a valid spr in '%s'", sprPath)
end

View File

@@ -196,6 +196,8 @@ GameDrawAuraOnTop = 109
GamePacketSizeU32 = 110
GamePacketCompression = 111
GameOldInformationBar = 112
LastGameFeature = 130
TextColors = {

Binary file not shown.

Binary file not shown.

Binary file not shown.