This commit is contained in:
OTCv8 2020-07-15 18:25:22 +02:00
parent f17ac1ec71
commit f6f88a9cb3
16 changed files with 51 additions and 34 deletions

View File

@ -1,6 +1,6 @@
-- CONFIG -- CONFIG
APP_NAME = "otclientv8" -- important, change it, it's name for config dir and files in appdata APP_NAME = "otclientv8" -- important, change it, it's name for config dir and files in appdata
APP_VERSION = 1337 -- client version for updater and login to identify outdated client APP_VERSION = 1340 -- client version for updater and login to identify outdated client
DEFAULT_LAYOUT = "retro" -- on android it's forced to "mobile", check code bellow 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 = "" -- If you don't use updater or other service, set it to updater = ""

View File

@ -15,7 +15,7 @@ local serverSelector
local clientVersionSelector local clientVersionSelector
local serverHostTextEdit local serverHostTextEdit
local rememberPasswordBox local rememberPasswordBox
local protos = {"740", "760", "772", "792", "800", "810", "854", "860", "870", "961", "1000", "1077", "1090", "1096", "1098", "1099", "1100", "1200"} local protos = {"740", "760", "772", "792", "800", "810", "854", "860", "870", "961", "1000", "1077", "1090", "1096", "1098", "1099", "1100", "1200", "1220"}
local checkedByUpdater = {} local checkedByUpdater = {}
@ -149,8 +149,8 @@ local function onTibia12HTTPResult(session, playdata)
for _, world in pairs(playdata["worlds"]) do for _, world in pairs(playdata["worlds"]) do
worlds[world.id] = { worlds[world.id] = {
name = world.name, name = world.name,
port = world.externalportunprotected or world.externalportprotected, port = world.externalportunprotected or world.externalportprotected or world.externaladdress,
address = world.externaladdressunprotected or world.externaladdressprotected address = world.externaladdressunprotected or world.externaladdressprotected or world.externalport
} }
end end
@ -414,8 +414,10 @@ function EnterGame.doLogin()
G.host = server_params[1] .. ":" .. server_params[2] .. ":" .. server_params[3] G.host = server_params[1] .. ":" .. server_params[2] .. ":" .. server_params[3]
G.clientVersion = tonumber(server_params[4]) G.clientVersion = tonumber(server_params[4])
elseif #server_params >= 3 then elseif #server_params >= 3 then
G.host = server_params[1] .. ":" .. server_params[2] if tonumber(server_params[3]) == server_params[3] then
G.clientVersion = tonumber(server_params[3]) G.host = server_params[1] .. ":" .. server_params[2]
G.clientVersion = tonumber(server_params[3])
end
end end
return EnterGame.doLoginHttp() return EnterGame.doLoginHttp()
end end

View File

@ -38,7 +38,7 @@ local function setup()
local targetPos = target:getPosition() local targetPos = target:getPosition()
if targetPos.x == 0xFFFF then return end if targetPos.x == 0xFFFF then return end
lastPos = pos lastPos = pos
CaveBot.addAction("usewith", itemId .. "," .. pos.x .. "," .. pos.y .. "," .. pos.z, true) CaveBot.addAction("usewith", itemId .. "," .. targetPos.x .. "," .. targetPos.y .. "," .. targetPos.z, true)
end) end)
end end

View File

@ -111,11 +111,13 @@ end
function setProtection(value) function setProtection(value)
protection = value protection = value
if protection then if protection then
emptyImbue.cost:setText(selectedImbue["cost"] + selectedImbue["protectionCost"])
emptyImbue.successRate:setText("100%") emptyImbue.successRate:setText("100%")
emptyImbue.successRate:setColor("green") emptyImbue.successRate:setColor("green")
protectionBtn:setImageClip(torect("66 0 66 66")) protectionBtn:setImageClip(torect("66 0 66 66"))
else else
if selectedImbue then if selectedImbue then
emptyImbue.cost:setText(selectedImbue["cost"])
emptyImbue.successRate:setText(selectedImbue["successRate"] .. "%") emptyImbue.successRate:setText(selectedImbue["successRate"] .. "%")
if selectedImbue["successRate"] > 50 then if selectedImbue["successRate"] > 50 then
emptyImbue.successRate:setColor("white") emptyImbue.successRate:setColor("white")
@ -219,7 +221,13 @@ function selectSlot(widget, slotId, activeSlot)
emptyImbue.imbue.onClick = function() emptyImbue.imbue.onClick = function()
imbuingWindow:hide() imbuingWindow:hide()
clearConfirmWindow = displayGeneralBox(tr('Confirm Imbuing Attempt'), tr('You are about to imbue your item with "' .. selectedImbue["name"] .. '".\nYour chance to succeed is ' .. selectedImbue["successRate"] .. '. It will consume the required astral sources and '.. selectedImbue["cost"]..' gold coins.\nDo you wish to proceed?'), { local cost = selectedImbue["cost"]
local successRate = selectedImbue["successRate"]
if protection then
cost = cost + selectedImbue["protectionCost"]
successRate = "100"
end
clearConfirmWindow = displayGeneralBox(tr('Confirm Imbuing Attempt'), 'You are about to imbue your item with "' .. selectedImbue["name"] .. '".\nYour chance to succeed is ' .. successRate .. '%. It will consume the required astral sources and '.. cost ..' gold coins.\nDo you wish to proceed?', {
{ text=tr('Yes'), callback=yesCallback }, { text=tr('Yes'), callback=yesCallback },
{ text=tr('No'), callback=noCallback }, { text=tr('No'), callback=noCallback },
anchor=AnchorHorizontalCenter}, yesCallback, noCallback) anchor=AnchorHorizontalCenter}, yesCallback, noCallback)

View File

@ -106,7 +106,7 @@ function setupSelector(widget, id, outfit, list)
widget.label:setText(list[pos][2]) widget.label:setText(list[pos][2])
updateOutfit() updateOutfit()
end end
return w return widget
end end
function create(currentOutfit, outfitList, mountList, wingList, auraList, shaderList) function create(currentOutfit, outfitList, mountList, wingList, auraList, shaderList)
@ -219,10 +219,12 @@ end
function accept() function accept()
local outfit = outfitWindow.type.creature:getOutfit() local outfit = outfitWindow.type.creature:getOutfit()
for i, child in pairs(outfitWindow.extensions:getChildren()) do for i, child in pairs(outfitWindow.extensions:getChildren()) do
if child:getId() == "shader" then if child.creature:getCreature() then
outfit[child:getId()] = child.creature:getOutfit().shader if child:getId() == "shader" then
else outfit[child:getId()] = child.creature:getOutfit().shader
outfit[child:getId()] = child.creature:getOutfit().type else
outfit[child:getId()] = child.creature:getOutfit().type
end
end end
end end
g_game.changeOutfit(outfit) g_game.changeOutfit(outfit)

View File

@ -157,13 +157,6 @@ MainWindow
fit-children: true fit-children: true
spacing: 3 spacing: 3
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: next.top
margin-bottom: 5
margin-top: 5
Button Button
id: outfitOkButton id: outfitOkButton
!text: tr('Ok') !text: tr('Ok')

View File

@ -2,7 +2,7 @@ function init()
-- add manually your shaders from /data/shaders -- add manually your shaders from /data/shaders
g_shaders.createOutfitShader("default", "/shaders/outfit_default_vertex", "/shaders/outfit_default_fragment") g_shaders.createOutfitShader("default", "/shaders/outfit_default_vertex", "/shaders/outfit_default_fragment")
--[[ g_shaders.createOutfitShader("stars", "/shaders/outfit_stars_vertex", "/shaders/outfit_stars_fragment") g_shaders.createOutfitShader("stars", "/shaders/outfit_stars_vertex", "/shaders/outfit_stars_fragment")
g_shaders.addTexture("stars", "/shaders/stars.png") g_shaders.addTexture("stars", "/shaders/stars.png")
g_shaders.createOutfitShader("gold", "/shaders/outfit_gold_vertex", "/shaders/outfit_gold_fragment") g_shaders.createOutfitShader("gold", "/shaders/outfit_gold_vertex", "/shaders/outfit_gold_fragment")
@ -13,7 +13,7 @@ function init()
g_shaders.createOutfitShader("line", "/shaders/outfit_line_vertex", "/shaders/outfit_line_fragment") g_shaders.createOutfitShader("line", "/shaders/outfit_line_vertex", "/shaders/outfit_line_fragment")
g_shaders.createOutfitShader("outline", "/shaders/outfit_outline_vertex", "/shaders/outfit_outline_fragment") ]]-- g_shaders.createOutfitShader("outline", "/shaders/outfit_outline_vertex", "/shaders/outfit_outline_fragment")
end end
function terminate() function terminate()

View File

@ -366,7 +366,7 @@ function processAd(data)
if data['image'] and data['image']:sub(1, 4):lower() == "http" then if data['image'] and data['image']:sub(1, 4):lower() == "http" then
HTTP.downloadImage(data['image'], function(path, err) HTTP.downloadImage(data['image'], function(path, err)
if err then g_logger.warning("HTTP error: " .. err) return end if err then g_logger.warning("HTTP error: " .. err .. " - " .. data['image']) return end
shop.adPanel:setHeight(shop.infoPanel:getHeight()) shop.adPanel:setHeight(shop.infoPanel:getHeight())
shop.adPanel.ad:setText("") shop.adPanel.ad:setText("")
shop.adPanel.ad:setImageSource(path) shop.adPanel.ad:setImageSource(path)
@ -407,7 +407,7 @@ function addCategory(data)
category = g_ui.createWidget('ShopCategoryImage', shop.categories) category = g_ui.createWidget('ShopCategoryImage', shop.categories)
if data["image"] and data["image"]:sub(1, 4):lower() == "http" then if data["image"] and data["image"]:sub(1, 4):lower() == "http" then
HTTP.downloadImage(data['image'], function(path, err) HTTP.downloadImage(data['image'], function(path, err)
if err then g_logger.warning("HTTP error: " .. err) return end if err then g_logger.warning("HTTP error: " .. err .. " - " .. data["image"]) return end
category.image:setImageSource(path) category.image:setImageSource(path)
end) end)
else else
@ -456,7 +456,7 @@ function addOffer(category, data)
offer = g_ui.createWidget('ShopOfferImage', shop.offers) offer = g_ui.createWidget('ShopOfferImage', shop.offers)
if data["image"] and data["image"]:sub(1, 4):lower() == "http" then if data["image"] and data["image"]:sub(1, 4):lower() == "http" then
HTTP.downloadImage(data['image'], function(path, err) HTTP.downloadImage(data['image'], function(path, err)
if err then g_logger.warning("HTTP error: " .. err) return end if err then g_logger.warning("HTTP error: " .. err .. " - " .. data['image']) return end
if not offer.image then return end if not offer.image then return end
offer.image:setImageSource(path) offer.image:setImageSource(path)
end) end)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -32,7 +32,7 @@ void Effect::draw(const Point& dest, int offsetX, int offsetY, bool animate, Lig
return; return;
if(animate) { if(animate) {
if(g_game.getFeature(Otc::GameEnhancedAnimations)) { if(g_game.getFeature(Otc::GameEnhancedAnimations) && rawGetThingType()->getAnimator()) {
// This requires a separate getPhaseAt method as using getPhase would make all magic effects use the same phase regardless of their appearance time // This requires a separate getPhaseAt method as using getPhase would make all magic effects use the same phase regardless of their appearance time
m_animationPhase = rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer, m_animationPhase); m_animationPhase = rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer, m_animationPhase);
} else { } else {
@ -46,11 +46,11 @@ void Effect::draw(const Point& dest, int offsetX, int offsetY, bool animate, Lig
} }
} }
int xPattern = offsetX % getNumPatternX(); int xPattern = m_position.x % getNumPatternX();
if(xPattern < 0) if(xPattern < 0)
xPattern += getNumPatternX(); xPattern += getNumPatternX();
int yPattern = offsetY % getNumPatternY(); int yPattern = m_position.y % getNumPatternY();
if(yPattern < 0) if(yPattern < 0)
yPattern += getNumPatternY(); yPattern += getNumPatternY();

View File

@ -420,7 +420,7 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerNews: case Proto::GameServerNews:
parseGameNews(msg); parseGameNews(msg);
break; break;
case Proto::GameServerSendBlessDialog: case Proto::GameServerBlessDialog:
parseBlessDialog(msg); parseBlessDialog(msg);
break; break;
case Proto::GameServerMessageDialog: case Proto::GameServerMessageDialog:
@ -468,7 +468,7 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerImbuementWindow: case Proto::GameServerImbuementWindow:
parseImbuementWindow(msg); parseImbuementWindow(msg);
break; break;
case Proto::GaneServerCloseImbuementWindow: case Proto::GameServerCloseImbuementWindow:
parseCloseImbuementWindow(msg); parseCloseImbuementWindow(msg);
break; break;
case Proto::GameServerCyclopediaNewDetails: case Proto::GameServerCyclopediaNewDetails:
@ -633,8 +633,9 @@ void ProtocolGame::parseRestingAreaState(const InputMessagePtr& msg)
void ProtocolGame::parseBlessings(const InputMessagePtr& msg) void ProtocolGame::parseBlessings(const InputMessagePtr& msg)
{ {
uint16 blessings = msg->getU16(); uint16 blessings = msg->getU16();
if (g_game.getFeature(Otc::GameTibia12Protocol)) if (g_game.getFeature(Otc::GameTibia12Protocol)) {
msg->getU8(); // blessStatus - 1 = Disabled | 2 = normal | 3 = green msg->getU8(); // blessStatus - 1 = Disabled | 2 = normal | 3 = green
}
m_localPlayer->setBlessings(blessings); m_localPlayer->setBlessings(blessings);
} }
@ -716,7 +717,7 @@ void ProtocolGame::parseCompleteStorePurchase(const InputMessagePtr& msg)
std::string message = msg->getString(); std::string message = msg->getString();
g_lua.callGlobalField("g_game", "onStorePurchase", message); g_lua.callGlobalField("g_game", "onStorePurchase", message);
if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getProtocolVersion() < 1220) { if (g_game.getProtocolVersion() < 1220) {
int coins = msg->getU32(); int coins = msg->getU32();
int transferableCoins = msg->getU32(); int transferableCoins = msg->getU32();
g_lua.callGlobalField("g_game", "onCoinBalance", coins, transferableCoins); g_lua.callGlobalField("g_game", "onCoinBalance", coins, transferableCoins);
@ -813,7 +814,8 @@ void ProtocolGame::parseStoreOffers(const InputMessagePtr& msg)
msg->getU16(); msg->getU16();
} }
if (g_game.getProtocolVersion() >= 1212) if (g_game.getProtocolVersion() >= 1212)
msg->getU8(); msg->getU8(); // has category?
msg->getString(); // filter msg->getString(); // filter
msg->getU32(); // TimeAddedToStore msg->getU32(); // TimeAddedToStore
msg->getU16(); // TimesBought msg->getU16(); // TimesBought
@ -2590,6 +2592,9 @@ void ProtocolGame::parseBlessDialog(const InputMessagePtr& msg)
for (int i = 0; i < totalBless; i++) { for (int i = 0; i < totalBless; i++) {
msg->getU16(); // bless bit wise msg->getU16(); // bless bit wise
msg->getU8(); // player bless count msg->getU8(); // player bless count
if (g_game.getClientVersion() >= 1220) {
msg->getU8(); // store?
}
} }
// parse general info // parse general info
@ -3102,7 +3107,7 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
creatureType = Proto::CreatureTypeNpc; creatureType = Proto::CreatureTypeNpc;
} }
if (creatureType == Proto::CreatureTypeSummonOwn) if (g_game.getFeature(Otc::GameTibia12Protocol) && creatureType == Proto::CreatureTypeSummonOwn)
msg->getU32(); // master msg->getU32(); // master
std::string name = g_game.formatCreatureName(msg->getString()); std::string name = g_game.formatCreatureName(msg->getString());
@ -3159,6 +3164,8 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
creatureType = msg->getU8(); creatureType = msg->getU8();
if (creatureType == Proto::CreatureTypeSummonOwn) if (creatureType == Proto::CreatureTypeSummonOwn)
msg->getU32(); // master msg->getU32(); // master
if (g_game.getClientVersion() >= 1220 && creatureType == Proto::CreatureTypePlayer)
msg->getU8(); // vocation id
} }
if(g_game.getFeature(Otc::GameCreatureIcons)) { if(g_game.getFeature(Otc::GameCreatureIcons)) {

View File

@ -802,6 +802,11 @@ void ProtocolGame::sendChangeOutfit(const Outfit& outfit)
{ {
OutputMessagePtr msg(new OutputMessage); OutputMessagePtr msg(new OutputMessage);
msg->addU8(Proto::ClientChangeOutfit); msg->addU8(Proto::ClientChangeOutfit);
if (g_game.getFeature(Otc::GameTibia12Protocol) && g_game.getClientVersion() >= 1220) {
msg->addU8(0); // outfit type
}
if(g_game.getFeature(Otc::GameLooktypeU16)) if(g_game.getFeature(Otc::GameLooktypeU16))
msg->addU16(outfit.getId()); msg->addU16(outfit.getId());
else else