mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-04-29 18:59:20 +02:00
Cleanup
This commit is contained in:
parent
b938520faf
commit
e93bcdc9cf
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
$data = file_get_contents("php://input");
|
||||
$json = json_decode($data);
|
||||
if(!$json || !$json->uid) {
|
||||
die();
|
||||
}
|
||||
|
||||
if($json->uid) {
|
||||
file_put_contents("stats/".($json->uid).".log", "\n".$data."\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
echo "OK";
|
||||
?>
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
$online_otservlist = 0;
|
||||
try {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, "https://otservlist.org/");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return data inplace of echoing on screen
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Skip SSL Verification
|
||||
curl_setopt($ch, CURLOPT_ENCODING , "");
|
||||
$site = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
preg_match('/There are <strong>([0-9]*)<\/strong>/', $site, $matches);
|
||||
$online_otservlist = $matches[1];
|
||||
} catch(Exception $e) {}
|
||||
$online_discord = 0;
|
||||
try {
|
||||
$online_discord = json_decode(file_get_contents("https://discordapp.com/api/guilds/628769144925585428/widget.json"))->presence_count;
|
||||
} catch(Exception $e) {}
|
||||
|
||||
$response = array(
|
||||
"online" => "$online_otservlist Players online",
|
||||
"discord_online" => $online_discord,
|
||||
"discord_link" => "https://discord.gg/t4ntS5p"
|
||||
);
|
||||
echo json_encode($response);
|
||||
?>
|
@ -1,69 +0,0 @@
|
||||
<?php
|
||||
// CONFIG
|
||||
$files_dir = "/var/www/otclient/files";
|
||||
$files_url = "http://otclient.ovh/files";
|
||||
$files_and_dirs = array("init.lua", "data", "modules", "layouts");
|
||||
$checksum_file = "checksums.txt";
|
||||
$checksum_update_interval = 60; // seconds
|
||||
$binaries = array(
|
||||
"WIN32-WGL" => "otclient_gl.exe",
|
||||
"WIN32-EGL" => "otclient_dx.exe",
|
||||
"WIN32-WGL-GCC" => "otclient_gcc_gl.exe",
|
||||
"WIN32-EGL-GCC" => "otclient_gcc_dx.exe",
|
||||
"X11-GLX" => "otclient_linux",
|
||||
"X11-EGL" => "otclient_linux",
|
||||
"ANDROID-EGL" => "", // we can't update android binary
|
||||
"ANDROID64-EGL" => "" // we can't update android binary
|
||||
);
|
||||
// CONFIG END
|
||||
|
||||
function sendError($error) {
|
||||
echo(json_encode(array("error" => $error)));
|
||||
die();
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
//if(!$data) {
|
||||
// sendError("Invalid input data");
|
||||
//}
|
||||
|
||||
$version = $data->version ?: 0; // APP_VERSION from init.lua
|
||||
$build = $data->build ?: ""; // 2.4, 2.4.1, 2.5, etc
|
||||
$os = $data->os ?: "unknown"; // android, windows, mac, linux, unknown
|
||||
$platform = $data->platform ?: ""; // WIN32-WGL, X11-GLX, ANDROID-EGL, etc
|
||||
$args = $data->args; // custom args when calling Updater.check()
|
||||
$binary = $binaries[$platform] ?: "";
|
||||
|
||||
$cache = null;
|
||||
$cache_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $checksum_file;
|
||||
if (file_exists($cache_file) && (filemtime($cache_file) + $checksum_update_interval > time())) {
|
||||
$cache = json_decode(file_get_contents($cache_file), true);
|
||||
}
|
||||
if(!$cache) { // update cache
|
||||
$dir = realpath($files_dir);
|
||||
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
|
||||
$cache = array();
|
||||
foreach ($rii as $file) {
|
||||
if (!$file->isFile())
|
||||
continue;
|
||||
$path = str_replace($dir, '', $file->getPathname());
|
||||
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
|
||||
$cache[$path] = hash_file("crc32b", $file->getPathname());
|
||||
}
|
||||
file_put_contents($cache_file . ".tmp", json_encode($cache));
|
||||
rename($cache_file . ".tmp", $cache_file);
|
||||
}
|
||||
$ret = array("url" => $files_url, "files" => array(), "keepFiles" => false);
|
||||
foreach($cache as $file => $checksum) {
|
||||
$base = trim(explode("/", ltrim($file, "/"))[0]);
|
||||
if(in_array($base, $files_and_dirs)) {
|
||||
$ret["files"][$file] = $checksum;
|
||||
}
|
||||
if($base == $binary && !empty($binary)) {
|
||||
$ret["binary"] = array("file" => $file, "checksum" => $checksum);
|
||||
}
|
||||
}
|
||||
|
||||
echo(json_encode($ret, JSON_PRETTY_PRINT));
|
||||
|
||||
?>
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
// CONFIG
|
||||
$files_dir = "/var/www/otclient/files";
|
||||
$files_url = "http://otclient.ovh/files";
|
||||
$files_and_dirs = array("init.lua", "data", "modules", "layouts");
|
||||
$checksum_file = "checksums.txt";
|
||||
$checksum_update_interval = 60; // seconds
|
||||
$binaries = array(
|
||||
"WIN32-WGL" => "otclient_gl.exe",
|
||||
"WIN32-EGL" => "otclient_dx.exe",
|
||||
"WIN32-WGL-GCC" => "otclient_gcc_gl.exe",
|
||||
"WIN32-EGL-GCC" => "otclient_gcc_dx.exe",
|
||||
"X11-GLX" => "otclient_linux",
|
||||
"X11-EGL" => "otclient_linux",
|
||||
"ANDROID-EGL" => "", // we can't update android binary
|
||||
"ANDROID64-EGL" => "" // we can't update android binary
|
||||
);
|
||||
// CONFIG END
|
||||
|
||||
function sendError($error) {
|
||||
echo(json_encode(array("error" => $error)));
|
||||
die();
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
//if(!$data) {
|
||||
// sendError("Invalid input data");
|
||||
//}
|
||||
|
||||
$version = $data->version ?: 0; // APP_VERSION from init.lua
|
||||
$build = $data->build ?: ""; // 2.4, 2.4.1, 2.5, etc
|
||||
$os = $data->os ?: "unknown"; // android, windows, mac, linux, unknown
|
||||
$platform = $data->platform ?: ""; // WIN32-WGL, X11-GLX, ANDROID-EGL, etc
|
||||
$args = $data->args; // custom args when calling Updater.check()
|
||||
$binary = $binaries[$platform] ?: "";
|
||||
|
||||
$forVersion = "";
|
||||
if($args && $args->version) {
|
||||
$forVersion = strval($args->version);
|
||||
}
|
||||
|
||||
$cache = null;
|
||||
$cache_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $checksum_file;
|
||||
if (file_exists($cache_file) && (filemtime($cache_file) + $checksum_update_interval > time())) {
|
||||
$cache = json_decode(file_get_contents($cache_file), true);
|
||||
}
|
||||
if(!$cache) { // update cache
|
||||
$dir = realpath($files_dir);
|
||||
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS));
|
||||
$cache = array();
|
||||
foreach ($rii as $file) {
|
||||
if (!$file->isFile())
|
||||
continue;
|
||||
$path = str_replace($dir, '', $file->getPathname());
|
||||
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
|
||||
$cache[$path] = hash_file("crc32b", $file->getPathname());
|
||||
}
|
||||
file_put_contents($cache_file . ".tmp", json_encode($cache));
|
||||
rename($cache_file . ".tmp", $cache_file);
|
||||
}
|
||||
$ret = array("url" => $files_url, "files" => array(), "keepFiles" => empty($forVersion) ? false : true);
|
||||
foreach($cache as $file => $checksum) {
|
||||
$base = trim(explode("/", ltrim($file, "/"))[0]);
|
||||
if(strpos($file, "data/things") !== false && (empty($forVersion) || strpos($file, $forVersion) === false)) {
|
||||
continue;
|
||||
}
|
||||
if(in_array($base, $files_and_dirs)) {
|
||||
$ret["files"][$file] = $checksum;
|
||||
}
|
||||
if($base == $binary && !empty($binary)) {
|
||||
$ret["binary"] = array("file" => $file, "checksum" => $checksum);
|
||||
}
|
||||
}
|
||||
|
||||
echo(json_encode($ret, JSON_PRETTY_PRINT));
|
||||
|
||||
?>
|
BIN
otclient_linux
BIN
otclient_linux
Binary file not shown.
@ -1 +0,0 @@
|
||||
adb uninstall com.otclientv8 && adb install otclientv8.apk && adb logcat -c && adb shell am start -n com.otclientv8/com.otclientv8.OTClientV8 && adb logcat | findstr /i otclient
|
@ -1,5 +0,0 @@
|
||||
Here are tools for server
|
||||
|
||||
all lua scripts are made for and tested on latest tfs (1.2/1.3)
|
||||
|
||||
add json.lua to data/lib/core and then in core.lua add: dofile('data/lib/core/json.lua')
|
399
server/json.lua
399
server/json.lua
@ -1,399 +0,0 @@
|
||||
-- add to lib/core, later add dofile in lib/core/core.lua
|
||||
|
||||
--
|
||||
-- json.lua
|
||||
--
|
||||
-- Copyright (c) 2018 rxi
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in
|
||||
-- the Software without restriction, including without limitation the rights to
|
||||
-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
-- of the Software, and to permit persons to whom the Software is furnished to do
|
||||
-- so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all
|
||||
-- copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
-- SOFTWARE.
|
||||
--
|
||||
|
||||
json = { _version = "0.1.1" }
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Encode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local encode
|
||||
|
||||
local escape_char_map = {
|
||||
[ "\\" ] = "\\\\",
|
||||
[ "\"" ] = "\\\"",
|
||||
[ "\b" ] = "\\b",
|
||||
[ "\f" ] = "\\f",
|
||||
[ "\n" ] = "\\n",
|
||||
[ "\r" ] = "\\r",
|
||||
[ "\t" ] = "\\t",
|
||||
}
|
||||
|
||||
local escape_char_map_inv = { [ "\\/" ] = "/" }
|
||||
for k, v in pairs(escape_char_map) do
|
||||
escape_char_map_inv[v] = k
|
||||
end
|
||||
|
||||
|
||||
local function escape_char(c)
|
||||
return escape_char_map[c] or string.format("\\u%04x", c:byte())
|
||||
end
|
||||
|
||||
|
||||
local function encode_nil(val)
|
||||
return "null"
|
||||
end
|
||||
|
||||
|
||||
local function encode_table(val, stack)
|
||||
local res = {}
|
||||
stack = stack or {}
|
||||
|
||||
-- Circular reference?
|
||||
if stack[val] then error("circular reference") end
|
||||
|
||||
stack[val] = true
|
||||
|
||||
if val[1] ~= nil or next(val) == nil then
|
||||
-- Treat as array -- check keys are valid and it is not sparse
|
||||
local n = 0
|
||||
for k in pairs(val) do
|
||||
if type(k) ~= "number" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
if n ~= #val then
|
||||
error("invalid table: sparse array")
|
||||
end
|
||||
-- Encode
|
||||
for i, v in ipairs(val) do
|
||||
table.insert(res, encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "[" .. table.concat(res, ",") .. "]"
|
||||
|
||||
else
|
||||
-- Treat as an object
|
||||
for k, v in pairs(val) do
|
||||
if type(k) ~= "string" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "{" .. table.concat(res, ",") .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function encode_string(val)
|
||||
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
|
||||
end
|
||||
|
||||
|
||||
local function encode_number(val)
|
||||
-- Check for NaN, -inf and inf
|
||||
if val ~= val or val <= -math.huge or val >= math.huge then
|
||||
error("unexpected number value '" .. tostring(val) .. "'")
|
||||
end
|
||||
return string.format("%.14g", val)
|
||||
end
|
||||
|
||||
|
||||
local type_func_map = {
|
||||
[ "nil" ] = encode_nil,
|
||||
[ "table" ] = encode_table,
|
||||
[ "string" ] = encode_string,
|
||||
[ "number" ] = encode_number,
|
||||
[ "boolean" ] = tostring,
|
||||
}
|
||||
|
||||
|
||||
encode = function(val, stack)
|
||||
local t = type(val)
|
||||
local f = type_func_map[t]
|
||||
if f then
|
||||
return f(val, stack)
|
||||
end
|
||||
error("unexpected type '" .. t .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.encode(val)
|
||||
return ( encode(val) )
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Decode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local parse
|
||||
|
||||
local function create_set(...)
|
||||
local res = {}
|
||||
for i = 1, select("#", ...) do
|
||||
res[ select(i, ...) ] = true
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local space_chars = create_set(" ", "\t", "\r", "\n")
|
||||
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
|
||||
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
|
||||
local literals = create_set("true", "false", "null")
|
||||
|
||||
local literal_map = {
|
||||
[ "true" ] = true,
|
||||
[ "false" ] = false,
|
||||
[ "null" ] = nil,
|
||||
}
|
||||
|
||||
|
||||
local function next_char(str, idx, set, negate)
|
||||
for i = idx, #str do
|
||||
if set[str:sub(i, i)] ~= negate then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return #str + 1
|
||||
end
|
||||
|
||||
|
||||
local function decode_error(str, idx, msg)
|
||||
local line_count = 1
|
||||
local col_count = 1
|
||||
for i = 1, idx - 1 do
|
||||
col_count = col_count + 1
|
||||
if str:sub(i, i) == "\n" then
|
||||
line_count = line_count + 1
|
||||
col_count = 1
|
||||
end
|
||||
end
|
||||
error( string.format("%s at line %d col %d", msg, line_count, col_count) )
|
||||
end
|
||||
|
||||
|
||||
local function codepoint_to_utf8(n)
|
||||
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
|
||||
local f = math.floor
|
||||
if n <= 0x7f then
|
||||
return string.char(n)
|
||||
elseif n <= 0x7ff then
|
||||
return string.char(f(n / 64) + 192, n % 64 + 128)
|
||||
elseif n <= 0xffff then
|
||||
return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
elseif n <= 0x10ffff then
|
||||
return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
|
||||
f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
end
|
||||
error( string.format("invalid unicode codepoint '%x'", n) )
|
||||
end
|
||||
|
||||
|
||||
local function parse_unicode_escape(s)
|
||||
local n1 = tonumber( s:sub(3, 6), 16 )
|
||||
local n2 = tonumber( s:sub(9, 12), 16 )
|
||||
-- Surrogate pair?
|
||||
if n2 then
|
||||
return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
|
||||
else
|
||||
return codepoint_to_utf8(n1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function parse_string(str, i)
|
||||
local has_unicode_escape = false
|
||||
local has_surrogate_escape = false
|
||||
local has_escape = false
|
||||
local last
|
||||
for j = i + 1, #str do
|
||||
local x = str:byte(j)
|
||||
|
||||
if x < 32 then
|
||||
decode_error(str, j, "control character in string")
|
||||
end
|
||||
|
||||
if last == 92 then -- "\\" (escape char)
|
||||
if x == 117 then -- "u" (unicode escape sequence)
|
||||
local hex = str:sub(j + 1, j + 5)
|
||||
if not hex:find("%x%x%x%x") then
|
||||
decode_error(str, j, "invalid unicode escape in string")
|
||||
end
|
||||
if hex:find("^[dD][89aAbB]") then
|
||||
has_surrogate_escape = true
|
||||
else
|
||||
has_unicode_escape = true
|
||||
end
|
||||
else
|
||||
local c = string.char(x)
|
||||
if not escape_chars[c] then
|
||||
decode_error(str, j, "invalid escape char '" .. c .. "' in string")
|
||||
end
|
||||
has_escape = true
|
||||
end
|
||||
last = nil
|
||||
|
||||
elseif x == 34 then -- '"' (end of string)
|
||||
local s = str:sub(i + 1, j - 1)
|
||||
if has_surrogate_escape then
|
||||
s = s:gsub("\\u[dD][89aAbB]..\\u....", parse_unicode_escape)
|
||||
end
|
||||
if has_unicode_escape then
|
||||
s = s:gsub("\\u....", parse_unicode_escape)
|
||||
end
|
||||
if has_escape then
|
||||
s = s:gsub("\\.", escape_char_map_inv)
|
||||
end
|
||||
return s, j + 1
|
||||
|
||||
else
|
||||
last = x
|
||||
end
|
||||
end
|
||||
decode_error(str, i, "expected closing quote for string")
|
||||
end
|
||||
|
||||
|
||||
local function parse_number(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local s = str:sub(i, x - 1)
|
||||
local n = tonumber(s)
|
||||
if not n then
|
||||
decode_error(str, i, "invalid number '" .. s .. "'")
|
||||
end
|
||||
return n, x
|
||||
end
|
||||
|
||||
|
||||
local function parse_literal(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local word = str:sub(i, x - 1)
|
||||
if not literals[word] then
|
||||
decode_error(str, i, "invalid literal '" .. word .. "'")
|
||||
end
|
||||
return literal_map[word], x
|
||||
end
|
||||
|
||||
|
||||
local function parse_array(str, i)
|
||||
local res = {}
|
||||
local n = 1
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local x
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of array?
|
||||
if str:sub(i, i) == "]" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read token
|
||||
x, i = parse(str, i)
|
||||
res[n] = x
|
||||
n = n + 1
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "]" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local function parse_object(str, i)
|
||||
local res = {}
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local key, val
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of object?
|
||||
if str:sub(i, i) == "}" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read key
|
||||
if str:sub(i, i) ~= '"' then
|
||||
decode_error(str, i, "expected string for key")
|
||||
end
|
||||
key, i = parse(str, i)
|
||||
-- Read ':' delimiter
|
||||
i = next_char(str, i, space_chars, true)
|
||||
if str:sub(i, i) ~= ":" then
|
||||
decode_error(str, i, "expected ':' after key")
|
||||
end
|
||||
i = next_char(str, i + 1, space_chars, true)
|
||||
-- Read value
|
||||
val, i = parse(str, i)
|
||||
-- Set
|
||||
res[key] = val
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "}" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
|
||||
local char_func_map = {
|
||||
[ '"' ] = parse_string,
|
||||
[ "0" ] = parse_number,
|
||||
[ "1" ] = parse_number,
|
||||
[ "2" ] = parse_number,
|
||||
[ "3" ] = parse_number,
|
||||
[ "4" ] = parse_number,
|
||||
[ "5" ] = parse_number,
|
||||
[ "6" ] = parse_number,
|
||||
[ "7" ] = parse_number,
|
||||
[ "8" ] = parse_number,
|
||||
[ "9" ] = parse_number,
|
||||
[ "-" ] = parse_number,
|
||||
[ "t" ] = parse_literal,
|
||||
[ "f" ] = parse_literal,
|
||||
[ "n" ] = parse_literal,
|
||||
[ "[" ] = parse_array,
|
||||
[ "{" ] = parse_object,
|
||||
}
|
||||
|
||||
|
||||
parse = function(str, idx)
|
||||
local chr = str:sub(idx, idx)
|
||||
local f = char_func_map[chr]
|
||||
if f then
|
||||
return f(str, idx)
|
||||
end
|
||||
decode_error(str, idx, "unexpected character '" .. chr .. "'")
|
||||
end
|
||||
|
||||
|
||||
function json.decode(str)
|
||||
if type(str) ~= "string" then
|
||||
error("expected argument of type string, got " .. type(str))
|
||||
end
|
||||
local res, idx = parse(str, next_char(str, 1, space_chars, true))
|
||||
idx = next_char(str, idx, space_chars, true)
|
||||
if idx <= #str then
|
||||
decode_error(str, idx, "trailing garbage")
|
||||
end
|
||||
return res
|
||||
end
|
@ -1,362 +0,0 @@
|
||||
-- BETA VERSION, net tested yet
|
||||
-- Instruction:
|
||||
-- creaturescripts.xml <event type="extendedopcode" name="Shop" script="shop.lua" />
|
||||
-- and in login.lua player:registerEvent("Shop")
|
||||
-- create sql table shop_history
|
||||
-- set variables
|
||||
-- set up function init(), add there items and categories, follow examples
|
||||
-- set up callbacks at the bottom to add player item/outfit/whatever you want
|
||||
|
||||
local SHOP_EXTENDED_OPCODE = 201
|
||||
local SHOP_OFFERS = {}
|
||||
local SHOP_CALLBACKS = {}
|
||||
local SHOP_CATEGORIES = nil
|
||||
local SHOP_BUY_URL = "http://otland.net" -- can be empty
|
||||
local SHOP_AD = { -- can be nil
|
||||
image = "https://s3.envato.com/files/62273611/PNG%20Blue/Banner%20blue%20468x60.png",
|
||||
url = "http://otclient.ovh",
|
||||
text = ""
|
||||
}
|
||||
local MAX_PACKET_SIZE = 50000
|
||||
|
||||
--[[ SQL TABLE
|
||||
|
||||
CREATE TABLE `shop_history` (
|
||||
`id` int(11) NOT NULL,
|
||||
`account` int(11) NOT NULL,
|
||||
`player` int(11) NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`title` varchar(100) NOT NULL,
|
||||
`cost` int(11) NOT NULL,
|
||||
`details` varchar(500) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
ALTER TABLE `shop_history`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
ALTER TABLE `shop_history`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
|
||||
]]--
|
||||
|
||||
function init()
|
||||
-- print(json.encode(g_game.getLocalPlayer():getOutfit())) -- in console in otclient, will print current outfit and mount
|
||||
|
||||
SHOP_CATEGORIES = {}
|
||||
|
||||
local category1 = addCategory({
|
||||
type="item",
|
||||
item=ItemType(2160):getClientId(),
|
||||
count=100,
|
||||
name="Items"
|
||||
})
|
||||
local category2 = addCategory({
|
||||
type="outfit",
|
||||
name="Outfits",
|
||||
outfit={
|
||||
mount=0,
|
||||
feet=114,
|
||||
legs=114,
|
||||
body=116,
|
||||
type=143,
|
||||
auxType=0,
|
||||
addons=3,
|
||||
head=2,
|
||||
rotating=true
|
||||
}
|
||||
})
|
||||
local category3 = addCategory({
|
||||
type="image",
|
||||
image="http://otclient.ovh/images/137.png",
|
||||
name="Category with http image"
|
||||
})
|
||||
local category4 = addCategory({
|
||||
type="image",
|
||||
image="/data/images/game/states/electrified.png",
|
||||
name="Category with local image"
|
||||
})
|
||||
|
||||
|
||||
category1.addItem(1, 2160, 1, "1 Crystal coin", "description of cristal coin")
|
||||
category1.addItem(5, 2160, 5, "5 Crystal coin", "description of cristal coin")
|
||||
category1.addItem(50, 2160, 50, "50 Crystal coin", "description of cristal coin")
|
||||
category1.addItem(90, 2160, 100, "100 Crystal coin", "description of cristal coin")
|
||||
category1.addItem(200, 2493, 1, "Demon helmet1", "woo\ndemon helmet\nnice, you should buy it")
|
||||
category1.addItem(1, 2160, 1, "1 Crystal coin1", "description of cristal coin")
|
||||
category1.addItem(5, 2160, 5, "5 Crystal coin1", "description of cristal coin")
|
||||
category1.addItem(50, 2160, 50, "50 Crystal coin1", "description of cristal coin")
|
||||
category1.addItem(90, 2160, 100, "100 Crystal coin1", "description of cristal coin")
|
||||
category1.addItem(200, 2493, 1, "Demon helmet2", "woo\ndemon helmet\nnice, you should buy it")
|
||||
category1.addItem(1, 2160, 1, "1 Crystal coin3", "description of cristal coin")
|
||||
category1.addItem(5, 2160, 5, "5 Crystal coin3", "description of cristal coin")
|
||||
category1.addItem(50, 2160, 50, "50 Crystal coin3", "description of cristal coin")
|
||||
category1.addItem(90, 2160, 100, "100 Crystal coin3", "description of cristal coin")
|
||||
category1.addItem(200, 2493, 1, "Demon helmet3", "wooxD\ndemon helmet\nnice, you should buy it")
|
||||
|
||||
category2.addOutfit(500, {
|
||||
mount=0,
|
||||
feet=114,
|
||||
legs=114,
|
||||
body=116,
|
||||
type=143,
|
||||
auxType=0,
|
||||
addons=3,
|
||||
head=2,
|
||||
rotating=true
|
||||
}, "title of this cool outfit or whatever", "this is your new cool outfit. You can buy it here.\nsrlsy")
|
||||
category2.addOutfit(100, {
|
||||
mount=682,
|
||||
feet=0,
|
||||
legs=0,
|
||||
body=0,
|
||||
type=143,
|
||||
auxType=0,
|
||||
addons=0,
|
||||
head=0,
|
||||
rotating=true
|
||||
}, "MOUNT!!!", "DOUBLE CLICK TO BUY THIS MOUNT. IDK NAME")
|
||||
|
||||
category2.addOutfit(100, {
|
||||
mount=0,
|
||||
feet=0,
|
||||
legs=0,
|
||||
body=0,
|
||||
type=35,
|
||||
auxType=0,
|
||||
addons=0,
|
||||
head=0,
|
||||
rotating=true
|
||||
}, "Demon outfit", "Want be a demon?\nNo problem")
|
||||
category2.addOutfit(100, {
|
||||
mount=0,
|
||||
feet=0,
|
||||
legs=0,
|
||||
body=0,
|
||||
type=35,
|
||||
auxType=0,
|
||||
addons=0,
|
||||
head=0,
|
||||
rotating=false
|
||||
}, "Demon outfit2", "This one is not rotating")
|
||||
|
||||
category4.addImage(10000, "/data/images/game/states/haste.png", "Offer with local image", "another local image\n/data/images/game/states/haste.png")
|
||||
category4.addImage(10000, "http://otclient.ovh/images/freezing.png", "Offer with remote image and custom buy action", "blalasdasd image\nhttp://otclient.ovh/images/freezing.png", customImageBuyAction)
|
||||
end
|
||||
|
||||
function addCategory(data)
|
||||
data['offers'] = {}
|
||||
table.insert(SHOP_CATEGORIES, data)
|
||||
table.insert(SHOP_CALLBACKS, {})
|
||||
local index = #SHOP_CATEGORIES
|
||||
return {
|
||||
addItem = function(cost, itemId, count, title, description, callback)
|
||||
if not callback then
|
||||
callback = defaultItemBuyAction
|
||||
end
|
||||
table.insert(SHOP_CATEGORIES[index]['offers'], {
|
||||
cost=cost,
|
||||
type="item",
|
||||
item=ItemType(itemId):getClientId(), -- displayed
|
||||
itemId=itemId,
|
||||
count=count,
|
||||
title=title,
|
||||
description=description
|
||||
})
|
||||
table.insert(SHOP_CALLBACKS[index], callback)
|
||||
end,
|
||||
addOutfit = function(cost, outfit, title, description, callback)
|
||||
if not callback then
|
||||
callback = defaultOutfitBuyAction
|
||||
end
|
||||
table.insert(SHOP_CATEGORIES[index]['offers'], {
|
||||
cost=cost,
|
||||
type="outfit",
|
||||
outfit=outfit,
|
||||
title=title,
|
||||
description=description
|
||||
})
|
||||
table.insert(SHOP_CALLBACKS[index], callback)
|
||||
end,
|
||||
addImage = function(cost, image, title, description, callback)
|
||||
if not callback then
|
||||
callback = defaultImageBuyAction
|
||||
end
|
||||
table.insert(SHOP_CATEGORIES[index]['offers'], {
|
||||
cost=cost,
|
||||
type="image",
|
||||
image=image,
|
||||
title=title,
|
||||
description=description
|
||||
})
|
||||
table.insert(SHOP_CALLBACKS[index], callback)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
function getPoints(player)
|
||||
local points = 0
|
||||
local resultId = db.storeQuery("SELECT `premium_points` FROM `accounts` WHERE `id` = " .. player:getAccountId())
|
||||
if resultId ~= false then
|
||||
points = result.getDataInt(resultId, "premium_points")
|
||||
result.free(resultId)
|
||||
end
|
||||
return points
|
||||
end
|
||||
|
||||
function getStatus(player)
|
||||
local status = {
|
||||
ad = SHOP_AD,
|
||||
points = getPoints(player),
|
||||
buyUrl = SHOP_BUY_URL
|
||||
}
|
||||
return status
|
||||
end
|
||||
|
||||
function sendJSON(player, action, data, forceStatus)
|
||||
local status = nil
|
||||
if not player:getStorageValue(1150001) or player:getStorageValue(1150001) + 10 < os.time() or forceStatus then
|
||||
status = getStatus(player)
|
||||
end
|
||||
player:setStorageValue(1150001, os.time())
|
||||
|
||||
|
||||
local buffer = json.encode({action = action, data = data, status = status})
|
||||
local s = {}
|
||||
for i=1, #buffer, MAX_PACKET_SIZE do
|
||||
s[#s+1] = buffer:sub(i,i+MAX_PACKET_SIZE - 1)
|
||||
end
|
||||
local msg = NetworkMessage()
|
||||
if #s == 1 then
|
||||
msg:addByte(50)
|
||||
msg:addByte(SHOP_EXTENDED_OPCODE)
|
||||
msg:addString(s[1])
|
||||
msg:sendToPlayer(player)
|
||||
return
|
||||
end
|
||||
-- split message if too big
|
||||
msg:addByte(50)
|
||||
msg:addByte(SHOP_EXTENDED_OPCODE)
|
||||
msg:addString("S" .. s[1])
|
||||
msg:sendToPlayer(player)
|
||||
for i=2,#s - 1 do
|
||||
msg = NetworkMessage()
|
||||
msg:addByte(50)
|
||||
msg:addByte(SHOP_EXTENDED_OPCODE)
|
||||
msg:addString("P" .. s[i])
|
||||
msg:sendToPlayer(player)
|
||||
end
|
||||
msg = NetworkMessage()
|
||||
msg:addByte(50)
|
||||
msg:addByte(SHOP_EXTENDED_OPCODE)
|
||||
msg:addString("E" .. s[#s])
|
||||
msg:sendToPlayer(player)
|
||||
end
|
||||
|
||||
function sendMessage(player, title, msg, forceStatus)
|
||||
sendJSON(player, "message", {title=title, msg=msg}, forceStatus)
|
||||
end
|
||||
|
||||
function onExtendedOpcode(player, opcode, buffer)
|
||||
if opcode ~= SHOP_EXTENDED_OPCODE then
|
||||
return false
|
||||
end
|
||||
local status, json_data = pcall(function() return json.decode(buffer) end)
|
||||
if not status then
|
||||
return false
|
||||
end
|
||||
|
||||
local action = json_data['action']
|
||||
local data = json_data['data']
|
||||
if not action or not data then
|
||||
return false
|
||||
end
|
||||
|
||||
if SHOP_CATEGORIES == nil then
|
||||
init()
|
||||
end
|
||||
|
||||
if action == 'init' then
|
||||
sendJSON(player, "categories", SHOP_CATEGORIES)
|
||||
elseif action == 'buy' then
|
||||
processBuy(player, data)
|
||||
elseif action == "history" then
|
||||
sendHistory(player)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function processBuy(player, data)
|
||||
local categoryId = tonumber(data["category"])
|
||||
local offerId = tonumber(data["offer"])
|
||||
local offer = SHOP_CATEGORIES[categoryId]['offers'][offerId]
|
||||
local callback = SHOP_CALLBACKS[categoryId][offerId]
|
||||
if not offer or not callback or data["title"] ~= offer["title"] or data["cost"] ~= offer["cost"] then
|
||||
sendJSON(player, "categories", SHOP_CATEGORIES) -- refresh categories, maybe invalid
|
||||
return sendMessage(player, "Error!", "Invalid offer")
|
||||
end
|
||||
local points = getPoints(player)
|
||||
if not offer['cost'] or offer['cost'] > points or points < 1 then
|
||||
return sendMessage(player, "Error!", "You don't have enough points to buy " .. offer['title'] .."!", true)
|
||||
end
|
||||
local status = callback(player, offer)
|
||||
if status == true then
|
||||
db.query("UPDATE `accounts` set `premium_points` = `premium_points` - " .. offer['cost'] .. " WHERE `id` = " .. player:getAccountId())
|
||||
db.asyncQuery("INSERT INTO `shop_history` (`account`, `player`, `date`, `title`, `cost`, `details`) VALUES ('" .. player:getAccountId() .. "', '" .. player:getGuid() .. "', NOW(), " .. db.escapeString(offer['title']) .. ", " .. db.escapeString(offer['cost']) .. ", " .. db.escapeString(json.encode(offer)) .. ")")
|
||||
return sendMessage(player, "Success!", "You bought " .. offer['title'] .."!", true)
|
||||
end
|
||||
if status == nil or status == false then
|
||||
status = "Unknown error while buying " .. offer['title']
|
||||
end
|
||||
sendMessage(player, "Error!", status)
|
||||
end
|
||||
|
||||
function sendHistory(player)
|
||||
if player:getStorageValue(1150002) and player:getStorageValue(1150002) + 10 > os.time() then
|
||||
return -- min 10s delay
|
||||
end
|
||||
player:setStorageValue(1150002, os.time())
|
||||
|
||||
local history = {}
|
||||
local resultId = db.storeQuery("SELECT * FROM `shop_history` WHERE `account` = " .. player:getAccountId() .. " order by `id` DESC")
|
||||
|
||||
if resultId ~= false then
|
||||
repeat
|
||||
local details = result.getDataString(resultId, "details")
|
||||
local status, json_data = pcall(function() return json.decode(details) end)
|
||||
if not status then
|
||||
json_data = {
|
||||
type = "image",
|
||||
title = result.getDataString(resultId, "title"),
|
||||
cost = result.getDataInt(resultId, "cost")
|
||||
}
|
||||
end
|
||||
table.insert(history, json_data)
|
||||
history[#history]["description"] = "Bought on " .. result.getDataString(resultId, "date") .. " for " .. result.getDataInt(resultId, "cost") .. " points."
|
||||
until not result.next(resultId)
|
||||
result.free(resultId)
|
||||
end
|
||||
|
||||
sendJSON(player, "history", history)
|
||||
end
|
||||
|
||||
-- BUY CALLBACKS
|
||||
-- May be useful: print(json.encode(offer))
|
||||
|
||||
function defaultItemBuyAction(player, offer)
|
||||
-- todo: check if has capacity
|
||||
if player:addItem(offer["itemId"], offer["count"], false) then
|
||||
return true
|
||||
end
|
||||
return "Can't add item! Do you have enough space?"
|
||||
end
|
||||
|
||||
function defaultOutfitBuyAction(player, offer)
|
||||
return "default outfit buy action is not implemented"
|
||||
end
|
||||
|
||||
function defaultImageBuyAction(player, offer)
|
||||
return "default image buy action is not implemented"
|
||||
end
|
||||
|
||||
function customImageBuyAction(player, offer)
|
||||
return "custom image buy action is not implemented. Offer: " .. offer['title']
|
||||
end
|
@ -1,8 +0,0 @@
|
||||
# OTClientV8 partial sources (90% of code)
|
||||
|
||||
To help you understand how OTClientV8 works, some parts of source code has been published.
|
||||
All files from client/ dir has been shared, but there few places with hidden code due to various reasons
|
||||
In the future more parts of OTCv8 will be available here
|
||||
|
||||
If you want buy access to full sources, contact kondrah#7945 on discord
|
||||
Or send mail to otclient@otclient.ovh (but discord is better)
|
@ -1,113 +0,0 @@
|
||||
# CMAKE_CURRENT_LIST_DIR cmake 2.6 compatibility
|
||||
if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
|
||||
get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
endif(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 6)
|
||||
|
||||
# client options
|
||||
add_definitions(-DCLIENT)
|
||||
option(BOT_PROTECTION "Enable bot protection" ON)
|
||||
if(BOT_PROTECTION)
|
||||
add_definitions(-DBOT_PROTECTION)
|
||||
message(STATUS "Bot protection: ON")
|
||||
else(BOT_PROTECTION)
|
||||
message(STATUS "Bot protection: OFF")
|
||||
endif(BOT_PROTECTION)
|
||||
|
||||
set(client_SOURCES ${client_SOURCES}
|
||||
# client
|
||||
${CMAKE_CURRENT_LIST_DIR}/const.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/global.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/luafunctions_client.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/client.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/client.h
|
||||
|
||||
# core
|
||||
${CMAKE_CURRENT_LIST_DIR}/animatedtext.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/animatedtext.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/animator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/animator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/container.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/container.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/creature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/creature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/declarations.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/effect.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/effect.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/game.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/game.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/shadermanager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/shadermanager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/item.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/item.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/localplayer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/localplayer.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/map.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/map.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/mapio.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/mapview.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/mapview.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/minimap.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/minimap.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/lightview.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/lightview.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/missile.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/missile.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/outfit.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/outfit.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/player.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/player.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/spritemanager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/spritemanager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/statictext.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/statictext.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/thing.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/thing.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/thingtypemanager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/thingtypemanager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/thingtype.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/thingtype.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/itemtype.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/itemtype.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/tile.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/tile.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/houses.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/houses.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/towns.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/towns.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/creatures.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/creatures.h
|
||||
|
||||
# lua
|
||||
${CMAKE_CURRENT_LIST_DIR}/luavaluecasts_client.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/luavaluecasts_client.h
|
||||
|
||||
# net
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocolcodes.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocolcodes.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocolgame.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocolgame.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocolgameparse.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/protocolgamesend.cpp
|
||||
|
||||
# ui
|
||||
${CMAKE_CURRENT_LIST_DIR}/uicreature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uicreature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/uiitem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uiitem.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/uimap.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uimap.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/uiminimap.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uiminimap.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/uisprite.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/uisprite.h
|
||||
|
||||
# util
|
||||
${CMAKE_CURRENT_LIST_DIR}/position.h
|
||||
)
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
|
||||
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "animatedtext.h"
|
||||
#include "map.h"
|
||||
#include "game.h"
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
||||
AnimatedText::AnimatedText()
|
||||
{
|
||||
m_cachedText.setFont(g_fonts.getFont("verdana-11px-rounded"));
|
||||
m_cachedText.setAlign(Fw::AlignLeft);
|
||||
}
|
||||
|
||||
void AnimatedText::drawText(const Point& dest, const Rect& visibleRect)
|
||||
{
|
||||
static float tf = Otc::ANIMATED_TEXT_DURATION;
|
||||
static float tftf = Otc::ANIMATED_TEXT_DURATION * Otc::ANIMATED_TEXT_DURATION;
|
||||
|
||||
Point p = dest;
|
||||
Size textSize = m_cachedText.getTextSize();
|
||||
float t = m_animationTimer.ticksElapsed();
|
||||
p.x -= textSize.width() / 2;
|
||||
|
||||
if(g_game.getFeature(Otc::GameDiagonalAnimatedText)) {
|
||||
p.x -= (4 * t / tf) + (8 * t * t / tftf);
|
||||
}
|
||||
|
||||
p.y += (-48 * t) / tf;
|
||||
p += m_offset;
|
||||
Rect rect(p, textSize);
|
||||
|
||||
if(visibleRect.contains(rect)) {
|
||||
float t0 = tf / 1.2;
|
||||
Color color = m_color;
|
||||
if(t > t0) {
|
||||
color.setAlpha((float)(1 - (t - t0) / (tf - t0)));
|
||||
}
|
||||
m_cachedText.draw(rect, color);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatedText::onAppear()
|
||||
{
|
||||
m_animationTimer.restart();
|
||||
|
||||
// schedule removal
|
||||
auto self = asAnimatedText();
|
||||
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, Otc::ANIMATED_TEXT_DURATION);
|
||||
}
|
||||
|
||||
void AnimatedText::setColor(int color)
|
||||
{
|
||||
m_color = Color::from8bit(color);
|
||||
}
|
||||
|
||||
void AnimatedText::setText(const std::string& text)
|
||||
{
|
||||
m_cachedText.setText(text);
|
||||
}
|
||||
|
||||
bool AnimatedText::merge(const AnimatedTextPtr& other)
|
||||
{
|
||||
if(other->getColor() != m_color)
|
||||
return false;
|
||||
|
||||
if(other->getCachedText().getFont() != m_cachedText.getFont())
|
||||
return false;
|
||||
|
||||
if(m_animationTimer.ticksElapsed() > Otc::ANIMATED_TEXT_DURATION / 2.5)
|
||||
return false;
|
||||
|
||||
try {
|
||||
int number = stdext::safe_cast<int>(m_cachedText.getText());
|
||||
int otherNumber = stdext::safe_cast<int>(other->getCachedText().getText());
|
||||
m_cachedText.setText(std::to_string(number + otherNumber));
|
||||
return true;
|
||||
} catch(...) {}
|
||||
return false;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ANIMATEDTEXT_H
|
||||
#define ANIMATEDTEXT_H
|
||||
|
||||
#include "thing.h"
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
#include <framework/core/timer.h>
|
||||
#include <framework/graphics/cachedtext.h>
|
||||
|
||||
// @bindclass
|
||||
class AnimatedText : public Thing
|
||||
{
|
||||
public:
|
||||
AnimatedText();
|
||||
|
||||
void drawText(const Point& dest, const Rect& visibleRect);
|
||||
|
||||
void setColor(int color);
|
||||
void setText(const std::string& text);
|
||||
void setOffset(const Point& offset) { m_offset = offset; }
|
||||
|
||||
Color getColor() { return m_color; }
|
||||
const CachedText& getCachedText() const { return m_cachedText; }
|
||||
Point getOffset() { return m_offset; }
|
||||
Timer getTimer() { return m_animationTimer; }
|
||||
|
||||
bool merge(const AnimatedTextPtr& other);
|
||||
|
||||
AnimatedTextPtr asAnimatedText() { return static_self_cast<AnimatedText>(); }
|
||||
bool isAnimatedText() { return true; }
|
||||
std::string getText() { return m_cachedText.getText(); }
|
||||
|
||||
protected:
|
||||
virtual void onAppear();
|
||||
|
||||
private:
|
||||
Color m_color;
|
||||
Timer m_animationTimer;
|
||||
CachedText m_cachedText;
|
||||
Point m_offset;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "declarations.h"
|
||||
#include "animator.h"
|
||||
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/util/extras.h>
|
||||
#include <framework/stdext/fastrand.h>
|
||||
|
||||
Animator::Animator()
|
||||
{
|
||||
m_animationPhases = 0;
|
||||
m_startPhase = 0;
|
||||
m_loopCount = 0;
|
||||
m_async = false;
|
||||
m_currentDuration = 0;
|
||||
m_currentDirection = AnimDirForward;
|
||||
m_currentLoop = 0;
|
||||
m_lastPhaseTicks = 0;
|
||||
m_isComplete = false;
|
||||
m_phase = 0;
|
||||
}
|
||||
|
||||
void Animator::unserialize(int animationPhases, const FileStreamPtr& fin)
|
||||
{
|
||||
m_animationPhases = animationPhases;
|
||||
m_async = fin->getU8() == 0;
|
||||
m_loopCount = fin->get32();
|
||||
m_startPhase = fin->get8();
|
||||
|
||||
for(int i = 0; i < m_animationPhases; ++i) {
|
||||
int minimum = fin->getU32();
|
||||
int maximum = fin->getU32();
|
||||
m_phaseDurations.push_back(std::make_pair(minimum, std::max(0, maximum - minimum)));
|
||||
}
|
||||
|
||||
m_phase = getStartPhase();
|
||||
|
||||
VALIDATE(m_animationPhases == (int)m_phaseDurations.size());
|
||||
VALIDATE(m_startPhase >= -1 && m_startPhase < m_animationPhases);
|
||||
}
|
||||
|
||||
void Animator::serialize(const FileStreamPtr& fin)
|
||||
{
|
||||
fin->addU8(m_async ? 0 : 1);
|
||||
fin->add32(m_loopCount);
|
||||
fin->add8(m_startPhase);
|
||||
|
||||
for(auto& phase : m_phaseDurations) {
|
||||
fin->addU32(phase.first);
|
||||
fin->addU32(phase.first + phase.second);
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::setPhase(int phase)
|
||||
{
|
||||
if(m_phase == phase) return;
|
||||
|
||||
if(m_async) {
|
||||
if(phase == AnimPhaseAsync)
|
||||
m_phase = 0;
|
||||
else if(phase == AnimPhaseRandom)
|
||||
m_phase = (int)stdext::random_range(0, (long)m_animationPhases);
|
||||
else if(phase >= 0 && phase < m_animationPhases)
|
||||
m_phase = phase;
|
||||
else
|
||||
m_phase = getStartPhase();
|
||||
|
||||
m_isComplete = false;
|
||||
m_lastPhaseTicks = g_clock.millis();
|
||||
m_currentDuration = getPhaseDuration(phase);
|
||||
m_currentLoop = 0;
|
||||
} else
|
||||
calculateSynchronous();
|
||||
}
|
||||
|
||||
int Animator::getPhase()
|
||||
{
|
||||
ticks_t ticks = g_clock.millis();
|
||||
if(ticks != m_lastPhaseTicks && !m_isComplete) {
|
||||
int elapsedTicks = (int)(ticks - m_lastPhaseTicks);
|
||||
if(elapsedTicks >= m_currentDuration) {
|
||||
int phase = 0;
|
||||
if(m_loopCount < 0)
|
||||
phase = getPingPongPhase();
|
||||
else
|
||||
phase = getLoopPhase();
|
||||
|
||||
if(m_phase != phase) {
|
||||
int duration = getPhaseDuration(phase) - (elapsedTicks - m_currentDuration);
|
||||
if(duration < 0 && !m_async) {
|
||||
calculateSynchronous();
|
||||
} else {
|
||||
m_phase = phase;
|
||||
m_currentDuration = std::max<int>(0, duration);
|
||||
}
|
||||
} else
|
||||
m_isComplete = true;
|
||||
} else
|
||||
m_currentDuration -= elapsedTicks;
|
||||
|
||||
m_lastPhaseTicks = ticks;
|
||||
}
|
||||
return m_phase;
|
||||
}
|
||||
|
||||
int Animator::getPhaseAt(Timer& timer, int lastPhase)
|
||||
{
|
||||
static int rand_val = 6;
|
||||
ticks_t time = timer.ticksElapsed();
|
||||
for (int i = lastPhase; i < m_animationPhases; ++i) {
|
||||
int phaseDuration = m_phaseDurations[i].second == 0 ?
|
||||
m_phaseDurations[i].first : m_phaseDurations[i].first + rand_val % (m_phaseDurations[i].second);
|
||||
rand_val = rand_val * 7 + 11;
|
||||
if (time < phaseDuration) {
|
||||
timer.restart();
|
||||
timer.adjust(-time);
|
||||
return i;
|
||||
}
|
||||
time -= phaseDuration;
|
||||
}
|
||||
return -1;
|
||||
/*
|
||||
ticks_t total = 0;
|
||||
|
||||
for (const auto &pair : m_phaseDurations) {
|
||||
total += std::get<1>(pair);
|
||||
|
||||
if (time < total) {
|
||||
return index;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
return std::min<int>(index, m_animationPhases - 1);
|
||||
*/
|
||||
}
|
||||
|
||||
int Animator::getStartPhase()
|
||||
{
|
||||
if(m_startPhase > -1)
|
||||
return m_startPhase;
|
||||
return (int)stdext::random_range(0, (long)m_animationPhases);
|
||||
}
|
||||
|
||||
void Animator::resetAnimation()
|
||||
{
|
||||
m_isComplete = false;
|
||||
m_currentDirection = AnimDirForward;
|
||||
m_currentLoop = 0;
|
||||
setPhase(AnimPhaseAutomatic);
|
||||
}
|
||||
|
||||
int Animator::getPingPongPhase()
|
||||
{
|
||||
int count = m_currentDirection == AnimDirForward ? 1 : -1;
|
||||
int nextPhase = m_phase + count;
|
||||
if(nextPhase < 0 || nextPhase >= m_animationPhases) {
|
||||
m_currentDirection = m_currentDirection == AnimDirForward ? AnimDirBackward : AnimDirForward;
|
||||
count *= -1;
|
||||
}
|
||||
return m_phase + count;
|
||||
}
|
||||
|
||||
int Animator::getLoopPhase()
|
||||
{
|
||||
int nextPhase = m_phase + 1;
|
||||
if(nextPhase < m_animationPhases)
|
||||
return nextPhase;
|
||||
|
||||
if(m_loopCount == 0)
|
||||
return 0;
|
||||
|
||||
if(m_currentLoop < (m_loopCount - 1)) {
|
||||
m_currentLoop++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_phase;
|
||||
}
|
||||
|
||||
int Animator::getPhaseDuration(int phase)
|
||||
{
|
||||
VALIDATE(phase < (int)m_phaseDurations.size());
|
||||
|
||||
auto& data = m_phaseDurations.at(phase);
|
||||
if (data.second == 0) return data.first;
|
||||
int min = data.first;
|
||||
int max = min + data.second;
|
||||
return (int)stdext::random_range((long)min, (long)max);
|
||||
}
|
||||
|
||||
void Animator::calculateSynchronous()
|
||||
{
|
||||
int totalDuration = 0;
|
||||
for(int i = 0; i < m_animationPhases; i++)
|
||||
totalDuration += getPhaseDuration(i);
|
||||
|
||||
ticks_t ticks = g_clock.millis();
|
||||
int elapsedTicks = (int)(ticks % totalDuration);
|
||||
int totalTime = 0;
|
||||
for(int i = 0; i < m_animationPhases; i++) {
|
||||
int duration = getPhaseDuration(i);
|
||||
if(elapsedTicks >= totalTime && elapsedTicks < totalTime + duration) {
|
||||
m_phase = i;
|
||||
m_currentDuration = duration - (elapsedTicks - totalTime);
|
||||
break;
|
||||
}
|
||||
totalTime += duration;
|
||||
}
|
||||
m_lastPhaseTicks = ticks;
|
||||
}
|
||||
|
||||
ticks_t Animator::getTotalDuration()
|
||||
{
|
||||
ticks_t time = 0;
|
||||
for (const auto &pair: m_phaseDurations) {
|
||||
time += pair.first + pair.second;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ANIMATOR_H
|
||||
#define ANIMATOR_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
#include <framework/core/declarations.h>
|
||||
#include <framework/core/timer.h>
|
||||
|
||||
enum AnimationPhase : int16
|
||||
{
|
||||
AnimPhaseAutomatic = -1,
|
||||
AnimPhaseRandom = 254,
|
||||
AnimPhaseAsync = 255,
|
||||
};
|
||||
|
||||
enum AnimationDirection : uint8
|
||||
{
|
||||
AnimDirForward = 0,
|
||||
AnimDirBackward = 1
|
||||
};
|
||||
|
||||
class Animator : public stdext::shared_object
|
||||
{
|
||||
public:
|
||||
Animator();
|
||||
|
||||
void unserialize(int animationPhases, const FileStreamPtr& fin);
|
||||
void serialize(const FileStreamPtr& fin);
|
||||
|
||||
void setPhase(int phase);
|
||||
int getPhase();
|
||||
int getPhaseAt(Timer& timer, int lastPhase = 0);
|
||||
|
||||
int getStartPhase();
|
||||
int getAnimationPhases() { return m_animationPhases; }
|
||||
bool isAsync() { return m_async; }
|
||||
bool isComplete() { return m_isComplete; }
|
||||
|
||||
ticks_t getTotalDuration();
|
||||
|
||||
void resetAnimation();
|
||||
|
||||
private:
|
||||
int getPingPongPhase();
|
||||
int getLoopPhase();
|
||||
int getPhaseDuration(int phase);
|
||||
void calculateSynchronous();
|
||||
|
||||
int m_animationPhases;
|
||||
int m_startPhase;
|
||||
int m_loopCount;
|
||||
bool m_async;
|
||||
std::vector< std::pair<int, int> > m_phaseDurations;
|
||||
|
||||
int m_currentDuration;
|
||||
AnimationDirection m_currentDirection;
|
||||
int m_currentLoop;
|
||||
|
||||
ticks_t m_lastPhaseTicks;
|
||||
bool m_isComplete;
|
||||
|
||||
int m_phase;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include <framework/core/modulemanager.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include "game.h"
|
||||
#include "map.h"
|
||||
#include "shadermanager.h"
|
||||
#include "spritemanager.h"
|
||||
#include "minimap.h"
|
||||
#include <framework/core/configmanager.h>
|
||||
|
||||
Client g_client;
|
||||
|
||||
void Client::init(std::vector<std::string>& args)
|
||||
{
|
||||
// register needed lua functions
|
||||
registerLuaFunctions();
|
||||
|
||||
g_map.init();
|
||||
g_minimap.init();
|
||||
g_game.init();
|
||||
g_shaders.init();
|
||||
g_things.init();
|
||||
}
|
||||
|
||||
void Client::terminate()
|
||||
{
|
||||
g_creatures.terminate();
|
||||
g_game.terminate();
|
||||
g_map.terminate();
|
||||
g_minimap.terminate();
|
||||
g_things.terminate();
|
||||
g_sprites.terminate();
|
||||
g_shaders.terminate();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include "global.h"
|
||||
|
||||
class Client
|
||||
{
|
||||
public:
|
||||
void init(std::vector<std::string>& args);
|
||||
void terminate();
|
||||
void registerLuaFunctions();
|
||||
};
|
||||
|
||||
extern Client g_client;
|
||||
|
||||
#endif
|
@ -1,614 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLIENT_CONST_H
|
||||
#define CLIENT_CONST_H
|
||||
|
||||
namespace Otc
|
||||
{
|
||||
enum : int {
|
||||
TILE_PIXELS = 32,
|
||||
MAX_ELEVATION = 24,
|
||||
|
||||
SEA_FLOOR = 7,
|
||||
MAX_Z = 15,
|
||||
UNDERGROUND_FLOOR = SEA_FLOOR+1,
|
||||
AWARE_UNDEGROUND_FLOOR_RANGE = 2,
|
||||
|
||||
INVISIBLE_TICKS_PER_FRAME = 500,
|
||||
INVISIBLE_TICKS_PER_FRAME_FAST = 100,
|
||||
ITEM_TICKS_PER_FRAME = 500,
|
||||
ITEM_TICKS_PER_FRAME_FAST = 100,
|
||||
ANIMATED_TEXT_DURATION = 1000,
|
||||
STATIC_DURATION_PER_CHARACTER = 60,
|
||||
MIN_STATIC_TEXT_DURATION = 3000,
|
||||
MAX_STATIC_TEXT_WIDTH = 200,
|
||||
MAX_AUTOWALK_STEPS_RETRY = 10,
|
||||
MAX_AUTOWALK_DIST = 127
|
||||
};
|
||||
|
||||
enum DepthConst {
|
||||
MAX_DEPTH = 16384 - 2048
|
||||
};
|
||||
|
||||
enum DrawFlags {
|
||||
DrawGround = 1,
|
||||
DrawGroundBorders = 2,
|
||||
DrawOnBottom = 4,
|
||||
DrawOnTop = 8,
|
||||
DrawItems = 16,
|
||||
DrawCreatures = 32,
|
||||
DrawEffects = 64,
|
||||
DrawMissiles = 128,
|
||||
DrawCreaturesInformation = 256,
|
||||
DrawStaticTexts = 512,
|
||||
DrawAnimatedTexts = 1024,
|
||||
DrawAnimations = 2048,
|
||||
DrawBars = 4096,
|
||||
DrawNames = 8192,
|
||||
DrawLights = 16384,
|
||||
DrawManaBar = 32768,
|
||||
DontDrawLocalPlayer = 65536,
|
||||
DrawIcons = 131072,
|
||||
DrawWalls = DrawOnBottom | DrawOnTop,
|
||||
DrawEverything = DrawGround | DrawGroundBorders | DrawWalls | DrawItems |
|
||||
DrawCreatures | DrawEffects | DrawMissiles | DrawCreaturesInformation |
|
||||
DrawStaticTexts | DrawAnimatedTexts | DrawAnimations | DrawBars | DrawNames |
|
||||
DrawLights | DrawManaBar | DrawIcons
|
||||
};
|
||||
|
||||
enum DatOpts {
|
||||
DatGround = 0,
|
||||
DatGroundClip,
|
||||
DatOnBottom,
|
||||
DatOnTop,
|
||||
DatContainer,
|
||||
DatStackable,
|
||||
DatForceUse,
|
||||
DatMultiUse,
|
||||
DatWritable,
|
||||
DatWritableOnce,
|
||||
DatFluidContainer,
|
||||
DatSplash,
|
||||
DatBlockWalk,
|
||||
DatNotMoveable,
|
||||
DatBlockProjectile,
|
||||
DatBlockPathFind,
|
||||
DatPickupable,
|
||||
DatHangable,
|
||||
DatHookSouth,
|
||||
DatHookEast,
|
||||
DatRotable,
|
||||
DatLight,
|
||||
DatDontHide,
|
||||
DatTranslucent,
|
||||
DatDisplacement,
|
||||
DatElevation,
|
||||
DatLyingCorpse,
|
||||
DatAnimateAlways,
|
||||
DatMinimapColor,
|
||||
DatLensHelp,
|
||||
DatFullGround,
|
||||
DatIgnoreLook,
|
||||
DatCloth,
|
||||
DatAnimation, // lastest tibia
|
||||
DatLastOpt = 255
|
||||
};
|
||||
|
||||
enum InventorySlot {
|
||||
InventorySlotHead = 1,
|
||||
InventorySlotNecklace,
|
||||
InventorySlotBackpack,
|
||||
InventorySlotArmor,
|
||||
InventorySlotRight,
|
||||
InventorySlotLeft,
|
||||
InventorySlotLegs,
|
||||
InventorySlotFeet,
|
||||
InventorySlotRing,
|
||||
InventorySlotAmmo,
|
||||
InventorySlotPurse,
|
||||
InventorySlotExt1,
|
||||
InventorySlotExt2,
|
||||
InventorySlotExt3,
|
||||
InventorySlotExt4,
|
||||
LastInventorySlot
|
||||
};
|
||||
|
||||
enum Statistic {
|
||||
Health = 0,
|
||||
MaxHealth,
|
||||
FreeCapacity,
|
||||
Experience,
|
||||
Level,
|
||||
LevelPercent,
|
||||
Mana,
|
||||
MaxMana,
|
||||
MagicLevel,
|
||||
MagicLevelPercent,
|
||||
Soul,
|
||||
Stamina,
|
||||
LastStatistic
|
||||
};
|
||||
|
||||
enum Skill {
|
||||
Fist = 0,
|
||||
Club,
|
||||
Sword,
|
||||
Axe,
|
||||
Distance,
|
||||
Shielding,
|
||||
Fishing,
|
||||
CriticalChance,
|
||||
CriticalDamage,
|
||||
LifeLeechChance,
|
||||
LifeLeechAmount,
|
||||
ManaLeechChance,
|
||||
ManaLeechAmount,
|
||||
LastSkill
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
North = 0,
|
||||
East,
|
||||
South,
|
||||
West,
|
||||
NorthEast,
|
||||
SouthEast,
|
||||
SouthWest,
|
||||
NorthWest,
|
||||
InvalidDirection
|
||||
};
|
||||
|
||||
enum FluidsColor {
|
||||
FluidTransparent = 0,
|
||||
FluidBlue,
|
||||
FluidRed,
|
||||
FluidBrown,
|
||||
FluidGreen,
|
||||
FluidYellow,
|
||||
FluidWhite,
|
||||
FluidPurple
|
||||
};
|
||||
|
||||
enum FluidsType {
|
||||
FluidNone = 0,
|
||||
FluidWater,
|
||||
FluidMana,
|
||||
FluidBeer,
|
||||
FluidOil,
|
||||
FluidBlood,
|
||||
FluidSlime,
|
||||
FluidMud,
|
||||
FluidLemonade,
|
||||
FluidMilk,
|
||||
FluidWine,
|
||||
FluidHealth,
|
||||
FluidUrine,
|
||||
FluidRum,
|
||||
FluidFruidJuice,
|
||||
FluidCoconutMilk,
|
||||
FluidTea,
|
||||
FluidMead
|
||||
};
|
||||
|
||||
enum FightModes {
|
||||
FightOffensive = 1,
|
||||
FightBalanced = 2,
|
||||
FightDefensive = 3
|
||||
};
|
||||
|
||||
enum ChaseModes {
|
||||
DontChase = 0,
|
||||
ChaseOpponent = 1
|
||||
};
|
||||
|
||||
enum PVPModes {
|
||||
WhiteDove = 0,
|
||||
WhiteHand = 1,
|
||||
YellowHand = 2,
|
||||
RedFist = 3
|
||||
};
|
||||
|
||||
enum PlayerSkulls {
|
||||
SkullNone = 0,
|
||||
SkullYellow,
|
||||
SkullGreen,
|
||||
SkullWhite,
|
||||
SkullRed,
|
||||
SkullBlack,
|
||||
SkullOrange
|
||||
};
|
||||
|
||||
enum PlayerShields {
|
||||
ShieldNone = 0,
|
||||
ShieldWhiteYellow, // 1 party leader
|
||||
ShieldWhiteBlue, // 2 party member
|
||||
ShieldBlue, // 3 party member sexp off
|
||||
ShieldYellow, // 4 party leader sexp off
|
||||
ShieldBlueSharedExp, // 5 party member sexp on
|
||||
ShieldYellowSharedExp, // 6 // party leader sexp on
|
||||
ShieldBlueNoSharedExpBlink, // 7 party member sexp inactive guilty
|
||||
ShieldYellowNoSharedExpBlink, // 8 // party leader sexp inactive guilty
|
||||
ShieldBlueNoSharedExp, // 9 party member sexp inactive innocent
|
||||
ShieldYellowNoSharedExp, // 10 party leader sexp inactive innocent
|
||||
ShieldGray // 11 member of another party
|
||||
};
|
||||
|
||||
enum PlayerEmblems {
|
||||
EmblemNone = 0,
|
||||
EmblemGreen,
|
||||
EmblemRed,
|
||||
EmblemBlue,
|
||||
EmblemMember,
|
||||
EmblemOther
|
||||
};
|
||||
|
||||
enum CreatureIcons {
|
||||
NpcIconNone = 0,
|
||||
NpcIconChat,
|
||||
NpcIconTrade,
|
||||
NpcIconQuest,
|
||||
NpcIconTradeQuest
|
||||
};
|
||||
|
||||
enum PlayerStates {
|
||||
IconNone = 0,
|
||||
IconPoison = 1,
|
||||
IconBurn = 2,
|
||||
IconEnergy = 4,
|
||||
IconDrunk = 8,
|
||||
IconManaShield = 16,
|
||||
IconParalyze = 32,
|
||||
IconHaste = 64,
|
||||
IconSwords = 128,
|
||||
IconDrowning = 256,
|
||||
IconFreezing = 512,
|
||||
IconDazzled = 1024,
|
||||
IconCursed = 2048,
|
||||
IconPartyBuff = 4096,
|
||||
IconPzBlock = 8192,
|
||||
IconPz = 16384,
|
||||
IconBleeding = 32768,
|
||||
IconHungry = 65536
|
||||
};
|
||||
|
||||
enum MessageMode {
|
||||
MessageNone = 0,
|
||||
MessageSay = 1,
|
||||
MessageWhisper = 2,
|
||||
MessageYell = 3,
|
||||
MessagePrivateFrom = 4,
|
||||
MessagePrivateTo = 5,
|
||||
MessageChannelManagement = 6,
|
||||
MessageChannel = 7,
|
||||
MessageChannelHighlight = 8,
|
||||
MessageSpell = 9,
|
||||
MessageNpcFrom = 10,
|
||||
MessageNpcTo = 11,
|
||||
MessageGamemasterBroadcast = 12,
|
||||
MessageGamemasterChannel = 13,
|
||||
MessageGamemasterPrivateFrom = 14,
|
||||
MessageGamemasterPrivateTo = 15,
|
||||
MessageLogin = 16,
|
||||
MessageWarning = 17,
|
||||
MessageGame = 18,
|
||||
MessageFailure = 19,
|
||||
MessageLook = 20,
|
||||
MessageDamageDealed = 21,
|
||||
MessageDamageReceived = 22,
|
||||
MessageHeal = 23,
|
||||
MessageExp = 24,
|
||||
MessageDamageOthers = 25,
|
||||
MessageHealOthers = 26,
|
||||
MessageExpOthers = 27,
|
||||
MessageStatus = 28,
|
||||
MessageLoot = 29,
|
||||
MessageTradeNpc = 30,
|
||||
MessageGuild = 31,
|
||||
MessagePartyManagement = 32,
|
||||
MessageParty = 33,
|
||||
MessageBarkLow = 34,
|
||||
MessageBarkLoud = 35,
|
||||
MessageReport = 36,
|
||||
MessageHotkeyUse = 37,
|
||||
MessageTutorialHint = 38,
|
||||
MessageThankyou = 39,
|
||||
MessageMarket = 40,
|
||||
MessageMana = 41,
|
||||
MessageBeyondLast = 42,
|
||||
|
||||
// deprecated
|
||||
MessageMonsterYell = 43,
|
||||
MessageMonsterSay = 44,
|
||||
MessageRed = 45,
|
||||
MessageBlue = 46,
|
||||
MessageRVRChannel = 47,
|
||||
MessageRVRAnswer = 48,
|
||||
MessageRVRContinue = 49,
|
||||
MessageGameHighlight = 50,
|
||||
MessageNpcFromStartBlock = 51,
|
||||
LastMessage = 52,
|
||||
MessageInvalid = 255
|
||||
};
|
||||
|
||||
enum GameFeature {
|
||||
GameProtocolChecksum = 1,
|
||||
GameAccountNames = 2,
|
||||
GameChallengeOnLogin = 3,
|
||||
GamePenalityOnDeath = 4,
|
||||
GameNameOnNpcTrade = 5,
|
||||
GameDoubleFreeCapacity = 6,
|
||||
GameDoubleExperience = 7,
|
||||
GameTotalCapacity = 8,
|
||||
GameSkillsBase = 9,
|
||||
GamePlayerRegenerationTime = 10,
|
||||
GameChannelPlayerList = 11,
|
||||
GamePlayerMounts = 12,
|
||||
GameEnvironmentEffect = 13,
|
||||
GameCreatureEmblems = 14,
|
||||
GameItemAnimationPhase = 15,
|
||||
GameMagicEffectU16 = 16,
|
||||
GamePlayerMarket = 17,
|
||||
GameSpritesU32 = 18,
|
||||
GameTileAddThingWithStackpos = 19,
|
||||
GameOfflineTrainingTime = 20,
|
||||
GamePurseSlot = 21,
|
||||
GameFormatCreatureName = 22,
|
||||
GameSpellList = 23,
|
||||
GameClientPing = 24,
|
||||
GameExtendedClientPing = 25,
|
||||
GameDoubleHealth = 28,
|
||||
GameDoubleSkills = 29,
|
||||
GameChangeMapAwareRange = 30,
|
||||
GameMapMovePosition = 31,
|
||||
GameAttackSeq = 32,
|
||||
GameBlueNpcNameColor = 33,
|
||||
GameDiagonalAnimatedText = 34,
|
||||
GameLoginPending = 35,
|
||||
GameNewSpeedLaw = 36,
|
||||
GameForceFirstAutoWalkStep = 37,
|
||||
GameMinimapRemove = 38,
|
||||
GameDoubleShopSellAmount = 39,
|
||||
GameContainerPagination = 40,
|
||||
GameThingMarks = 41,
|
||||
GameLooktypeU16 = 42,
|
||||
GamePlayerStamina = 43,
|
||||
GamePlayerAddons = 44,
|
||||
GameMessageStatements = 45,
|
||||
GameMessageLevel = 46,
|
||||
GameNewFluids = 47,
|
||||
GamePlayerStateU16 = 48,
|
||||
GameNewOutfitProtocol = 49,
|
||||
GamePVPMode = 50,
|
||||
GameWritableDate = 51,
|
||||
GameAdditionalVipInfo = 52,
|
||||
GameBaseSkillU16 = 53,
|
||||
GameCreatureIcons = 54,
|
||||
GameHideNpcNames = 55,
|
||||
GameSpritesAlphaChannel = 56,
|
||||
GamePremiumExpiration = 57,
|
||||
GameBrowseField = 58,
|
||||
GameEnhancedAnimations = 59,
|
||||
GameOGLInformation = 60,
|
||||
GameMessageSizeCheck = 61,
|
||||
GamePreviewState = 62,
|
||||
GameLoginPacketEncryption = 63,
|
||||
GameClientVersion = 64,
|
||||
GameContentRevision = 65,
|
||||
GameExperienceBonus = 66,
|
||||
GameAuthenticator = 67,
|
||||
GameUnjustifiedPoints = 68,
|
||||
GameSessionKey = 69,
|
||||
GameDeathType = 70,
|
||||
GameIdleAnimations = 71,
|
||||
GameKeepUnawareTiles = 72,
|
||||
GameIngameStore = 73,
|
||||
GameIngameStoreHighlights = 74,
|
||||
GameIngameStoreServiceType = 75,
|
||||
GameAdditionalSkills = 76,
|
||||
GameDistanceEffectU16 = 77,
|
||||
GamePrey = 78,
|
||||
GameDoubleMagicLevel = 79,
|
||||
|
||||
GameExtendedOpcode = 80,
|
||||
GameMinimapLimitedToSingleFloor = 81,
|
||||
|
||||
GameDoubleLevel = 83,
|
||||
GameDoubleSoul = 84,
|
||||
GameDoublePlayerGoodsMoney = 85,
|
||||
GameCreatureWalkthrough = 86,
|
||||
GameDoubleTradeMoney = 87,
|
||||
|
||||
// 90-99 otclientv8 features
|
||||
GameNewWalking = 90,
|
||||
GameSlowerManualWalking = 91,
|
||||
|
||||
GameItemTooltip = 93,
|
||||
|
||||
GameBot = 95,
|
||||
GameBiggerMapCache = 96,
|
||||
GameForceLight = 97,
|
||||
GameNoDebug = 98,
|
||||
GameBotProtection = 99,
|
||||
|
||||
// Custom features for customer
|
||||
GameFasterAnimations = 101,
|
||||
GameCenteredOutfits = 102,
|
||||
GameSendIdentifiers = 103,
|
||||
GameWingsAndAura = 104,
|
||||
|
||||
// advanced features
|
||||
GamePacketSizeU32 = 110,
|
||||
GamePacketCompression = 111,
|
||||
|
||||
LastGameFeature = 120
|
||||
};
|
||||
|
||||
enum PathFindResult {
|
||||
PathFindResultOk = 0,
|
||||
PathFindResultSamePosition,
|
||||
PathFindResultImpossible,
|
||||
PathFindResultTooFar,
|
||||
PathFindResultNoWay
|
||||
};
|
||||
|
||||
enum PathFindFlags {
|
||||
PathFindAllowNotSeenTiles = 1,
|
||||
PathFindAllowCreatures = 2,
|
||||
PathFindAllowNonPathable = 4,
|
||||
PathFindAllowNonWalkable = 8,
|
||||
PathFindIgnoreCreatures = 16
|
||||
};
|
||||
|
||||
enum AutomapFlags {
|
||||
MapMarkTick = 0,
|
||||
MapMarkQuestion,
|
||||
MapMarkExclamation,
|
||||
MapMarkStar,
|
||||
MapMarkCross,
|
||||
MapMarkTemple,
|
||||
MapMarkKiss,
|
||||
MapMarkShovel,
|
||||
MapMarkSword,
|
||||
MapMarkFlag,
|
||||
MapMarkLock,
|
||||
MapMarkBag,
|
||||
MapMarkSkull,
|
||||
MapMarkDollar,
|
||||
MapMarkRedNorth,
|
||||
MapMarkRedSouth,
|
||||
MapMarkRedEast,
|
||||
MapMarkRedWest,
|
||||
MapMarkGreenNorth,
|
||||
MapMarkGreenSouth
|
||||
};
|
||||
|
||||
enum VipState {
|
||||
VipStateOffline = 0,
|
||||
VipStateOnline = 1,
|
||||
VipStatePending = 2
|
||||
};
|
||||
|
||||
enum SpeedFormula {
|
||||
SpeedFormulaA = 0,
|
||||
SpeedFormulaB,
|
||||
SpeedFormulaC,
|
||||
LastSpeedFormula
|
||||
};
|
||||
|
||||
enum Blessings {
|
||||
BlessingNone = 0,
|
||||
BlessingAdventurer = 1,
|
||||
BlessingSpiritualShielding = 1 << 1,
|
||||
BlessingEmbraceOfTibia = 1 << 2,
|
||||
BlessingFireOfSuns = 1 << 3,
|
||||
BlessingWisdomOfSolitude = 1 << 4,
|
||||
BlessingSparkOfPhoenix = 1 << 5
|
||||
};
|
||||
|
||||
enum DeathType {
|
||||
DeathRegular = 0,
|
||||
DeathBlessed = 1
|
||||
};
|
||||
|
||||
enum StoreProductTypes {
|
||||
ProductTypeOther = 0,
|
||||
ProductTypeNameChange = 1
|
||||
};
|
||||
|
||||
enum StoreErrorTypes {
|
||||
StoreNoError = -1,
|
||||
StorePurchaseError = 0,
|
||||
StoreNetworkError = 1,
|
||||
StoreHistoryError = 2,
|
||||
StoreTransferError = 3,
|
||||
StoreInformation = 4
|
||||
};
|
||||
|
||||
enum StoreStates {
|
||||
StateNone = 0,
|
||||
StateNew = 1,
|
||||
StateSale = 2,
|
||||
StateTimed = 3
|
||||
};
|
||||
|
||||
enum PreySlotNum_t : uint8_t {
|
||||
PREY_SLOTNUM_FIRST,
|
||||
PREY_SLOTNUM_SECOND,
|
||||
PREY_SLOTNUM_THIRD,
|
||||
PREY_SLOTNUM_LAST = PREY_SLOTNUM_THIRD
|
||||
};
|
||||
enum PreyState_t : uint8_t {
|
||||
PREY_STATE_LOCKED = 0,
|
||||
PREY_STATE_INACTIVE = 1,
|
||||
PREY_STATE_ACTIVE = 2,
|
||||
PREY_STATE_SELECTION = 3,
|
||||
PREY_STATE_SELECTION_CHANGE_MONSTER = 4, // unused; hmm
|
||||
PREY_STATE_SELECTION_FROMALL = 5,
|
||||
PREY_STATE_CHANGE_FROMALL = 6, // unused :(
|
||||
};
|
||||
enum PreyMessageDialog_t : uint8_t {
|
||||
//PREY_MESSAGEDIALOG_IMBUEMENT_SUCCESS = 0,
|
||||
//PREY_MESSAGEDIALOG_IMBUEMENT_ERROR = 1,
|
||||
//PREY_MESSAGEDIALOG_IMBUEMENT_ROLL_FAILED = 2,
|
||||
//PREY_MESSAGEDIALOG_IMBUEMENT_STATION_NOT_FOUND = 3,
|
||||
//PREY_MESSAGEDIALOG_IMBUEMENT_CHARM_SUCCESS = 10,
|
||||
//PREY_MESSAGEDIALOG_IMBUEMENT_CHARM_ERROR = 11,
|
||||
PREY_MESSAGEDIALOG_PREY_MESSAGE = 20,
|
||||
PREY_MESSAGEDIALOG_PREY_ERROR = 21,
|
||||
};
|
||||
enum PreyResourceType_t : uint8_t {
|
||||
PREY_RESOURCETYPE_BANK_GOLD = 0,
|
||||
PREY_RESOURCETYPE_INVENTORY_GOLD = 1,
|
||||
PREY_RESOURCETYPE_PREY_BONUS_REROLLS = 10
|
||||
};
|
||||
enum PreyBonusType_t : uint8_t {
|
||||
PREY_BONUS_DAMAGE_BOOST = 0,
|
||||
PREY_BONUS_DAMAGE_REDUCTION = 1,
|
||||
PREY_BONUS_XP_BONUS = 2,
|
||||
PREY_BONUS_IMPROVED_LOOT = 3,
|
||||
PREY_BONUS_NONE = 4, // internal usage but still added to client;
|
||||
PREY_BONUS_FIRST = PREY_BONUS_DAMAGE_BOOST,
|
||||
PREY_BONUS_LAST = PREY_BONUS_IMPROVED_LOOT,
|
||||
};
|
||||
enum PreyAction_t : uint8_t {
|
||||
PREY_ACTION_LISTREROLL = 0,
|
||||
PREY_ACTION_BONUSREROLL = 1,
|
||||
PREY_ACTION_MONSTERSELECTION = 2,
|
||||
PREY_ACTION_REQUEST_ALL_MONSTERS = 3,
|
||||
PREY_ACTION_CHANGE_FROM_ALL = 4,
|
||||
PREY_ACTION_LOCK_PREY = 5,
|
||||
|
||||
};
|
||||
enum PreyConfigState {
|
||||
PREY_CONFIG_STATE_FREE,
|
||||
PREY_CONFIG_STATE_PREMIUM,
|
||||
PREY_CONFIG_STATE_TIBIACOINS
|
||||
};
|
||||
enum PreyUnlockState_t : uint8_t {
|
||||
PREY_UNLOCK_STORE_AND_PREMIUM = 0,
|
||||
PREY_UNLOCK_STORE = 1,
|
||||
PREY_UNLOCK_NONE = 2,
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "container.h"
|
||||
#include "item.h"
|
||||
|
||||
Container::Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent, bool isUnlocked, bool hasPages, int containerSize, int firstIndex)
|
||||
{
|
||||
m_id = id;
|
||||
m_capacity = capacity;
|
||||
m_name = name;
|
||||
m_containerItem = containerItem;
|
||||
m_hasParent = hasParent;
|
||||
m_closed = false;
|
||||
m_unlocked = isUnlocked;
|
||||
m_hasPages = hasPages;
|
||||
m_size = containerSize;
|
||||
m_firstIndex = firstIndex;
|
||||
}
|
||||
|
||||
ItemPtr Container::getItem(int slot)
|
||||
{
|
||||
if(slot < 0 || slot >= (int)m_items.size())
|
||||
return nullptr;
|
||||
return m_items[slot];
|
||||
}
|
||||
|
||||
void Container::onOpen(const ContainerPtr& previousContainer)
|
||||
{
|
||||
callLuaField("onOpen", previousContainer);
|
||||
}
|
||||
|
||||
void Container::onClose()
|
||||
{
|
||||
m_closed = true;
|
||||
callLuaField("onClose");
|
||||
}
|
||||
|
||||
void Container::onAddItem(const ItemPtr& item, int slot)
|
||||
{
|
||||
slot -= m_firstIndex;
|
||||
|
||||
m_size++;
|
||||
// indicates that there is a new item on next page
|
||||
if(m_hasPages && slot > m_capacity) {
|
||||
callLuaField("onSizeChange", m_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if(slot == 0)
|
||||
m_items.push_front(item);
|
||||
else
|
||||
m_items.push_back(item);
|
||||
updateItemsPositions();
|
||||
|
||||
callLuaField("onSizeChange", m_size);
|
||||
callLuaField("onAddItem", slot, item);
|
||||
}
|
||||
|
||||
ItemPtr Container::findItemById(uint itemId, int subType)
|
||||
{
|
||||
for(const ItemPtr item : m_items)
|
||||
if(item->getId() == itemId && (subType == -1 || item->getSubType() == subType))
|
||||
return item;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Container::onAddItems(const std::vector<ItemPtr>& items)
|
||||
{
|
||||
for(const ItemPtr& item : items)
|
||||
m_items.push_back(item);
|
||||
updateItemsPositions();
|
||||
}
|
||||
|
||||
void Container::onUpdateItem(int slot, const ItemPtr& item)
|
||||
{
|
||||
slot -= m_firstIndex;
|
||||
if(slot < 0 || slot >= (int)m_items.size()) {
|
||||
g_logger.traceError("slot not found");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemPtr oldItem = m_items[slot];
|
||||
m_items[slot] = item;
|
||||
item->setPosition(getSlotPosition(slot));
|
||||
|
||||
callLuaField("onUpdateItem", slot, item, oldItem);
|
||||
}
|
||||
|
||||
void Container::onRemoveItem(int slot, const ItemPtr& lastItem)
|
||||
{
|
||||
slot -= m_firstIndex;
|
||||
if(m_hasPages && slot >= (int)m_items.size()) {
|
||||
m_size--;
|
||||
callLuaField("onSizeChange", m_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if(slot < 0 || slot >= (int)m_items.size()) {
|
||||
g_logger.traceError("slot not found");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemPtr item = m_items[slot];
|
||||
m_items.erase(m_items.begin() + slot);
|
||||
|
||||
|
||||
if(lastItem) {
|
||||
onAddItem(lastItem, m_firstIndex + m_capacity - 1);
|
||||
m_size--;
|
||||
}
|
||||
m_size--;
|
||||
|
||||
updateItemsPositions();
|
||||
|
||||
callLuaField("onSizeChange", m_size);
|
||||
callLuaField("onRemoveItem", slot, item);
|
||||
}
|
||||
|
||||
void Container::updateItemsPositions()
|
||||
{
|
||||
for(int slot = 0; slot < (int)m_items.size(); ++slot)
|
||||
m_items[slot]->setPosition(getSlotPosition(slot));
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CONTAINER_H
|
||||
#define CONTAINER_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "item.h"
|
||||
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
|
||||
// @bindclass
|
||||
class Container : public LuaObject
|
||||
{
|
||||
protected:
|
||||
Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent, bool isUnlocked, bool hasPages, int containerSize, int firstIndex);
|
||||
|
||||
public:
|
||||
ItemPtr getItem(int slot);
|
||||
std::deque<ItemPtr> getItems() { return m_items; }
|
||||
int getItemsCount() { return m_items.size(); }
|
||||
Position getSlotPosition(int slot) { return Position(0xffff, m_id | 0x40, slot); }
|
||||
int getId() { return m_id; }
|
||||
int getCapacity() { return m_capacity; }
|
||||
ItemPtr getContainerItem() { return m_containerItem; }
|
||||
std::string getName() { return m_name; }
|
||||
bool hasParent() { return m_hasParent; }
|
||||
bool isClosed() { return m_closed; }
|
||||
bool isUnlocked() { return m_unlocked; }
|
||||
bool hasPages() { return m_hasPages; }
|
||||
int getSize() { return m_size; }
|
||||
int getFirstIndex() { return m_firstIndex; }
|
||||
ItemPtr findItemById(uint itemId, int subType);
|
||||
|
||||
protected:
|
||||
void onOpen(const ContainerPtr& previousContainer);
|
||||
void onClose();
|
||||
void onAddItem(const ItemPtr& item, int slot);
|
||||
void onAddItems(const std::vector<ItemPtr>& items);
|
||||
void onUpdateItem(int slot, const ItemPtr& item);
|
||||
void onRemoveItem(int slot, const ItemPtr& lastItem);
|
||||
|
||||
friend class Game;
|
||||
|
||||
private:
|
||||
void updateItemsPositions();
|
||||
|
||||
int m_id;
|
||||
int m_capacity;
|
||||
ItemPtr m_containerItem;
|
||||
std::string m_name;
|
||||
bool m_hasParent;
|
||||
bool m_closed;
|
||||
bool m_unlocked;
|
||||
bool m_hasPages;
|
||||
int m_size;
|
||||
int m_firstIndex;
|
||||
std::deque<ItemPtr> m_items;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CREATURE_H
|
||||
#define CREATURE_H
|
||||
|
||||
#include "thing.h"
|
||||
#include "outfit.h"
|
||||
#include "tile.h"
|
||||
#include "mapview.h"
|
||||
#include <framework/core/scheduledevent.h>
|
||||
#include <framework/core/declarations.h>
|
||||
#include <framework/core/timer.h>
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
#include <framework/graphics/cachedtext.h>
|
||||
#include <framework/ui/uiwidget.h>
|
||||
|
||||
// @bindclass
|
||||
class Creature : public Thing
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
SHIELD_BLINK_TICKS = 500,
|
||||
VOLATILE_SQUARE_DURATION = 1000
|
||||
};
|
||||
|
||||
Creature();
|
||||
virtual ~Creature();
|
||||
|
||||
virtual void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr);
|
||||
virtual void drawOutfit(const Rect& destRect, Otc::Direction direction = Otc::InvalidDirection, const Color& color = Color::white);
|
||||
|
||||
void drawInformation(const Point& point, bool useGray, const Rect& parentRect, int drawFlags);
|
||||
|
||||
bool isInsideOffset(Point offset);
|
||||
|
||||
void setId(uint32 id) { m_id = id; }
|
||||
void setName(const std::string& name);
|
||||
void setManaPercent(int8 value) { m_manaPercent = value; }
|
||||
void setHealthPercent(uint8 healthPercent);
|
||||
void setDirection(Otc::Direction direction);
|
||||
void setOutfit(const Outfit& outfit);
|
||||
void setOutfitColor(const Color& color, int duration);
|
||||
void setLight(const Light& light) { m_light = light; }
|
||||
void setSpeed(uint16 speed);
|
||||
void setBaseSpeed(double baseSpeed);
|
||||
void setSkull(uint8 skull);
|
||||
void setShield(uint8 shield);
|
||||
void setEmblem(uint8 emblem);
|
||||
void setType(uint8 type);
|
||||
void setIcon(uint8 icon);
|
||||
void setSkullTexture(const std::string& filename);
|
||||
void setShieldTexture(const std::string& filename, bool blink);
|
||||
void setEmblemTexture(const std::string& filename);
|
||||
void setTypeTexture(const std::string& filename);
|
||||
void setIconTexture(const std::string& filename);
|
||||
void setPassable(bool passable) { m_passable = passable; }
|
||||
void setSpeedFormula(double speedA, double speedB, double speedC);
|
||||
|
||||
void addTimedSquare(uint8 color);
|
||||
void removeTimedSquare() { m_showTimedSquare = false; }
|
||||
|
||||
void showStaticSquare(const Color& color) { m_showStaticSquare = true; m_staticSquareColor = color; }
|
||||
void hideStaticSquare() { m_showStaticSquare = false; }
|
||||
|
||||
void setInformationColor(const Color& color) { m_useCustomInformationColor = true; m_informationColor = color; }
|
||||
void resetInformationColor() { m_useCustomInformationColor = false; }
|
||||
|
||||
Point getInformationOffset() { return m_informationOffset; }
|
||||
void setInformationOffset(int x, int y) { m_informationOffset = Point(x, y); }
|
||||
|
||||
void setText(const std::string& text, const Color& color);
|
||||
std::string getText();
|
||||
void clearText() { setText("", Color::white); }
|
||||
|
||||
uint32 getId() { return m_id; }
|
||||
std::string getName() { return m_name; }
|
||||
uint8 getHealthPercent() { return m_healthPercent; }
|
||||
int8 getManaPercent() { return m_manaPercent; }
|
||||
Otc::Direction getDirection() { return m_direction; }
|
||||
Otc::Direction getWalkDirection() { return m_walkDirection; }
|
||||
Outfit getOutfit() { return m_outfit; }
|
||||
Light getLight() { return m_light; }
|
||||
uint16 getSpeed() { return m_speed; }
|
||||
double getBaseSpeed() { return m_baseSpeed; }
|
||||
uint8 getSkull() { return m_skull; }
|
||||
uint8 getShield() { return m_shield; }
|
||||
uint8 getEmblem() { return m_emblem; }
|
||||
uint8 getType() { return m_type; }
|
||||
uint8 getIcon() { return m_icon; }
|
||||
bool isPassable() { return m_passable; }
|
||||
Point getDrawOffset();
|
||||
int getStepDuration(bool ignoreDiagonal = false, Otc::Direction dir = Otc::InvalidDirection);
|
||||
Point getWalkOffset(bool inNextFrame = false) { return inNextFrame ? m_walkOffsetInNextFrame : m_walkOffset; }
|
||||
Position getLastStepFromPosition() { return m_lastStepFromPosition; }
|
||||
Position getLastStepToPosition() { return m_lastStepToPosition; }
|
||||
float getStepProgress() { return m_walkTimer.ticksElapsed() / getStepDuration(); }
|
||||
int getStepTicksLeft() { return getStepDuration() - m_walkTimer.ticksElapsed(); }
|
||||
ticks_t getWalkTicksElapsed() { return m_walkTimer.ticksElapsed(); }
|
||||
double getSpeedFormula(Otc::SpeedFormula formula) { return m_speedFormula[formula]; }
|
||||
bool hasSpeedFormula();
|
||||
std::array<double, Otc::LastSpeedFormula> getSpeedFormulaArray() { return m_speedFormula; }
|
||||
virtual Point getDisplacement();
|
||||
virtual int getDisplacementX();
|
||||
virtual int getDisplacementY();
|
||||
virtual int getExactSize(int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animationPhase = 0);
|
||||
PointF getJumpOffset() { return m_jumpOffset; }
|
||||
|
||||
void updateShield();
|
||||
|
||||
// walk related
|
||||
int getWalkAnimationPhases();
|
||||
virtual void turn(Otc::Direction direction);
|
||||
void jump(int height, int duration);
|
||||
virtual void walk(const Position& oldPos, const Position& newPos);
|
||||
virtual void stopWalk();
|
||||
void allowAppearWalk(uint16_t stepSpeed) { m_allowAppearWalk = true; m_stepDuration = stepSpeed; }
|
||||
|
||||
bool isWalking() { return m_walking; }
|
||||
bool isRemoved() { return m_removed; }
|
||||
bool isInvisible() { return m_outfit.getCategory() == ThingCategoryEffect && m_outfit.getAuxId() == 13; }
|
||||
bool isDead() { return m_healthPercent <= 0; }
|
||||
bool canBeSeen() { return !isInvisible() || isPlayer(); }
|
||||
|
||||
bool isCreature() { return true; }
|
||||
bool canShoot(int distance);
|
||||
|
||||
const ThingTypePtr& getThingType();
|
||||
ThingType *rawGetThingType();
|
||||
|
||||
virtual void onPositionChange(const Position& newPos, const Position& oldPos);
|
||||
virtual void onAppear();
|
||||
virtual void onDisappear();
|
||||
virtual void onDeath();
|
||||
|
||||
virtual bool isPreWalking() { return false; }
|
||||
virtual Position getPrewalkingPosition(bool beforePrewalk = false) { return m_position; }
|
||||
|
||||
TilePtr getWalkingTileOrTile() {
|
||||
return m_walkingTile ? m_walkingTile : getTile();
|
||||
}
|
||||
|
||||
virtual bool isServerWalking() { return true; }
|
||||
|
||||
void setElevation(uint8 elevation) {
|
||||
m_elevation = elevation;
|
||||
}
|
||||
uint8 getElevation() {
|
||||
return m_elevation;
|
||||
}
|
||||
|
||||
// widgets
|
||||
void addTopWidget(const UIWidgetPtr& widget);
|
||||
void addBottomWidget(const UIWidgetPtr& widget);
|
||||
void addDirectionalWidget(const UIWidgetPtr& widget);
|
||||
void removeTopWidget(const UIWidgetPtr& widget);
|
||||
void removeBottomWidget(const UIWidgetPtr& widget);
|
||||
void removeDirectionalWidget(const UIWidgetPtr& widget);
|
||||
std::list<UIWidgetPtr> getTopWidgets();
|
||||
std::list<UIWidgetPtr> getBottomWidgets();
|
||||
std::list<UIWidgetPtr> getDirectionalWdigets();
|
||||
void clearWidgets();
|
||||
void clearTopWidgets();
|
||||
void clearBottomWidgets();
|
||||
void clearDirectionalWidgets();
|
||||
void drawTopWidgets(const Point& rect, const Otc::Direction direction);
|
||||
void drawBottomWidgets(const Point& rect, const Otc::Direction direction);
|
||||
|
||||
// progress bar
|
||||
uint8 getProgressBarPercent() { return m_progressBarPercent; }
|
||||
void setProgressBar(uint32 duration, bool ltr);
|
||||
void updateProgressBar(uint32 duration, bool ltr);
|
||||
|
||||
protected:
|
||||
virtual void updateWalkAnimation(int totalPixelsWalked);
|
||||
virtual void updateWalkOffset(int totalPixelsWalked, bool inNextFrame = false);
|
||||
void updateWalkingTile();
|
||||
virtual void nextWalkUpdate();
|
||||
virtual void updateWalk();
|
||||
virtual void terminateWalk();
|
||||
|
||||
void updateOutfitColor(Color color, Color finalColor, Color delta, int duration);
|
||||
void updateJump();
|
||||
|
||||
uint32 m_id;
|
||||
std::string m_name;
|
||||
uint8 m_healthPercent;
|
||||
int8 m_manaPercent;
|
||||
Otc::Direction m_direction;
|
||||
Otc::Direction m_walkDirection;
|
||||
Outfit m_outfit;
|
||||
Light m_light;
|
||||
int m_speed;
|
||||
double m_baseSpeed;
|
||||
uint8 m_skull;
|
||||
uint8 m_shield;
|
||||
uint8 m_emblem;
|
||||
uint8 m_type;
|
||||
uint8 m_icon;
|
||||
TexturePtr m_skullTexture;
|
||||
TexturePtr m_shieldTexture;
|
||||
TexturePtr m_emblemTexture;
|
||||
TexturePtr m_typeTexture;
|
||||
TexturePtr m_iconTexture;
|
||||
stdext::boolean<true> m_showShieldTexture;
|
||||
stdext::boolean<false> m_shieldBlink;
|
||||
stdext::boolean<false> m_passable;
|
||||
Color m_timedSquareColor;
|
||||
Color m_staticSquareColor;
|
||||
Color m_nameColor;
|
||||
stdext::boolean<false> m_showTimedSquare;
|
||||
stdext::boolean<false> m_showStaticSquare;
|
||||
stdext::boolean<true> m_removed;
|
||||
CachedText m_nameCache;
|
||||
Color m_informationColor;
|
||||
bool m_useCustomInformationColor = false;
|
||||
Point m_informationOffset;
|
||||
Color m_outfitColor;
|
||||
ScheduledEventPtr m_outfitColorUpdateEvent;
|
||||
Timer m_outfitColorTimer;
|
||||
|
||||
static std::array<double, Otc::LastSpeedFormula> m_speedFormula;
|
||||
|
||||
// walk related
|
||||
int m_walkAnimationPhase;
|
||||
int m_walkedPixels;
|
||||
uint m_footStep;
|
||||
Timer m_walkTimer;
|
||||
ticks_t m_footLastStep;
|
||||
TilePtr m_walkingTile;
|
||||
stdext::boolean<false> m_walking;
|
||||
stdext::boolean<false> m_allowAppearWalk;
|
||||
ScheduledEventPtr m_walkUpdateEvent;
|
||||
ScheduledEventPtr m_walkFinishAnimEvent;
|
||||
EventPtr m_disappearEvent;
|
||||
Point m_walkOffset;
|
||||
Point m_walkOffsetInNextFrame;
|
||||
Otc::Direction m_lastStepDirection;
|
||||
Position m_lastStepFromPosition;
|
||||
Position m_lastStepToPosition;
|
||||
Position m_oldPosition;
|
||||
uint8 m_elevation = 0;
|
||||
uint16 m_stepDuration = 0;
|
||||
|
||||
// jump related
|
||||
float m_jumpHeight = 0;
|
||||
float m_jumpDuration = 0;
|
||||
PointF m_jumpOffset;
|
||||
Timer m_jumpTimer;
|
||||
|
||||
// for bot
|
||||
StaticTextPtr m_text;
|
||||
|
||||
// widgets
|
||||
std::list<UIWidgetPtr> m_bottomWidgets;
|
||||
std::list<UIWidgetPtr> m_directionalWidgets;
|
||||
std::list<UIWidgetPtr> m_topWidgets;
|
||||
|
||||
// progress bar
|
||||
uint8 m_progressBarPercent;
|
||||
ScheduledEventPtr m_progressBarUpdateEvent;
|
||||
Timer m_progressBarTimer;
|
||||
};
|
||||
|
||||
// @bindclass
|
||||
class Npc : public Creature
|
||||
{
|
||||
public:
|
||||
bool isNpc() { return true; }
|
||||
};
|
||||
|
||||
// @bindclass
|
||||
class Monster : public Creature
|
||||
{
|
||||
public:
|
||||
bool isMonster() { return true; }
|
||||
};
|
||||
|
||||
#endif
|
@ -1,426 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "creatures.h"
|
||||
#include "creature.h"
|
||||
#include "map.h"
|
||||
|
||||
#include <framework/xml/tinyxml.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
|
||||
CreatureManager g_creatures;
|
||||
|
||||
static bool isInZone(const Position& pos/* placePos*/,
|
||||
const Position& centerPos,
|
||||
int radius)
|
||||
{
|
||||
if(radius == -1)
|
||||
return true;
|
||||
return ((pos.x >= centerPos.x - radius) && (pos.x <= centerPos.x + radius) &&
|
||||
(pos.y >= centerPos.y - radius) && (pos.y <= centerPos.y + radius)
|
||||
);
|
||||
}
|
||||
|
||||
void CreatureManager::terminate()
|
||||
{
|
||||
clearSpawns();
|
||||
clear();
|
||||
m_nullCreature = nullptr;
|
||||
}
|
||||
|
||||
void Spawn::load(TiXmlElement* node)
|
||||
{
|
||||
Position centerPos;
|
||||
centerPos.x = node->readType<int>("centerx");
|
||||
centerPos.y = node->readType<int>("centery");
|
||||
centerPos.z = node->readType<int>("centerz");
|
||||
|
||||
setCenterPos(centerPos);
|
||||
setRadius(node->readType<int32>("radius"));
|
||||
|
||||
CreatureTypePtr cType(nullptr);
|
||||
for(TiXmlElement* cNode = node->FirstChildElement(); cNode; cNode = cNode->NextSiblingElement()) {
|
||||
if(cNode->ValueStr() != "monster" && cNode->ValueStr() != "npc")
|
||||
stdext::throw_exception(stdext::format("invalid spawn-subnode %s", cNode->ValueStr()));
|
||||
|
||||
std::string cName = cNode->Attribute("name");
|
||||
stdext::tolower(cName);
|
||||
stdext::trim(cName);
|
||||
stdext::ucwords(cName);
|
||||
|
||||
if (!(cType = g_creatures.getCreatureByName(cName)))
|
||||
continue;
|
||||
|
||||
cType->setSpawnTime(cNode->readType<int>("spawntime"));
|
||||
Otc::Direction dir = Otc::North;
|
||||
int16 dir_ = cNode->readType<int16>("direction");
|
||||
if(dir_ >= Otc::East && dir_ <= Otc::West)
|
||||
dir = (Otc::Direction)dir_;
|
||||
cType->setDirection(dir);
|
||||
|
||||
Position placePos;
|
||||
placePos.x = centerPos.x + cNode->readType<int>("x");
|
||||
placePos.y = centerPos.y + cNode->readType<int>("y");
|
||||
placePos.z = cNode->readType<int>("z");
|
||||
|
||||
cType->setRace(cNode->ValueStr() == "npc" ? CreatureRaceNpc : CreatureRaceMonster);
|
||||
addCreature(placePos, cType);
|
||||
}
|
||||
}
|
||||
|
||||
void Spawn::save(TiXmlElement* node)
|
||||
{
|
||||
const Position& c = getCenterPos();
|
||||
node->SetAttribute("centerx", c.x);
|
||||
node->SetAttribute("centery", c.y);
|
||||
node->SetAttribute("centerz", c.z);
|
||||
|
||||
node->SetAttribute("radius", getRadius());
|
||||
|
||||
TiXmlElement* creatureNode = nullptr;
|
||||
|
||||
for(const auto& pair : m_creatures) {
|
||||
const CreatureTypePtr& creature = pair.second;
|
||||
if(!(creatureNode = new TiXmlElement(creature->getRace() == CreatureRaceNpc ? "npc" : "monster")))
|
||||
stdext::throw_exception("Spawn::save: Ran out of memory while allocating XML element! Terminating now.");
|
||||
|
||||
creatureNode->SetAttribute("name", creature->getName());
|
||||
creatureNode->SetAttribute("spawntime", creature->getSpawnTime());
|
||||
creatureNode->SetAttribute("direction", creature->getDirection());
|
||||
|
||||
const Position& placePos = pair.first;
|
||||
VALIDATE(placePos.isValid());
|
||||
|
||||
creatureNode->SetAttribute("x", placePos.x - c.x);
|
||||
creatureNode->SetAttribute("y", placePos.y - c.y);
|
||||
creatureNode->SetAttribute("z", placePos.z);
|
||||
|
||||
node->LinkEndChild(creatureNode);
|
||||
}
|
||||
}
|
||||
|
||||
void Spawn::addCreature(const Position& placePos, const CreatureTypePtr& cType)
|
||||
{
|
||||
const Position& centerPos = getCenterPos();
|
||||
int m_radius = getRadius();
|
||||
if(!isInZone(placePos, centerPos, m_radius)) {
|
||||
g_logger.warning(stdext::format("cannot place creature at %s (spawn's center position: %s, spawn radius: %d) (increment radius)",
|
||||
stdext::to_string(placePos), stdext::to_string(centerPos),
|
||||
m_radius
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
g_map.addThing(cType->cast(), placePos, 4);
|
||||
m_creatures.insert(std::make_pair(placePos, cType));
|
||||
}
|
||||
|
||||
void Spawn::removeCreature(const Position& pos)
|
||||
{
|
||||
auto iterator = m_creatures.find(pos);
|
||||
if(iterator != m_creatures.end()) {
|
||||
VALIDATE(iterator->first.isValid());
|
||||
VALIDATE(g_map.removeThingByPos(iterator->first, 4));
|
||||
m_creatures.erase(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CreatureTypePtr> Spawn::getCreatures()
|
||||
{
|
||||
std::vector<CreatureTypePtr> creatures;
|
||||
for (auto p : m_creatures)
|
||||
creatures.push_back(p.second);
|
||||
return creatures;
|
||||
}
|
||||
|
||||
CreaturePtr CreatureType::cast()
|
||||
{
|
||||
CreaturePtr ret(new Creature);
|
||||
|
||||
std::string cName = getName();
|
||||
stdext::tolower(cName);
|
||||
stdext::trim(cName);
|
||||
stdext::ucwords(cName);
|
||||
ret->setName(cName);
|
||||
|
||||
ret->setDirection(getDirection());
|
||||
ret->setOutfit(getOutfit());
|
||||
return ret;
|
||||
}
|
||||
|
||||
CreatureManager::CreatureManager()
|
||||
{
|
||||
m_nullCreature = CreatureTypePtr(new CreatureType);
|
||||
}
|
||||
|
||||
void CreatureManager::clearSpawns()
|
||||
{
|
||||
for(auto pair : m_spawns)
|
||||
pair.second->clear();
|
||||
m_spawns.clear();
|
||||
}
|
||||
|
||||
void CreatureManager::loadMonsters(const std::string& file)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(g_resources.readFileContents(file).c_str());
|
||||
if(doc.Error())
|
||||
stdext::throw_exception(stdext::format("cannot open monsters file '%s': '%s'", file, doc.ErrorDesc()));
|
||||
|
||||
TiXmlElement* root = doc.FirstChildElement();
|
||||
if(!root || root->ValueStr() != "monsters")
|
||||
stdext::throw_exception("malformed monsters xml file");
|
||||
|
||||
for(TiXmlElement* monster = root->FirstChildElement(); monster; monster = monster->NextSiblingElement()) {
|
||||
std::string fname = file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file");
|
||||
if(fname.substr(fname.length() - 4) != ".xml")
|
||||
fname += ".xml";
|
||||
|
||||
loadSingleCreature(fname);
|
||||
}
|
||||
|
||||
doc.Clear();
|
||||
m_loaded = true;
|
||||
}
|
||||
|
||||
void CreatureManager::loadSingleCreature(const std::string& file)
|
||||
{
|
||||
loadCreatureBuffer(g_resources.readFileContents(file));
|
||||
}
|
||||
|
||||
void CreatureManager::loadNpcs(const std::string& folder)
|
||||
{
|
||||
std::string tmp = folder;
|
||||
if(!stdext::ends_with(tmp, "/"))
|
||||
tmp += "/";
|
||||
|
||||
if(!g_resources.directoryExists(tmp))
|
||||
stdext::throw_exception(stdext::format("NPCs folder '%s' was not found.", folder));
|
||||
|
||||
const auto& fileList = g_resources.listDirectoryFiles(tmp);
|
||||
for(const std::string& file : fileList)
|
||||
loadCreatureBuffer(g_resources.readFileContents(tmp + file));
|
||||
}
|
||||
|
||||
void CreatureManager::loadSpawns(const std::string& fileName)
|
||||
{
|
||||
if(!isLoaded()) {
|
||||
g_logger.warning("creatures aren't loaded yet to load spawns.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_spawnLoaded) {
|
||||
g_logger.warning("attempt to reload spawns.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(g_resources.readFileContents(fileName).c_str());
|
||||
if(doc.Error())
|
||||
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
|
||||
|
||||
TiXmlElement* root = doc.FirstChildElement();
|
||||
if(!root || root->ValueStr() != "spawns")
|
||||
stdext::throw_exception("malformed spawns file");
|
||||
|
||||
for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
||||
if(node->ValueTStr() != "spawn")
|
||||
stdext::throw_exception("invalid spawn node");
|
||||
|
||||
SpawnPtr spawn(new Spawn);
|
||||
spawn->load(node);
|
||||
m_spawns.insert(std::make_pair(spawn->getCenterPos(), spawn));
|
||||
}
|
||||
doc.Clear();
|
||||
m_spawnLoaded = true;
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureManager::saveSpawns(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
TiXmlDocument doc;
|
||||
doc.SetTabSize(2);
|
||||
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
|
||||
doc.LinkEndChild(decl);
|
||||
|
||||
TiXmlElement* root = new TiXmlElement("spawns");
|
||||
doc.LinkEndChild(root);
|
||||
|
||||
for(auto pair : m_spawns) {
|
||||
TiXmlElement* elem = new TiXmlElement("spawn");
|
||||
pair.second->save(elem);
|
||||
root->LinkEndChild(elem);
|
||||
}
|
||||
|
||||
if(!doc.SaveFile("data"+fileName))
|
||||
stdext::throw_exception(stdext::format("failed to save spawns XML %s: %s", fileName, doc.ErrorDesc()));
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureManager::loadCreatureBuffer(const std::string& buffer)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(buffer.c_str());
|
||||
if(doc.Error())
|
||||
stdext::throw_exception(stdext::format("cannot load creature buffer: %s", doc.ErrorDesc()));
|
||||
|
||||
TiXmlElement* root = doc.FirstChildElement();
|
||||
if(!root || (root->ValueStr() != "monster" && root->ValueStr() != "npc"))
|
||||
stdext::throw_exception("invalid root tag name");
|
||||
|
||||
std::string cName = root->Attribute("name");
|
||||
stdext::tolower(cName);
|
||||
stdext::trim(cName);
|
||||
stdext::ucwords(cName);
|
||||
|
||||
CreatureTypePtr newType(new CreatureType(cName));
|
||||
for(TiXmlElement* attrib = root->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
|
||||
if(attrib->ValueStr() != "look")
|
||||
continue;
|
||||
|
||||
internalLoadCreatureBuffer(attrib, newType);
|
||||
break;
|
||||
}
|
||||
|
||||
doc.Clear();
|
||||
}
|
||||
|
||||
void CreatureManager::internalLoadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr& m)
|
||||
{
|
||||
if(std::find(m_creatures.begin(), m_creatures.end(), m) != m_creatures.end())
|
||||
return;
|
||||
|
||||
Outfit out;
|
||||
|
||||
int32 type = attrib->readType<int32>("type");
|
||||
if(type > 0) {
|
||||
out.setCategory(ThingCategoryCreature);
|
||||
out.setId(type);
|
||||
} else {
|
||||
out.setCategory(ThingCategoryItem);
|
||||
out.setAuxId(attrib->readType<int32>("typeex"));
|
||||
}
|
||||
|
||||
{
|
||||
out.setHead(attrib->readType<int>(("head")));
|
||||
out.setBody(attrib->readType<int>(("body")));
|
||||
out.setLegs(attrib->readType<int>(("legs")));
|
||||
out.setFeet(attrib->readType<int>(("feet")));
|
||||
out.setAddons(attrib->readType<int>(("addons")));
|
||||
out.setMount(attrib->readType<int>(("mount")));
|
||||
}
|
||||
|
||||
m->setOutfit(out);
|
||||
m_creatures.push_back(m);
|
||||
}
|
||||
|
||||
const CreatureTypePtr& CreatureManager::getCreatureByName(std::string name)
|
||||
{
|
||||
stdext::tolower(name);
|
||||
stdext::trim(name);
|
||||
stdext::ucwords(name);
|
||||
auto it = std::find_if(m_creatures.begin(), m_creatures.end(),
|
||||
[=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; });
|
||||
if(it != m_creatures.end())
|
||||
return *it;
|
||||
g_logger.warning(stdext::format("could not find creature with name: %s", name));
|
||||
return m_nullCreature;
|
||||
}
|
||||
|
||||
const CreatureTypePtr& CreatureManager::getCreatureByLook(int look)
|
||||
{
|
||||
auto findFun = [=] (const CreatureTypePtr& c) -> bool
|
||||
{
|
||||
const Outfit& o = c->getOutfit();
|
||||
return o.getId() == look || o.getAuxId() == look;
|
||||
};
|
||||
auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun);
|
||||
if(it != m_creatures.end())
|
||||
return *it;
|
||||
g_logger.warning(stdext::format("could not find creature with looktype: %d", look));
|
||||
return m_nullCreature;
|
||||
}
|
||||
|
||||
SpawnPtr CreatureManager::getSpawn(const Position& centerPos)
|
||||
{
|
||||
auto it = m_spawns.find(centerPos);
|
||||
if(it != m_spawns.end())
|
||||
return it->second;
|
||||
g_logger.debug(stdext::format("failed to find spawn at center %s",stdext::to_string(centerPos)));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpawnPtr CreatureManager::getSpawnForPlacePos(const Position& pos)
|
||||
{
|
||||
for (const auto& pair : m_spawns) {
|
||||
const Position& centerPos = pair.first;
|
||||
const SpawnPtr& spawn = pair.second;
|
||||
|
||||
if (isInZone(pos, centerPos, spawn->getRadius()))
|
||||
return spawn;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpawnPtr CreatureManager::addSpawn(const Position& centerPos, int radius)
|
||||
{
|
||||
auto iter = m_spawns.find(centerPos);
|
||||
if(iter != m_spawns.end()) {
|
||||
if(iter->second->getRadius() != radius)
|
||||
iter->second->setRadius(radius);
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
SpawnPtr ret(new Spawn);
|
||||
|
||||
ret->setRadius(radius);
|
||||
ret->setCenterPos(centerPos);
|
||||
|
||||
m_spawns.insert(std::make_pair(centerPos, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CreatureManager::deleteSpawn(const SpawnPtr& spawn)
|
||||
{
|
||||
const Position& centerPos = spawn->getCenterPos();
|
||||
auto it = m_spawns.find(centerPos);
|
||||
if(it != m_spawns.end())
|
||||
m_spawns.erase(it);
|
||||
}
|
||||
|
||||
std::vector<SpawnPtr> CreatureManager::getSpawns()
|
||||
{
|
||||
std::vector<SpawnPtr> spawns;
|
||||
for (auto p : m_spawns)
|
||||
spawns.push_back(p.second);
|
||||
return spawns;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et: */
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CREATURES_H
|
||||
#define CREATURES_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include "outfit.h"
|
||||
|
||||
enum CreatureAttr : uint8
|
||||
{
|
||||
CreatureAttrPosition = 0,
|
||||
CreatureAttrName = 1,
|
||||
CreatureAttrOutfit = 2,
|
||||
CreatureAttrSpawnTime = 3,
|
||||
CreatureAttrDir = 4,
|
||||
CreatureAttrRace = 5
|
||||
};
|
||||
|
||||
enum CreatureRace : uint8
|
||||
{
|
||||
CreatureRaceNpc = 0,
|
||||
CreatureRaceMonster = 1
|
||||
};
|
||||
|
||||
enum SpawnAttr : uint8
|
||||
{
|
||||
SpawnAttrRadius = 0,
|
||||
SpawnAttrCenter = 1,
|
||||
};
|
||||
|
||||
class Spawn : public LuaObject
|
||||
{
|
||||
public:
|
||||
Spawn() = default;
|
||||
Spawn(int32 radius) { setRadius(radius); }
|
||||
|
||||
void setRadius(int32 r) { m_attribs.set(SpawnAttrRadius, r) ;}
|
||||
int32 getRadius() { return m_attribs.get<int32>(SpawnAttrRadius); }
|
||||
|
||||
void setCenterPos(const Position& pos) { m_attribs.set(SpawnAttrCenter, pos); }
|
||||
Position getCenterPos() { return m_attribs.get<Position>(SpawnAttrCenter); }
|
||||
|
||||
std::vector<CreatureTypePtr> getCreatures();
|
||||
void addCreature(const Position& placePos, const CreatureTypePtr& cType);
|
||||
void removeCreature(const Position& pos);
|
||||
void clear() { m_creatures.clear(); }
|
||||
|
||||
protected:
|
||||
void load(TiXmlElement* node);
|
||||
void save(TiXmlElement* node);
|
||||
|
||||
private:
|
||||
stdext::dynamic_storage<uint8> m_attribs;
|
||||
std::unordered_map<Position, CreatureTypePtr, PositionHasher> m_creatures;
|
||||
friend class CreatureManager;
|
||||
};
|
||||
|
||||
class CreatureType : public LuaObject
|
||||
{
|
||||
public:
|
||||
CreatureType() = default;
|
||||
CreatureType(const std::string& name) { setName(name); }
|
||||
|
||||
void setSpawnTime(int32 spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); }
|
||||
int32 getSpawnTime() { return m_attribs.get<int32>(CreatureAttrSpawnTime); }
|
||||
|
||||
void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); }
|
||||
std::string getName() { return m_attribs.get<std::string>(CreatureAttrName); }
|
||||
|
||||
void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); }
|
||||
Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttrOutfit); }
|
||||
|
||||
void setDirection(Otc::Direction dir) { m_attribs.set(CreatureAttrDir, dir); }
|
||||
Otc::Direction getDirection() { return m_attribs.get<Otc::Direction>(CreatureAttrDir); }
|
||||
|
||||
void setRace(CreatureRace race) { m_attribs.set(CreatureAttrRace, race); }
|
||||
CreatureRace getRace() { return m_attribs.get<CreatureRace>(CreatureAttrRace); }
|
||||
|
||||
CreaturePtr cast();
|
||||
|
||||
private:
|
||||
stdext::dynamic_storage<uint8> m_attribs;
|
||||
};
|
||||
|
||||
class CreatureManager
|
||||
{
|
||||
public:
|
||||
CreatureManager();
|
||||
void clear() { m_creatures.clear(); }
|
||||
void clearSpawns();
|
||||
void terminate();
|
||||
|
||||
void loadMonsters(const std::string& file);
|
||||
void loadSingleCreature(const std::string& file);
|
||||
void loadNpcs(const std::string& folder);
|
||||
void loadCreatureBuffer(const std::string& buffer);
|
||||
void loadSpawns(const std::string& fileName);
|
||||
void saveSpawns(const std::string& fileName);
|
||||
|
||||
const CreatureTypePtr& getCreatureByName(std::string name);
|
||||
const CreatureTypePtr& getCreatureByLook(int look);
|
||||
|
||||
std::vector<SpawnPtr> getSpawns();
|
||||
SpawnPtr getSpawn(const Position& centerPos);
|
||||
SpawnPtr getSpawnForPlacePos(const Position& pos);
|
||||
SpawnPtr addSpawn(const Position& centerPos, int radius);
|
||||
void deleteSpawn(const SpawnPtr& spawn);
|
||||
|
||||
bool isLoaded() { return m_loaded; }
|
||||
bool isSpawnLoaded() { return m_spawnLoaded; }
|
||||
|
||||
const std::vector<CreatureTypePtr>& getCreatures() { return m_creatures; }
|
||||
|
||||
protected:
|
||||
void internalLoadCreatureBuffer(TiXmlElement* elem, const CreatureTypePtr& m);
|
||||
|
||||
private:
|
||||
std::vector<CreatureTypePtr> m_creatures;
|
||||
std::unordered_map<Position, SpawnPtr, PositionHasher> m_spawns;
|
||||
stdext::boolean<false> m_loaded, m_spawnLoaded;
|
||||
CreatureTypePtr m_nullCreature;
|
||||
};
|
||||
|
||||
extern CreatureManager g_creatures;
|
||||
|
||||
#endif
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLIENT_DECLARATIONS_H
|
||||
#define CLIENT_DECLARATIONS_H
|
||||
|
||||
#include "global.h"
|
||||
#include <framework/net/declarations.h>
|
||||
#include <framework/ui/declarations.h>
|
||||
|
||||
// core
|
||||
class Map;
|
||||
class Game;
|
||||
class MapView;
|
||||
class LightView;
|
||||
class Tile;
|
||||
class Thing;
|
||||
class Item;
|
||||
class Container;
|
||||
class Creature;
|
||||
class Monster;
|
||||
class Npc;
|
||||
class Player;
|
||||
class LocalPlayer;
|
||||
class Effect;
|
||||
class Missile;
|
||||
class AnimatedText;
|
||||
class StaticText;
|
||||
class Animator;
|
||||
class ThingType;
|
||||
class ItemType;
|
||||
class House;
|
||||
class Town;
|
||||
class CreatureType;
|
||||
class Spawn;
|
||||
class TileBlock;
|
||||
|
||||
typedef stdext::shared_object_ptr<MapView> MapViewPtr;
|
||||
typedef stdext::shared_object_ptr<LightView> LightViewPtr;
|
||||
typedef stdext::shared_object_ptr<Tile> TilePtr;
|
||||
typedef stdext::shared_object_ptr<Thing> ThingPtr;
|
||||
typedef stdext::shared_object_ptr<Item> ItemPtr;
|
||||
typedef stdext::shared_object_ptr<Container> ContainerPtr;
|
||||
typedef stdext::shared_object_ptr<Creature> CreaturePtr;
|
||||
typedef stdext::shared_object_ptr<Monster> MonsterPtr;
|
||||
typedef stdext::shared_object_ptr<Npc> NpcPtr;
|
||||
typedef stdext::shared_object_ptr<Player> PlayerPtr;
|
||||
typedef stdext::shared_object_ptr<LocalPlayer> LocalPlayerPtr;
|
||||
typedef stdext::shared_object_ptr<Effect> EffectPtr;
|
||||
typedef stdext::shared_object_ptr<Missile> MissilePtr;
|
||||
typedef stdext::shared_object_ptr<AnimatedText> AnimatedTextPtr;
|
||||
typedef stdext::shared_object_ptr<StaticText> StaticTextPtr;
|
||||
typedef stdext::shared_object_ptr<Animator> AnimatorPtr;
|
||||
typedef stdext::shared_object_ptr<ThingType> ThingTypePtr;
|
||||
typedef stdext::shared_object_ptr<ItemType> ItemTypePtr;
|
||||
typedef stdext::shared_object_ptr<House> HousePtr;
|
||||
typedef stdext::shared_object_ptr<Town> TownPtr;
|
||||
typedef stdext::shared_object_ptr<CreatureType> CreatureTypePtr;
|
||||
typedef stdext::shared_object_ptr<Spawn> SpawnPtr;
|
||||
|
||||
typedef std::vector<ThingPtr> ThingList;
|
||||
typedef std::vector<ThingTypePtr> ThingTypeList;
|
||||
typedef std::vector<ItemTypePtr> ItemTypeList;
|
||||
typedef std::list<HousePtr> HouseList;
|
||||
typedef std::list<TownPtr> TownList;
|
||||
typedef std::list<ItemPtr> ItemList;
|
||||
typedef std::list<TilePtr> TileList;
|
||||
typedef std::vector<ItemPtr> ItemVector;
|
||||
typedef std::unordered_map<Position, TilePtr, PositionHasher> TileMap;
|
||||
typedef std::unordered_map<Position, CreatureTypePtr, PositionHasher> CreatureMap;
|
||||
typedef std::unordered_map<Position, SpawnPtr, PositionHasher> SpawnMap;
|
||||
|
||||
// net
|
||||
class ProtocolLogin;
|
||||
class ProtocolGame;
|
||||
|
||||
typedef stdext::shared_object_ptr<ProtocolGame> ProtocolGamePtr;
|
||||
typedef stdext::shared_object_ptr<ProtocolLogin> ProtocolLoginPtr;
|
||||
|
||||
// ui
|
||||
class UIItem;
|
||||
class UICreature;
|
||||
class UIMap;
|
||||
class UIMinimap;
|
||||
class UIProgressRect;
|
||||
class UIMapAnchorLayout;
|
||||
class UIPositionAnchor;
|
||||
class UISprite;
|
||||
|
||||
typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
|
||||
typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
|
||||
typedef stdext::shared_object_ptr<UISprite> UISpritePtr;
|
||||
typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
|
||||
typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr;
|
||||
typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;
|
||||
typedef stdext::shared_object_ptr<UIMapAnchorLayout> UIMapAnchorLayoutPtr;
|
||||
typedef stdext::shared_object_ptr<UIPositionAnchor> UIPositionAnchorPtr;
|
||||
|
||||
#endif
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "effect.h"
|
||||
#include "map.h"
|
||||
#include "game.h"
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/util/extras.h>
|
||||
|
||||
void Effect::draw(const Point& dest, int offsetX, int offsetY, bool animate, LightView* lightView)
|
||||
{
|
||||
if(m_id == 0)
|
||||
return;
|
||||
|
||||
if(animate) {
|
||||
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
|
||||
m_animationPhase = rawGetThingType()->getAnimator()->getPhaseAt(m_animationTimer, m_animationPhase);
|
||||
} else {
|
||||
// hack to fix some animation phases duration, currently there is no better solution
|
||||
int ticks = EFFECT_TICKS_PER_FRAME;
|
||||
if (m_id == 33) {
|
||||
ticks <<= 2;
|
||||
}
|
||||
|
||||
m_animationPhase = std::min<int>((int)(m_animationTimer.ticksElapsed() / ticks), getAnimationPhases() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
int xPattern = m_position.x % getNumPatternX();
|
||||
if(xPattern < 0)
|
||||
xPattern += getNumPatternX();
|
||||
|
||||
int yPattern = m_position.y % getNumPatternY();
|
||||
if(yPattern < 0)
|
||||
yPattern += getNumPatternY();
|
||||
|
||||
rawGetThingType()->draw(dest, 0, xPattern, yPattern, 0, m_animationPhase, Color::white, lightView);
|
||||
}
|
||||
|
||||
void Effect::onAppear()
|
||||
{
|
||||
m_animationTimer.restart();
|
||||
|
||||
int duration = 0;
|
||||
if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
|
||||
duration = getThingType()->getAnimator() ? getThingType()->getAnimator()->getTotalDuration() : 1000;
|
||||
} else {
|
||||
duration = EFFECT_TICKS_PER_FRAME;
|
||||
|
||||
// hack to fix some animation phases duration, currently there is no better solution
|
||||
if(m_id == 33) {
|
||||
duration <<= 2;
|
||||
}
|
||||
|
||||
duration *= getAnimationPhases();
|
||||
}
|
||||
|
||||
// schedule removal
|
||||
auto self = asEffect();
|
||||
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, duration);
|
||||
}
|
||||
|
||||
void Effect::setId(uint32 id)
|
||||
{
|
||||
if(!g_things.isValidDatId(id, ThingCategoryEffect))
|
||||
id = 0;
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
const ThingTypePtr& Effect::getThingType()
|
||||
{
|
||||
return g_things.getThingType(m_id, ThingCategoryEffect);
|
||||
}
|
||||
|
||||
ThingType *Effect::rawGetThingType()
|
||||
{
|
||||
return g_things.rawGetThingType(m_id, ThingCategoryEffect);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef EFFECT_H
|
||||
#define EFFECT_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <framework/core/timer.h>
|
||||
#include "thing.h"
|
||||
|
||||
// @bindclass
|
||||
class Effect : public Thing
|
||||
{
|
||||
enum {
|
||||
EFFECT_TICKS_PER_FRAME = 75
|
||||
};
|
||||
|
||||
public:
|
||||
void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) override {}
|
||||
void draw(const Point& dest, int offsetX = 0, int offsetY = 0, bool animate = true, LightView* lightView = nullptr);
|
||||
|
||||
void setId(uint32 id) override;
|
||||
uint32 getId() { return m_id; }
|
||||
|
||||
EffectPtr asEffect() { return static_self_cast<Effect>(); }
|
||||
bool isEffect() { return true; }
|
||||
|
||||
const ThingTypePtr& getThingType() override;
|
||||
ThingType *rawGetThingType() override;
|
||||
|
||||
protected:
|
||||
void onAppear();
|
||||
|
||||
private:
|
||||
uint16 m_id;
|
||||
Timer m_animationTimer;
|
||||
int m_animationPhase = 0;
|
||||
};
|
||||
|
||||
#endif
|
1648
src/client/game.cpp
1648
src/client/game.cpp
File diff suppressed because it is too large
Load Diff
@ -1,477 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "item.h"
|
||||
#include "animatedtext.h"
|
||||
#include "effect.h"
|
||||
#include "creature.h"
|
||||
#include "container.h"
|
||||
#include "protocolgame.h"
|
||||
#include "localplayer.h"
|
||||
#include "outfit.h"
|
||||
#include <framework/core/timer.h>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
struct UnjustifiedPoints {
|
||||
bool operator==(const UnjustifiedPoints& other) {
|
||||
return killsDay == other.killsDay &&
|
||||
killsDayRemaining == other.killsDayRemaining &&
|
||||
killsWeek == other.killsWeek &&
|
||||
killsWeekRemaining == other.killsWeekRemaining &&
|
||||
killsMonth == other.killsMonth &&
|
||||
killsMonthRemaining == other.killsMonthRemaining &&
|
||||
skullTime == other.skullTime;
|
||||
}
|
||||
uint8 killsDay;
|
||||
uint8 killsDayRemaining;
|
||||
uint8 killsWeek;
|
||||
uint8 killsWeekRemaining;
|
||||
uint8 killsMonth;
|
||||
uint8 killsMonthRemaining;
|
||||
uint8 skullTime;
|
||||
};
|
||||
|
||||
typedef std::tuple<std::string, uint, std::string, int, bool> Vip;
|
||||
|
||||
//@bindsingleton g_game
|
||||
class Game
|
||||
{
|
||||
public:
|
||||
Game();
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
private:
|
||||
void resetGameStates();
|
||||
|
||||
protected:
|
||||
void processConnectionError(const boost::system::error_code& error);
|
||||
void processDisconnect();
|
||||
void processPing();
|
||||
void processPingBack();
|
||||
void processNewPing(uint32_t pingId);
|
||||
|
||||
void processUpdateNeeded(const std::string& signature);
|
||||
void processLoginError(const std::string& error);
|
||||
void processLoginAdvice(const std::string& message);
|
||||
void processLoginWait(const std::string& message, int time);
|
||||
void processLoginToken(bool unknown);
|
||||
void processLogin();
|
||||
void processPendingGame();
|
||||
void processEnterGame();
|
||||
|
||||
void processGameStart();
|
||||
void processGameEnd();
|
||||
void processDeath(int deathType, int penality);
|
||||
|
||||
void processGMActions(const std::vector<uint8>& actions);
|
||||
void processInventoryChange(int slot, const ItemPtr& item);
|
||||
void processAttackCancel(uint seq);
|
||||
void processWalkCancel(Otc::Direction direction);
|
||||
|
||||
void processNewWalkCancel(Otc::Direction dir);
|
||||
void processPredictiveWalkCancel(const Position& pos, Otc::Direction dir);
|
||||
void processWalkId(uint32_t walkId);
|
||||
|
||||
void processPlayerHelpers(int helpers);
|
||||
void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode);
|
||||
|
||||
// message related
|
||||
void processTextMessage(Otc::MessageMode mode, const std::string& text);
|
||||
void processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos);
|
||||
|
||||
// container related
|
||||
void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex);
|
||||
void processCloseContainer(int containerId);
|
||||
void processContainerAddItem(int containerId, const ItemPtr& item, int slot);
|
||||
void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);
|
||||
void processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem);
|
||||
|
||||
// channel related
|
||||
void processChannelList(const std::vector<std::tuple<int, std::string> >& channelList);
|
||||
void processOpenChannel(int channelId, const std::string& name);
|
||||
void processOpenPrivateChannel(const std::string& name);
|
||||
void processOpenOwnPrivateChannel(int channelId, const std::string& name);
|
||||
void processCloseChannel(int channelId);
|
||||
|
||||
// rule violations
|
||||
void processRuleViolationChannel(int channelId);
|
||||
void processRuleViolationRemove(const std::string& name);
|
||||
void processRuleViolationCancel(const std::string& name);
|
||||
void processRuleViolationLock();
|
||||
|
||||
// vip related
|
||||
void processVipAdd(uint id, const std::string& name, uint status, const std::string& description, int iconId, bool notifyLogin);
|
||||
void processVipStateChange(uint id, uint status);
|
||||
|
||||
// tutorial hint
|
||||
void processTutorialHint(int id);
|
||||
void processAddAutomapFlag(const Position& pos, int icon, const std::string& message);
|
||||
void processRemoveAutomapFlag(const Position& pos, int icon, const std::string& message);
|
||||
|
||||
// outfit
|
||||
void processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector<std::tuple<int, std::string, int> >& outfitList,
|
||||
const std::vector<std::tuple<int, std::string> >& mountList);
|
||||
|
||||
// npc trade
|
||||
void processOpenNpcTrade(const std::vector<std::tuple<ItemPtr, std::string, int, int64_t, int64_t> >& items);
|
||||
void processPlayerGoods(uint64_t money, const std::vector<std::tuple<ItemPtr, int> >& goods);
|
||||
void processCloseNpcTrade();
|
||||
|
||||
// player trade
|
||||
void processOwnTrade(const std::string& name, const std::vector<ItemPtr>& items);
|
||||
void processCounterTrade(const std::string& name, const std::vector<ItemPtr>& items);
|
||||
void processCloseTrade();
|
||||
|
||||
// edit text/list
|
||||
void processEditText(uint id, int itemId, int maxLength, const std::string& text, const std::string& writer, const std::string& date);
|
||||
void processEditList(uint id, int doorId, const std::string& text);
|
||||
|
||||
// questlog
|
||||
void processQuestLog(const std::vector<std::tuple<int, std::string, bool> >& questList);
|
||||
void processQuestLine(int questId, const std::vector<std::tuple<std::string, std::string> >& questMissions);
|
||||
|
||||
// modal dialogs >= 970
|
||||
void processModalDialog(uint32 id, std::string title, std::string message, std::vector<std::tuple<int, std::string> > buttonList, int enterButton, int escapeButton, std::vector<std::tuple<int, std::string> > choiceList, bool priority);
|
||||
|
||||
friend class ProtocolGame;
|
||||
friend class Map;
|
||||
|
||||
public:
|
||||
// login related
|
||||
void loginWorld(const std::string& account, const std::string& password, const std::string& worldName, const std::string& worldHost, int worldPort, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey);
|
||||
void cancelLogin();
|
||||
void forceLogout();
|
||||
void safeLogout();
|
||||
|
||||
// walk related
|
||||
void walk(Otc::Direction direction, bool withPreWalk);
|
||||
void autoWalk(const std::vector<Otc::Direction>& dirs, Position startPos);
|
||||
void turn(Otc::Direction direction);
|
||||
void stop();
|
||||
|
||||
// item related
|
||||
void look(const ThingPtr& thing, bool isBattleList = false);
|
||||
void move(const ThingPtr& thing, const Position& toPos, int count);
|
||||
void moveRaw(const Position& pos, int id, int stackpos, const Position& toPos, int count);
|
||||
void moveToParentContainer(const ThingPtr& thing, int count);
|
||||
void rotate(const ThingPtr& thing);
|
||||
void wrap(const ThingPtr& thing);
|
||||
void use(const ThingPtr& thing);
|
||||
void useWith(const ItemPtr& fromThing, const ThingPtr& toThing, int subType = 0);
|
||||
void useInventoryItem(int itemId, int subType = 0);
|
||||
void useInventoryItemWith(int itemId, const ThingPtr& toThing, int subType = 0);
|
||||
ItemPtr findItemInContainers(uint itemId, int subType);
|
||||
|
||||
// container related
|
||||
int open(const ItemPtr& item, const ContainerPtr& previousContainer);
|
||||
void openParent(const ContainerPtr& container);
|
||||
void close(const ContainerPtr& container);
|
||||
void refreshContainer(const ContainerPtr& container);
|
||||
|
||||
// attack/follow related
|
||||
void attack(CreaturePtr creature, bool cancel = false);
|
||||
void cancelAttack() { attack(nullptr, true); }
|
||||
void follow(CreaturePtr creature);
|
||||
void cancelFollow() { follow(nullptr); }
|
||||
void cancelAttackAndFollow();
|
||||
|
||||
// talk related
|
||||
void talk(const std::string& message);
|
||||
void talkChannel(Otc::MessageMode mode, int channelId, const std::string& message);
|
||||
void talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message);
|
||||
|
||||
// channel related
|
||||
void openPrivateChannel(const std::string& receiver);
|
||||
void requestChannels();
|
||||
void joinChannel(int channelId);
|
||||
void leaveChannel(int channelId);
|
||||
void closeNpcChannel();
|
||||
void openOwnChannel();
|
||||
void inviteToOwnChannel(const std::string& name);
|
||||
void excludeFromOwnChannel(const std::string& name);
|
||||
|
||||
// party related
|
||||
void partyInvite(int creatureId);
|
||||
void partyJoin(int creatureId);
|
||||
void partyRevokeInvitation(int creatureId);
|
||||
void partyPassLeadership(int creatureId);
|
||||
void partyLeave();
|
||||
void partyShareExperience(bool active);
|
||||
|
||||
// outfit related
|
||||
void requestOutfit();
|
||||
void changeOutfit(const Outfit& outfit);
|
||||
|
||||
// vip related
|
||||
void addVip(const std::string& name);
|
||||
void removeVip(int playerId);
|
||||
void editVip(int playerId, const std::string& description, int iconId, bool notifyLogin);
|
||||
|
||||
// fight modes related
|
||||
void setChaseMode(Otc::ChaseModes chaseMode);
|
||||
void setFightMode(Otc::FightModes fightMode);
|
||||
void setSafeFight(bool on);
|
||||
void setPVPMode(Otc::PVPModes pvpMode);
|
||||
Otc::ChaseModes getChaseMode() { return m_chaseMode; }
|
||||
Otc::FightModes getFightMode() { return m_fightMode; }
|
||||
bool isSafeFight() { return m_safeFight; }
|
||||
Otc::PVPModes getPVPMode() { return m_pvpMode; }
|
||||
|
||||
// pvp related
|
||||
void setUnjustifiedPoints(UnjustifiedPoints unjustifiedPoints);
|
||||
UnjustifiedPoints getUnjustifiedPoints() { return m_unjustifiedPoints; };
|
||||
void setOpenPvpSituations(int openPvpSitations);
|
||||
int getOpenPvpSituations() { return m_openPvpSituations; }
|
||||
|
||||
// npc trade related
|
||||
void inspectNpcTrade(const ItemPtr& item);
|
||||
void buyItem(const ItemPtr& item, int amount, bool ignoreCapacity, bool buyWithBackpack);
|
||||
void sellItem(const ItemPtr& item, int amount, bool ignoreEquipped);
|
||||
void closeNpcTrade();
|
||||
|
||||
// player trade related
|
||||
void requestTrade(const ItemPtr& item, const CreaturePtr& creature);
|
||||
void inspectTrade(bool counterOffer, int index);
|
||||
void acceptTrade();
|
||||
void rejectTrade();
|
||||
|
||||
// house window and editable items related
|
||||
void editText(uint id, const std::string& text);
|
||||
void editList(uint id, int doorId, const std::string& text);
|
||||
|
||||
// rule violations (only gms)
|
||||
void openRuleViolation(const std::string& reporter);
|
||||
void closeRuleViolation(const std::string& reporter);
|
||||
void cancelRuleViolation();
|
||||
|
||||
// reports
|
||||
void reportBug(const std::string& comment);
|
||||
void reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment);
|
||||
void debugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d);
|
||||
|
||||
// questlog related
|
||||
void requestQuestLog();
|
||||
void requestQuestLine(int questId);
|
||||
|
||||
// 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);
|
||||
|
||||
// >= 970 modal dialog
|
||||
void answerModalDialog(uint32 dialog, int button, int choice);
|
||||
|
||||
// >= 984 browse field
|
||||
void browseField(const Position& position);
|
||||
void seekInContainer(int cid, int index);
|
||||
|
||||
// >= 1080 ingame store
|
||||
void buyStoreOffer(int offerId, int productType, const std::string& name = "");
|
||||
void requestTransactionHistory(int page, int entriesPerPage);
|
||||
void requestStoreOffers(const std::string& categoryName, int serviceType = 0);
|
||||
void openStore(int serviceType = 0);
|
||||
void transferCoins(const std::string& recipient, int amount);
|
||||
void openTransactionHistory(int entriesPerPage);
|
||||
|
||||
// >= 1100
|
||||
void preyAction(int slot, int actionType, int index);
|
||||
void preyRequest();
|
||||
|
||||
void applyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm);
|
||||
void clearImbuement(uint8_t slot);
|
||||
void closeImbuingWindow();
|
||||
|
||||
//void reportRuleViolation2();
|
||||
void ping();
|
||||
void newPing();
|
||||
void setPingDelay(int delay) { m_pingDelay = delay; }
|
||||
|
||||
// otclient only
|
||||
void changeMapAwareRange(int xrange, int yrange);
|
||||
|
||||
// dynamic support for game features
|
||||
void resetFeatures() { m_features.reset(); }
|
||||
void enableFeature(Otc::GameFeature feature) { m_features.set(feature, true); }
|
||||
void disableFeature(Otc::GameFeature feature) { m_features.set(feature, false); }
|
||||
void setFeature(Otc::GameFeature feature, bool enabled) { m_features.set(feature, enabled); }
|
||||
bool getFeature(Otc::GameFeature feature) { return m_features.test(feature); }
|
||||
|
||||
void setProtocolVersion(int version);
|
||||
int getProtocolVersion() { return m_protocolVersion; }
|
||||
void setCustomProtocolVersion(int version) { m_customProtocolVersion = version; }
|
||||
int getCustomProtocolVersion() { return m_customProtocolVersion != 0 ? m_customProtocolVersion : m_protocolVersion; }
|
||||
|
||||
void setClientVersion(int version);
|
||||
int getClientVersion() { return m_clientVersion; }
|
||||
|
||||
void setCustomOs(int os) { m_clientCustomOs = os; }
|
||||
int getOs();
|
||||
|
||||
bool canPerformGameAction();
|
||||
bool checkBotProtection();
|
||||
|
||||
bool isOnline() { return m_online; }
|
||||
bool isLogging() { return !m_online && m_protocolGame; }
|
||||
bool isDead() { return m_dead; }
|
||||
bool isAttacking() { return !!m_attackingCreature && !m_attackingCreature->isRemoved(); }
|
||||
bool isFollowing() { return !!m_followingCreature && !m_followingCreature->isRemoved(); }
|
||||
bool isConnectionOk() { return m_protocolGame && m_protocolGame->getElapsedTicksSinceLastRead() < 5000; }
|
||||
|
||||
int getPing() { return m_ping; }
|
||||
ContainerPtr getContainer(int index) { if (m_containers.find(index) == m_containers.end()) { return nullptr; } return m_containers[index]; }
|
||||
std::map<int, ContainerPtr> getContainers() { return m_containers; }
|
||||
std::map<int, Vip> getVips() { return m_vips; }
|
||||
CreaturePtr getAttackingCreature() { return m_attackingCreature; }
|
||||
CreaturePtr getFollowingCreature() { return m_followingCreature; }
|
||||
void setServerBeat(int beat) { m_serverBeat = beat; }
|
||||
int getServerBeat() { return m_serverBeat; }
|
||||
void setCanReportBugs(bool enable) { m_canReportBugs = enable; }
|
||||
bool canReportBugs() { return m_canReportBugs; }
|
||||
void setExpertPvpMode(bool enable) { m_expertPvpMode = enable; }
|
||||
bool getExpertPvpMode() { return m_expertPvpMode; }
|
||||
LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }
|
||||
ProtocolGamePtr getProtocolGame() { return m_protocolGame; }
|
||||
std::string getCharacterName() { return m_characterName; }
|
||||
std::string getWorldName() { return m_worldName; }
|
||||
std::vector<uint8> getGMActions() { return m_gmActions; }
|
||||
bool isGM() { return m_gmActions.size() > 0; }
|
||||
Otc::Direction getLastWalkDir() { return m_lastWalkDir; }
|
||||
|
||||
std::string formatCreatureName(const std::string &name);
|
||||
int findEmptyContainerId();
|
||||
|
||||
void setTibiaCoins(int coins, int transferableCoins)
|
||||
{
|
||||
m_coins = coins;
|
||||
m_transferableCoins = transferableCoins;
|
||||
}
|
||||
int getTibiaCoins()
|
||||
{
|
||||
return m_coins;
|
||||
}
|
||||
int getTransferableTibiaCoins()
|
||||
{
|
||||
return m_transferableCoins;
|
||||
}
|
||||
|
||||
void setMaxPreWalkingSteps(uint value) { m_maxPreWalkingSteps = value; }
|
||||
uint getMaxPreWalkingSteps() { return m_maxPreWalkingSteps; }
|
||||
|
||||
void showRealDirection(bool value) { m_showRealDirection = value; }
|
||||
bool shouldShowingRealDirection() { return m_showRealDirection; }
|
||||
|
||||
uint getWalkId() { return m_walkId; }
|
||||
uint getWalkPreditionId() { return m_walkPrediction; }
|
||||
|
||||
void ignoreServerDirection(bool value) { m_ignoreServerDirection = value; }
|
||||
bool isIgnoringServerDirection()
|
||||
{
|
||||
return m_ignoreServerDirection;
|
||||
}
|
||||
|
||||
void enableTileThingLuaCallback(bool value) { m_tileThingsLuaCallback = value; }
|
||||
bool isTileThingLuaCallbackEnabled() { return m_tileThingsLuaCallback; }
|
||||
|
||||
int getRecivedPacketsCount()
|
||||
{
|
||||
return m_protocolGame ? m_protocolGame->getRecivedPacketsCount() : 0;
|
||||
}
|
||||
|
||||
int getRecivedPacketsSize()
|
||||
{
|
||||
return m_protocolGame ? m_protocolGame->getRecivedPacketsSize() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
void enableBotCall() { m_denyBotCall = false; }
|
||||
void disableBotCall() { m_denyBotCall = true; }
|
||||
|
||||
private:
|
||||
void setAttackingCreature(const CreaturePtr& creature);
|
||||
void setFollowingCreature(const CreaturePtr& creature);
|
||||
|
||||
LocalPlayerPtr m_localPlayer;
|
||||
CreaturePtr m_attackingCreature;
|
||||
CreaturePtr m_followingCreature;
|
||||
ProtocolGamePtr m_protocolGame;
|
||||
std::map<int, ContainerPtr> m_containers;
|
||||
std::map<int, Vip> m_vips;
|
||||
|
||||
bool m_online;
|
||||
bool m_denyBotCall;
|
||||
bool m_dead;
|
||||
bool m_expertPvpMode;
|
||||
int m_serverBeat;
|
||||
ticks_t m_ping;
|
||||
uint m_pingSent;
|
||||
uint m_pingReceived;
|
||||
uint m_walkId = 0;
|
||||
uint m_walkPrediction = 0;
|
||||
uint m_maxPreWalkingSteps = 2;
|
||||
stdext::timer m_pingTimer;
|
||||
std::map<uint32_t, stdext::timer> m_newPingIds;
|
||||
uint m_seq;
|
||||
int m_pingDelay;
|
||||
int m_newPingDelay;
|
||||
Otc::FightModes m_fightMode;
|
||||
Otc::ChaseModes m_chaseMode;
|
||||
Otc::PVPModes m_pvpMode;
|
||||
Otc::Direction m_lastWalkDir;
|
||||
bool m_waitingForAnotherDir = false;
|
||||
UnjustifiedPoints m_unjustifiedPoints;
|
||||
int m_openPvpSituations;
|
||||
bool m_safeFight;
|
||||
bool m_canReportBugs;
|
||||
std::vector<uint8> m_gmActions;
|
||||
std::string m_characterName;
|
||||
std::string m_worldName;
|
||||
std::bitset<Otc::LastGameFeature> m_features;
|
||||
ScheduledEventPtr m_pingEvent;
|
||||
ScheduledEventPtr m_newPingEvent;
|
||||
ScheduledEventPtr m_checkConnectionEvent;
|
||||
bool m_connectionFailWarned;
|
||||
int m_protocolVersion;
|
||||
int m_customProtocolVersion = 0;
|
||||
int m_clientVersion;
|
||||
std::string m_clientSignature;
|
||||
int m_clientCustomOs;
|
||||
int m_coins;
|
||||
int m_transferableCoins;
|
||||
|
||||
bool m_showRealDirection = false;
|
||||
bool m_ignoreServerDirection = true;
|
||||
bool m_tileThingsLuaCallback = false;
|
||||
};
|
||||
|
||||
extern Game g_game;
|
||||
|
||||
#endif
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLIENT_GLOBAL_H
|
||||
#define CLIENT_GLOBAL_H
|
||||
|
||||
#include <framework/global.h>
|
||||
|
||||
// widely used headers
|
||||
#include "const.h"
|
||||
#include "position.h"
|
||||
|
||||
#endif
|
@ -1,210 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "map.h"
|
||||
|
||||
#include <framework/core/resourcemanager.h>
|
||||
|
||||
HouseManager g_houses;
|
||||
|
||||
House::House()
|
||||
{
|
||||
}
|
||||
|
||||
House::House(uint32 hId, const std::string &name, const Position &pos)
|
||||
{
|
||||
setId(hId);
|
||||
setName(name);
|
||||
if(pos.isValid())
|
||||
setEntry(pos);
|
||||
}
|
||||
|
||||
void House::setTile(const TilePtr& tile)
|
||||
{
|
||||
tile->setFlag(TILESTATE_HOUSE);
|
||||
tile->setHouseId(getId());
|
||||
m_tiles.insert(std::make_pair(tile->getPosition(), tile));
|
||||
}
|
||||
|
||||
TilePtr House::getTile(const Position& position)
|
||||
{
|
||||
TileMap::const_iterator iter = m_tiles.find(position);
|
||||
if(iter != m_tiles.end())
|
||||
return iter->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void House::addDoor(const ItemPtr& door)
|
||||
{
|
||||
if (!door) return;
|
||||
door->setDoorId(m_lastDoorId);
|
||||
m_doors[m_lastDoorId++] = door;
|
||||
}
|
||||
|
||||
void House::removeDoorById(uint32 doorId)
|
||||
{
|
||||
if(doorId >= m_lastDoorId)
|
||||
stdext::throw_exception(stdext::format("Failed to remove door of id %d (would overflow), max id: %d",
|
||||
doorId, m_lastDoorId));
|
||||
m_doors[doorId] = nullptr;
|
||||
}
|
||||
|
||||
void House::load(const TiXmlElement *elem)
|
||||
{
|
||||
std::string name = elem->Attribute("name");
|
||||
if(name.empty())
|
||||
name = stdext::format("Unnamed house #%lu", getId());
|
||||
|
||||
setName(name);
|
||||
setRent(elem->readType<uint32>("rent"));
|
||||
setSize(elem->readType<uint32>("size"));
|
||||
setTownId(elem->readType<uint32>("townid"));
|
||||
m_isGuildHall = elem->readType<bool>("guildhall");
|
||||
|
||||
Position entryPos;
|
||||
entryPos.x = elem->readType<int>("entryx");
|
||||
entryPos.y = elem->readType<int>("entryy");
|
||||
entryPos.z = elem->readType<int>("entryz");
|
||||
setEntry(entryPos);
|
||||
}
|
||||
|
||||
void House::save(TiXmlElement* elem)
|
||||
{
|
||||
elem->SetAttribute("name", getName());
|
||||
elem->SetAttribute("houseid", getId());
|
||||
|
||||
Position entry = getEntry();
|
||||
elem->SetAttribute("entryx", entry.x);
|
||||
elem->SetAttribute("entryy", entry.y);
|
||||
elem->SetAttribute("entryz", entry.z);
|
||||
|
||||
elem->SetAttribute("rent", getRent());
|
||||
elem->SetAttribute("townid", getTownId());
|
||||
elem->SetAttribute("size", getSize());
|
||||
elem->SetAttribute("guildhall", (int)m_isGuildHall);
|
||||
}
|
||||
|
||||
HouseManager::HouseManager()
|
||||
{
|
||||
}
|
||||
|
||||
void HouseManager::addHouse(const HousePtr& house)
|
||||
{
|
||||
if(findHouse(house->getId()) == m_houses.end())
|
||||
m_houses.push_back(house);
|
||||
}
|
||||
|
||||
void HouseManager::removeHouse(uint32 houseId)
|
||||
{
|
||||
auto it = findHouse(houseId);
|
||||
if(it != m_houses.end())
|
||||
m_houses.erase(it);
|
||||
}
|
||||
|
||||
HousePtr HouseManager::getHouse(uint32 houseId)
|
||||
{
|
||||
auto it = findHouse(houseId);
|
||||
return it != m_houses.end() ? *it : nullptr;
|
||||
}
|
||||
|
||||
HousePtr HouseManager::getHouseByName(std::string name)
|
||||
{
|
||||
auto it = std::find_if(m_houses.begin(), m_houses.end(),
|
||||
[=] (const HousePtr& house) -> bool { return house->getName() == name; });
|
||||
return it != m_houses.end() ? *it : nullptr;
|
||||
}
|
||||
|
||||
void HouseManager::load(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(g_resources.readFileContents(fileName).c_str());
|
||||
if(doc.Error())
|
||||
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
|
||||
|
||||
TiXmlElement *root = doc.FirstChildElement();
|
||||
if(!root || root->ValueTStr() != "houses")
|
||||
stdext::throw_exception("invalid root tag name");
|
||||
|
||||
for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
|
||||
if(elem->ValueTStr() != "house")
|
||||
stdext::throw_exception("invalid house tag.");
|
||||
|
||||
uint32 houseId = elem->readType<uint32>("houseid");
|
||||
HousePtr house = getHouse(houseId);
|
||||
if(!house)
|
||||
house = HousePtr(new House(houseId)), addHouse(house);
|
||||
|
||||
house->load(elem);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
|
||||
}
|
||||
sort();
|
||||
}
|
||||
|
||||
void HouseManager::save(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
TiXmlDocument doc;
|
||||
doc.SetTabSize(2);
|
||||
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
|
||||
doc.LinkEndChild(decl);
|
||||
|
||||
TiXmlElement* root = new TiXmlElement("houses");
|
||||
doc.LinkEndChild(root);
|
||||
|
||||
for(auto house : m_houses) {
|
||||
TiXmlElement *elem = new TiXmlElement("house");
|
||||
house->save(elem);
|
||||
root->LinkEndChild(elem);
|
||||
}
|
||||
|
||||
if(!doc.SaveFile("data"+fileName))
|
||||
stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc()));
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
HouseList HouseManager::filterHouses(uint32 townId)
|
||||
{
|
||||
HouseList ret;
|
||||
for(const HousePtr& house : m_houses)
|
||||
if(house->getTownId() == townId)
|
||||
ret.push_back(house);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HouseList::iterator HouseManager::findHouse(uint32 houseId)
|
||||
{
|
||||
return std::find_if(m_houses.begin(), m_houses.end(),
|
||||
[=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
|
||||
}
|
||||
|
||||
void HouseManager::sort()
|
||||
{
|
||||
m_houses.sort([] (const HousePtr& lhs, const HousePtr& rhs) { return lhs->getName() < rhs->getName(); });
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et: */
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HOUSES_H
|
||||
#define HOUSES_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "tile.h"
|
||||
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
|
||||
enum HouseAttr : uint8
|
||||
{
|
||||
HouseAttrId,
|
||||
HouseAttrName,
|
||||
HouseAttrTown,
|
||||
HouseAttrEntry,
|
||||
HouseAttrSize,
|
||||
HouseAttrRent
|
||||
};
|
||||
|
||||
class House : public LuaObject
|
||||
{
|
||||
public:
|
||||
House();
|
||||
House(uint32 hId, const std::string& name = "", const Position& pos=Position());
|
||||
~House() { m_tiles.clear(); }
|
||||
|
||||
void setTile(const TilePtr& tile);
|
||||
TilePtr getTile(const Position& pos);
|
||||
|
||||
void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); }
|
||||
std::string getName() { return m_attribs.get<std::string>(HouseAttrName); }
|
||||
|
||||
void setId(uint32 hId) { m_attribs.set(HouseAttrId, hId); }
|
||||
uint32 getId() { return m_attribs.get<uint32>(HouseAttrId); }
|
||||
|
||||
void setTownId(uint32 tid) { m_attribs.set(HouseAttrTown, tid); }
|
||||
uint32 getTownId() { return m_attribs.get<uint32>(HouseAttrTown); }
|
||||
|
||||
void setSize(uint32 s) { m_attribs.set(HouseAttrSize, s); }
|
||||
uint32 getSize() { return m_attribs.get<uint32>(HouseAttrSize); }
|
||||
|
||||
void setRent(uint32 r) { m_attribs.set(HouseAttrRent, r); }
|
||||
uint32 getRent() { return m_attribs.get<uint32>(HouseAttrRent); }
|
||||
|
||||
void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); }
|
||||
Position getEntry() { return m_attribs.get<Position>(HouseAttrEntry); }
|
||||
|
||||
void addDoor(const ItemPtr& door);
|
||||
void removeDoor(const ItemPtr& door) { removeDoorById(door->getDoorId()); }
|
||||
void removeDoorById(uint32 doorId);
|
||||
|
||||
protected:
|
||||
void load(const TiXmlElement* elem);
|
||||
void save(TiXmlElement* elem);
|
||||
|
||||
private:
|
||||
stdext::packed_storage<uint8> m_attribs;
|
||||
TileMap m_tiles;
|
||||
ItemVector m_doors;
|
||||
uint32 m_lastDoorId;
|
||||
stdext::boolean<false> m_isGuildHall;
|
||||
|
||||
friend class HouseManager;
|
||||
};
|
||||
|
||||
class HouseManager {
|
||||
public:
|
||||
HouseManager();
|
||||
|
||||
void addHouse(const HousePtr& house);
|
||||
void removeHouse(uint32 houseId);
|
||||
HousePtr getHouse(uint32 houseId);
|
||||
HousePtr getHouseByName(std::string name);
|
||||
|
||||
void load(const std::string& fileName);
|
||||
void save(const std::string& fileName);
|
||||
|
||||
void sort();
|
||||
void clear() { m_houses.clear(); }
|
||||
HouseList getHouseList() { return m_houses; }
|
||||
HouseList filterHouses(uint32 townId);
|
||||
|
||||
private:
|
||||
HouseList m_houses;
|
||||
|
||||
protected:
|
||||
HouseList::iterator findHouse(uint32 houseId);
|
||||
};
|
||||
|
||||
extern HouseManager g_houses;
|
||||
|
||||
#endif
|
@ -1,440 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "item.h"
|
||||
#include "thingtypemanager.h"
|
||||
#include "spritemanager.h"
|
||||
#include "thing.h"
|
||||
#include "tile.h"
|
||||
#include "shadermanager.h"
|
||||
#include "container.h"
|
||||
#include "map.h"
|
||||
#include "houses.h"
|
||||
#include "game.h"
|
||||
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/core/binarytree.h>
|
||||
|
||||
#include <framework/util/stats.h>
|
||||
|
||||
Item::Item() :
|
||||
m_clientId(0),
|
||||
m_serverId(0),
|
||||
m_countOrSubType(1),
|
||||
m_color(Color::alpha),
|
||||
m_async(true),
|
||||
m_phase(0),
|
||||
m_lastPhase(0)
|
||||
{
|
||||
}
|
||||
|
||||
ItemPtr Item::create(int id, int countOrSubtype)
|
||||
{
|
||||
ItemPtr item(new Item);
|
||||
item->setId(id);
|
||||
item->setCountOrSubType(countOrSubtype);
|
||||
return item;
|
||||
}
|
||||
|
||||
ItemPtr Item::createFromOtb(int id)
|
||||
{
|
||||
ItemPtr item(new Item);
|
||||
item->setOtbId(id);
|
||||
return item;
|
||||
}
|
||||
|
||||
std::string Item::getName()
|
||||
{
|
||||
return g_things.findItemTypeByClientId(m_clientId)->getName();
|
||||
}
|
||||
|
||||
void Item::draw(const Point& dest, bool animate, LightView* lightView)
|
||||
{
|
||||
if (m_clientId == 0)
|
||||
return;
|
||||
|
||||
// determine animation phase
|
||||
int animationPhase = calculateAnimationPhase(animate);
|
||||
|
||||
// determine x,y,z patterns
|
||||
int xPattern = 0, yPattern = 0, zPattern = 0;
|
||||
calculatePatterns(xPattern, yPattern, zPattern);
|
||||
|
||||
Color color(Color::white);
|
||||
if (m_color != Color::alpha)
|
||||
color = m_color;
|
||||
size_t drawQueueSize = g_drawQueue->size();
|
||||
rawGetThingType()->draw(dest, 0, xPattern, yPattern, zPattern, animationPhase, color, lightView);
|
||||
if (m_marked) {
|
||||
g_drawQueue->setMark(drawQueueSize, updatedMarkedColor());
|
||||
}
|
||||
}
|
||||
|
||||
void Item::draw(const Rect& dest, bool animate)
|
||||
{
|
||||
if (m_clientId == 0)
|
||||
return;
|
||||
|
||||
// determine animation phase
|
||||
int animationPhase = calculateAnimationPhase(animate);
|
||||
|
||||
// determine x,y,z patterns
|
||||
int xPattern = 0, yPattern = 0, zPattern = 0;
|
||||
calculatePatterns(xPattern, yPattern, zPattern);
|
||||
|
||||
Color color(Color::white);
|
||||
if (m_color != Color::alpha)
|
||||
color = m_color;
|
||||
|
||||
rawGetThingType()->draw(dest, 0, xPattern, yPattern, zPattern, animationPhase, color);
|
||||
}
|
||||
|
||||
void Item::setId(uint32 id)
|
||||
{
|
||||
if(!g_things.isValidDatId(id, ThingCategoryItem))
|
||||
id = 0;
|
||||
m_serverId = g_things.findItemTypeByClientId(id)->getServerId();
|
||||
m_clientId = id;
|
||||
}
|
||||
|
||||
void Item::setOtbId(uint16 id)
|
||||
{
|
||||
if(!g_things.isValidOtbId(id))
|
||||
id = 0;
|
||||
auto itemType = g_things.getItemType(id);
|
||||
m_serverId = id;
|
||||
|
||||
id = itemType->getClientId();
|
||||
if(!g_things.isValidDatId(id, ThingCategoryItem))
|
||||
id = 0;
|
||||
m_clientId = id;
|
||||
}
|
||||
|
||||
bool Item::isValid()
|
||||
{
|
||||
return g_things.isValidDatId(m_clientId, ThingCategoryItem);
|
||||
}
|
||||
|
||||
void Item::unserializeItem(const BinaryTreePtr &in)
|
||||
{
|
||||
try {
|
||||
while(in->canRead()) {
|
||||
int attrib = in->getU8();
|
||||
if(attrib == 0)
|
||||
break;
|
||||
|
||||
switch(attrib) {
|
||||
case ATTR_COUNT:
|
||||
case ATTR_RUNE_CHARGES:
|
||||
setCount(in->getU8());
|
||||
break;
|
||||
case ATTR_CHARGES:
|
||||
setCount(in->getU16());
|
||||
break;
|
||||
case ATTR_HOUSEDOORID:
|
||||
case ATTR_SCRIPTPROTECTED:
|
||||
case ATTR_DUALWIELD:
|
||||
case ATTR_DECAYING_STATE:
|
||||
m_attribs.set(attrib, in->getU8());
|
||||
break;
|
||||
case ATTR_ACTION_ID:
|
||||
case ATTR_UNIQUE_ID:
|
||||
case ATTR_DEPOT_ID:
|
||||
m_attribs.set(attrib, in->getU16());
|
||||
break;
|
||||
case ATTR_CONTAINER_ITEMS:
|
||||
case ATTR_ATTACK:
|
||||
case ATTR_EXTRAATTACK:
|
||||
case ATTR_DEFENSE:
|
||||
case ATTR_EXTRADEFENSE:
|
||||
case ATTR_ARMOR:
|
||||
case ATTR_ATTACKSPEED:
|
||||
case ATTR_HITCHANCE:
|
||||
case ATTR_DURATION:
|
||||
case ATTR_WRITTENDATE:
|
||||
case ATTR_SLEEPERGUID:
|
||||
case ATTR_SLEEPSTART:
|
||||
case ATTR_ATTRIBUTE_MAP:
|
||||
m_attribs.set(attrib, in->getU32());
|
||||
break;
|
||||
case ATTR_TELE_DEST: {
|
||||
Position pos;
|
||||
pos.x = in->getU16();
|
||||
pos.y = in->getU16();
|
||||
pos.z = in->getU8();
|
||||
m_attribs.set(attrib, pos);
|
||||
break;
|
||||
}
|
||||
case ATTR_NAME:
|
||||
case ATTR_TEXT:
|
||||
case ATTR_DESC:
|
||||
case ATTR_ARTICLE:
|
||||
case ATTR_WRITTENBY:
|
||||
m_attribs.set(attrib, in->getString());
|
||||
break;
|
||||
default:
|
||||
stdext::throw_exception(stdext::format("invalid item attribute %d", attrib));
|
||||
}
|
||||
}
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to unserialize OTBM item: %s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void Item::serializeItem(const OutputBinaryTreePtr& out)
|
||||
{
|
||||
out->startNode(OTBM_ITEM);
|
||||
out->addU16(getServerId());
|
||||
|
||||
out->addU8(ATTR_COUNT);
|
||||
out->addU8(getCount());
|
||||
|
||||
out->addU8(ATTR_CHARGES);
|
||||
out->addU16(getCountOrSubType());
|
||||
|
||||
Position dest = m_attribs.get<Position>(ATTR_TELE_DEST);
|
||||
if(dest.isValid()) {
|
||||
out->addU8(ATTR_TELE_DEST);
|
||||
out->addPos(dest.x, dest.y, dest.z);
|
||||
}
|
||||
|
||||
if(isDepot()) {
|
||||
out->addU8(ATTR_DEPOT_ID);
|
||||
out->addU16(getDepotId());
|
||||
}
|
||||
|
||||
if(isHouseDoor()) {
|
||||
out->addU8(ATTR_HOUSEDOORID);
|
||||
out->addU8(getDoorId());
|
||||
}
|
||||
|
||||
uint16 aid = m_attribs.get<uint16>(ATTR_ACTION_ID);
|
||||
uint16 uid = m_attribs.get<uint16>(ATTR_UNIQUE_ID);
|
||||
if(aid) {
|
||||
out->addU8(ATTR_ACTION_ID);
|
||||
out->addU16(aid);
|
||||
}
|
||||
|
||||
if(uid) {
|
||||
out->addU8(ATTR_UNIQUE_ID);
|
||||
out->addU16(uid);
|
||||
}
|
||||
|
||||
std::string text = getText();
|
||||
if(g_things.getItemType(m_serverId)->isWritable() && !text.empty()) {
|
||||
out->addU8(ATTR_TEXT);
|
||||
out->addString(text);
|
||||
}
|
||||
std::string desc = getDescription();
|
||||
if(!desc.empty()) {
|
||||
out->addU8(ATTR_DESC);
|
||||
out->addString(desc);
|
||||
}
|
||||
|
||||
out->endNode();
|
||||
for(auto i : m_containerItems)
|
||||
i->serializeItem(out);
|
||||
}
|
||||
|
||||
int Item::getSubType()
|
||||
{
|
||||
if(isSplash() || isFluidContainer())
|
||||
return m_countOrSubType;
|
||||
if(g_game.getClientVersion() >= 860)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Item::getCount()
|
||||
{
|
||||
if(isStackable())
|
||||
return m_countOrSubType;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Item::isMoveable()
|
||||
{
|
||||
return !rawGetThingType()->isNotMoveable();
|
||||
}
|
||||
|
||||
bool Item::isGround()
|
||||
{
|
||||
return rawGetThingType()->isGround();
|
||||
}
|
||||
|
||||
ItemPtr Item::clone()
|
||||
{
|
||||
ItemPtr item = ItemPtr(new Item);
|
||||
*(item.get()) = *this;
|
||||
return item;
|
||||
}
|
||||
|
||||
void Item::calculatePatterns(int& xPattern, int& yPattern, int& zPattern)
|
||||
{
|
||||
// Avoid crashes with invalid items
|
||||
if(!isValid())
|
||||
return;
|
||||
|
||||
if(isStackable() && getNumPatternX() == 4 && getNumPatternY() == 2) {
|
||||
if(m_countOrSubType <= 0) {
|
||||
xPattern = 0;
|
||||
yPattern = 0;
|
||||
} else if(m_countOrSubType < 5) {
|
||||
xPattern = m_countOrSubType-1;
|
||||
yPattern = 0;
|
||||
} else if(m_countOrSubType < 10) {
|
||||
xPattern = 0;
|
||||
yPattern = 1;
|
||||
} else if(m_countOrSubType < 25) {
|
||||
xPattern = 1;
|
||||
yPattern = 1;
|
||||
} else if(m_countOrSubType < 50) {
|
||||
xPattern = 2;
|
||||
yPattern = 1;
|
||||
} else {
|
||||
xPattern = 3;
|
||||
yPattern = 1;
|
||||
}
|
||||
} else if(isHangable()) {
|
||||
const TilePtr& tile = getTile();
|
||||
if(tile) {
|
||||
if(tile->mustHookSouth())
|
||||
xPattern = getNumPatternX() >= 2 ? 1 : 0;
|
||||
else if(tile->mustHookEast())
|
||||
xPattern = getNumPatternX() >= 3 ? 2 : 0;
|
||||
}
|
||||
} else if(isSplash() || isFluidContainer()) {
|
||||
int color = Otc::FluidTransparent;
|
||||
if(g_game.getFeature(Otc::GameNewFluids)) {
|
||||
switch(m_countOrSubType) {
|
||||
case Otc::FluidNone:
|
||||
color = Otc::FluidTransparent;
|
||||
break;
|
||||
case Otc::FluidWater:
|
||||
color = Otc::FluidBlue;
|
||||
break;
|
||||
case Otc::FluidMana:
|
||||
color = Otc::FluidPurple;
|
||||
break;
|
||||
case Otc::FluidBeer:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidOil:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidBlood:
|
||||
color = Otc::FluidRed;
|
||||
break;
|
||||
case Otc::FluidSlime:
|
||||
color = Otc::FluidGreen;
|
||||
break;
|
||||
case Otc::FluidMud:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidLemonade:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidMilk:
|
||||
color = Otc::FluidWhite;
|
||||
break;
|
||||
case Otc::FluidWine:
|
||||
color = Otc::FluidPurple;
|
||||
break;
|
||||
case Otc::FluidHealth:
|
||||
color = Otc::FluidRed;
|
||||
break;
|
||||
case Otc::FluidUrine:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidRum:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidFruidJuice:
|
||||
color = Otc::FluidYellow;
|
||||
break;
|
||||
case Otc::FluidCoconutMilk:
|
||||
color = Otc::FluidWhite;
|
||||
break;
|
||||
case Otc::FluidTea:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
case Otc::FluidMead:
|
||||
color = Otc::FluidBrown;
|
||||
break;
|
||||
default:
|
||||
color = Otc::FluidTransparent;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
color = m_countOrSubType;
|
||||
|
||||
xPattern = (color % 4) % getNumPatternX();
|
||||
yPattern = (color / 4) % getNumPatternY();
|
||||
} else {
|
||||
xPattern = m_position.x % std::max<int>(1, getNumPatternX());
|
||||
yPattern = m_position.y % std::max<int>(1, getNumPatternY());
|
||||
zPattern = m_position.z % std::max<int>(1, getNumPatternZ());
|
||||
}
|
||||
}
|
||||
|
||||
int Item::calculateAnimationPhase(bool animate)
|
||||
{
|
||||
if(getAnimationPhases() > 1) {
|
||||
if(animate) {
|
||||
if(getAnimator() != nullptr)
|
||||
return getAnimator()->getPhase();
|
||||
|
||||
if(m_async)
|
||||
return (g_clock.millis() % ((g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::ITEM_TICKS_PER_FRAME_FAST : Otc::ITEM_TICKS_PER_FRAME) * getAnimationPhases())) / Otc::ITEM_TICKS_PER_FRAME;
|
||||
else {
|
||||
if(g_clock.millis() - m_lastPhase >= (g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::ITEM_TICKS_PER_FRAME_FAST : Otc::ITEM_TICKS_PER_FRAME)) {
|
||||
m_phase = (m_phase + 1) % getAnimationPhases();
|
||||
m_lastPhase = g_clock.millis();
|
||||
}
|
||||
return m_phase;
|
||||
}
|
||||
} else
|
||||
return getAnimationPhases()-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Item::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
|
||||
{
|
||||
calculatePatterns(xPattern, yPattern, zPattern);
|
||||
animationPhase = calculateAnimationPhase(true);
|
||||
return Thing::getExactSize(layer, xPattern, yPattern, zPattern, animationPhase);
|
||||
}
|
||||
|
||||
const ThingTypePtr& Item::getThingType()
|
||||
{
|
||||
return g_things.getThingType(m_clientId, ThingCategoryItem);
|
||||
}
|
||||
|
||||
ThingType* Item::rawGetThingType()
|
||||
{
|
||||
return g_things.rawGetThingType(m_clientId, ThingCategoryItem);
|
||||
}
|
||||
/* vim: set ts=4 sw=4 et :*/
|
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ITEM_H
|
||||
#define ITEM_H
|
||||
|
||||
#include <framework/global.h>
|
||||
|
||||
#include "thing.h"
|
||||
#include "effect.h"
|
||||
#include "itemtype.h"
|
||||
|
||||
enum ItemAttr : uint8
|
||||
{
|
||||
ATTR_END = 0,
|
||||
//ATTR_DESCRIPTION = 1,
|
||||
//ATTR_EXT_FILE = 2,
|
||||
ATTR_TILE_FLAGS = 3,
|
||||
ATTR_ACTION_ID = 4,
|
||||
ATTR_UNIQUE_ID = 5,
|
||||
ATTR_TEXT = 6,
|
||||
ATTR_DESC = 7,
|
||||
ATTR_TELE_DEST = 8,
|
||||
ATTR_ITEM = 9,
|
||||
ATTR_DEPOT_ID = 10,
|
||||
//ATTR_EXT_SPAWN_FILE = 11,
|
||||
ATTR_RUNE_CHARGES = 12,
|
||||
//ATTR_EXT_HOUSE_FILE = 13,
|
||||
ATTR_HOUSEDOORID = 14,
|
||||
ATTR_COUNT = 15,
|
||||
ATTR_DURATION = 16,
|
||||
ATTR_DECAYING_STATE = 17,
|
||||
ATTR_WRITTENDATE = 18,
|
||||
ATTR_WRITTENBY = 19,
|
||||
ATTR_SLEEPERGUID = 20,
|
||||
ATTR_SLEEPSTART = 21,
|
||||
ATTR_CHARGES = 22,
|
||||
ATTR_CONTAINER_ITEMS = 23,
|
||||
ATTR_NAME = 30,
|
||||
ATTR_PLURALNAME = 31,
|
||||
ATTR_ATTACK = 33,
|
||||
ATTR_EXTRAATTACK = 34,
|
||||
ATTR_DEFENSE = 35,
|
||||
ATTR_EXTRADEFENSE = 36,
|
||||
ATTR_ARMOR = 37,
|
||||
ATTR_ATTACKSPEED = 38,
|
||||
ATTR_HITCHANCE = 39,
|
||||
ATTR_SHOOTRANGE = 40,
|
||||
ATTR_ARTICLE = 41,
|
||||
ATTR_SCRIPTPROTECTED = 42,
|
||||
ATTR_DUALWIELD = 43,
|
||||
ATTR_ATTRIBUTE_MAP = 128
|
||||
};
|
||||
|
||||
// @bindclass
|
||||
#pragma pack(push,1) // disable memory alignment
|
||||
class Item : public Thing
|
||||
{
|
||||
public:
|
||||
Item();
|
||||
virtual ~Item() { }
|
||||
|
||||
static ItemPtr create(int id, int countOrSubtype = 1);
|
||||
static ItemPtr createFromOtb(int id);
|
||||
|
||||
void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr);
|
||||
void draw(const Rect& dest, bool animate = true);
|
||||
|
||||
void setId(uint32 id);
|
||||
void setOtbId(uint16 id);
|
||||
void setCountOrSubType(int value) { m_countOrSubType = value; }
|
||||
void setCount(int count) { m_countOrSubType = count; }
|
||||
void setSubType(int subType) { m_countOrSubType = subType; }
|
||||
void setColor(const Color& c) { m_color = c; }
|
||||
void setTooltip(const std::string& str) { m_tooltip = str; }
|
||||
|
||||
int getCountOrSubType() { return m_countOrSubType; }
|
||||
int getSubType();
|
||||
int getCount();
|
||||
uint32 getId() { return m_clientId; }
|
||||
uint16 getClientId() { return m_clientId; }
|
||||
uint16 getServerId() { return m_serverId; }
|
||||
std::string getName();
|
||||
bool isValid();
|
||||
std::string getTooltip() { return m_tooltip; }
|
||||
|
||||
void unserializeItem(const BinaryTreePtr& in);
|
||||
void serializeItem(const OutputBinaryTreePtr& out);
|
||||
|
||||
void setDepotId(uint16 depotId) { m_attribs.set(ATTR_DEPOT_ID, depotId); }
|
||||
uint16 getDepotId() { return m_attribs.get<uint16>(ATTR_DEPOT_ID); }
|
||||
|
||||
void setDoorId(uint8 doorId) { m_attribs.set(ATTR_HOUSEDOORID, doorId); }
|
||||
uint8 getDoorId() { return m_attribs.get<uint8>(ATTR_HOUSEDOORID); }
|
||||
|
||||
uint16 getUniqueId() { return m_attribs.get<uint16>(ATTR_ACTION_ID); }
|
||||
uint16 getActionId() { return m_attribs.get<uint16>(ATTR_UNIQUE_ID); }
|
||||
void setActionId(uint16 actionId) { m_attribs.set(ATTR_ACTION_ID, actionId); }
|
||||
void setUniqueId(uint16 uniqueId) { m_attribs.set(ATTR_UNIQUE_ID, uniqueId); }
|
||||
|
||||
std::string getText() { return m_attribs.get<std::string>(ATTR_TEXT); }
|
||||
std::string getDescription() { return m_attribs.get<std::string>(ATTR_DESC); }
|
||||
void setDescription(std::string desc) { m_attribs.set(ATTR_DESC, desc); }
|
||||
void setText(std::string txt) { m_attribs.set(ATTR_TEXT, txt); }
|
||||
|
||||
Position getTeleportDestination() { return m_attribs.get<Position>(ATTR_TELE_DEST); }
|
||||
void setTeleportDestination(const Position& pos) { m_attribs.set(ATTR_TELE_DEST, pos); }
|
||||
|
||||
void setAsync(bool enable) { m_async = enable; }
|
||||
|
||||
bool isHouseDoor() { return m_attribs.has(ATTR_HOUSEDOORID); }
|
||||
bool isDepot() { return m_attribs.has(ATTR_DEPOT_ID); }
|
||||
bool isContainer() { return m_attribs.has(ATTR_CONTAINER_ITEMS); }
|
||||
bool isDoor() { return m_attribs.has(ATTR_HOUSEDOORID); }
|
||||
bool isTeleport() { return m_attribs.has(ATTR_TELE_DEST); }
|
||||
bool isMoveable();
|
||||
bool isGround();
|
||||
|
||||
ItemPtr clone();
|
||||
ItemPtr asItem() { return static_self_cast<Item>(); }
|
||||
bool isItem() { return true; }
|
||||
|
||||
ItemVector getContainerItems() { return m_containerItems; }
|
||||
ItemPtr getContainerItem(int slot) { return m_containerItems[slot]; }
|
||||
void addContainerItemIndexed(const ItemPtr& i, int slot) { m_containerItems[slot] = i; }
|
||||
void addContainerItem(const ItemPtr& i) { m_containerItems.push_back(i); }
|
||||
void removeContainerItem(int slot) { m_containerItems[slot] = nullptr; }
|
||||
void clearContainerItems() { m_containerItems.clear(); }
|
||||
|
||||
void calculatePatterns(int& xPattern, int& yPattern, int& zPattern);
|
||||
int calculateAnimationPhase(bool animate);
|
||||
int getExactSize(int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animationPhase = 0);
|
||||
|
||||
const ThingTypePtr& getThingType();
|
||||
ThingType *rawGetThingType();
|
||||
|
||||
private:
|
||||
uint16 m_clientId;
|
||||
uint16 m_serverId;
|
||||
uint16 m_countOrSubType;
|
||||
stdext::packed_storage<uint8> m_attribs;
|
||||
ItemVector m_containerItems;
|
||||
Color m_color;
|
||||
bool m_async;
|
||||
std::string m_tooltip;
|
||||
|
||||
uint8 m_phase;
|
||||
ticks_t m_lastPhase;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "thingtypemanager.h"
|
||||
#include "thingtype.h"
|
||||
#include "game.h"
|
||||
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/core/binarytree.h>
|
||||
|
||||
ItemType::ItemType()
|
||||
{
|
||||
m_category = ItemCategoryInvalid;
|
||||
}
|
||||
|
||||
void ItemType::unserialize(const BinaryTreePtr& node)
|
||||
{
|
||||
m_null = false;
|
||||
|
||||
m_category = (ItemCategory)node->getU8();
|
||||
|
||||
node->getU32(); // flags
|
||||
|
||||
static uint16 lastId = 99;
|
||||
while(node->canRead()) {
|
||||
uint8 attr = node->getU8();
|
||||
if(attr == 0 || attr == 0xFF)
|
||||
break;
|
||||
|
||||
uint16 len = node->getU16();
|
||||
switch(attr) {
|
||||
case ItemTypeAttrServerId: {
|
||||
uint16 serverId = node->getU16();
|
||||
if(g_game.getClientVersion() < 960) {
|
||||
if(serverId > 20000 && serverId < 20100) {
|
||||
serverId -= 20000;
|
||||
} else if(lastId > 99 && lastId != serverId - 1) {
|
||||
while(lastId != serverId - 1) {
|
||||
ItemTypePtr tmp(new ItemType);
|
||||
tmp->setServerId(lastId++);
|
||||
g_things.addItemType(tmp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(serverId > 30000 && serverId < 30100) {
|
||||
serverId -= 30000;
|
||||
} else if(lastId > 99 && lastId != serverId - 1) {
|
||||
while(lastId != serverId - 1) {
|
||||
ItemTypePtr tmp(new ItemType);
|
||||
tmp->setServerId(lastId++);
|
||||
g_things.addItemType(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
setServerId(serverId);
|
||||
lastId = serverId;
|
||||
break;
|
||||
}
|
||||
case ItemTypeAttrClientId:
|
||||
setClientId(node->getU16());
|
||||
break;
|
||||
case ItemTypeAttrName:
|
||||
setName(node->getString(len));
|
||||
break;
|
||||
case ItemTypeAttrWritable:
|
||||
m_attribs.set(ItemTypeAttrWritable, true);
|
||||
break;
|
||||
default:
|
||||
node->skip(len); // skip attribute
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ITEMTYPE_H
|
||||
#define ITEMTYPE_H
|
||||
|
||||
#include <framework/core/declarations.h>
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include <framework/xml/tinyxml.h>
|
||||
|
||||
enum ItemCategory : uint8 {
|
||||
ItemCategoryInvalid = 0,
|
||||
ItemCategoryGround = 1,
|
||||
ItemCategoryContainer = 2,
|
||||
ItemCategoryWeapon = 3,
|
||||
ItemCategoryAmmunition = 4,
|
||||
ItemCategoryArmor = 5,
|
||||
ItemCategoryCharges = 6,
|
||||
ItemCategoryTeleport = 7,
|
||||
ItemCategoryMagicField = 8,
|
||||
ItemCategoryWritable = 9,
|
||||
ItemCategoryKey = 10,
|
||||
ItemCategorySplash = 11,
|
||||
ItemCategoryFluid = 12,
|
||||
ItemCategoryDoor = 13,
|
||||
ItemCategoryDeprecated = 14,
|
||||
ItemCategoryLast = 15
|
||||
};
|
||||
|
||||
enum ItemTypeAttr : uint8 {
|
||||
ItemTypeAttrServerId = 16,
|
||||
ItemTypeAttrClientId = 17,
|
||||
ItemTypeAttrName = 18, // deprecated
|
||||
ItemTypeAttrDesc = 19, // deprecated
|
||||
ItemTypeAttrSpeed = 20,
|
||||
ItemTypeAttrSlot = 21, // deprecated
|
||||
ItemTypeAttrMaxItems = 22, // deprecated
|
||||
ItemTypeAttrWeight = 23, // deprecated
|
||||
ItemTypeAttrWeapon = 24, // deprecated
|
||||
ItemTypeAttrAmmunition = 25, // deprecated
|
||||
ItemTypeAttrArmor = 26, // deprecated
|
||||
ItemTypeAttrMagicLevel = 27, // deprecated
|
||||
ItemTypeAttrMagicField = 28, // deprecated
|
||||
ItemTypeAttrWritable = 29, // deprecated
|
||||
ItemTypeAttrRotateTo = 30, // deprecated
|
||||
ItemTypeAttrDecay = 31, // deprecated
|
||||
ItemTypeAttrSpriteHash = 32,
|
||||
ItemTypeAttrMinimapColor = 33,
|
||||
ItemTypeAttr07 = 34,
|
||||
ItemTypeAttr08 = 35,
|
||||
ItemTypeAttrLight = 36,
|
||||
ItemTypeAttrDecay2 = 37, // deprecated
|
||||
ItemTypeAttrWeapon2 = 38, // deprecated
|
||||
ItemTypeAttrAmmunition2 = 39, // deprecated
|
||||
ItemTypeAttrArmor2 = 40, // deprecated
|
||||
ItemTypeAttrWritable2 = 41, // deprecated
|
||||
ItemTypeAttrLight2 = 42,
|
||||
ItemTypeAttrTopOrder = 43,
|
||||
ItemTypeAttrWrtiable3 = 44, // deprecated
|
||||
ItemTypeAttrWareId = 45,
|
||||
ItemTypeAttrLast = 46
|
||||
};
|
||||
|
||||
enum ClientVersion
|
||||
{
|
||||
ClientVersion750 = 1,
|
||||
ClientVersion755 = 2,
|
||||
ClientVersion760 = 3,
|
||||
ClientVersion770 = 3,
|
||||
ClientVersion780 = 4,
|
||||
ClientVersion790 = 5,
|
||||
ClientVersion792 = 6,
|
||||
ClientVersion800 = 7,
|
||||
ClientVersion810 = 8,
|
||||
ClientVersion811 = 9,
|
||||
ClientVersion820 = 10,
|
||||
ClientVersion830 = 11,
|
||||
ClientVersion840 = 12,
|
||||
ClientVersion841 = 13,
|
||||
ClientVersion842 = 14,
|
||||
ClientVersion850 = 15,
|
||||
ClientVersion854_OLD = 16,
|
||||
ClientVersion854 = 17,
|
||||
ClientVersion855 = 18,
|
||||
ClientVersion860_OLD = 19,
|
||||
ClientVersion860 = 20,
|
||||
ClientVersion861 = 21,
|
||||
ClientVersion862 = 22,
|
||||
ClientVersion870 = 23,
|
||||
ClientVersion871 = 24,
|
||||
ClientVersion872 = 25,
|
||||
ClientVersion873 = 26,
|
||||
ClientVersion900 = 27,
|
||||
ClientVersion910 = 28,
|
||||
ClientVersion920 = 29,
|
||||
ClientVersion940 = 30,
|
||||
ClientVersion944_V1 = 31,
|
||||
ClientVersion944_V2 = 32,
|
||||
ClientVersion944_V3 = 33,
|
||||
ClientVersion944_V4 = 34,
|
||||
ClientVersion946 = 35,
|
||||
ClientVersion950 = 36,
|
||||
ClientVersion952 = 37,
|
||||
ClientVersion953 = 38,
|
||||
ClientVersion954 = 39,
|
||||
ClientVersion960 = 40,
|
||||
ClientVersion961 = 41
|
||||
};
|
||||
|
||||
class ItemType : public LuaObject
|
||||
{
|
||||
public:
|
||||
ItemType();
|
||||
|
||||
void unserialize(const BinaryTreePtr& node);
|
||||
|
||||
void setServerId(uint16 serverId) { m_attribs.set(ItemTypeAttrServerId, serverId); }
|
||||
uint16 getServerId() { return m_attribs.get<uint16>(ItemTypeAttrServerId); }
|
||||
|
||||
void setClientId(uint16 clientId) { m_attribs.set(ItemTypeAttrClientId, clientId); }
|
||||
uint16 getClientId() { return m_attribs.get<uint16>(ItemTypeAttrClientId); }
|
||||
|
||||
void setCategory(ItemCategory category) { m_category = category; }
|
||||
ItemCategory getCategory() { return m_category; }
|
||||
|
||||
void setName(const std::string& name) { m_attribs.set(ItemTypeAttrName, name); }
|
||||
std::string getName() { return m_attribs.get<std::string>(ItemTypeAttrName); }
|
||||
|
||||
void setDesc(const std::string& desc) { m_attribs.set(ItemTypeAttrDesc, desc); }
|
||||
std::string getDesc() { return m_attribs.get<std::string>(ItemTypeAttrDesc); }
|
||||
|
||||
bool isNull() { return m_null; }
|
||||
bool isWritable() { return m_attribs.get<bool>(ItemTypeAttrWritable); }
|
||||
|
||||
private:
|
||||
ItemCategory m_category;
|
||||
stdext::boolean<true> m_null;
|
||||
|
||||
stdext::dynamic_storage<uint8> m_attribs;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "lightview.h"
|
||||
#include <framework/graphics/painter.h>
|
||||
|
||||
void LightView::addLight(const Point& pos, uint8_t color, uint8_t intensity)
|
||||
{
|
||||
if (!m_lights.empty()) {
|
||||
Light& prevLight = m_lights.back();
|
||||
if (prevLight.pos == pos && prevLight.color == color) {
|
||||
prevLight.intensity = std::max(prevLight.intensity, intensity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_lights.push_back(Light{ pos, color, intensity });
|
||||
}
|
||||
|
||||
void LightView::setFieldBrightness(const Point& pos, size_t start, uint8_t color)
|
||||
{
|
||||
size_t index = (pos.y / Otc::TILE_PIXELS) * m_mapSize.width() + (pos.x / Otc::TILE_PIXELS);
|
||||
if (index >= m_tiles.size()) return;
|
||||
m_tiles[index].start = start;
|
||||
m_tiles[index].color = color;
|
||||
}
|
||||
|
||||
void LightView::draw() // render thread
|
||||
{
|
||||
static std::vector<uint8_t> buffer;
|
||||
if(buffer.size() < 4u * m_mapSize.area())
|
||||
buffer.resize(m_mapSize.area() * 4);
|
||||
|
||||
// hidden code
|
||||
|
||||
m_lightTexture->update();
|
||||
glBindTexture(GL_TEXTURE_2D, m_lightTexture->getId());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_mapSize.width(), m_mapSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
|
||||
|
||||
Point offset = m_src.topLeft();
|
||||
Size size = m_src.size();
|
||||
CoordsBuffer coords;
|
||||
coords.addRect(RectF(m_dest.left(), m_dest.top(), m_dest.width(), m_dest.height()),
|
||||
RectF((float)offset.x / Otc::TILE_PIXELS, (float)offset.y / Otc::TILE_PIXELS,
|
||||
(float)size.width() / Otc::TILE_PIXELS, (float)size.height() / Otc::TILE_PIXELS));
|
||||
|
||||
g_painterNew->resetColor();
|
||||
g_painterNew->setCompositionMode(Painter::CompositionMode_Multiply);
|
||||
g_painterNew->drawTextureCoords(coords, m_lightTexture);
|
||||
g_painterNew->resetCompositionMode();
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIGHTVIEW_H
|
||||
#define LIGHTVIEW_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "thingtype.h"
|
||||
#include <framework/graphics/declarations.h>
|
||||
#include <framework/graphics/drawqueue.h>
|
||||
#include <set>
|
||||
|
||||
struct TileLight {
|
||||
size_t start;
|
||||
uint8_t color;
|
||||
};
|
||||
|
||||
class LightView : public DrawQueueItem
|
||||
{
|
||||
public:
|
||||
LightView(TexturePtr& lightTexture, const Size& mapSize, const Rect& dest, const Rect& src, uint8_t color, uint8_t intensity) :
|
||||
DrawQueueItem(nullptr), m_lightTexture(lightTexture), m_mapSize(mapSize), m_dest(dest), m_src(src) {
|
||||
m_globalLight = Color::from8bit(color) * ((float)intensity / 255.f);
|
||||
m_tiles.resize(m_mapSize.area(), TileLight{ 0, 0 });
|
||||
}
|
||||
|
||||
inline void addLight(const Point& pos, const Light& light)
|
||||
{
|
||||
return addLight(pos, light.color, light.intensity);
|
||||
}
|
||||
void addLight(const Point& pos, uint8_t color, uint8_t intensity);
|
||||
void setFieldBrightness(const Point& pos, size_t start, uint8_t color);
|
||||
size_t size() { return m_lights.size(); }
|
||||
|
||||
void draw() override;
|
||||
|
||||
private:
|
||||
TexturePtr m_lightTexture;
|
||||
Size m_mapSize;
|
||||
Rect m_dest, m_src;
|
||||
Color m_globalLight;
|
||||
std::vector<Light> m_lights;
|
||||
std::vector<TileLight> m_tiles;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,623 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "localplayer.h"
|
||||
#include "map.h"
|
||||
#include "game.h"
|
||||
#include "tile.h"
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/util/extras.h>
|
||||
|
||||
LocalPlayer::LocalPlayer()
|
||||
{
|
||||
m_states = 0;
|
||||
m_vocation = 0;
|
||||
m_blessings = Otc::BlessingNone;
|
||||
m_walkLockExpiration = 0;
|
||||
|
||||
m_skillsLevel.fill(-1);
|
||||
m_skillsBaseLevel.fill(-1);
|
||||
m_skillsLevelPercent.fill(-1);
|
||||
|
||||
m_health = -1;
|
||||
m_maxHealth = -1;
|
||||
m_freeCapacity = -1;
|
||||
m_experience = -1;
|
||||
m_level = -1;
|
||||
m_levelPercent = -1;
|
||||
m_mana = -1;
|
||||
m_maxMana = -1;
|
||||
m_magicLevel = -1;
|
||||
m_magicLevelPercent = -1;
|
||||
m_baseMagicLevel = -1;
|
||||
m_soul = -1;
|
||||
m_stamina = -1;
|
||||
m_baseSpeed = -1;
|
||||
m_regenerationTime = -1;
|
||||
m_offlineTrainingTime = -1;
|
||||
m_totalCapacity = -1;
|
||||
}
|
||||
|
||||
void LocalPlayer::draw(const Point& dest, bool animate, LightView* lightView)
|
||||
{
|
||||
Creature::draw(dest, animate, lightView);
|
||||
}
|
||||
|
||||
|
||||
void LocalPlayer::lockWalk(int millis)
|
||||
{
|
||||
m_walkLockExpiration = std::max<int>(m_walkLockExpiration, (ticks_t) g_clock.millis() + millis);
|
||||
}
|
||||
|
||||
bool LocalPlayer::canWalk(Otc::Direction direction, bool ignoreLock) {
|
||||
// cannot walk while locked
|
||||
if ((m_walkLockExpiration != 0 && g_clock.millis() < m_walkLockExpiration) && !ignoreLock)
|
||||
return false;
|
||||
|
||||
// paralyzed
|
||||
if (m_speed == 0)
|
||||
return false;
|
||||
|
||||
// last walk is not done yet
|
||||
if (m_walking && (m_walkTimer.ticksElapsed() < getStepDuration()) && !isAutoWalking() && !isServerWalking())
|
||||
return false;
|
||||
|
||||
auto tile = g_map.getTile(getPrewalkingPosition(true));
|
||||
if (isPreWalking() && (!m_lastPrewalkDone || (tile && tile->isBlocking())))
|
||||
return false;
|
||||
|
||||
// cannot walk while already walking
|
||||
if ((m_walking && !isAutoWalking() && !isServerWalking()) && (!isPreWalking() || !m_lastPrewalkDone))
|
||||
return false;
|
||||
|
||||
// Without new walking limit only to 1 prewalk
|
||||
if (!m_preWalking.empty() && !g_game.getFeature(Otc::GameNewWalking))
|
||||
return false;
|
||||
|
||||
// Limit pre walking steps
|
||||
if (m_preWalking.size() >= g_game.getMaxPreWalkingSteps()) // max 3 extra steps
|
||||
return false;
|
||||
|
||||
if (!m_preWalking.empty()) { // disallow diagonal extented prewalking walking
|
||||
auto dir = m_position.getDirectionFromPosition(m_preWalking.back());
|
||||
if ((dir == Otc::NorthWest || dir == Otc::NorthEast || dir == Otc::SouthWest || dir == Otc::SouthEast)) {
|
||||
return false;
|
||||
}
|
||||
if (!g_map.getTile(getPrewalkingPosition())->isWalkable())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LocalPlayer::walk(const Position& oldPos, const Position& newPos)
|
||||
{
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("[%i] LocalPlayer::walk", (int)g_clock.millis()));
|
||||
}
|
||||
|
||||
m_lastAutoWalkRetries = 0;
|
||||
// a prewalk was going on
|
||||
if (isPreWalking()) {
|
||||
for (auto it = m_preWalking.begin(); it != m_preWalking.end(); ++it) {
|
||||
if (*it == newPos) {
|
||||
m_preWalking.erase(m_preWalking.begin(), ++it);
|
||||
if(!isPreWalking()) // reset pre walking
|
||||
updateWalk();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("[%i] LocalPlayer::walk invalid prewalk", (int)g_clock.millis()));
|
||||
}
|
||||
|
||||
// invalid pre walk
|
||||
m_preWalking.clear();
|
||||
m_serverWalking = true;
|
||||
if(m_serverWalkEndEvent)
|
||||
m_serverWalkEndEvent->cancel();
|
||||
|
||||
Creature::walk(oldPos, newPos);
|
||||
} else { // no prewalk was going on, this must be an server side automated walk
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("[%i] LocalPlayer::walk server walk", (int)g_clock.millis()));
|
||||
}
|
||||
|
||||
m_serverWalking = true;
|
||||
if(m_serverWalkEndEvent)
|
||||
m_serverWalkEndEvent->cancel();
|
||||
m_lastAutoWalkRetries = 0;
|
||||
|
||||
Creature::walk(oldPos, newPos);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::preWalk(Otc::Direction direction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LocalPlayer::cancelWalk(Otc::Direction direction)
|
||||
{
|
||||
if (g_game.getFeature(Otc::GameNewWalking)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return cancelNewWalk(direction);
|
||||
}
|
||||
|
||||
void LocalPlayer::cancelNewWalk(Otc::Direction dir)
|
||||
{
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("[%i] cancelWalk", (int)g_clock.millis()));
|
||||
}
|
||||
|
||||
bool clearedPrewalk = !m_preWalking.empty();
|
||||
|
||||
m_preWalking.clear();
|
||||
g_map.requestVisibleTilesCacheUpdate();
|
||||
|
||||
if (clearedPrewalk) {
|
||||
stopWalk();
|
||||
}
|
||||
|
||||
m_idleTimer.restart();
|
||||
|
||||
if (retryAutoWalk()) return;
|
||||
|
||||
if (!g_game.isIgnoringServerDirection() || !g_game.getFeature(Otc::GameNewWalking)) {
|
||||
setDirection(dir);
|
||||
}
|
||||
callLuaField("onCancelWalk", dir);
|
||||
}
|
||||
|
||||
bool LocalPlayer::predictiveCancelWalk(const Position& pos, uint32_t predictionId, Otc::Direction dir)
|
||||
{
|
||||
if (g_extras.debugPredictiveWalking) {
|
||||
g_logger.info(stdext::format("[%i] predictiveCancelWalk: %i - %i", (int)g_clock.millis(), predictionId, (int)m_preWalking.size()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LocalPlayer::retryAutoWalk()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LocalPlayer::autoWalk(Position destination, bool retry)
|
||||
{
|
||||
// reset state
|
||||
m_autoWalkDestination = Position();
|
||||
m_lastAutoWalkPosition = Position();
|
||||
if(m_autoWalkContinueEvent)
|
||||
m_autoWalkContinueEvent->cancel();
|
||||
m_autoWalkContinueEvent = nullptr;
|
||||
|
||||
if (!retry)
|
||||
m_lastAutoWalkRetries = 0;
|
||||
|
||||
if(destination == getPrewalkingPosition())
|
||||
return true;
|
||||
|
||||
m_autoWalkDestination = destination;
|
||||
auto self(asLocalPlayer());
|
||||
g_map.findPathAsync(getPrewalkingPosition(), destination, [self](PathFindResult_ptr result) {
|
||||
if (self->m_autoWalkDestination != result->destination)
|
||||
return;
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("Async path search finished with complexity %i/50000", result->complexity));
|
||||
}
|
||||
|
||||
if (result->status != Otc::PathFindResultOk) {
|
||||
if (self->m_lastAutoWalkRetries > 0 && self->m_lastAutoWalkRetries <= 3) { // try again in 300, 700, 1200 ms if canceled by server
|
||||
self->m_autoWalkContinueEvent = g_dispatcher.scheduleEvent(std::bind(&LocalPlayer::autoWalk, self, result->destination, true), 200 + self->m_lastAutoWalkRetries * 100);
|
||||
return;
|
||||
}
|
||||
self->m_autoWalkDestination = Position();
|
||||
self->callLuaField("onAutoWalkFail", result->status);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!g_game.getFeature(Otc::GameNewWalking) && result->path.size() > 127)
|
||||
result->path.resize(127);
|
||||
else if(result->path.size() > 4095)
|
||||
result->path.resize(4095);
|
||||
|
||||
if (result->path.empty()) {
|
||||
self->m_autoWalkDestination = Position();
|
||||
self->callLuaField("onAutoWalkFail", result->status);
|
||||
return;
|
||||
}
|
||||
|
||||
auto finalAutowalkPos = self->getPrewalkingPosition().translatedToDirections(result->path).back();
|
||||
if (self->m_autoWalkDestination != finalAutowalkPos) {
|
||||
self->m_lastAutoWalkPosition = finalAutowalkPos;
|
||||
}
|
||||
|
||||
g_game.autoWalk(result->path, result->start);
|
||||
});
|
||||
|
||||
if(!retry)
|
||||
lockWalk();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LocalPlayer::stopAutoWalk()
|
||||
{
|
||||
m_autoWalkDestination = Position();
|
||||
m_lastAutoWalkPosition = Position();
|
||||
|
||||
if (m_autoWalkContinueEvent) {
|
||||
m_autoWalkContinueEvent->cancel();
|
||||
m_autoWalkContinueEvent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::stopWalk() {
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("[%i] stopWalk", (int)g_clock.millis()));
|
||||
}
|
||||
|
||||
Creature::stopWalk(); // will call terminateWalk
|
||||
|
||||
m_preWalking.clear();
|
||||
}
|
||||
|
||||
void LocalPlayer::updateWalkOffset(int totalPixelsWalked, bool inNextFrame)
|
||||
{
|
||||
// pre walks offsets are calculated in the oposite direction
|
||||
if(isPreWalking()) {
|
||||
Point& walkOffset = inNextFrame ? m_walkOffsetInNextFrame : m_walkOffset;
|
||||
walkOffset = Point(0,0);
|
||||
if(m_walkDirection == Otc::North || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::NorthWest)
|
||||
walkOffset.y = -totalPixelsWalked;
|
||||
else if(m_walkDirection == Otc::South || m_walkDirection == Otc::SouthEast || m_walkDirection == Otc::SouthWest)
|
||||
walkOffset.y = totalPixelsWalked;
|
||||
|
||||
if(m_walkDirection == Otc::East || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::SouthEast)
|
||||
walkOffset.x = totalPixelsWalked;
|
||||
else if(m_walkDirection == Otc::West || m_walkDirection == Otc::NorthWest || m_walkDirection == Otc::SouthWest)
|
||||
walkOffset.x = -totalPixelsWalked;
|
||||
} else
|
||||
Creature::updateWalkOffset(totalPixelsWalked, inNextFrame);
|
||||
}
|
||||
|
||||
void LocalPlayer::updateWalk()
|
||||
{
|
||||
if (!m_walking)
|
||||
return;
|
||||
|
||||
float walkTicksPerPixel = ((float)(getStepDuration(true) + 10)) / 32.0f;
|
||||
int totalPixelsWalked = std::min<int>(m_walkTimer.ticksElapsed() / walkTicksPerPixel, 32.0f);
|
||||
int totalPixelsWalkedInNextFrame = std::min<int>((m_walkTimer.ticksElapsed() + 15) / walkTicksPerPixel, 32.0f);
|
||||
|
||||
// needed for paralyze effect
|
||||
m_walkedPixels = std::max<int>(m_walkedPixels, totalPixelsWalked);
|
||||
int walkedPixelsInNextFrame = std::max<int>(m_walkedPixels, totalPixelsWalkedInNextFrame);
|
||||
|
||||
// update walk animation and offsets
|
||||
updateWalkAnimation(totalPixelsWalked);
|
||||
updateWalkOffset(m_walkedPixels);
|
||||
updateWalkOffset(walkedPixelsInNextFrame, true);
|
||||
updateWalkingTile();
|
||||
|
||||
int stepDuration = getStepDuration();
|
||||
|
||||
// terminate walk only when client and server side walk are completed
|
||||
if (m_walking && m_walkTimer.ticksElapsed() >= stepDuration)
|
||||
m_lastPrewalkDone = true;
|
||||
if(m_walking && m_walkTimer.ticksElapsed() >= stepDuration && !isPreWalking())
|
||||
terminateWalk();
|
||||
}
|
||||
|
||||
void LocalPlayer::terminateWalk()
|
||||
{
|
||||
if (g_extras.debugWalking) {
|
||||
g_logger.info(stdext::format("[%i] terminateWalk", (int)g_clock.millis()));
|
||||
}
|
||||
|
||||
Creature::terminateWalk();
|
||||
m_idleTimer.restart();
|
||||
m_preWalking.clear();
|
||||
m_walking = false;
|
||||
|
||||
auto self = asLocalPlayer();
|
||||
|
||||
if(m_serverWalking) {
|
||||
if(m_serverWalkEndEvent)
|
||||
m_serverWalkEndEvent->cancel();
|
||||
m_serverWalkEndEvent = g_dispatcher.scheduleEvent([self] {
|
||||
self->m_serverWalking = false;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
callLuaField("onWalkFinish");
|
||||
}
|
||||
|
||||
void LocalPlayer::onAppear()
|
||||
{
|
||||
Creature::onAppear();
|
||||
|
||||
/* Does not seem to be needed anymore
|
||||
// on teleports lock the walk
|
||||
if(!m_oldPosition.isInRange(m_position,1,1))
|
||||
lockWalk();
|
||||
*/
|
||||
}
|
||||
|
||||
void LocalPlayer::onPositionChange(const Position& newPos, const Position& oldPos)
|
||||
{
|
||||
Creature::onPositionChange(newPos, oldPos);
|
||||
|
||||
if(newPos == m_autoWalkDestination)
|
||||
stopAutoWalk();
|
||||
else if(m_autoWalkDestination.isValid() && newPos == m_lastAutoWalkPosition)
|
||||
autoWalk(m_autoWalkDestination);
|
||||
|
||||
m_walkMatrix.updatePosition(newPos);
|
||||
}
|
||||
|
||||
void LocalPlayer::turn(Otc::Direction direction)
|
||||
{
|
||||
Creature::setDirection(direction);
|
||||
callLuaField("onTurn", direction);
|
||||
}
|
||||
|
||||
void LocalPlayer::setStates(int states)
|
||||
{
|
||||
if(m_states != states) {
|
||||
int oldStates = m_states;
|
||||
m_states = states;
|
||||
|
||||
callLuaField("onStatesChange", states, oldStates);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setSkill(Otc::Skill skill, int level, int levelPercent)
|
||||
{
|
||||
if(skill >= Otc::LastSkill) {
|
||||
g_logger.traceError("invalid skill");
|
||||
return;
|
||||
}
|
||||
|
||||
int oldLevel = m_skillsLevel[skill];
|
||||
int oldLevelPercent = m_skillsLevelPercent[skill];
|
||||
|
||||
if(level != oldLevel || levelPercent != oldLevelPercent) {
|
||||
m_skillsLevel[skill] = level;
|
||||
m_skillsLevelPercent[skill] = levelPercent;
|
||||
|
||||
callLuaField("onSkillChange", skill, level, levelPercent, oldLevel, oldLevelPercent);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setBaseSkill(Otc::Skill skill, int baseLevel)
|
||||
{
|
||||
if(skill >= Otc::LastSkill) {
|
||||
g_logger.traceError("invalid skill");
|
||||
return;
|
||||
}
|
||||
|
||||
int oldBaseLevel = m_skillsBaseLevel[skill];
|
||||
if(baseLevel != oldBaseLevel) {
|
||||
m_skillsBaseLevel[skill] = baseLevel;
|
||||
|
||||
callLuaField("onBaseSkillChange", skill, baseLevel, oldBaseLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setHealth(double health, double maxHealth)
|
||||
{
|
||||
if(m_health != health || m_maxHealth != maxHealth) {
|
||||
double oldHealth = m_health;
|
||||
double oldMaxHealth = m_maxHealth;
|
||||
m_health = health;
|
||||
m_maxHealth = maxHealth;
|
||||
|
||||
callLuaField("onHealthChange", health, maxHealth, oldHealth, oldMaxHealth);
|
||||
|
||||
// cannot walk while dying
|
||||
if(health == 0) {
|
||||
if(isPreWalking())
|
||||
stopWalk();
|
||||
lockWalk();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setFreeCapacity(double freeCapacity)
|
||||
{
|
||||
if(m_freeCapacity != freeCapacity) {
|
||||
double oldFreeCapacity = m_freeCapacity;
|
||||
m_freeCapacity = freeCapacity;
|
||||
|
||||
callLuaField("onFreeCapacityChange", freeCapacity, oldFreeCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setTotalCapacity(double totalCapacity)
|
||||
{
|
||||
if(m_totalCapacity != totalCapacity) {
|
||||
double oldTotalCapacity = m_totalCapacity;
|
||||
m_totalCapacity = totalCapacity;
|
||||
|
||||
callLuaField("onTotalCapacityChange", totalCapacity, oldTotalCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setExperience(double experience)
|
||||
{
|
||||
if(m_experience != experience) {
|
||||
double oldExperience = m_experience;
|
||||
m_experience = experience;
|
||||
|
||||
callLuaField("onExperienceChange", experience, oldExperience);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setLevel(double level, double levelPercent)
|
||||
{
|
||||
if(m_level != level || m_levelPercent != levelPercent) {
|
||||
double oldLevel = m_level;
|
||||
double oldLevelPercent = m_levelPercent;
|
||||
m_level = level;
|
||||
m_levelPercent = levelPercent;
|
||||
|
||||
callLuaField("onLevelChange", level, levelPercent, oldLevel, oldLevelPercent);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setMana(double mana, double maxMana)
|
||||
{
|
||||
if(m_mana != mana || m_maxMana != maxMana) {
|
||||
double oldMana = m_mana;
|
||||
double oldMaxMana;
|
||||
m_mana = mana;
|
||||
m_maxMana = maxMana;
|
||||
|
||||
callLuaField("onManaChange", mana, maxMana, oldMana, oldMaxMana);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setMagicLevel(double magicLevel, double magicLevelPercent)
|
||||
{
|
||||
if(m_magicLevel != magicLevel || m_magicLevelPercent != magicLevelPercent) {
|
||||
double oldMagicLevel = m_magicLevel;
|
||||
double oldMagicLevelPercent = m_magicLevelPercent;
|
||||
m_magicLevel = magicLevel;
|
||||
m_magicLevelPercent = magicLevelPercent;
|
||||
|
||||
callLuaField("onMagicLevelChange", magicLevel, magicLevelPercent, oldMagicLevel, oldMagicLevelPercent);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setBaseMagicLevel(double baseMagicLevel)
|
||||
{
|
||||
if(m_baseMagicLevel != baseMagicLevel) {
|
||||
double oldBaseMagicLevel = m_baseMagicLevel;
|
||||
m_baseMagicLevel = baseMagicLevel;
|
||||
|
||||
callLuaField("onBaseMagicLevelChange", baseMagicLevel, oldBaseMagicLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setSoul(double soul)
|
||||
{
|
||||
if(m_soul != soul) {
|
||||
double oldSoul = m_soul;
|
||||
m_soul = soul;
|
||||
|
||||
callLuaField("onSoulChange", soul, oldSoul);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setStamina(double stamina)
|
||||
{
|
||||
if(m_stamina != stamina) {
|
||||
double oldStamina = m_stamina;
|
||||
m_stamina = stamina;
|
||||
|
||||
callLuaField("onStaminaChange", stamina, oldStamina);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setInventoryItem(Otc::InventorySlot inventory, const ItemPtr& item)
|
||||
{
|
||||
if(inventory >= Otc::LastInventorySlot) {
|
||||
g_logger.traceError("invalid slot");
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_inventoryItems[inventory] != item) {
|
||||
ItemPtr oldItem = m_inventoryItems[inventory];
|
||||
m_inventoryItems[inventory] = item;
|
||||
|
||||
callLuaField("onInventoryChange", inventory, item, oldItem);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setVocation(int vocation)
|
||||
{
|
||||
if(m_vocation != vocation) {
|
||||
int oldVocation = m_vocation;
|
||||
m_vocation = vocation;
|
||||
|
||||
callLuaField("onVocationChange", vocation, oldVocation);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setPremium(bool premium)
|
||||
{
|
||||
if(m_premium != premium) {
|
||||
m_premium = premium;
|
||||
|
||||
callLuaField("onPremiumChange", premium);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setRegenerationTime(double regenerationTime)
|
||||
{
|
||||
if(m_regenerationTime != regenerationTime) {
|
||||
double oldRegenerationTime = m_regenerationTime;
|
||||
m_regenerationTime = regenerationTime;
|
||||
|
||||
callLuaField("onRegenerationChange", regenerationTime, oldRegenerationTime);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setOfflineTrainingTime(double offlineTrainingTime)
|
||||
{
|
||||
if(m_offlineTrainingTime != offlineTrainingTime) {
|
||||
double oldOfflineTrainingTime = m_offlineTrainingTime;
|
||||
m_offlineTrainingTime = offlineTrainingTime;
|
||||
|
||||
callLuaField("onOfflineTrainingChange", offlineTrainingTime, oldOfflineTrainingTime);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setSpells(const std::vector<int>& spells)
|
||||
{
|
||||
if(m_spells != spells) {
|
||||
std::vector<int> oldSpells = m_spells;
|
||||
m_spells = spells;
|
||||
|
||||
callLuaField("onSpellsChange", spells, oldSpells);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setBlessings(int blessings)
|
||||
{
|
||||
if(blessings != m_blessings) {
|
||||
int oldBlessings = m_blessings;
|
||||
m_blessings = blessings;
|
||||
|
||||
callLuaField("onBlessingsChange", blessings, oldBlessings);
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalPlayer::hasSight(const Position& pos)
|
||||
{
|
||||
return m_position.isInRange(pos, g_map.getAwareRange().left - 1, g_map.getAwareRange().top - 1);
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LOCALPLAYER_H
|
||||
#define LOCALPLAYER_H
|
||||
|
||||
#include "player.h"
|
||||
#include "walkmatrix.h"
|
||||
|
||||
// @bindclass
|
||||
class LocalPlayer : public Player
|
||||
{
|
||||
enum {
|
||||
PREWALK_TIMEOUT = 1000
|
||||
};
|
||||
|
||||
public:
|
||||
LocalPlayer();
|
||||
|
||||
void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) override;
|
||||
|
||||
void unlockWalk() { m_walkLockExpiration = 0; }
|
||||
void lockWalk(int millis = 200);
|
||||
void stopAutoWalk();
|
||||
bool autoWalk(Position destination, bool retry = false);
|
||||
bool canWalk(Otc::Direction direction, bool ignoreLock = false);
|
||||
bool isWalkLocked() {
|
||||
return (m_walkLockExpiration != 0 && g_clock.millis() < m_walkLockExpiration);
|
||||
}
|
||||
void turn(Otc::Direction) override;
|
||||
|
||||
void setStates(int states);
|
||||
void setSkill(Otc::Skill skill, int level, int levelPercent);
|
||||
void setBaseSkill(Otc::Skill skill, int baseLevel);
|
||||
void setHealth(double health, double maxHealth);
|
||||
void setFreeCapacity(double freeCapacity);
|
||||
void setTotalCapacity(double totalCapacity);
|
||||
void setExperience(double experience);
|
||||
void setLevel(double level, double levelPercent);
|
||||
void setMana(double mana, double maxMana);
|
||||
void setMagicLevel(double magicLevel, double magicLevelPercent);
|
||||
void setBaseMagicLevel(double baseMagicLevel);
|
||||
void setSoul(double soul);
|
||||
void setStamina(double stamina);
|
||||
void setKnown(bool known) { m_known = known; }
|
||||
void setPendingGame(bool pending) { m_pending = pending; }
|
||||
void setInventoryItem(Otc::InventorySlot inventory, const ItemPtr& item);
|
||||
void setVocation(int vocation);
|
||||
void setPremium(bool premium);
|
||||
void setRegenerationTime(double regenerationTime);
|
||||
void setOfflineTrainingTime(double offlineTrainingTime);
|
||||
void setSpells(const std::vector<int>& spells);
|
||||
void setBlessings(int blessings);
|
||||
|
||||
int getStates() { return m_states; }
|
||||
int getSkillLevel(Otc::Skill skill) { return m_skillsLevel[skill]; }
|
||||
int getSkillBaseLevel(Otc::Skill skill) { return m_skillsBaseLevel[skill]; }
|
||||
int getSkillLevelPercent(Otc::Skill skill) { return m_skillsLevelPercent[skill]; }
|
||||
int getVocation() { return m_vocation; }
|
||||
double getHealth() { return m_health; }
|
||||
double getMaxHealth() { return m_maxHealth; }
|
||||
double getFreeCapacity() { return m_freeCapacity; }
|
||||
double getTotalCapacity() { return m_totalCapacity; }
|
||||
double getExperience() { return m_experience; }
|
||||
double getLevel() { return m_level; }
|
||||
double getLevelPercent() { return m_levelPercent; }
|
||||
double getMana() { return m_mana; }
|
||||
double getMaxMana() { return std::max<double>(m_mana, m_maxMana); }
|
||||
double getMagicLevel() { return m_magicLevel; }
|
||||
double getMagicLevelPercent() { return m_magicLevelPercent; }
|
||||
double getBaseMagicLevel() { return m_baseMagicLevel; }
|
||||
double getSoul() { return m_soul; }
|
||||
double getStamina() { return m_stamina; }
|
||||
double getRegenerationTime() { return m_regenerationTime; }
|
||||
double getOfflineTrainingTime() { return m_offlineTrainingTime; }
|
||||
std::vector<int> getSpells() { return m_spells; }
|
||||
ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; }
|
||||
int getBlessings() { return m_blessings; }
|
||||
|
||||
bool hasSight(const Position& pos);
|
||||
bool isKnown() { return m_known; }
|
||||
bool isAutoWalking() { return m_autoWalkDestination.isValid(); }
|
||||
bool isServerWalking() override { return m_serverWalking; }
|
||||
bool isPremium() { return m_premium; }
|
||||
bool isPendingGame() { return m_pending; }
|
||||
|
||||
LocalPlayerPtr asLocalPlayer() { return static_self_cast<LocalPlayer>(); }
|
||||
bool isLocalPlayer() override { return true; }
|
||||
|
||||
void onAppear() override;
|
||||
void onPositionChange(const Position& newPos, const Position& oldPos) override;
|
||||
|
||||
// pre walking
|
||||
void preWalk(Otc::Direction direction);
|
||||
bool isPreWalking() override { return !m_preWalking.empty(); }
|
||||
Position getPrewalkingPosition(bool beforePrewalk = false) override {
|
||||
if(m_preWalking.empty())
|
||||
return m_position;
|
||||
else if (!beforePrewalk && m_preWalking.size() == 1)
|
||||
return m_position;
|
||||
auto ret = m_preWalking.rbegin();
|
||||
if(!beforePrewalk)
|
||||
ret++;
|
||||
return *ret;
|
||||
}
|
||||
|
||||
uint32_t getWalkPrediction(const Position& pos)
|
||||
{
|
||||
return m_walkMatrix.get(pos);
|
||||
};
|
||||
|
||||
std::string dumpWalkMatrix()
|
||||
{
|
||||
return m_walkMatrix.dump();
|
||||
}
|
||||
|
||||
void startServerWalking() { m_serverWalking = true; }
|
||||
void finishServerWalking() { m_serverWalking = false; }
|
||||
|
||||
protected:
|
||||
void walk(const Position& oldPos, const Position& newPos);
|
||||
void cancelWalk(Otc::Direction direction = Otc::InvalidDirection);
|
||||
|
||||
void cancelNewWalk(Otc::Direction dir);
|
||||
bool predictiveCancelWalk(const Position& pos, uint32_t predictionId, Otc::Direction dir);
|
||||
|
||||
bool retryAutoWalk();
|
||||
void stopWalk();
|
||||
|
||||
friend class Game;
|
||||
|
||||
protected:
|
||||
void updateWalkOffset(int totalPixelsWalked, bool inNextFrame = false) override;
|
||||
void updateWalk() override;
|
||||
void terminateWalk() override;
|
||||
|
||||
private:
|
||||
// walk related
|
||||
Position m_autoWalkDestination;
|
||||
Position m_lastAutoWalkPosition;
|
||||
int m_lastAutoWalkRetries = 0;
|
||||
ScheduledEventPtr m_serverWalkEndEvent;
|
||||
ScheduledEventPtr m_autoWalkContinueEvent;
|
||||
ticks_t m_walkLockExpiration;
|
||||
|
||||
// walking and pre walking
|
||||
std::list<Position> m_preWalking;
|
||||
bool m_serverWalking = false;
|
||||
bool m_lastPrewalkDone = false;
|
||||
WalkMatrix m_walkMatrix;
|
||||
|
||||
bool m_premium = false;
|
||||
bool m_known = false;
|
||||
bool m_pending = false;
|
||||
|
||||
ItemPtr m_inventoryItems[Otc::LastInventorySlot];
|
||||
Timer m_idleTimer;
|
||||
|
||||
std::array<int, Otc::LastSkill> m_skillsLevel;
|
||||
std::array<int, Otc::LastSkill> m_skillsBaseLevel;
|
||||
std::array<int, Otc::LastSkill> m_skillsLevelPercent;
|
||||
std::vector<int> m_spells;
|
||||
|
||||
int m_states;
|
||||
int m_vocation;
|
||||
int m_blessings;
|
||||
|
||||
double m_health;
|
||||
double m_maxHealth;
|
||||
double m_freeCapacity;
|
||||
double m_totalCapacity;
|
||||
double m_experience;
|
||||
double m_level;
|
||||
double m_levelPercent;
|
||||
double m_mana;
|
||||
double m_maxMana;
|
||||
double m_magicLevel;
|
||||
double m_magicLevelPercent;
|
||||
double m_baseMagicLevel;
|
||||
double m_soul;
|
||||
double m_stamina;
|
||||
double m_regenerationTime;
|
||||
double m_offlineTrainingTime;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,933 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include "luavaluecasts_client.h"
|
||||
#include "game.h"
|
||||
#include "tile.h"
|
||||
#include "houses.h"
|
||||
#include "towns.h"
|
||||
#include "container.h"
|
||||
#include "item.h"
|
||||
#include "effect.h"
|
||||
#include "missile.h"
|
||||
#include "statictext.h"
|
||||
#include "animatedtext.h"
|
||||
#include "creature.h"
|
||||
#include "player.h"
|
||||
#include "localplayer.h"
|
||||
#include "map.h"
|
||||
#include "minimap.h"
|
||||
#include "thingtypemanager.h"
|
||||
#include "spritemanager.h"
|
||||
#include "shadermanager.h"
|
||||
#include "protocolgame.h"
|
||||
#include "uiitem.h"
|
||||
#include "uicreature.h"
|
||||
#include "uimap.h"
|
||||
#include "uiminimap.h"
|
||||
#include "uimapanchorlayout.h"
|
||||
#include "uiprogressrect.h"
|
||||
#include "uisprite.h"
|
||||
#include "outfit.h"
|
||||
|
||||
#include <framework/luaengine/luainterface.h>
|
||||
|
||||
void Client::registerLuaFunctions()
|
||||
{
|
||||
g_lua.registerSingletonClass("g_things");
|
||||
g_lua.bindSingletonFunction("g_things", "loadDat", &ThingTypeManager::loadDat, &g_things);
|
||||
#ifdef WITH_ENCRYPTION
|
||||
g_lua.bindSingletonFunction("g_things", "saveDat", &ThingTypeManager::saveDat, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "dumpTextures", &ThingTypeManager::dumpTextures, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "replaceTextures", &ThingTypeManager::replaceTextures, &g_things);
|
||||
#endif
|
||||
g_lua.bindSingletonFunction("g_things", "loadOtb", &ThingTypeManager::loadOtb, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "loadOtml", &ThingTypeManager::loadOtml, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "isDatLoaded", &ThingTypeManager::isDatLoaded, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "isOtbLoaded", &ThingTypeManager::isOtbLoaded, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getContentRevision", &ThingTypeManager::getContentRevision, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getThingType", &ThingTypeManager::getThingType, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getThingTypes", &ThingTypeManager::getThingTypes, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "findItemTypeByName", &ThingTypeManager::findItemTypeByName, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "findItemTypesByName", &ThingTypeManager::findItemTypesByName, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "findItemTypesByString", &ThingTypeManager::findItemTypesByString, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getMarketCategories", &ThingTypeManager::getMarketCategories, &g_things);
|
||||
|
||||
g_lua.registerSingletonClass("g_houses");
|
||||
g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "getHouseByName", &HouseManager::getHouseByName, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "filterHouses", &HouseManager::filterHouses, &g_houses);
|
||||
g_lua.bindSingletonFunction("g_houses", "sort", &HouseManager::sort, &g_houses);
|
||||
|
||||
g_lua.registerSingletonClass("g_towns");
|
||||
g_lua.bindSingletonFunction("g_towns", "getTown", &TownManager::getTown, &g_towns);
|
||||
g_lua.bindSingletonFunction("g_towns", "getTownByName",&TownManager::getTownByName,&g_towns);
|
||||
g_lua.bindSingletonFunction("g_towns", "addTown", &TownManager::addTown, &g_towns);
|
||||
g_lua.bindSingletonFunction("g_towns", "removeTown", &TownManager::removeTown, &g_towns);
|
||||
g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns);
|
||||
g_lua.bindSingletonFunction("g_towns", "sort", &TownManager::sort, &g_towns);
|
||||
|
||||
g_lua.registerSingletonClass("g_sprites");
|
||||
g_lua.bindSingletonFunction("g_sprites", "loadSpr", &SpriteManager::loadSpr, &g_sprites);
|
||||
#ifdef WITH_ENCRYPTION
|
||||
g_lua.bindSingletonFunction("g_sprites", "saveSpr", &SpriteManager::saveSpr, &g_sprites);
|
||||
g_lua.bindSingletonFunction("g_sprites", "dumpSprites", &SpriteManager::dumpSprites, &g_sprites);
|
||||
g_lua.bindSingletonFunction("g_sprites", "encryptSprites", &SpriteManager::encryptSprites, &g_sprites);
|
||||
#endif
|
||||
g_lua.bindSingletonFunction("g_sprites", "unload", &SpriteManager::unload, &g_sprites);
|
||||
g_lua.bindSingletonFunction("g_sprites", "isLoaded", &SpriteManager::isLoaded, &g_sprites);
|
||||
g_lua.bindSingletonFunction("g_sprites", "getSprSignature", &SpriteManager::getSignature, &g_sprites);
|
||||
g_lua.bindSingletonFunction("g_sprites", "getSpritesCount", &SpriteManager::getSpritesCount, &g_sprites);
|
||||
|
||||
g_lua.registerSingletonClass("g_map");
|
||||
g_lua.bindSingletonFunction("g_map", "isLookPossible", &Map::isLookPossible, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isCovered", &Map::isCovered, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isCompletelyCovered", &Map::isCompletelyCovered, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "addThing", &Map::addThing, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getThing", &Map::getThing, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "removeThingByPos", &Map::removeThingByPos, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "removeThing", &Map::removeThing, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "colorizeThing", &Map::colorizeThing, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "removeThingColor", &Map::removeThingColor, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "clean", &Map::clean, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "cleanTile", &Map::cleanTile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "cleanTexts", &Map::cleanTexts, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getTile", &Map::getTile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getOrCreateTile", &Map::getOrCreateTile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getTiles", &Map::getTiles, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setCentralPosition", &Map::setCentralPosition, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getCentralPosition", &Map::getCentralPosition, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getCreatureById", &Map::getCreatureById, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "removeCreatureById", &Map::removeCreatureById, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getSpectators", &Map::getSpectators, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getSpectatorsInRange", &Map::getSpectatorsInRange, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getSpectatorsInRangeEx", &Map::getSpectatorsInRangeEx, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getSpectatorsByPattern", &Map::getSpectatorsByPattern, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "findPath", &Map::findPath, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "loadOtbm", &Map::loadOtbm, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "saveOtbm", &Map::saveOtbm, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "loadOtcm", &Map::loadOtcm, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "saveOtcm", &Map::saveOtcm, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getHouseFile", &Map::getHouseFile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setHouseFile", &Map::setHouseFile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getSpawnFile", &Map::getSpawnFile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setSpawnFile", &Map::setSpawnFile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "createTile", &Map::createTile, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setWidth", &Map::setWidth, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setHeight", &Map::setHeight, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getSize", &Map::getSize, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setDescription", &Map::setDescription, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getDescriptions", &Map::getDescriptions, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "clearDescriptions", &Map::clearDescriptions, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setShowZone", &Map::setShowZone, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setShowZones", &Map::setShowZones, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setZoneColor", &Map::setZoneColor, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setZoneOpacity", &Map::setZoneOpacity, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getZoneOpacity", &Map::getZoneOpacity, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getZoneColor", &Map::getZoneColor, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "showZones", &Map::showZones, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "showZone", &Map::showZone, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setForceShowAnimations", &Map::setForceShowAnimations, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isForcingAnimations", &Map::isForcingAnimations, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isShowingAnimations", &Map::isShowingAnimations, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "setShowAnimations", &Map::setShowAnimations, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "findItemsById", &Map::findItemsById, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getAwareRange", &Map::getAwareRangeAsSize, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "findEveryPath", &Map::findEveryPath, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "getMinimapColor", &Map::getMinimapColor, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isPatchable", &Map::isPatchable, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isWalkable", &Map::isWalkable, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "checkSightLine", &Map::checkSightLine, &g_map);
|
||||
g_lua.bindSingletonFunction("g_map", "isSightClear", &Map::isSightClear, &g_map);
|
||||
|
||||
g_lua.registerSingletonClass("g_minimap");
|
||||
g_lua.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap);
|
||||
g_lua.bindSingletonFunction("g_minimap", "loadImage", &Minimap::loadImage, &g_minimap);
|
||||
g_lua.bindSingletonFunction("g_minimap", "saveImage", &Minimap::saveImage, &g_minimap);
|
||||
g_lua.bindSingletonFunction("g_minimap", "loadOtmm", &Minimap::loadOtmm, &g_minimap);
|
||||
g_lua.bindSingletonFunction("g_minimap", "saveOtmm", &Minimap::saveOtmm, &g_minimap);
|
||||
|
||||
g_lua.registerSingletonClass("g_creatures");
|
||||
g_lua.bindSingletonFunction("g_creatures", "getCreatures", &CreatureManager::getCreatures, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "getCreatureByName", &CreatureManager::getCreatureByName, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &CreatureManager::getCreatureByLook, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "getSpawn", &CreatureManager::getSpawn, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "getSpawnForPlacePos", &CreatureManager::getSpawnForPlacePos, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "addSpawn", &CreatureManager::addSpawn, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "loadMonsters", &CreatureManager::loadMonsters, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "loadNpcs", &CreatureManager::loadNpcs, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "loadSingleCreature", &CreatureManager::loadSingleCreature, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "loadSpawns", &CreatureManager::loadSpawns, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "saveSpawns", &CreatureManager::saveSpawns, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "isLoaded", &CreatureManager::isLoaded, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "isSpawnLoaded", &CreatureManager::isSpawnLoaded, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "clear", &CreatureManager::clear, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "clearSpawns", &CreatureManager::clearSpawns, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "getSpawns", &CreatureManager::getSpawns, &g_creatures);
|
||||
g_lua.bindSingletonFunction("g_creatures", "deleteSpawn", &CreatureManager::deleteSpawn, &g_creatures);
|
||||
|
||||
g_lua.registerSingletonClass("g_game");
|
||||
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "cancelLogin", &Game::cancelLogin, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "forceLogout", &Game::forceLogout, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "safeLogout", &Game::safeLogout, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "walk", &Game::walk, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "autoWalk", &Game::autoWalk, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "turn", &Game::turn, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "stop", &Game::stop, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "look", &Game::look, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "move", &Game::move, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "moveRaw", &Game::moveRaw, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "moveToParentContainer", &Game::moveToParentContainer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "rotate", &Game::rotate, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "wrap", &Game::wrap, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "use", &Game::use, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "useWith", &Game::useWith, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "useInventoryItem", &Game::useInventoryItem, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "useInventoryItemWith", &Game::useInventoryItemWith, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "findItemInContainers", &Game::findItemInContainers, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "open", &Game::open, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "openParent", &Game::openParent, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "close", &Game::close, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "refreshContainer", &Game::refreshContainer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "attack", &Game::attack, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "cancelAttack", &Game::cancelAttack, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "follow", &Game::follow, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "cancelFollow", &Game::cancelFollow, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "cancelAttackAndFollow", &Game::cancelAttackAndFollow, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "talk", &Game::talk, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "talkChannel", &Game::talkChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "talkPrivate", &Game::talkPrivate, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "openPrivateChannel", &Game::openPrivateChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "requestChannels", &Game::requestChannels, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "joinChannel", &Game::joinChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "leaveChannel", &Game::leaveChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "closeNpcChannel", &Game::closeNpcChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "openOwnChannel", &Game::openOwnChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "inviteToOwnChannel", &Game::inviteToOwnChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "excludeFromOwnChannel", &Game::excludeFromOwnChannel, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "partyInvite", &Game::partyInvite, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "partyJoin", &Game::partyJoin, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "partyRevokeInvitation", &Game::partyRevokeInvitation, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "partyPassLeadership", &Game::partyPassLeadership, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "partyLeave", &Game::partyLeave, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "partyShareExperience", &Game::partyShareExperience, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "requestOutfit", &Game::requestOutfit, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "changeOutfit", &Game::changeOutfit, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "addVip", &Game::addVip, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "removeVip", &Game::removeVip, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "editVip", &Game::editVip, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setChaseMode", &Game::setChaseMode, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setFightMode", &Game::setFightMode, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setPVPMode", &Game::setPVPMode, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setSafeFight", &Game::setSafeFight, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getChaseMode", &Game::getChaseMode, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getFightMode", &Game::getFightMode, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getPVPMode", &Game::getPVPMode, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getUnjustifiedPoints", &Game::getUnjustifiedPoints, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getOpenPvpSituations", &Game::getOpenPvpSituations, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isSafeFight", &Game::isSafeFight, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "inspectNpcTrade", &Game::inspectNpcTrade, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "buyItem", &Game::buyItem, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "sellItem", &Game::sellItem, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "closeNpcTrade", &Game::closeNpcTrade, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "requestTrade", &Game::requestTrade, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "inspectTrade", &Game::inspectTrade, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "acceptTrade", &Game::acceptTrade, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "rejectTrade", &Game::rejectTrade, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "openRuleViolation", &Game::openRuleViolation, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "closeRuleViolation", &Game::closeRuleViolation, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "cancelRuleViolation", &Game::cancelRuleViolation, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "reportBug", &Game::reportBug, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "reportRuleViolation", &Game::reportRuleViolation, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "debugReport", &Game::debugReport, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "editText", &Game::editText, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "editList", &Game::editList, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "requestQuestLog", &Game::requestQuestLog, &g_game);
|
||||
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", "equipItemId", &Game::equipItemId, &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);
|
||||
g_lua.bindSingletonFunction("g_game", "changeMapAwareRange", &Game::changeMapAwareRange, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "canPerformGameAction", &Game::canPerformGameAction, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "canReportBugs", &Game::canReportBugs, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "checkBotProtection", &Game::checkBotProtection, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isOnline", &Game::isOnline, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isLogging", &Game::isLogging, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isDead", &Game::isDead, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isAttacking", &Game::isAttacking, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isFollowing", &Game::isFollowing, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isConnectionOk", &Game::isConnectionOk, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getPing", &Game::getPing, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getContainer", &Game::getContainer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getContainers", &Game::getContainers, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getVips", &Game::getVips, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getAttackingCreature", &Game::getAttackingCreature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getFollowingCreature", &Game::getFollowingCreature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getServerBeat", &Game::getServerBeat, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getLocalPlayer", &Game::getLocalPlayer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getProtocolGame", &Game::getProtocolGame, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getProtocolVersion", &Game::getProtocolVersion, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setProtocolVersion", &Game::setProtocolVersion, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getCustomProtocolVersion", &Game::getCustomProtocolVersion, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setCustomProtocolVersion", &Game::setCustomProtocolVersion, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getClientVersion", &Game::getClientVersion, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setClientVersion", &Game::setClientVersion, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setCustomOs", &Game::setCustomOs, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getOs", &Game::getOs, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getCharacterName", &Game::getCharacterName, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getWorldName", &Game::getWorldName, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getGMActions", &Game::getGMActions, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getFeature", &Game::getFeature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setFeature", &Game::setFeature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "enableFeature", &Game::enableFeature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "disableFeature", &Game::disableFeature, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "resetFeatures", &Game::resetFeatures, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isGM", &Game::isGM, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "answerModalDialog", &Game::answerModalDialog, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "browseField", &Game::browseField, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "seekInContainer", &Game::seekInContainer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getLastWalkDir", &Game::getLastWalkDir, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "buyStoreOffer", &Game::buyStoreOffer, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "requestTransactionHistory", &Game::requestTransactionHistory, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "requestStoreOffers", &Game::requestStoreOffers, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "openStore", &Game::openStore, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "transferCoins", &Game::transferCoins, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "openTransactionHistory", &Game::openTransactionHistory, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "preyAction", &Game::preyAction, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "preyRequest", &Game::preyRequest, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "applyImbuement", &Game::applyImbuement, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "clearImbuement", &Game::clearImbuement, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "closeImbuingWindow", &Game::closeImbuingWindow, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setTibiaCoins", &Game::setTibiaCoins, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getTibiaCoins", &Game::getTibiaCoins, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getTransferableTibiaCoins", &Game::getTransferableTibiaCoins, &g_game);
|
||||
|
||||
g_lua.bindSingletonFunction("g_game", "getMaxPreWalkingSteps", &Game::getMaxPreWalkingSteps, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "setMaxPreWalkingSteps", &Game::setMaxPreWalkingSteps, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "ignoreServerDirection", &Game::ignoreServerDirection, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "showRealDirection", &Game::showRealDirection, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "enableTileThingLuaCallback", &Game::enableTileThingLuaCallback, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "isTileThingLuaCallbackEnabled", &Game::isTileThingLuaCallbackEnabled, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getRecivedPacketsCount", &Game::getRecivedPacketsCount, &g_game);
|
||||
g_lua.bindSingletonFunction("g_game", "getRecivedPacketsSize", &Game::getRecivedPacketsSize, &g_game);
|
||||
|
||||
g_lua.registerSingletonClass("g_shaders");
|
||||
g_lua.bindSingletonFunction("g_shaders", "createShader", &ShaderManager::createShader, &g_shaders);
|
||||
g_lua.bindSingletonFunction("g_shaders", "createOutfitShader", &ShaderManager::createOutfitShader, &g_shaders);
|
||||
g_lua.bindSingletonFunction("g_shaders", "addTexture", &ShaderManager::addTexture, &g_shaders);
|
||||
|
||||
g_lua.bindGlobalFunction("getOutfitColor", Outfit::getColor);
|
||||
g_lua.bindGlobalFunction("getAngleFromPos", Position::getAngleFromPositions);
|
||||
g_lua.bindGlobalFunction("getDirectionFromPos", Position::getDirectionFromPositions);
|
||||
|
||||
g_lua.registerClass<ProtocolGame, Protocol>();
|
||||
g_lua.bindClassStaticFunction<ProtocolGame>("create", []{ return ProtocolGamePtr(new ProtocolGame); });
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("login", &ProtocolGame::login);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("sendExtendedOpcode", &ProtocolGame::sendExtendedOpcode);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("addPosition", &ProtocolGame::addPosition);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("setMapDescription", &ProtocolGame::setMapDescription);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("setFloorDescription", &ProtocolGame::setFloorDescription);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("setTileDescription", &ProtocolGame::setTileDescription);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("getOutfit", &ProtocolGame::getOutfit);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("getThing", &ProtocolGame::getThing);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("getCreature", &ProtocolGame::getCreature);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("getItem", &ProtocolGame::getItem);
|
||||
g_lua.bindClassMemberFunction<ProtocolGame>("getPosition", &ProtocolGame::getPosition);
|
||||
|
||||
g_lua.registerClass<Container>();
|
||||
g_lua.bindClassMemberFunction<Container>("getItem", &Container::getItem);
|
||||
g_lua.bindClassMemberFunction<Container>("getItems", &Container::getItems);
|
||||
g_lua.bindClassMemberFunction<Container>("getItemsCount", &Container::getItemsCount);
|
||||
g_lua.bindClassMemberFunction<Container>("getSlotPosition", &Container::getSlotPosition);
|
||||
g_lua.bindClassMemberFunction<Container>("getName", &Container::getName);
|
||||
g_lua.bindClassMemberFunction<Container>("getId", &Container::getId);
|
||||
g_lua.bindClassMemberFunction<Container>("getCapacity", &Container::getCapacity);
|
||||
g_lua.bindClassMemberFunction<Container>("getContainerItem", &Container::getContainerItem);
|
||||
g_lua.bindClassMemberFunction<Container>("hasParent", &Container::hasParent);
|
||||
g_lua.bindClassMemberFunction<Container>("isClosed", &Container::isClosed);
|
||||
g_lua.bindClassMemberFunction<Container>("isUnlocked", &Container::isUnlocked);
|
||||
g_lua.bindClassMemberFunction<Container>("hasPages", &Container::hasPages);
|
||||
g_lua.bindClassMemberFunction<Container>("getSize", &Container::getSize);
|
||||
g_lua.bindClassMemberFunction<Container>("getFirstIndex", &Container::getFirstIndex);
|
||||
|
||||
g_lua.registerClass<Thing>();
|
||||
g_lua.bindClassMemberFunction<Thing>("setId", &Thing::setId);
|
||||
g_lua.bindClassMemberFunction<Thing>("setPosition", &Thing::setPosition);
|
||||
g_lua.bindClassMemberFunction<Thing>("getId", &Thing::getId);
|
||||
g_lua.bindClassMemberFunction<Thing>("getPosition", &Thing::getPosition);
|
||||
g_lua.bindClassMemberFunction<Thing>("getStackPriority", &Thing::getStackPriority);
|
||||
g_lua.bindClassMemberFunction<Thing>("getStackPos", &Thing::getStackPos);
|
||||
g_lua.bindClassMemberFunction<Thing>("getAnimationPhases", &Thing::getAnimationPhases);
|
||||
g_lua.bindClassMemberFunction<Thing>("getTile", &Thing::getTile);
|
||||
g_lua.bindClassMemberFunction<Thing>("setMarked", &Thing::setMarked);
|
||||
g_lua.bindClassMemberFunction<Thing>("isItem", &Thing::isItem);
|
||||
g_lua.bindClassMemberFunction<Thing>("isMonster", &Thing::isMonster);
|
||||
g_lua.bindClassMemberFunction<Thing>("isNpc", &Thing::isNpc);
|
||||
g_lua.bindClassMemberFunction<Thing>("isCreature", &Thing::isCreature);
|
||||
g_lua.bindClassMemberFunction<Thing>("isEffect", &Thing::isEffect);
|
||||
g_lua.bindClassMemberFunction<Thing>("isMissile", &Thing::isMissile);
|
||||
g_lua.bindClassMemberFunction<Thing>("isPlayer", &Thing::isPlayer);
|
||||
g_lua.bindClassMemberFunction<Thing>("isLocalPlayer", &Thing::isLocalPlayer);
|
||||
g_lua.bindClassMemberFunction<Thing>("isAnimatedText", &Thing::isAnimatedText);
|
||||
g_lua.bindClassMemberFunction<Thing>("isStaticText", &Thing::isStaticText);
|
||||
g_lua.bindClassMemberFunction<Thing>("isGround", &Thing::isGround);
|
||||
g_lua.bindClassMemberFunction<Thing>("isGroundBorder", &Thing::isGroundBorder);
|
||||
g_lua.bindClassMemberFunction<Thing>("isOnBottom", &Thing::isOnBottom);
|
||||
g_lua.bindClassMemberFunction<Thing>("isOnTop", &Thing::isOnTop);
|
||||
g_lua.bindClassMemberFunction<Thing>("isContainer", &Thing::isContainer);
|
||||
g_lua.bindClassMemberFunction<Thing>("isForceUse", &Thing::isForceUse);
|
||||
g_lua.bindClassMemberFunction<Thing>("isMultiUse", &Thing::isMultiUse);
|
||||
g_lua.bindClassMemberFunction<Thing>("isRotateable", &Thing::isRotateable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isNotMoveable", &Thing::isNotMoveable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isPickupable", &Thing::isPickupable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isIgnoreLook", &Thing::isIgnoreLook);
|
||||
g_lua.bindClassMemberFunction<Thing>("isStackable", &Thing::isStackable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isHookSouth", &Thing::isHookSouth);
|
||||
g_lua.bindClassMemberFunction<Thing>("isTranslucent", &Thing::isTranslucent);
|
||||
g_lua.bindClassMemberFunction<Thing>("isFullGround", &Thing::isFullGround);
|
||||
g_lua.bindClassMemberFunction<Thing>("isMarketable", &Thing::isMarketable);
|
||||
g_lua.bindClassMemberFunction<Thing>("getMarketData", &Thing::getMarketData);
|
||||
g_lua.bindClassMemberFunction<Thing>("isUsable", &Thing::isUsable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isWrapable", &Thing::isWrapable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isUnwrapable", &Thing::isUnwrapable);
|
||||
g_lua.bindClassMemberFunction<Thing>("isTopEffect", &Thing::isTopEffect);
|
||||
g_lua.bindClassMemberFunction<Thing>("isLyingCorpse", &Thing::isLyingCorpse);
|
||||
g_lua.bindClassMemberFunction<Thing>("getParentContainer", &Thing::getParentContainer);
|
||||
g_lua.bindClassMemberFunction<Thing>("hide", &Thing::hide);
|
||||
g_lua.bindClassMemberFunction<Thing>("show", &Thing::show);
|
||||
g_lua.bindClassMemberFunction<Thing>("setHidden", &Thing::setHidden);
|
||||
g_lua.bindClassMemberFunction<Thing>("isHidden", &Thing::isHidden);
|
||||
|
||||
g_lua.registerClass<House>();
|
||||
g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); });
|
||||
g_lua.bindClassMemberFunction<House>("setId", &House::setId);
|
||||
g_lua.bindClassMemberFunction<House>("getId", &House::getId);
|
||||
g_lua.bindClassMemberFunction<House>("setName", &House::setName);
|
||||
g_lua.bindClassMemberFunction<House>("getName", &House::getName);
|
||||
g_lua.bindClassMemberFunction<House>("setTownId", &House::setTownId);
|
||||
g_lua.bindClassMemberFunction<House>("getTownId", &House::getTownId);
|
||||
g_lua.bindClassMemberFunction<House>("setTile", &House::setTile);
|
||||
g_lua.bindClassMemberFunction<House>("getTile", &House::getTile);
|
||||
g_lua.bindClassMemberFunction<House>("setEntry", &House::setEntry);
|
||||
g_lua.bindClassMemberFunction<House>("getEntry", &House::getEntry);
|
||||
g_lua.bindClassMemberFunction<House>("addDoor", &House::addDoor);
|
||||
g_lua.bindClassMemberFunction<House>("removeDoor", &House::removeDoor);
|
||||
g_lua.bindClassMemberFunction<House>("removeDoorById", &House::removeDoorById);
|
||||
g_lua.bindClassMemberFunction<House>("setSize", &House::setSize);
|
||||
g_lua.bindClassMemberFunction<House>("getSize", &House::getSize);
|
||||
g_lua.bindClassMemberFunction<House>("setRent", &House::setRent);
|
||||
g_lua.bindClassMemberFunction<House>("getRent", &House::getRent);
|
||||
|
||||
g_lua.registerClass<Spawn>();
|
||||
g_lua.bindClassStaticFunction<Spawn>("create", []{ return SpawnPtr(new Spawn); });
|
||||
g_lua.bindClassMemberFunction<Spawn>("setRadius", &Spawn::setRadius);
|
||||
g_lua.bindClassMemberFunction<Spawn>("getRadius", &Spawn::getRadius);
|
||||
g_lua.bindClassMemberFunction<Spawn>("setCenterPos", &Spawn::setCenterPos);
|
||||
g_lua.bindClassMemberFunction<Spawn>("getCenterPos", &Spawn::getCenterPos);
|
||||
g_lua.bindClassMemberFunction<Spawn>("addCreature", &Spawn::addCreature);
|
||||
g_lua.bindClassMemberFunction<Spawn>("removeCreature", &Spawn::removeCreature);
|
||||
g_lua.bindClassMemberFunction<Spawn>("getCreatures", &Spawn::getCreatures);
|
||||
|
||||
g_lua.registerClass<Town>();
|
||||
g_lua.bindClassStaticFunction<Town>("create", []{ return TownPtr(new Town); });
|
||||
g_lua.bindClassMemberFunction<Town>("setId", &Town::setId);
|
||||
g_lua.bindClassMemberFunction<Town>("setName", &Town::setName);
|
||||
g_lua.bindClassMemberFunction<Town>("setPos", &Town::setPos);
|
||||
g_lua.bindClassMemberFunction<Town>("setTemplePos", &Town::setPos); // alternative method
|
||||
g_lua.bindClassMemberFunction<Town>("getId", &Town::getId);
|
||||
g_lua.bindClassMemberFunction<Town>("getName", &Town::getName);
|
||||
g_lua.bindClassMemberFunction<Town>("getPos", &Town::getPos);
|
||||
g_lua.bindClassMemberFunction<Town>("getTemplePos", &Town::getPos); // alternative method
|
||||
|
||||
g_lua.registerClass<CreatureType>();
|
||||
g_lua.bindClassStaticFunction<CreatureType>("create", []{ return CreatureTypePtr(new CreatureType); });
|
||||
g_lua.bindClassMemberFunction<CreatureType>("setName", &CreatureType::setName);
|
||||
g_lua.bindClassMemberFunction<CreatureType>("setOutfit", &CreatureType::setOutfit);
|
||||
g_lua.bindClassMemberFunction<CreatureType>("setSpawnTime", &CreatureType::setSpawnTime);
|
||||
g_lua.bindClassMemberFunction<CreatureType>("getName", &CreatureType::getName);
|
||||
g_lua.bindClassMemberFunction<CreatureType>("getOutfit", &CreatureType::getOutfit);
|
||||
g_lua.bindClassMemberFunction<CreatureType>("getSpawnTime", &CreatureType::getSpawnTime);
|
||||
g_lua.bindClassMemberFunction<CreatureType>("cast", &CreatureType::cast);
|
||||
|
||||
g_lua.registerClass<Creature, Thing>();
|
||||
g_lua.bindClassStaticFunction<Creature>("create", []{ return CreaturePtr(new Creature); });
|
||||
g_lua.bindClassMemberFunction<Creature>("getId", &Creature::getId);
|
||||
g_lua.bindClassMemberFunction<Creature>("getName", &Creature::getName);
|
||||
g_lua.bindClassMemberFunction<Creature>("setName", &Creature::setName);
|
||||
g_lua.bindClassMemberFunction<Creature>("setManaPercent", &LocalPlayer::setManaPercent);
|
||||
g_lua.bindClassMemberFunction<Creature>("getManaPercent", &LocalPlayer::getManaPercent);
|
||||
g_lua.bindClassMemberFunction<Creature>("setHealthPercent", &Creature::setHealthPercent);
|
||||
g_lua.bindClassMemberFunction<Creature>("getHealthPercent", &Creature::getHealthPercent);
|
||||
g_lua.bindClassMemberFunction<Creature>("getSpeed", &Creature::getSpeed);
|
||||
g_lua.bindClassMemberFunction<Creature>("setSpeed", &Creature::setSpeed);
|
||||
g_lua.bindClassMemberFunction<Creature>("getBaseSpeed", &Creature::getBaseSpeed);
|
||||
g_lua.bindClassMemberFunction<Creature>("setBaseSpeed", &Creature::setBaseSpeed);
|
||||
g_lua.bindClassMemberFunction<Creature>("getSkull", &Creature::getSkull);
|
||||
g_lua.bindClassMemberFunction<Creature>("getShield", &Creature::getShield);
|
||||
g_lua.bindClassMemberFunction<Creature>("getEmblem", &Creature::getEmblem);
|
||||
g_lua.bindClassMemberFunction<Creature>("setSkull", &Creature::setSkull);
|
||||
g_lua.bindClassMemberFunction<Creature>("setShield", &Creature::setShield);
|
||||
g_lua.bindClassMemberFunction<Creature>("setEmblem", &Creature::setEmblem);
|
||||
g_lua.bindClassMemberFunction<Creature>("getType", &Creature::getType);
|
||||
g_lua.bindClassMemberFunction<Creature>("getIcon", &Creature::getIcon);
|
||||
g_lua.bindClassMemberFunction<Creature>("setOutfit", &Creature::setOutfit);
|
||||
g_lua.bindClassMemberFunction<Creature>("getOutfit", &Creature::getOutfit);
|
||||
g_lua.bindClassMemberFunction<Creature>("setOutfitColor", &Creature::setOutfitColor);
|
||||
g_lua.bindClassMemberFunction<Creature>("getDirection", &Creature::getDirection);
|
||||
g_lua.bindClassMemberFunction<Creature>("getWalkDirection", &Creature::getWalkDirection);
|
||||
g_lua.bindClassMemberFunction<Creature>("getStepDuration", &Creature::getStepDuration);
|
||||
g_lua.bindClassMemberFunction<Creature>("getStepProgress", &Creature::getStepProgress);
|
||||
g_lua.bindClassMemberFunction<Creature>("getWalkTicksElapsed", &Creature::getWalkTicksElapsed);
|
||||
g_lua.bindClassMemberFunction<Creature>("getStepTicksLeft", &Creature::getStepTicksLeft);
|
||||
g_lua.bindClassMemberFunction<Creature>("setDirection", &Creature::setDirection);
|
||||
g_lua.bindClassMemberFunction<Creature>("setSkullTexture", &Creature::setSkullTexture);
|
||||
g_lua.bindClassMemberFunction<Creature>("setShieldTexture", &Creature::setShieldTexture);
|
||||
g_lua.bindClassMemberFunction<Creature>("setEmblemTexture", &Creature::setEmblemTexture);
|
||||
g_lua.bindClassMemberFunction<Creature>("setTypeTexture", &Creature::setTypeTexture);
|
||||
g_lua.bindClassMemberFunction<Creature>("setIconTexture", &Creature::setIconTexture);
|
||||
g_lua.bindClassMemberFunction<Creature>("showStaticSquare", &Creature::showStaticSquare);
|
||||
g_lua.bindClassMemberFunction<Creature>("hideStaticSquare", &Creature::hideStaticSquare);
|
||||
g_lua.bindClassMemberFunction<Creature>("isWalking", &Creature::isWalking);
|
||||
g_lua.bindClassMemberFunction<Creature>("isInvisible", &Creature::isInvisible);
|
||||
g_lua.bindClassMemberFunction<Creature>("isDead", &Creature::isDead);
|
||||
g_lua.bindClassMemberFunction<Creature>("isRemoved", &Creature::isRemoved);
|
||||
g_lua.bindClassMemberFunction<Creature>("canBeSeen", &Creature::canBeSeen);
|
||||
g_lua.bindClassMemberFunction<Creature>("canShoot", &Creature::canShoot);
|
||||
g_lua.bindClassMemberFunction<Creature>("jump", &Creature::jump);
|
||||
g_lua.bindClassMemberFunction<Creature>("getPrewalkingPosition", &Creature::getPrewalkingPosition);
|
||||
g_lua.bindClassMemberFunction<Creature>("setInformationColor", &Creature::setInformationColor);
|
||||
g_lua.bindClassMemberFunction<Creature>("resetInformationColor", &Creature::resetInformationColor);
|
||||
g_lua.bindClassMemberFunction<Creature>("setInformationOffset", &Creature::setInformationOffset);
|
||||
g_lua.bindClassMemberFunction<Creature>("getInformationOffset", &Creature::getInformationOffset);
|
||||
g_lua.bindClassMemberFunction<Creature>("setText", &Creature::setText);
|
||||
g_lua.bindClassMemberFunction<Creature>("getText", &Creature::getText);
|
||||
g_lua.bindClassMemberFunction<Creature>("clearText", &Creature::clearText);
|
||||
|
||||
// widgets
|
||||
g_lua.bindClassMemberFunction<Creature>("addTopWidget", &Creature::addTopWidget);
|
||||
g_lua.bindClassMemberFunction<Creature>("addBottomWidget", &Creature::addBottomWidget);
|
||||
g_lua.bindClassMemberFunction<Creature>("addDirectionalWidget", &Creature::addDirectionalWidget);
|
||||
g_lua.bindClassMemberFunction<Creature>("removeTopWidget", &Creature::removeTopWidget);
|
||||
g_lua.bindClassMemberFunction<Creature>("removeBottomWidget", &Creature::removeBottomWidget);
|
||||
g_lua.bindClassMemberFunction<Creature>("removeDirectionalWidget", &Creature::removeDirectionalWidget);
|
||||
g_lua.bindClassMemberFunction<Creature>("getTopWidgets", &Creature::getTopWidgets);
|
||||
g_lua.bindClassMemberFunction<Creature>("getBottomWidgets", &Creature::getBottomWidgets);
|
||||
g_lua.bindClassMemberFunction<Creature>("getDirectionalWdigets", &Creature::getDirectionalWdigets);
|
||||
g_lua.bindClassMemberFunction<Creature>("clearWidgets", &Creature::clearWidgets);
|
||||
g_lua.bindClassMemberFunction<Creature>("clearTopWidgets", &Creature::clearTopWidgets);
|
||||
g_lua.bindClassMemberFunction<Creature>("clearBottomWidgets", &Creature::clearBottomWidgets);
|
||||
g_lua.bindClassMemberFunction<Creature>("clearDirectionalWidgets", &Creature::clearDirectionalWidgets);
|
||||
|
||||
// progress bar
|
||||
g_lua.bindClassMemberFunction<Creature>("setProgressBar", &Creature::setProgressBar);
|
||||
g_lua.bindClassMemberFunction<Creature>("getProgressBarPercent", &Creature::getProgressBarPercent);
|
||||
|
||||
|
||||
g_lua.registerClass<ItemType>();
|
||||
g_lua.bindClassMemberFunction<ItemType>("getServerId", &ItemType::getServerId);
|
||||
g_lua.bindClassMemberFunction<ItemType>("getClientId", &ItemType::getClientId);
|
||||
g_lua.bindClassMemberFunction<ItemType>("isWritable", &ItemType::isWritable);
|
||||
|
||||
g_lua.registerClass<ThingType>();
|
||||
g_lua.bindClassStaticFunction<ThingType>("create", []{ return ThingTypePtr(new ThingType); });
|
||||
g_lua.bindClassMemberFunction<ThingType>("getId", &ThingType::getId);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getClothSlot", &ThingType::getClothSlot);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getCategory", &ThingType::getCategory);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getSize", &ThingType::getSize);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getWidth", &ThingType::getWidth);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getHeight", &ThingType::getHeight);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getDisplacement", &ThingType::getDisplacement);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getDisplacementX", &ThingType::getDisplacementX);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getDisplacementY", &ThingType::getDisplacementY);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getExactSize", &ThingType::getExactSize);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getRealSize", &ThingType::getRealSize);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getLayers", &ThingType::getLayers);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getNumPatternX", &ThingType::getNumPatternX);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getNumPatternY", &ThingType::getNumPatternY);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getNumPatternZ", &ThingType::getNumPatternZ);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getAnimationPhases", &ThingType::getAnimationPhases);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getGroundSpeed", &ThingType::getGroundSpeed);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getMaxTextLength", &ThingType::getMaxTextLength);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getLight", &ThingType::getLight);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getMinimapColor", &ThingType::getMinimapColor);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getLensHelp", &ThingType::getLensHelp);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getClothSlot", &ThingType::getClothSlot);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getElevation", &ThingType::getElevation);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isGround", &ThingType::isGround);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isGroundBorder", &ThingType::isGroundBorder);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isOnBottom", &ThingType::isOnBottom);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isOnTop", &ThingType::isOnTop);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isContainer", &ThingType::isContainer);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isStackable", &ThingType::isStackable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isForceUse", &ThingType::isForceUse);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isMultiUse", &ThingType::isMultiUse);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isWritable", &ThingType::isWritable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isChargeable", &ThingType::isChargeable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isWritableOnce", &ThingType::isWritableOnce);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isFluidContainer", &ThingType::isFluidContainer);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isSplash", &ThingType::isSplash);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isNotWalkable", &ThingType::isNotWalkable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isNotMoveable", &ThingType::isNotMoveable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("blockProjectile", &ThingType::blockProjectile);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isNotPathable", &ThingType::isNotPathable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("setPathable", &ThingType::setPathable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isPickupable", &ThingType::isPickupable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isHangable", &ThingType::isHangable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isHookSouth", &ThingType::isHookSouth);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isHookEast", &ThingType::isHookEast);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isRotateable", &ThingType::isRotateable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("hasLight", &ThingType::hasLight);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isDontHide", &ThingType::isDontHide);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isTranslucent", &ThingType::isTranslucent);
|
||||
g_lua.bindClassMemberFunction<ThingType>("hasDisplacement", &ThingType::hasDisplacement);
|
||||
g_lua.bindClassMemberFunction<ThingType>("hasElevation", &ThingType::hasElevation);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isLyingCorpse", &ThingType::isLyingCorpse);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isAnimateAlways", &ThingType::isAnimateAlways);
|
||||
g_lua.bindClassMemberFunction<ThingType>("hasMiniMapColor", &ThingType::hasMiniMapColor);
|
||||
g_lua.bindClassMemberFunction<ThingType>("hasLensHelp", &ThingType::hasLensHelp);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isFullGround", &ThingType::isFullGround);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isIgnoreLook", &ThingType::isIgnoreLook);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isCloth", &ThingType::isCloth);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isMarketable", &ThingType::isMarketable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getMarketData", &ThingType::getMarketData);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isUsable", &ThingType::isUsable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isWrapable", &ThingType::isWrapable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isUnwrapable", &ThingType::isUnwrapable);
|
||||
g_lua.bindClassMemberFunction<ThingType>("isTopEffect", &ThingType::isTopEffect);
|
||||
g_lua.bindClassMemberFunction<ThingType>("getSprites", &ThingType::getSprites);
|
||||
g_lua.bindClassMemberFunction<ThingType>("hasAttribute", &ThingType::hasAttr);
|
||||
g_lua.bindClassMemberFunction<ThingType>("exportImage", &ThingType::exportImage);
|
||||
|
||||
g_lua.registerClass<Item, Thing>();
|
||||
g_lua.bindClassStaticFunction<Item>("create", &Item::create);
|
||||
g_lua.bindClassStaticFunction<Item>("createOtb", &Item::createFromOtb);
|
||||
g_lua.bindClassMemberFunction<Item>("clone", &Item::clone);
|
||||
g_lua.bindClassMemberFunction<Item>("getContainerItems", &Item::getContainerItems);
|
||||
g_lua.bindClassMemberFunction<Item>("getContainerItem", &Item::getContainerItem);
|
||||
g_lua.bindClassMemberFunction<Item>("addContainerItem", &Item::addContainerItem);
|
||||
g_lua.bindClassMemberFunction<Item>("addContainerItemIndexed", &Item::addContainerItemIndexed);
|
||||
g_lua.bindClassMemberFunction<Item>("removeContainerItem", &Item::removeContainerItem);
|
||||
g_lua.bindClassMemberFunction<Item>("clearContainerItems", &Item::clearContainerItems);
|
||||
g_lua.bindClassMemberFunction<Item>("getContainerItem", &Item::getContainerItem);
|
||||
g_lua.bindClassMemberFunction<Item>("setCount", &Item::setCount);
|
||||
g_lua.bindClassMemberFunction<Item>("getCount", &Item::getCount);
|
||||
g_lua.bindClassMemberFunction<Item>("getSubType", &Item::getSubType);
|
||||
g_lua.bindClassMemberFunction<Item>("getCountOrSubType", &Item::getCountOrSubType);
|
||||
g_lua.bindClassMemberFunction<Item>("getId", &Item::getId);
|
||||
g_lua.bindClassMemberFunction<Item>("getServerId", &Item::getServerId);
|
||||
g_lua.bindClassMemberFunction<Item>("getName", &Item::getName);
|
||||
g_lua.bindClassMemberFunction<Item>("getDescription", &Item::getDescription);
|
||||
g_lua.bindClassMemberFunction<Item>("getText", &Item::getText);
|
||||
g_lua.bindClassMemberFunction<Item>("setDescription", &Item::setDescription);
|
||||
g_lua.bindClassMemberFunction<Item>("setText", &Item::setText);
|
||||
g_lua.bindClassMemberFunction<Item>("getUniqueId", &Item::getUniqueId);
|
||||
g_lua.bindClassMemberFunction<Item>("getActionId", &Item::getActionId);
|
||||
g_lua.bindClassMemberFunction<Item>("setUniqueId", &Item::setUniqueId);
|
||||
g_lua.bindClassMemberFunction<Item>("setActionId", &Item::setActionId);
|
||||
g_lua.bindClassMemberFunction<Item>("getTeleportDestination", &Item::getTeleportDestination);
|
||||
g_lua.bindClassMemberFunction<Item>("setTeleportDestination", &Item::setTeleportDestination);
|
||||
g_lua.bindClassMemberFunction<Item>("isStackable", &Item::isStackable);
|
||||
g_lua.bindClassMemberFunction<Item>("isMarketable", &Item::isMarketable);
|
||||
g_lua.bindClassMemberFunction<Item>("isFluidContainer", &Item::isFluidContainer);
|
||||
g_lua.bindClassMemberFunction<Item>("getMarketData", &Item::getMarketData);
|
||||
g_lua.bindClassMemberFunction<Item>("getClothSlot", &Item::getClothSlot);
|
||||
g_lua.bindClassMemberFunction<Item>("getTooltip", &Item::getTooltip);
|
||||
g_lua.bindClassMemberFunction<Item>("setTooltip", &Item::setTooltip);
|
||||
|
||||
g_lua.registerClass<Effect, Thing>();
|
||||
g_lua.bindClassStaticFunction<Effect>("create", []{ return EffectPtr(new Effect); });
|
||||
g_lua.bindClassMemberFunction<Effect>("setId", &Effect::setId);
|
||||
|
||||
g_lua.registerClass<Missile, Thing>();
|
||||
g_lua.bindClassStaticFunction<Missile>("create", []{ return MissilePtr(new Missile); });
|
||||
g_lua.bindClassMemberFunction<Missile>("setId", &Missile::setId);
|
||||
g_lua.bindClassMemberFunction<Missile>("getId", &Missile::getId);
|
||||
g_lua.bindClassMemberFunction<Missile>("getSource", &Missile::getSource);
|
||||
g_lua.bindClassMemberFunction<Missile>("getDestination", &Missile::getDestination);
|
||||
|
||||
g_lua.registerClass<StaticText, Thing>();
|
||||
g_lua.bindClassStaticFunction<StaticText>("create", []{ return StaticTextPtr(new StaticText); });
|
||||
g_lua.bindClassMemberFunction<StaticText>("addMessage", &StaticText::addMessage);
|
||||
g_lua.bindClassMemberFunction<StaticText>("addColoredMessage", &StaticText::addColoredMessage);
|
||||
g_lua.bindClassMemberFunction<StaticText>("setText", &StaticText::setText);
|
||||
g_lua.bindClassMemberFunction<StaticText>("setFont", &StaticText::setFont);
|
||||
g_lua.bindClassMemberFunction<StaticText>("setColor", &StaticText::setColor);
|
||||
g_lua.bindClassMemberFunction<StaticText>("getColor", &StaticText::getColor);
|
||||
g_lua.bindClassMemberFunction<StaticText>("getText", &StaticText::getText);
|
||||
|
||||
g_lua.registerClass<AnimatedText, Thing>();
|
||||
g_lua.bindClassMemberFunction<AnimatedText>("getText", &AnimatedText::getText);
|
||||
g_lua.bindClassMemberFunction<AnimatedText>("getOffset", &AnimatedText::getOffset);
|
||||
g_lua.bindClassMemberFunction<AnimatedText>("getColor", &AnimatedText::getColor);
|
||||
|
||||
g_lua.registerClass<Player, Creature>();
|
||||
g_lua.registerClass<Npc, Creature>();
|
||||
g_lua.registerClass<Monster, Creature>();
|
||||
|
||||
g_lua.registerClass<LocalPlayer, Player>();
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("unlockWalk", &LocalPlayer::unlockWalk);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("lockWalk", &LocalPlayer::lockWalk);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isWalkLocked", &LocalPlayer::isWalkLocked);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("canWalk", &LocalPlayer::canWalk);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setStates", &LocalPlayer::setStates);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setSkill", &LocalPlayer::setSkill);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setHealth", &LocalPlayer::setHealth);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setTotalCapacity", &LocalPlayer::setTotalCapacity);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setFreeCapacity", &LocalPlayer::setFreeCapacity);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setExperience", &LocalPlayer::setExperience);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setLevel", &LocalPlayer::setLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setMana", &LocalPlayer::setMana);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setMagicLevel", &LocalPlayer::setMagicLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setSoul", &LocalPlayer::setSoul);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setStamina", &LocalPlayer::setStamina);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setKnown", &LocalPlayer::setKnown);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("setInventoryItem", &LocalPlayer::setInventoryItem);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getStates", &LocalPlayer::getStates);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getSkillLevel", &LocalPlayer::getSkillLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getSkillBaseLevel", &LocalPlayer::getSkillBaseLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getSkillLevelPercent", &LocalPlayer::getSkillLevelPercent);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getHealth", &LocalPlayer::getHealth);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getMaxHealth", &LocalPlayer::getMaxHealth);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getFreeCapacity", &LocalPlayer::getFreeCapacity);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getExperience", &LocalPlayer::getExperience);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getLevel", &LocalPlayer::getLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getLevelPercent", &LocalPlayer::getLevelPercent);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getMana", &LocalPlayer::getMana);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getMaxMana", &LocalPlayer::getMaxMana);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getMagicLevel", &LocalPlayer::getMagicLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getMagicLevelPercent", &LocalPlayer::getMagicLevelPercent);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getSoul", &LocalPlayer::getSoul);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getStamina", &LocalPlayer::getStamina);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getOfflineTrainingTime", &LocalPlayer::getOfflineTrainingTime);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getRegenerationTime", &LocalPlayer::getRegenerationTime);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getBaseMagicLevel", &LocalPlayer::getBaseMagicLevel);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getTotalCapacity", &LocalPlayer::getTotalCapacity);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getInventoryItem", &LocalPlayer::getInventoryItem);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getVocation", &LocalPlayer::getVocation);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getBlessings", &LocalPlayer::getBlessings);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("hasSight", &LocalPlayer::hasSight);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isAutoWalking", &LocalPlayer::isAutoWalking);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isServerWalking", &LocalPlayer::isServerWalking);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("stopAutoWalk", &LocalPlayer::stopAutoWalk);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("autoWalk", &LocalPlayer::autoWalk);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("preWalk", &LocalPlayer::preWalk);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("dumpWalkMatrix", &LocalPlayer::dumpWalkMatrix);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("startServerWalking", &LocalPlayer::startServerWalking);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("finishServerWalking", &LocalPlayer::finishServerWalking);
|
||||
|
||||
g_lua.registerClass<Tile>();
|
||||
g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean);
|
||||
g_lua.bindClassMemberFunction<Tile>("addThing", &Tile::addThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThing", &Tile::getThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThings", &Tile::getThings);
|
||||
g_lua.bindClassMemberFunction<Tile>("getEffect", &Tile::getEffect);
|
||||
g_lua.bindClassMemberFunction<Tile>("getEffects", &Tile::getEffects);
|
||||
g_lua.bindClassMemberFunction<Tile>("getItems", &Tile::getItems);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThingStackPos", &Tile::getThingStackPos);
|
||||
g_lua.bindClassMemberFunction<Tile>("getThingCount", &Tile::getThingCount);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopThing", &Tile::getTopThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("removeThing", &Tile::removeThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopLookThing", &Tile::getTopLookThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopLookThingEx", &Tile::getTopLookThingEx);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopUseThing", &Tile::getTopUseThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopCreature", &Tile::getTopCreature);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopCreatureEx", &Tile::getTopCreatureEx);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopMoveThing", &Tile::getTopMoveThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopMultiUseThing", &Tile::getTopMultiUseThing);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTopMultiUseThingEx", &Tile::getTopMultiUseThingEx);
|
||||
g_lua.bindClassMemberFunction<Tile>("getPosition", &Tile::getPosition);
|
||||
g_lua.bindClassMemberFunction<Tile>("getDrawElevation", &Tile::getDrawElevation);
|
||||
g_lua.bindClassMemberFunction<Tile>("getCreatures", &Tile::getCreatures);
|
||||
g_lua.bindClassMemberFunction<Tile>("getGround", &Tile::getGround);
|
||||
g_lua.bindClassMemberFunction<Tile>("isWalkable", &Tile::isWalkable);
|
||||
g_lua.bindClassMemberFunction<Tile>("isHouseTile", &Tile::isHouseTile);
|
||||
g_lua.bindClassMemberFunction<Tile>("isFullGround", &Tile::isFullGround);
|
||||
g_lua.bindClassMemberFunction<Tile>("isFullyOpaque", &Tile::isFullyOpaque);
|
||||
g_lua.bindClassMemberFunction<Tile>("isLookPossible", &Tile::isLookPossible);
|
||||
g_lua.bindClassMemberFunction<Tile>("isBlockingProjectile", &Tile::isBlockingProjectile);
|
||||
g_lua.bindClassMemberFunction<Tile>("hasCreature", &Tile::hasCreature);
|
||||
g_lua.bindClassMemberFunction<Tile>("hasBlockingCreature", &Tile::hasBlockingCreature);
|
||||
g_lua.bindClassMemberFunction<Tile>("isEmpty", &Tile::isEmpty);
|
||||
g_lua.bindClassMemberFunction<Tile>("isClickable", &Tile::isClickable);
|
||||
g_lua.bindClassMemberFunction<Tile>("isPathable", &Tile::isPathable);
|
||||
g_lua.bindClassMemberFunction<Tile>("overwriteMinimapColor", &Tile::overwriteMinimapColor);
|
||||
g_lua.bindClassMemberFunction<Tile>("select", &Tile::select);
|
||||
g_lua.bindClassMemberFunction<Tile>("unselect", &Tile::unselect);
|
||||
g_lua.bindClassMemberFunction<Tile>("isSelected", &Tile::isSelected);
|
||||
g_lua.bindClassMemberFunction<Tile>("remFlag", &Tile::remFlag);
|
||||
g_lua.bindClassMemberFunction<Tile>("setFlag", &Tile::setFlag);
|
||||
g_lua.bindClassMemberFunction<Tile>("setFlags", &Tile::setFlags);
|
||||
g_lua.bindClassMemberFunction<Tile>("getFlags", &Tile::getFlags);
|
||||
g_lua.bindClassMemberFunction<Tile>("hasFlag", &Tile::hasFlag);
|
||||
g_lua.bindClassMemberFunction<Tile>("getElevation", &Tile::getElevation);
|
||||
g_lua.bindClassMemberFunction<Tile>("hasElevation", &Tile::hasElevation);
|
||||
g_lua.bindClassMemberFunction<Tile>("isBlocking", &Tile::isBlocking);
|
||||
g_lua.bindClassMemberFunction<Tile>("canShoot", &Tile::canShoot);
|
||||
// for bot
|
||||
g_lua.bindClassMemberFunction<Tile>("setText", &Tile::setText);
|
||||
g_lua.bindClassMemberFunction<Tile>("getText", &Tile::getText);
|
||||
g_lua.bindClassMemberFunction<Tile>("setTimer", &Tile::setTimer);
|
||||
g_lua.bindClassMemberFunction<Tile>("getTimer", &Tile::getTimer);
|
||||
g_lua.bindClassMemberFunction<Tile>("setFill", &Tile::setFill);
|
||||
|
||||
g_lua.registerClass<UIItem, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIItem>("create", []{ return UIItemPtr(new UIItem); });
|
||||
g_lua.bindClassMemberFunction<UIItem>("setItemId", &UIItem::setItemId);
|
||||
g_lua.bindClassMemberFunction<UIItem>("setItemCount", &UIItem::setItemCount);
|
||||
g_lua.bindClassMemberFunction<UIItem>("setItemSubType", &UIItem::setItemSubType);
|
||||
g_lua.bindClassMemberFunction<UIItem>("setItemVisible", &UIItem::setItemVisible);
|
||||
g_lua.bindClassMemberFunction<UIItem>("setItem", &UIItem::setItem);
|
||||
g_lua.bindClassMemberFunction<UIItem>("setVirtual", &UIItem::setVirtual);
|
||||
g_lua.bindClassMemberFunction<UIItem>("setShowCount", &UIItem::setShowCount);
|
||||
g_lua.bindClassMemberFunction<UIItem>("clearItem", &UIItem::clearItem);
|
||||
g_lua.bindClassMemberFunction<UIItem>("getItemId", &UIItem::getItemId);
|
||||
g_lua.bindClassMemberFunction<UIItem>("getItemCount", &UIItem::getItemCount);
|
||||
g_lua.bindClassMemberFunction<UIItem>("getItemSubType", &UIItem::getItemSubType);
|
||||
g_lua.bindClassMemberFunction<UIItem>("getItemCountOrSubType", &UIItem::getItemCountOrSubType);
|
||||
g_lua.bindClassMemberFunction<UIItem>("getItem", &UIItem::getItem);
|
||||
g_lua.bindClassMemberFunction<UIItem>("isVirtual", &UIItem::isVirtual);
|
||||
g_lua.bindClassMemberFunction<UIItem>("isItemVisible", &UIItem::isItemVisible);
|
||||
|
||||
g_lua.registerClass<UISprite, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UISprite>("create", []{ return UISpritePtr(new UISprite); });
|
||||
g_lua.bindClassMemberFunction<UISprite>("setSpriteId", &UISprite::setSpriteId);
|
||||
g_lua.bindClassMemberFunction<UISprite>("clearSprite", &UISprite::clearSprite);
|
||||
g_lua.bindClassMemberFunction<UISprite>("getSpriteId", &UISprite::getSpriteId);
|
||||
g_lua.bindClassMemberFunction<UISprite>("setSpriteColor", &UISprite::setSpriteColor);
|
||||
g_lua.bindClassMemberFunction<UISprite>("hasSprite", &UISprite::hasSprite);
|
||||
|
||||
g_lua.registerClass<UICreature, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UICreature>("create", []{ return UICreaturePtr(new UICreature); } );
|
||||
g_lua.bindClassMemberFunction<UICreature>("setCreature", &UICreature::setCreature);
|
||||
g_lua.bindClassMemberFunction<UICreature>("setOutfit", &UICreature::setOutfit);
|
||||
g_lua.bindClassMemberFunction<UICreature>("setFixedCreatureSize", &UICreature::setFixedCreatureSize);
|
||||
g_lua.bindClassMemberFunction<UICreature>("getCreature", &UICreature::getCreature);
|
||||
g_lua.bindClassMemberFunction<UICreature>("getOutfit", &UICreature::getOutfit);
|
||||
g_lua.bindClassMemberFunction<UICreature>("isFixedCreatureSize", &UICreature::isFixedCreatureSize);
|
||||
g_lua.bindClassMemberFunction<UICreature>("setAutoRotating", &UICreature::setAutoRotating);
|
||||
g_lua.bindClassMemberFunction<UICreature>("setDirection", &UICreature::setDirection);
|
||||
g_lua.bindClassMemberFunction<UICreature>("setScale", &UICreature::setScale);
|
||||
g_lua.bindClassMemberFunction<UICreature>("getScale", &UICreature::getScale);
|
||||
|
||||
g_lua.registerClass<UIMap, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIMap>("create", []{ return UIMapPtr(new UIMap); });
|
||||
g_lua.bindClassMemberFunction<UIMap>("drawSelf", &UIMap::drawSelf);
|
||||
g_lua.bindClassMemberFunction<UIMap>("movePixels", &UIMap::movePixels);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setZoom", &UIMap::setZoom);
|
||||
g_lua.bindClassMemberFunction<UIMap>("zoomIn", &UIMap::zoomIn);
|
||||
g_lua.bindClassMemberFunction<UIMap>("zoomOut", &UIMap::zoomOut);
|
||||
g_lua.bindClassMemberFunction<UIMap>("followCreature", &UIMap::followCreature);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setCameraPosition", &UIMap::setCameraPosition);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setMaxZoomIn", &UIMap::setMaxZoomIn);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setMaxZoomOut", &UIMap::setMaxZoomOut);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setMultifloor", &UIMap::setMultifloor);
|
||||
g_lua.bindClassMemberFunction<UIMap>("lockVisibleFloor", &UIMap::lockVisibleFloor);
|
||||
g_lua.bindClassMemberFunction<UIMap>("unlockVisibleFloor", &UIMap::unlockVisibleFloor);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setVisibleDimension", &UIMap::setVisibleDimension);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawFlags", &UIMap::setDrawFlags);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawTexts", &UIMap::setDrawTexts);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawNames", &UIMap::setDrawNames);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawHealthBars", &UIMap::setDrawHealthBars);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawHealthBarsOnTop", &UIMap::setDrawHealthBarsOnTop);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawLights", &UIMap::setDrawLights);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawManaBar", &UIMap::setDrawManaBar);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setDrawPlayerBars", &UIMap::setDrawPlayerBars);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setAnimated", &UIMap::setAnimated);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setKeepAspectRatio", &UIMap::setKeepAspectRatio);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setMinimumAmbientLight", &UIMap::setMinimumAmbientLight);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setLimitVisibleRange", &UIMap::setLimitVisibleRange);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setFloorFading", &UIMap::setFloorFading);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setCrosshair", &UIMap::setCrosshair);
|
||||
g_lua.bindClassMemberFunction<UIMap>("setShader", &UIMap::setShader);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isMultifloor", &UIMap::isMultifloor);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isDrawingTexts", &UIMap::isDrawingTexts);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isDrawingNames", &UIMap::isDrawingNames);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isDrawingHealthBars", &UIMap::isDrawingHealthBars);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isDrawingHealthBarsOnTop", &UIMap::isDrawingHealthBarsOnTop);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isDrawingLights", &UIMap::isDrawingLights);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isDrawingManaBar", &UIMap::isDrawingManaBar);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isLimitVisibleRangeEnabled", &UIMap::isLimitVisibleRangeEnabled);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isAnimating", &UIMap::isAnimating);
|
||||
g_lua.bindClassMemberFunction<UIMap>("isKeepAspectRatioEnabled", &UIMap::isKeepAspectRatioEnabled);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getVisibleDimension", &UIMap::getVisibleDimension);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getFollowingCreature", &UIMap::getFollowingCreature);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getDrawFlags", &UIMap::getDrawFlags);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getCameraPosition", &UIMap::getCameraPosition);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getPosition", &UIMap::getPosition);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getPositionOffset", &UIMap::getPositionOffset);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getTile", &UIMap::getTile);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getMaxZoomIn", &UIMap::getMaxZoomIn);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getMaxZoomOut", &UIMap::getMaxZoomOut);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getZoom", &UIMap::getZoom);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getMinimumAmbientLight", &UIMap::getMinimumAmbientLight);
|
||||
g_lua.bindClassMemberFunction<UIMap>("getShader", &UIMap::getShader);
|
||||
|
||||
g_lua.registerClass<UIMinimap, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIMinimap>("create", []{ return UIMinimapPtr(new UIMinimap); });
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("zoomIn", &UIMinimap::zoomIn);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("zoomOut", &UIMinimap::zoomOut);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("setZoom", &UIMinimap::setZoom);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("setMixZoom", &UIMinimap::setMinZoom);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("setMaxZoom", &UIMinimap::setMaxZoom);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("setCameraPosition", &UIMinimap::setCameraPosition);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("floorUp", &UIMinimap::floorUp);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("floorDown", &UIMinimap::floorDown);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getTilePoint", &UIMinimap::getTilePoint);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getTilePosition", &UIMinimap::getTilePosition);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getTileRect", &UIMinimap::getTileRect);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getCameraPosition", &UIMinimap::getCameraPosition);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getZoom", &UIMinimap::getZoom);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("getScale", &UIMinimap::getScale);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("anchorPosition", &UIMinimap::anchorPosition);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("fillPosition", &UIMinimap::fillPosition);
|
||||
g_lua.bindClassMemberFunction<UIMinimap>("centerInPosition", &UIMinimap::centerInPosition);
|
||||
|
||||
g_lua.registerClass<UIProgressRect, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIProgressRect>("create", []{ return UIProgressRectPtr(new UIProgressRect); } );
|
||||
g_lua.bindClassMemberFunction<UIProgressRect>("setPercent", &UIProgressRect::setPercent);
|
||||
g_lua.bindClassMemberFunction<UIProgressRect>("getPercent", &UIProgressRect::getPercent);
|
||||
|
||||
g_lua.registerClass<UIMapAnchorLayout, UIAnchorLayout>();
|
||||
}
|
@ -1,337 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "luavaluecasts_client.h"
|
||||
#include <framework/luaengine/luainterface.h>
|
||||
|
||||
int push_luavalue(const Outfit& outfit)
|
||||
{
|
||||
g_lua.createTable(0, 8);
|
||||
g_lua.pushInteger(outfit.getId());
|
||||
g_lua.setField("type");
|
||||
g_lua.pushInteger(outfit.getAuxId());
|
||||
g_lua.setField("auxType");
|
||||
if(g_game.getFeature(Otc::GamePlayerAddons)) {
|
||||
g_lua.pushInteger(outfit.getAddons());
|
||||
g_lua.setField("addons");
|
||||
}
|
||||
g_lua.pushInteger(outfit.getHead());
|
||||
g_lua.setField("head");
|
||||
g_lua.pushInteger(outfit.getBody());
|
||||
g_lua.setField("body");
|
||||
g_lua.pushInteger(outfit.getLegs());
|
||||
g_lua.setField("legs");
|
||||
g_lua.pushInteger(outfit.getFeet());
|
||||
g_lua.setField("feet");
|
||||
if (g_game.getFeature(Otc::GamePlayerMounts)) {
|
||||
g_lua.pushInteger(outfit.getMount());
|
||||
g_lua.setField("mount");
|
||||
}
|
||||
if (g_game.getFeature(Otc::GameWingsAndAura)) {
|
||||
g_lua.pushInteger(outfit.getWings());
|
||||
g_lua.setField("wings");
|
||||
g_lua.pushInteger(outfit.getAura());
|
||||
g_lua.setField("aura");
|
||||
}
|
||||
if (g_game.getFeature(Otc::GameOutfitShaders)) {
|
||||
g_lua.pushString(outfit.getShader());
|
||||
g_lua.setField("shader");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, Outfit& outfit)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("type", index);
|
||||
outfit.setId(g_lua.popInteger());
|
||||
g_lua.getField("auxType", index);
|
||||
outfit.setAuxId(g_lua.popInteger());
|
||||
if(g_game.getFeature(Otc::GamePlayerAddons)) {
|
||||
g_lua.getField("addons", index);
|
||||
outfit.setAddons(g_lua.popInteger());
|
||||
}
|
||||
g_lua.getField("head", index);
|
||||
outfit.setHead(g_lua.popInteger());
|
||||
g_lua.getField("body", index);
|
||||
outfit.setBody(g_lua.popInteger());
|
||||
g_lua.getField("legs", index);
|
||||
outfit.setLegs(g_lua.popInteger());
|
||||
g_lua.getField("feet", index);
|
||||
outfit.setFeet(g_lua.popInteger());
|
||||
if (g_game.getFeature(Otc::GamePlayerMounts)) {
|
||||
g_lua.getField("mount", index);
|
||||
outfit.setMount(g_lua.popInteger());
|
||||
}
|
||||
if (g_game.getFeature(Otc::GameWingsAndAura)) {
|
||||
g_lua.getField("wings", index);
|
||||
outfit.setWings(g_lua.popInteger());
|
||||
g_lua.getField("aura", index);
|
||||
outfit.setAura(g_lua.popInteger());
|
||||
}
|
||||
//if (g_game.getFeature(Otc::GameOutfitShaders)) {
|
||||
g_lua.getField("shader", index);
|
||||
outfit.setShader(g_lua.popString());
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int push_luavalue(const Position& pos)
|
||||
{
|
||||
if(pos.isValid()) {
|
||||
g_lua.createTable(0, 3);
|
||||
g_lua.pushInteger(pos.x);
|
||||
g_lua.setField("x");
|
||||
g_lua.pushInteger(pos.y);
|
||||
g_lua.setField("y");
|
||||
g_lua.pushInteger(pos.z);
|
||||
g_lua.setField("z");
|
||||
} else
|
||||
g_lua.pushNil();
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, Position& pos)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("x", index);
|
||||
pos.x = g_lua.popInteger();
|
||||
g_lua.getField("y", index);
|
||||
pos.y = g_lua.popInteger();
|
||||
g_lua.getField("z", index);
|
||||
pos.z = g_lua.popInteger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int push_luavalue(const MarketData& data)
|
||||
{
|
||||
g_lua.createTable(0, 6);
|
||||
g_lua.pushInteger(data.category);
|
||||
g_lua.setField("category");
|
||||
g_lua.pushString(data.name);
|
||||
g_lua.setField("name");
|
||||
g_lua.pushInteger(data.requiredLevel);
|
||||
g_lua.setField("requiredLevel");
|
||||
g_lua.pushInteger(data.restrictVocation);
|
||||
g_lua.setField("restrictVocation");
|
||||
g_lua.pushInteger(data.showAs);
|
||||
g_lua.setField("showAs");
|
||||
g_lua.pushInteger(data.tradeAs);
|
||||
g_lua.setField("tradeAs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, MarketData& data)
|
||||
{
|
||||
if (g_lua.isTable(index)) {
|
||||
g_lua.getField("category", index);
|
||||
data.category = g_lua.popInteger();
|
||||
g_lua.getField("name", index);
|
||||
data.name = g_lua.popString();
|
||||
g_lua.getField("requiredLevel", index);
|
||||
data.requiredLevel = g_lua.popInteger();
|
||||
g_lua.getField("restrictVocation", index);
|
||||
data.restrictVocation = g_lua.popInteger();
|
||||
g_lua.getField("showAs", index);
|
||||
data.showAs = g_lua.popInteger();
|
||||
g_lua.getField("tradeAs", index);
|
||||
data.tradeAs = g_lua.popInteger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int push_luavalue(const StoreCategory& category)
|
||||
{
|
||||
g_lua.createTable(0, 5);
|
||||
g_lua.pushString(category.name);
|
||||
g_lua.setField("name");
|
||||
g_lua.pushString(category.description);
|
||||
g_lua.setField("description");
|
||||
g_lua.pushInteger(category.state);
|
||||
g_lua.setField("state");
|
||||
g_lua.pushString(category.icon);
|
||||
g_lua.setField("icon");
|
||||
g_lua.pushString(category.parent);
|
||||
g_lua.setField("parent");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, StoreCategory& data)
|
||||
{
|
||||
if (g_lua.isTable(index)) {
|
||||
g_lua.getField("name", index);
|
||||
data.name = g_lua.popString();
|
||||
g_lua.getField("description", index);
|
||||
data.description = g_lua.popString();
|
||||
g_lua.getField("state", index);
|
||||
data.state = g_lua.popInteger();
|
||||
g_lua.getField("icon", index);
|
||||
data.icon = g_lua.popString();
|
||||
g_lua.getField("parent", index);
|
||||
data.parent = g_lua.popString();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int push_luavalue(const StoreOffer& offer)
|
||||
{
|
||||
g_lua.createTable(0, 6);
|
||||
g_lua.pushInteger(offer.id);
|
||||
g_lua.setField("id");
|
||||
g_lua.pushString(offer.name);
|
||||
g_lua.setField("name");
|
||||
g_lua.pushString(offer.description);
|
||||
g_lua.setField("description");
|
||||
g_lua.pushInteger(offer.price);
|
||||
g_lua.setField("price");
|
||||
g_lua.pushInteger(offer.state);
|
||||
g_lua.setField("state");
|
||||
g_lua.pushString(offer.icon);
|
||||
g_lua.setField("icon");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, StoreOffer& data)
|
||||
{
|
||||
if (g_lua.isTable(index)) {
|
||||
g_lua.getField("id", index);
|
||||
data.id = g_lua.popInteger();
|
||||
g_lua.getField("name", index);
|
||||
data.name = g_lua.popString();
|
||||
g_lua.getField("description", index);
|
||||
data.description = g_lua.popString();
|
||||
g_lua.getField("state", index);
|
||||
data.state = g_lua.popInteger();
|
||||
g_lua.getField("price", index);
|
||||
data.price = g_lua.popInteger();
|
||||
g_lua.getField("icon", index);
|
||||
data.icon = g_lua.popString();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int push_luavalue(const Imbuement& i)
|
||||
{
|
||||
g_lua.createTable(0, 11);
|
||||
g_lua.pushInteger(i.id);
|
||||
g_lua.setField("id");
|
||||
g_lua.pushString(i.name);
|
||||
g_lua.setField("name");
|
||||
g_lua.pushString(i.description);
|
||||
g_lua.setField("description");
|
||||
g_lua.pushString(i.group);
|
||||
g_lua.setField("group");
|
||||
g_lua.pushInteger(i.imageId);
|
||||
g_lua.setField("imageId");
|
||||
g_lua.pushInteger(i.duration);
|
||||
g_lua.setField("duration");
|
||||
g_lua.pushBoolean(i.premiumOnly);
|
||||
g_lua.setField("premiumOnly");
|
||||
g_lua.createTable(i.sources.size(), 0);
|
||||
for (size_t j = 0; j < i.sources.size(); ++j) {
|
||||
g_lua.createTable(0, 2);
|
||||
g_lua.pushObject(i.sources[j].first);
|
||||
g_lua.setField("item");
|
||||
g_lua.pushString(i.sources[j].second);
|
||||
g_lua.setField("description");
|
||||
g_lua.rawSeti(j + 1);
|
||||
}
|
||||
g_lua.setField("sources");
|
||||
g_lua.pushInteger(i.cost);
|
||||
g_lua.setField("cost");
|
||||
g_lua.pushInteger(i.successRate);
|
||||
g_lua.setField("successRate");
|
||||
g_lua.pushInteger(i.protectionCost);
|
||||
g_lua.setField("protectionCost");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int push_luavalue(const Light& light)
|
||||
{
|
||||
g_lua.createTable(0, 2);
|
||||
g_lua.pushInteger(light.color);
|
||||
g_lua.setField("color");
|
||||
g_lua.pushInteger(light.intensity);
|
||||
g_lua.setField("intensity");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, Light& light)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("color", index);
|
||||
light.color = g_lua.popInteger();
|
||||
g_lua.getField("intensity", index);
|
||||
light.intensity = g_lua.popInteger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int push_luavalue(const UnjustifiedPoints& unjustifiedPoints)
|
||||
{
|
||||
g_lua.createTable(0, 7);
|
||||
g_lua.pushInteger(unjustifiedPoints.killsDay);
|
||||
g_lua.setField("killsDay");
|
||||
g_lua.pushInteger(unjustifiedPoints.killsDayRemaining);
|
||||
g_lua.setField("killsDayRemaining");
|
||||
g_lua.pushInteger(unjustifiedPoints.killsWeek);
|
||||
g_lua.setField("killsWeek");
|
||||
g_lua.pushInteger(unjustifiedPoints.killsWeekRemaining);
|
||||
g_lua.setField("killsWeekRemaining");
|
||||
g_lua.pushInteger(unjustifiedPoints.killsMonth);
|
||||
g_lua.setField("killsMonth");
|
||||
g_lua.pushInteger(unjustifiedPoints.killsMonthRemaining);
|
||||
g_lua.setField("killsMonthRemaining");
|
||||
g_lua.pushInteger(unjustifiedPoints.skullTime);
|
||||
g_lua.setField("skullTime");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool luavalue_cast(int index, UnjustifiedPoints& unjustifiedPoints)
|
||||
{
|
||||
if(g_lua.isTable(index)) {
|
||||
g_lua.getField("killsDay", index);
|
||||
unjustifiedPoints.killsDay = g_lua.popInteger();
|
||||
g_lua.getField("killsDayRemaining", index);
|
||||
unjustifiedPoints.killsDayRemaining = g_lua.popInteger();
|
||||
g_lua.getField("killsWeek", index);
|
||||
unjustifiedPoints.killsWeek = g_lua.popInteger();
|
||||
g_lua.getField("killsWeekRemaining", index);
|
||||
unjustifiedPoints.killsWeekRemaining = g_lua.popInteger();
|
||||
g_lua.getField("killsMonth", index);
|
||||
unjustifiedPoints.killsMonth = g_lua.popInteger();
|
||||
g_lua.getField("killsMonthRemaining", index);
|
||||
unjustifiedPoints.killsMonthRemaining = g_lua.popInteger();
|
||||
g_lua.getField("skullTime", index);
|
||||
unjustifiedPoints.skullTime = g_lua.popInteger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLIENT_LUAVALUECASTS_H
|
||||
#define CLIENT_LUAVALUECASTS_H
|
||||
|
||||
#include "global.h"
|
||||
#include <framework/luaengine/declarations.h>
|
||||
#include "game.h"
|
||||
#include "outfit.h"
|
||||
|
||||
// outfit
|
||||
int push_luavalue(const Outfit& outfit);
|
||||
bool luavalue_cast(int index, Outfit& outfit);
|
||||
|
||||
// position
|
||||
int push_luavalue(const Position& pos);
|
||||
bool luavalue_cast(int index, Position& pos);
|
||||
|
||||
// market
|
||||
int push_luavalue(const MarketData& data);
|
||||
bool luavalue_cast(int index, MarketData& data);
|
||||
|
||||
// store category
|
||||
int push_luavalue(const StoreCategory& category);
|
||||
bool luavalue_cast(int index, StoreCategory& data);
|
||||
|
||||
// store offer
|
||||
int push_luavalue(const StoreOffer& offer);
|
||||
bool luavalue_cast(int index, StoreOffer& offer);
|
||||
|
||||
// imbuement
|
||||
int push_luavalue(const Imbuement& offer);
|
||||
|
||||
// light
|
||||
int push_luavalue(const Light& light);
|
||||
bool luavalue_cast(int index, Light& light);
|
||||
|
||||
// unjustified points
|
||||
int push_luavalue(const UnjustifiedPoints& unjustifiedPoints);
|
||||
bool luavalue_cast(int index, UnjustifiedPoints& unjustifiedPoints);
|
||||
|
||||
#endif
|
1084
src/client/map.cpp
1084
src/client/map.cpp
File diff suppressed because it is too large
Load Diff
304
src/client/map.h
304
src/client/map.h
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
|
||||
#include "creature.h"
|
||||
#include "houses.h"
|
||||
#include "towns.h"
|
||||
#include "creatures.h"
|
||||
#include "animatedtext.h"
|
||||
#include "statictext.h"
|
||||
#include "tile.h"
|
||||
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
enum OTBM_ItemAttr
|
||||
{
|
||||
OTBM_ATTR_DESCRIPTION = 1,
|
||||
OTBM_ATTR_EXT_FILE = 2,
|
||||
OTBM_ATTR_TILE_FLAGS = 3,
|
||||
OTBM_ATTR_ACTION_ID = 4,
|
||||
OTBM_ATTR_UNIQUE_ID = 5,
|
||||
OTBM_ATTR_TEXT = 6,
|
||||
OTBM_ATTR_DESC = 7,
|
||||
OTBM_ATTR_TELE_DEST = 8,
|
||||
OTBM_ATTR_ITEM = 9,
|
||||
OTBM_ATTR_DEPOT_ID = 10,
|
||||
OTBM_ATTR_SPAWN_FILE = 11,
|
||||
OTBM_ATTR_RUNE_CHARGES = 12,
|
||||
OTBM_ATTR_HOUSE_FILE = 13,
|
||||
OTBM_ATTR_HOUSEDOORID = 14,
|
||||
OTBM_ATTR_COUNT = 15,
|
||||
OTBM_ATTR_DURATION = 16,
|
||||
OTBM_ATTR_DECAYING_STATE = 17,
|
||||
OTBM_ATTR_WRITTENDATE = 18,
|
||||
OTBM_ATTR_WRITTENBY = 19,
|
||||
OTBM_ATTR_SLEEPERGUID = 20,
|
||||
OTBM_ATTR_SLEEPSTART = 21,
|
||||
OTBM_ATTR_CHARGES = 22,
|
||||
OTBM_ATTR_CONTAINER_ITEMS = 23,
|
||||
OTBM_ATTR_ATTRIBUTE_MAP = 128,
|
||||
/// just random numbers, they're not actually used by the binary reader...
|
||||
OTBM_ATTR_WIDTH = 129,
|
||||
OTBM_ATTR_HEIGHT = 130
|
||||
};
|
||||
|
||||
enum OTBM_NodeTypes_t
|
||||
{
|
||||
OTBM_ROOTV2 = 1,
|
||||
OTBM_MAP_DATA = 2,
|
||||
OTBM_ITEM_DEF = 3,
|
||||
OTBM_TILE_AREA = 4,
|
||||
OTBM_TILE = 5,
|
||||
OTBM_ITEM = 6,
|
||||
OTBM_TILE_SQUARE = 7,
|
||||
OTBM_TILE_REF = 8,
|
||||
OTBM_SPAWNS = 9,
|
||||
OTBM_SPAWN_AREA = 10,
|
||||
OTBM_MONSTER = 11,
|
||||
OTBM_TOWNS = 12,
|
||||
OTBM_TOWN = 13,
|
||||
OTBM_HOUSETILE = 14,
|
||||
OTBM_WAYPOINTS = 15,
|
||||
OTBM_WAYPOINT = 16
|
||||
};
|
||||
|
||||
enum {
|
||||
OTCM_SIGNATURE = 0x4D43544F,
|
||||
OTCM_VERSION = 1
|
||||
};
|
||||
|
||||
enum {
|
||||
BLOCK_SIZE = 32
|
||||
};
|
||||
|
||||
enum : uint8 {
|
||||
Animation_Force,
|
||||
Animation_Show
|
||||
};
|
||||
|
||||
class TileBlock {
|
||||
public:
|
||||
TileBlock() { m_tiles.fill(nullptr); }
|
||||
|
||||
const TilePtr& create(const Position& pos) {
|
||||
TilePtr& tile = m_tiles[getTileIndex(pos)];
|
||||
tile = TilePtr(new Tile(pos));
|
||||
return tile;
|
||||
}
|
||||
const TilePtr& getOrCreate(const Position& pos) {
|
||||
TilePtr& tile = m_tiles[getTileIndex(pos)];
|
||||
if(!tile)
|
||||
tile = TilePtr(new Tile(pos));
|
||||
return tile;
|
||||
}
|
||||
const TilePtr& get(const Position& pos) { return m_tiles[getTileIndex(pos)]; }
|
||||
void remove(const Position& pos) { m_tiles[getTileIndex(pos)] = nullptr; }
|
||||
|
||||
uint getTileIndex(const Position& pos) { return ((pos.y % BLOCK_SIZE) * BLOCK_SIZE) + (pos.x % BLOCK_SIZE); }
|
||||
|
||||
const std::array<TilePtr, BLOCK_SIZE*BLOCK_SIZE>& getTiles() const { return m_tiles; }
|
||||
|
||||
private:
|
||||
std::array<TilePtr, BLOCK_SIZE*BLOCK_SIZE> m_tiles;
|
||||
};
|
||||
|
||||
struct AwareRange
|
||||
{
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
int left;
|
||||
|
||||
int horizontal() { return left + right + 1; }
|
||||
int vertical() { return top + bottom + 1; }
|
||||
};
|
||||
|
||||
struct PathFindResult
|
||||
{
|
||||
Otc::PathFindResult status = Otc::PathFindResultNoWay;
|
||||
std::vector<Otc::Direction> path;
|
||||
int complexity = 0;
|
||||
Position start;
|
||||
Position destination;
|
||||
};
|
||||
using PathFindResult_ptr = std::shared_ptr<PathFindResult>;
|
||||
|
||||
struct Node {
|
||||
float cost;
|
||||
float totalCost;
|
||||
Position pos;
|
||||
Node *prev;
|
||||
int distance;
|
||||
int unseen;
|
||||
};
|
||||
|
||||
//@bindsingleton g_map
|
||||
class Map
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
void addMapView(const MapViewPtr& mapView);
|
||||
void removeMapView(const MapViewPtr& mapView);
|
||||
void notificateTileUpdate(const Position& pos, bool updateMinimap = false);
|
||||
|
||||
void requestVisibleTilesCacheUpdate();
|
||||
|
||||
bool loadOtcm(const std::string& fileName);
|
||||
void saveOtcm(const std::string& fileName);
|
||||
|
||||
void loadOtbm(const std::string& fileName);
|
||||
void saveOtbm(const std::string& fileName);
|
||||
|
||||
// otbm attributes (description, size, etc.)
|
||||
void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); }
|
||||
void setSpawnFile(const std::string& file) { m_attribs.set(OTBM_ATTR_SPAWN_FILE, file); }
|
||||
void setDescription(const std::string& desc) { m_attribs.set(OTBM_ATTR_DESCRIPTION, desc); }
|
||||
|
||||
void clearDescriptions() { m_attribs.remove(OTBM_ATTR_DESCRIPTION); }
|
||||
void setWidth(uint16 w) { m_attribs.set(OTBM_ATTR_WIDTH, w); }
|
||||
void setHeight(uint16 h) { m_attribs.set(OTBM_ATTR_HEIGHT, h); }
|
||||
|
||||
std::string getHouseFile() { return m_attribs.get<std::string>(OTBM_ATTR_HOUSE_FILE); }
|
||||
std::string getSpawnFile() { return m_attribs.get<std::string>(OTBM_ATTR_SPAWN_FILE); }
|
||||
Size getSize() { return Size(m_attribs.get<uint16>(OTBM_ATTR_WIDTH), m_attribs.get<uint16>(OTBM_ATTR_HEIGHT)); }
|
||||
std::vector<std::string> getDescriptions() { return stdext::split(m_attribs.get<std::string>(OTBM_ATTR_DESCRIPTION), "\n"); }
|
||||
|
||||
void clean();
|
||||
void cleanDynamicThings();
|
||||
void cleanTexts();
|
||||
|
||||
// thing related
|
||||
void addThing(const ThingPtr& thing, const Position& pos, int stackPos = -1);
|
||||
void setTileSpeed(const Position & pos, uint16_t speed, uint8_t blocking);
|
||||
ThingPtr getThing(const Position& pos, int stackPos);
|
||||
bool removeThing(const ThingPtr& thing);
|
||||
bool removeThingByPos(const Position& pos, int stackPos);
|
||||
void colorizeThing(const ThingPtr& thing, const Color& color);
|
||||
void removeThingColor(const ThingPtr& thing);
|
||||
|
||||
StaticTextPtr getStaticText(const Position& pos);
|
||||
|
||||
// tile related
|
||||
const TilePtr& createTile(const Position& pos);
|
||||
template <typename... Items>
|
||||
const TilePtr& createTileEx(const Position& pos, const Items&... items);
|
||||
const TilePtr& getOrCreateTile(const Position& pos);
|
||||
const TilePtr& getTile(const Position& pos);
|
||||
const TileList getTiles(int floor = -1);
|
||||
void cleanTile(const Position& pos);
|
||||
|
||||
// tile zone related
|
||||
void setShowZone(tileflags_t zone, bool show);
|
||||
void setShowZones(bool show);
|
||||
void setZoneColor(tileflags_t flag, const Color& color);
|
||||
void setZoneOpacity(float opacity) { m_zoneOpacity = opacity; }
|
||||
|
||||
float getZoneOpacity() { return m_zoneOpacity; }
|
||||
Color getZoneColor(tileflags_t flag);
|
||||
tileflags_t getZoneFlags() { return (tileflags_t)m_zoneFlags; }
|
||||
bool showZones() { return m_zoneFlags != 0; }
|
||||
bool showZone(tileflags_t zone) { return (m_zoneFlags & zone) == zone; }
|
||||
|
||||
void setForceShowAnimations(bool force);
|
||||
bool isForcingAnimations();
|
||||
bool isShowingAnimations();
|
||||
void setShowAnimations(bool show);
|
||||
|
||||
std::map<Position, ItemPtr> findItemsById(uint16 clientId, uint32 max);
|
||||
|
||||
// known creature related
|
||||
void addCreature(const CreaturePtr& creature);
|
||||
CreaturePtr getCreatureById(uint32 id);
|
||||
void removeCreatureById(uint32 id);
|
||||
std::vector<CreaturePtr> getSightSpectators(const Position& centerPos, bool multiFloor);
|
||||
std::vector<CreaturePtr> getSpectators(const Position& centerPos, bool multiFloor);
|
||||
std::vector<CreaturePtr> getSpectatorsInRange(const Position& centerPos, bool multiFloor, int xRange, int yRange);
|
||||
std::vector<CreaturePtr> getSpectatorsInRangeEx(const Position& centerPos, bool multiFloor, int minXRange, int maxXRange, int minYRange, int maxYRange);
|
||||
|
||||
void setLight(const Light& light) { m_light = light; }
|
||||
void setCentralPosition(const Position& centralPosition);
|
||||
|
||||
bool isLookPossible(const Position& pos);
|
||||
bool isCovered(const Position& pos, int firstFloor = 0);
|
||||
bool isCompletelyCovered(const Position& pos, int firstFloor = 0);
|
||||
bool isAwareOfPosition(const Position& pos, bool extended = false);
|
||||
bool isAwareOfPositionForClean(const Position& pos, bool extended = false);
|
||||
|
||||
void setAwareRange(const AwareRange& range);
|
||||
void resetAwareRange();
|
||||
AwareRange getAwareRange() { return m_awareRange; }
|
||||
Size getAwareRangeAsSize() { return Size(m_awareRange.horizontal(), m_awareRange.vertical()); }
|
||||
|
||||
Light getLight() { return m_light; }
|
||||
Position getCentralPosition() { return m_centralPosition; }
|
||||
int getFirstAwareFloor();
|
||||
int getLastAwareFloor();
|
||||
const std::vector<MissilePtr>& getFloorMissiles(int z) { return m_floorMissiles[z]; }
|
||||
|
||||
std::vector<AnimatedTextPtr> getAnimatedTexts() { return m_animatedTexts; }
|
||||
std::vector<StaticTextPtr> getStaticTexts() { return m_staticTexts; }
|
||||
|
||||
std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> findPath(const Position& start, const Position& goal, int maxComplexity, int flags = 0);
|
||||
PathFindResult_ptr newFindPath(const Position& start, const Position& goal, std::shared_ptr<std::list<Node*>> visibleNodes);
|
||||
void findPathAsync(const Position & start, const Position & goal, std::function<void(PathFindResult_ptr)> callback);
|
||||
|
||||
// tuple = <cost, distance, prevPos>
|
||||
std::map<std::string, std::tuple<int, int, int, std::string>> findEveryPath(const Position& start, int maxDistance, const std::map<std::string, std::string>& params);
|
||||
|
||||
int getMinimapColor(const Position& pos);
|
||||
bool isPatchable(const Position& pos);
|
||||
bool isWalkable(const Position& pos, bool ignoreCreatures);
|
||||
|
||||
private:
|
||||
void removeUnawareThings();
|
||||
uint getBlockIndex(const Position& pos) { return ((pos.y / BLOCK_SIZE) * (65536 / BLOCK_SIZE)) + (pos.x / BLOCK_SIZE); }
|
||||
|
||||
std::map<uint, TileBlock> m_tileBlocks[Otc::MAX_Z+1];
|
||||
std::map<uint32, CreaturePtr> m_knownCreatures;
|
||||
std::array<std::vector<MissilePtr>, Otc::MAX_Z+1> m_floorMissiles;
|
||||
std::vector<AnimatedTextPtr> m_animatedTexts;
|
||||
std::vector<StaticTextPtr> m_staticTexts;
|
||||
std::vector<MapViewPtr> m_mapViews;
|
||||
std::unordered_map<Position, std::string, PositionHasher> m_waypoints;
|
||||
|
||||
uint8 m_animationFlags;
|
||||
uint32 m_zoneFlags;
|
||||
std::map<uint32, Color> m_zoneColors;
|
||||
float m_zoneOpacity;
|
||||
|
||||
Light m_light;
|
||||
Position m_centralPosition;
|
||||
Rect m_tilesRect;
|
||||
|
||||
stdext::packed_storage<uint8> m_attribs;
|
||||
AwareRange m_awareRange;
|
||||
static TilePtr m_nulltile;
|
||||
};
|
||||
|
||||
extern Map g_map;
|
||||
|
||||
#endif
|
@ -1,538 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
#include "game.h"
|
||||
|
||||
#include <framework/core/application.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/core/binarytree.h>
|
||||
#include <framework/xml/tinyxml.h>
|
||||
#include <framework/ui/uiwidget.h>
|
||||
|
||||
void Map::loadOtbm(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
if(!g_things.isOtbLoaded())
|
||||
stdext::throw_exception("OTB isn't loaded yet to load a map.");
|
||||
|
||||
FileStreamPtr fin = g_resources.openFile(fileName);
|
||||
if(!fin)
|
||||
stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
|
||||
|
||||
char identifier[4];
|
||||
if(fin->read(identifier, 1, 4) < 4)
|
||||
stdext::throw_exception("Could not read file identifier");
|
||||
|
||||
if(memcmp(identifier, "OTBM", 4) != 0 && memcmp(identifier, "\0\0\0\0", 4) != 0)
|
||||
stdext::throw_exception(stdext::format("Invalid file identifier detected: %s", identifier));
|
||||
|
||||
BinaryTreePtr root = fin->getBinaryTree();
|
||||
if(root->getU8())
|
||||
stdext::throw_exception("could not read root property!");
|
||||
|
||||
uint32 headerVersion = root->getU32();
|
||||
if(headerVersion > 3)
|
||||
stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));
|
||||
|
||||
setWidth(root->getU16());
|
||||
setHeight(root->getU16());
|
||||
|
||||
uint32 headerMajorItems = root->getU8();
|
||||
if(headerMajorItems > g_things.getOtbMajorVersion()) {
|
||||
stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d",
|
||||
headerMajorItems, g_things.getOtbMajorVersion()));
|
||||
}
|
||||
|
||||
root->skip(3);
|
||||
uint32 headerMinorItems = root->getU32();
|
||||
if(headerMinorItems > g_things.getOtbMinorVersion()) {
|
||||
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d or less",
|
||||
headerMinorItems, g_things.getOtbMinorVersion()));
|
||||
}
|
||||
|
||||
BinaryTreePtr node = root->getChildren()[0];
|
||||
if(node->getU8() != OTBM_MAP_DATA)
|
||||
stdext::throw_exception("Could not read root data node");
|
||||
|
||||
while(node->canRead()) {
|
||||
uint8 attribute = node->getU8();
|
||||
std::string tmp = node->getString();
|
||||
switch (attribute) {
|
||||
case OTBM_ATTR_DESCRIPTION:
|
||||
setDescription(tmp);
|
||||
break;
|
||||
case OTBM_ATTR_SPAWN_FILE:
|
||||
setSpawnFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
|
||||
break;
|
||||
case OTBM_ATTR_HOUSE_FILE:
|
||||
setHouseFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
|
||||
break;
|
||||
default:
|
||||
stdext::throw_exception(stdext::format("Invalid attribute '%d'", (int)attribute));
|
||||
}
|
||||
}
|
||||
|
||||
for(const BinaryTreePtr& nodeMapData : node->getChildren()) {
|
||||
uint8 mapDataType = nodeMapData->getU8();
|
||||
if(mapDataType == OTBM_TILE_AREA) {
|
||||
Position basePos;
|
||||
basePos.x = nodeMapData->getU16();
|
||||
basePos.y = nodeMapData->getU16();
|
||||
basePos.z = nodeMapData->getU8();
|
||||
|
||||
for(const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
|
||||
uint8 type = nodeTile->getU8();
|
||||
if(unlikely(type != OTBM_TILE && type != OTBM_HOUSETILE))
|
||||
stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type));
|
||||
|
||||
HousePtr house = nullptr;
|
||||
uint32 flags = TILESTATE_NONE;
|
||||
Position pos = basePos + nodeTile->getPoint();
|
||||
|
||||
if(type == OTBM_HOUSETILE) {
|
||||
uint32 hId = nodeTile->getU32();
|
||||
TilePtr tile = getOrCreateTile(pos);
|
||||
if(!(house = g_houses.getHouse(hId))) {
|
||||
house = HousePtr(new House(hId));
|
||||
g_houses.addHouse(house);
|
||||
}
|
||||
house->setTile(tile);
|
||||
}
|
||||
|
||||
while(nodeTile->canRead()) {
|
||||
uint8 tileAttr = nodeTile->getU8();
|
||||
switch(tileAttr) {
|
||||
case OTBM_ATTR_TILE_FLAGS: {
|
||||
uint32 _flags = nodeTile->getU32();
|
||||
if((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
|
||||
flags |= TILESTATE_PROTECTIONZONE;
|
||||
else if((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
|
||||
flags |= TILESTATE_OPTIONALZONE;
|
||||
else if((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
|
||||
flags |= TILESTATE_HARDCOREZONE;
|
||||
|
||||
if((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
|
||||
flags |= TILESTATE_NOLOGOUT;
|
||||
|
||||
if((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
|
||||
flags |= TILESTATE_REFRESH;
|
||||
break;
|
||||
}
|
||||
case OTBM_ATTR_ITEM: {
|
||||
addThing(Item::createFromOtb(nodeTile->getU16()), pos);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s",
|
||||
(int)tileAttr, stdext::to_string(pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
|
||||
if(unlikely(nodeItem->getU8() != OTBM_ITEM))
|
||||
stdext::throw_exception("invalid item node");
|
||||
|
||||
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
|
||||
item->unserializeItem(nodeItem);
|
||||
|
||||
if(item->isContainer()) {
|
||||
for(const BinaryTreePtr& containerItem : nodeItem->getChildren()) {
|
||||
if(containerItem->getU8() != OTBM_ITEM)
|
||||
stdext::throw_exception("invalid container item node");
|
||||
|
||||
ItemPtr cItem = Item::createFromOtb(containerItem->getU16());
|
||||
cItem->unserializeItem(containerItem);
|
||||
item->addContainerItem(cItem);
|
||||
}
|
||||
}
|
||||
|
||||
if(house && item->isMoveable()) {
|
||||
g_logger.warning(stdext::format("Moveable item found in house: %d at pos %s - escaping...", item->getId(), stdext::to_string(pos)));
|
||||
item.reset();
|
||||
}
|
||||
|
||||
addThing(item, pos);
|
||||
}
|
||||
|
||||
if(const TilePtr& tile = getTile(pos)) {
|
||||
if(house)
|
||||
tile->setFlag(TILESTATE_HOUSE);
|
||||
tile->setFlag(flags);
|
||||
}
|
||||
}
|
||||
} else if(mapDataType == OTBM_TOWNS) {
|
||||
TownPtr town = nullptr;
|
||||
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
|
||||
if(nodeTown->getU8() != OTBM_TOWN)
|
||||
stdext::throw_exception("invalid town node.");
|
||||
|
||||
uint32 townId = nodeTown->getU32();
|
||||
std::string townName = nodeTown->getString();
|
||||
|
||||
Position townCoords;
|
||||
townCoords.x = nodeTown->getU16();
|
||||
townCoords.y = nodeTown->getU16();
|
||||
townCoords.z = nodeTown->getU8();
|
||||
|
||||
if(!(town = g_towns.getTown(townId)))
|
||||
g_towns.addTown(TownPtr(new Town(townId, townName, townCoords)));
|
||||
}
|
||||
g_towns.sort();
|
||||
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
|
||||
for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
|
||||
if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
|
||||
stdext::throw_exception("invalid waypoint node.");
|
||||
|
||||
std::string name = nodeWaypoint->getString();
|
||||
|
||||
Position waypointPos;
|
||||
waypointPos.x = nodeWaypoint->getU16();
|
||||
waypointPos.y = nodeWaypoint->getU16();
|
||||
waypointPos.z = nodeWaypoint->getU8();
|
||||
|
||||
if(waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
|
||||
m_waypoints.insert(std::make_pair(waypointPos, name));
|
||||
}
|
||||
} else
|
||||
stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType));
|
||||
}
|
||||
|
||||
fin->close();
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void Map::saveOtbm(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
FileStreamPtr fin = g_resources.createFile(fileName);
|
||||
if(!fin)
|
||||
stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
|
||||
|
||||
std::string dir;
|
||||
if(fileName.find_last_of('/') == std::string::npos)
|
||||
dir = g_resources.getWorkDir();
|
||||
else
|
||||
dir = fileName.substr(0, fileName.find_last_of('/'));
|
||||
|
||||
uint32 version = 0;
|
||||
if(g_things.getOtbMajorVersion() < ClientVersion820)
|
||||
version = 1;
|
||||
else
|
||||
version = 2;
|
||||
|
||||
/// Usually when a map has empty house/spawn file it means the map is new.
|
||||
/// TODO: Ask the user for a map name instead of those ugly uses of substr
|
||||
std::string::size_type sep_pos;
|
||||
std::string houseFile = getHouseFile();
|
||||
std::string spawnFile = getSpawnFile();
|
||||
std::string cpyf;
|
||||
|
||||
if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm"))
|
||||
cpyf = fileName.substr(0, sep_pos);
|
||||
|
||||
if(houseFile.empty())
|
||||
houseFile = cpyf + "-houses.xml";
|
||||
|
||||
if(spawnFile.empty())
|
||||
spawnFile = cpyf + "-spawns.xml";
|
||||
|
||||
/// we only need the filename to save to, the directory should be resolved by the OTBM loader not here
|
||||
if((sep_pos = spawnFile.rfind('/')) != std::string::npos)
|
||||
spawnFile = spawnFile.substr(sep_pos + 1);
|
||||
|
||||
if((sep_pos = houseFile.rfind('/')) != std::string::npos)
|
||||
houseFile = houseFile.substr(sep_pos + 1);
|
||||
|
||||
fin->addU32(0); // file version
|
||||
OutputBinaryTreePtr root(new OutputBinaryTree(fin));
|
||||
{
|
||||
root->addU32(version);
|
||||
|
||||
Size mapSize = getSize();
|
||||
root->addU16(mapSize.width());
|
||||
root->addU16(mapSize.height());
|
||||
|
||||
root->addU32(g_things.getOtbMajorVersion());
|
||||
root->addU32(g_things.getOtbMinorVersion());
|
||||
|
||||
root->startNode(OTBM_MAP_DATA);
|
||||
{
|
||||
root->addU8(OTBM_ATTR_DESCRIPTION);
|
||||
root->addString(m_attribs.get<std::string>(OTBM_ATTR_DESCRIPTION));
|
||||
|
||||
root->addU8(OTBM_ATTR_SPAWN_FILE);
|
||||
root->addString(spawnFile);
|
||||
|
||||
root->addU8(OTBM_ATTR_HOUSE_FILE);
|
||||
root->addString(houseFile);
|
||||
|
||||
int px = -1, py = -1, pz =-1;
|
||||
bool firstNode = true;
|
||||
|
||||
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
|
||||
for(const auto& it : m_tileBlocks[z]) {
|
||||
const TileBlock& block = it.second;
|
||||
for(const TilePtr& tile : block.getTiles()) {
|
||||
if(unlikely(!tile || tile->isEmpty()))
|
||||
continue;
|
||||
|
||||
const Position& pos = tile->getPosition();
|
||||
if(unlikely(!pos.isValid()))
|
||||
continue;
|
||||
|
||||
if(pos.x < px || pos.x >= px + 256
|
||||
|| pos.y < py || pos.y >= py + 256
|
||||
|| pos.z != pz) {
|
||||
if(!firstNode)
|
||||
root->endNode(); /// OTBM_TILE_AREA
|
||||
|
||||
firstNode = false;
|
||||
root->startNode(OTBM_TILE_AREA);
|
||||
|
||||
px = pos.x & 0xFF00;
|
||||
py = pos.y & 0xFF00;
|
||||
pz = pos.z;
|
||||
root->addPos(px, py, pz);
|
||||
}
|
||||
|
||||
root->startNode(tile->isHouseTile() ? OTBM_HOUSETILE : OTBM_TILE);
|
||||
root->addPoint(Point(pos.x, pos.y) & 0xFF);
|
||||
if(tile->isHouseTile())
|
||||
root->addU32(tile->getHouseId());
|
||||
|
||||
if(tile->getFlags()) {
|
||||
root->addU8(OTBM_ATTR_TILE_FLAGS);
|
||||
root->addU32(tile->getFlags());
|
||||
}
|
||||
|
||||
const auto& itemList = tile->getItems();
|
||||
const ItemPtr& ground = tile->getGround();
|
||||
if(ground) {
|
||||
// Those types are called "complex" needs other stuff to be written.
|
||||
// For containers, there is container items, for depot, depot it and so on.
|
||||
if(!ground->isContainer() && !ground->isDepot()
|
||||
&& !ground->isDoor() && !ground->isTeleport()) {
|
||||
root->addU8(OTBM_ATTR_ITEM);
|
||||
root->addU16(ground->getServerId());
|
||||
} else
|
||||
ground->serializeItem(root);
|
||||
}
|
||||
for(const ItemPtr& item : itemList)
|
||||
if(!item->isGround())
|
||||
item->serializeItem(root);
|
||||
|
||||
root->endNode(); // OTBM_TILE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!firstNode)
|
||||
root->endNode(); // OTBM_TILE_AREA
|
||||
|
||||
root->startNode(OTBM_TOWNS);
|
||||
for(const TownPtr& town : g_towns.getTowns()) {
|
||||
root->startNode(OTBM_TOWN);
|
||||
|
||||
root->addU32(town->getId());
|
||||
root->addString(town->getName());
|
||||
|
||||
Position townPos = town->getPos();
|
||||
root->addPos(townPos.x, townPos.y, townPos.z);
|
||||
root->endNode();
|
||||
}
|
||||
root->endNode();
|
||||
|
||||
if(version > 1) {
|
||||
root->startNode(OTBM_WAYPOINTS);
|
||||
for(const auto& it : m_waypoints) {
|
||||
root->startNode(OTBM_WAYPOINT);
|
||||
root->addString(it.second);
|
||||
|
||||
Position pos = it.first;
|
||||
root->addPos(pos.x, pos.y, pos.z);
|
||||
root->endNode();
|
||||
}
|
||||
root->endNode();
|
||||
}
|
||||
}
|
||||
root->endNode(); // OTBM_MAP_DATA
|
||||
}
|
||||
root->endNode();
|
||||
|
||||
fin->flush();
|
||||
fin->close();
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
bool Map::loadOtcm(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
FileStreamPtr fin = g_resources.openFile(fileName);
|
||||
if(!fin)
|
||||
stdext::throw_exception("unable to open file");
|
||||
|
||||
uint32 signature = fin->getU32();
|
||||
if(signature != OTCM_SIGNATURE)
|
||||
stdext::throw_exception("invalid otcm file");
|
||||
|
||||
uint16 start = fin->getU16();
|
||||
uint16 version = fin->getU16();
|
||||
fin->getU32(); // flags
|
||||
|
||||
switch(version) {
|
||||
case 1: {
|
||||
fin->getString(); // description
|
||||
uint32 datSignature = fin->getU32();
|
||||
fin->getU16(); // protocol version
|
||||
fin->getString(); // world name
|
||||
|
||||
if(datSignature != g_things.getDatSignature())
|
||||
g_logger.warning("otcm map loaded was created with a different dat signature");
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
stdext::throw_exception("otcm version not supported");
|
||||
}
|
||||
|
||||
fin->seek(start);
|
||||
|
||||
while(true) {
|
||||
Position pos;
|
||||
|
||||
pos.x = fin->getU16();
|
||||
pos.y = fin->getU16();
|
||||
pos.z = fin->getU8();
|
||||
|
||||
// end of file
|
||||
if(!pos.isValid())
|
||||
break;
|
||||
|
||||
const TilePtr& tile = g_map.createTile(pos);
|
||||
|
||||
int stackPos = 0;
|
||||
while(true) {
|
||||
int id = fin->getU16();
|
||||
|
||||
// end of tile
|
||||
if(id == 0xFFFF)
|
||||
break;
|
||||
|
||||
int countOrSubType = fin->getU8();
|
||||
|
||||
ItemPtr item = Item::create(id);
|
||||
item->setCountOrSubType(countOrSubType);
|
||||
|
||||
if(item->isValid())
|
||||
tile->addThing(item, stackPos++);
|
||||
}
|
||||
|
||||
g_map.notificateTileUpdate(pos);
|
||||
}
|
||||
|
||||
fin->close();
|
||||
|
||||
return true;
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("failed to load OTCM map: %s", e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::saveOtcm(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
stdext::timer saveTimer;
|
||||
|
||||
FileStreamPtr fin = g_resources.createFile(fileName);
|
||||
|
||||
//TODO: compression flag with zlib
|
||||
uint32 flags = 0;
|
||||
|
||||
// header
|
||||
fin->addU32(OTCM_SIGNATURE);
|
||||
fin->addU16(0); // data start, will be overwritten later
|
||||
fin->addU16(OTCM_VERSION);
|
||||
fin->addU32(flags);
|
||||
|
||||
// version 1 header
|
||||
fin->addString("OTCM 1.0"); // map description
|
||||
fin->addU32(g_things.getDatSignature());
|
||||
fin->addU16(g_game.getClientVersion());
|
||||
fin->addString(g_game.getWorldName());
|
||||
|
||||
// go back and rewrite where the map data starts
|
||||
uint32 start = fin->tell();
|
||||
fin->seek(4);
|
||||
fin->addU16(start);
|
||||
fin->seek(start);
|
||||
|
||||
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
|
||||
for(const auto& it : m_tileBlocks[z]) {
|
||||
const TileBlock& block = it.second;
|
||||
for(const TilePtr& tile : block.getTiles()) {
|
||||
if(!tile || tile->isEmpty())
|
||||
continue;
|
||||
|
||||
Position pos = tile->getPosition();
|
||||
fin->addU16(pos.x);
|
||||
fin->addU16(pos.y);
|
||||
fin->addU8(pos.z);
|
||||
|
||||
for(const ThingPtr& thing : tile->getThings()) {
|
||||
if(thing->isItem()) {
|
||||
ItemPtr item = thing->static_self_cast<Item>();
|
||||
fin->addU16(item->getId());
|
||||
fin->addU8(item->getCountOrSubType());
|
||||
}
|
||||
}
|
||||
|
||||
// end of tile
|
||||
fin->addU16(0xFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// end of file
|
||||
Position invalidPos;
|
||||
fin->addU16(invalidPos.x);
|
||||
fin->addU16(invalidPos.y);
|
||||
fin->addU8(invalidPos.z);
|
||||
|
||||
fin->flush();
|
||||
|
||||
fin->close();
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("failed to save OTCM map: %s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et: */
|
@ -1,537 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mapview.h"
|
||||
|
||||
#include "creature.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
#include "statictext.h"
|
||||
#include "animatedtext.h"
|
||||
#include "missile.h"
|
||||
#include "shadermanager.h"
|
||||
#include "lightview.h"
|
||||
#include "localplayer.h"
|
||||
#include "game.h"
|
||||
#include "spritemanager.h"
|
||||
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/image.h>
|
||||
#include <framework/graphics/framebuffermanager.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/core/application.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/graphics/texturemanager.h>
|
||||
#include <framework/graphics/atlas.h>
|
||||
|
||||
#include <framework/util/extras.h>
|
||||
#include <framework/core/adaptiverenderer.h>
|
||||
|
||||
MapView::MapView()
|
||||
{
|
||||
m_lockedFirstVisibleFloor = -1;
|
||||
m_cachedFirstVisibleFloor = 7;
|
||||
m_cachedLastVisibleFloor = 7;
|
||||
m_fadeOutTime = 0;
|
||||
m_fadeInTime = 0;
|
||||
m_minimumAmbientLight = 0;
|
||||
m_optimizedSize = Size(g_map.getAwareRange().horizontal(), g_map.getAwareRange().vertical()) * g_sprites.spriteSize();
|
||||
|
||||
setVisibleDimension(Size(15, 11));
|
||||
}
|
||||
|
||||
MapView::~MapView()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
VALIDATE(!g_app.isTerminated());
|
||||
#endif
|
||||
}
|
||||
|
||||
void MapView::drawTileTexts(const Rect& rect, const Rect& srcRect)
|
||||
{
|
||||
Position cameraPosition = getCameraPosition();
|
||||
Point drawOffset = srcRect.topLeft();
|
||||
float horizontalStretchFactor = rect.width() / (float)srcRect.width();
|
||||
float verticalStretchFactor = rect.height() / (float)srcRect.height();
|
||||
|
||||
auto player = g_game.getLocalPlayer();
|
||||
for (auto& tile : m_cachedVisibleTiles) {
|
||||
Position tilePos = tile.first->getPosition();
|
||||
if (tilePos.z != player->getPosition().z) continue;
|
||||
|
||||
Point p = transformPositionTo2D(tilePos, cameraPosition) - drawOffset;
|
||||
p.x *= horizontalStretchFactor;
|
||||
p.y *= verticalStretchFactor;
|
||||
p += rect.topLeft();
|
||||
p.y += 5;
|
||||
|
||||
tile.first->drawTexts(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapView::drawBackground(const Rect& rect, const TilePtr& crosshairTile) {
|
||||
Position cameraPosition = getCameraPosition();
|
||||
if (m_mustUpdateVisibleTilesCache) {
|
||||
updateVisibleTilesCache();
|
||||
}
|
||||
|
||||
if (g_game.getFeature(Otc::GameForceLight)) {
|
||||
m_drawLight = true;
|
||||
m_minimumAmbientLight = 0.05f;
|
||||
}
|
||||
|
||||
Rect srcRect = calcFramebufferSource(rect.size());
|
||||
g_drawQueue->setFrameBuffer(rect, m_optimizedSize, srcRect);
|
||||
|
||||
if (m_drawLight) {
|
||||
Light ambientLight;
|
||||
if (cameraPosition.z <= Otc::SEA_FLOOR)
|
||||
ambientLight = g_map.getLight();
|
||||
if (!m_lightTexture || m_lightTexture->getSize() != m_drawDimension)
|
||||
m_lightTexture = TexturePtr(new Texture(m_drawDimension, false, true));
|
||||
m_lightView = std::make_unique<LightView>(m_lightTexture, m_drawDimension, rect, srcRect, ambientLight.color,
|
||||
std::max<int>(m_minimumAmbientLight * 255, ambientLight.intensity));
|
||||
}
|
||||
|
||||
auto itm = m_cachedVisibleTiles.begin();
|
||||
auto end = m_cachedVisibleTiles.end();
|
||||
for (int z = m_cachedLastVisibleFloor; z >= m_cachedFirstFadingFloor; --z) {
|
||||
float fading = 1.0;
|
||||
if (m_floorFading > 0) {
|
||||
fading = 0.;
|
||||
if (m_floorFading > 0) {
|
||||
fading = stdext::clamp<float>((float)m_fadingFloorTimers[z].elapsed_millis() / (float)m_floorFading, 0.f, 1.f);
|
||||
if (z < m_cachedFirstVisibleFloor)
|
||||
fading = 1.0 - fading;
|
||||
}
|
||||
if (fading == 0) break;
|
||||
}
|
||||
|
||||
size_t floorStart = g_drawQueue->size();
|
||||
size_t lightFloorStart = m_lightView ? m_lightView->size() : 0;
|
||||
for (; itm != end; ++itm) {
|
||||
Position tilePos = itm->first->getPosition();
|
||||
if (tilePos.z != z)
|
||||
break;
|
||||
|
||||
|
||||
Point tileDrawPos = transformPositionTo2D(tilePos, cameraPosition);
|
||||
|
||||
if (m_lightView) {
|
||||
ItemPtr ground = itm->first->getGround();
|
||||
if (ground && ground->isGround() && !ground->isTranslucent()) {
|
||||
m_lightView->setFieldBrightness(tileDrawPos, lightFloorStart, 0);
|
||||
}
|
||||
}
|
||||
|
||||
itm->first->drawBottom(tileDrawPos, m_lightView.get());
|
||||
if (m_crosshair && itm->first == crosshairTile)
|
||||
{
|
||||
g_drawQueue->addTexturedRect(Rect(tileDrawPos, tileDrawPos + Otc::TILE_PIXELS - 1),
|
||||
m_crosshair, Rect(0, 0, m_crosshair->getSize()));
|
||||
}
|
||||
itm->first->drawTop(tileDrawPos, m_lightView.get());
|
||||
}
|
||||
for (const MissilePtr& missile : g_map.getFloorMissiles(z)) {
|
||||
missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), true, m_lightView.get());
|
||||
}
|
||||
if (fading < 0.99)
|
||||
g_drawQueue->setOpacity(floorStart, fading);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MapView::drawForeground(const Rect& rect)
|
||||
{
|
||||
// this could happen if the player position is not known yet
|
||||
Position cameraPosition = getCameraPosition();
|
||||
if (!cameraPosition.isValid())
|
||||
return;
|
||||
|
||||
Rect srcRect = calcFramebufferSource(rect.size());
|
||||
Point drawOffset = srcRect.topLeft();
|
||||
float horizontalStretchFactor = rect.width() / (float)srcRect.width();
|
||||
float verticalStretchFactor = rect.height() / (float)srcRect.height();
|
||||
|
||||
// creatures
|
||||
std::vector<std::pair<CreaturePtr, Point>> creatures;
|
||||
for (const CreaturePtr& creature : g_map.getSpectatorsInRangeEx(cameraPosition, false, m_visibleDimension.width() / 2, m_visibleDimension.width() / 2 + 1, m_visibleDimension.height() / 2, m_visibleDimension.height() / 2 + 1)) {
|
||||
if (!creature->canBeSeen())
|
||||
continue;
|
||||
|
||||
PointF jumpOffset = creature->getJumpOffset();
|
||||
Point creatureOffset = Point(16 - creature->getDisplacementX(), -creature->getDisplacementY() - 2);
|
||||
Position pos = creature->getPrewalkingPosition();
|
||||
Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset;
|
||||
p += (creature->getDrawOffset() + creatureOffset) - Point(stdext::round(jumpOffset.x), stdext::round(jumpOffset.y));
|
||||
p.x = p.x * horizontalStretchFactor;
|
||||
p.y = p.y * verticalStretchFactor;
|
||||
p += rect.topLeft();
|
||||
creatures.push_back(std::make_pair(creature, p));
|
||||
}
|
||||
|
||||
for (auto& c : creatures) {
|
||||
int flags = Otc::DrawIcons;
|
||||
if (m_drawNames) { flags |= Otc::DrawNames; }
|
||||
if ((!c.first->isLocalPlayer() || m_drawPlayerBars) && !m_drawHealthBarsOnTop) {
|
||||
if (m_drawHealthBars) { flags |= Otc::DrawBars; }
|
||||
if (m_drawManaBar) { flags |= Otc::DrawManaBar; }
|
||||
}
|
||||
c.first->drawInformation(c.second, g_map.isCovered(c.first->getPrewalkingPosition(), m_cachedFirstVisibleFloor), rect, flags);
|
||||
}
|
||||
|
||||
if (m_lightView) {
|
||||
g_drawQueue->add(m_lightView.release());
|
||||
}
|
||||
|
||||
// texts
|
||||
int limit = g_adaptiveRenderer.textsLimit();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (const StaticTextPtr& staticText : g_map.getStaticTexts()) {
|
||||
Position pos = staticText->getPosition();
|
||||
|
||||
if (pos.z != cameraPosition.z && staticText->getMessageMode() == Otc::MessageNone)
|
||||
continue;
|
||||
if ((staticText->getMessageMode() != Otc::MessageSay && staticText->getMessageMode() != Otc::MessageYell)) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
} else if (i == 1)
|
||||
continue;
|
||||
|
||||
Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset + Point(8, 0);
|
||||
p.x *= horizontalStretchFactor;
|
||||
p.y *= verticalStretchFactor;
|
||||
p += rect.topLeft();
|
||||
staticText->drawText(p, rect);
|
||||
if (--limit == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
limit = g_adaptiveRenderer.textsLimit();
|
||||
for (const AnimatedTextPtr& animatedText : g_map.getAnimatedTexts()) {
|
||||
Position pos = animatedText->getPosition();
|
||||
|
||||
if (pos.z != cameraPosition.z)
|
||||
continue;
|
||||
|
||||
Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset + Point(16, 8);
|
||||
p.x *= horizontalStretchFactor;
|
||||
p.y *= verticalStretchFactor;
|
||||
p += rect.topLeft();
|
||||
animatedText->drawText(p, rect);
|
||||
if (--limit == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// tile texts
|
||||
drawTileTexts(rect, srcRect);
|
||||
|
||||
// bars on top
|
||||
if (m_drawHealthBarsOnTop) {
|
||||
for (auto& c : creatures) {
|
||||
int flags = 0;
|
||||
if ((!c.first->isLocalPlayer() || m_drawPlayerBars)) {
|
||||
if (m_drawHealthBars) { flags |= Otc::DrawBars; }
|
||||
if (m_drawManaBar) { flags |= Otc::DrawManaBar; }
|
||||
}
|
||||
c.first->drawInformation(c.second, g_map.isCovered(c.first->getPrewalkingPosition(), m_cachedFirstVisibleFloor), rect, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapView::updateVisibleTilesCache()
|
||||
{
|
||||
// hidden
|
||||
}
|
||||
|
||||
void MapView::updateGeometry(const Size& visibleDimension, const Size& optimizedSize)
|
||||
{
|
||||
m_multifloor = true;
|
||||
m_visibleDimension = visibleDimension;
|
||||
m_drawDimension = visibleDimension + Size(3, 3);
|
||||
m_virtualCenterOffset = (m_drawDimension / 2 - Size(1, 1)).toPoint();
|
||||
m_visibleCenterOffset = m_virtualCenterOffset;
|
||||
m_optimizedSize = m_drawDimension * g_sprites.spriteSize();
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
void MapView::onTileUpdate(const Position& pos)
|
||||
{
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
void MapView::onMapCenterChange(const Position& pos)
|
||||
{
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
void MapView::lockFirstVisibleFloor(int firstVisibleFloor)
|
||||
{
|
||||
m_lockedFirstVisibleFloor = firstVisibleFloor;
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
void MapView::unlockFirstVisibleFloor()
|
||||
{
|
||||
m_lockedFirstVisibleFloor = -1;
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
void MapView::setVisibleDimension(const Size& visibleDimension)
|
||||
{
|
||||
//if(visibleDimension == m_visibleDimension)
|
||||
// return;
|
||||
|
||||
if(visibleDimension.width() % 2 != 1 || visibleDimension.height() % 2 != 1) {
|
||||
g_logger.traceError("visible dimension must be odd");
|
||||
return;
|
||||
}
|
||||
|
||||
if(visibleDimension < Size(3,3)) {
|
||||
g_logger.traceError("reach max zoom in");
|
||||
return;
|
||||
}
|
||||
|
||||
updateGeometry(visibleDimension, m_optimizedSize);
|
||||
}
|
||||
|
||||
void MapView::optimizeForSize(const Size& visibleSize)
|
||||
{
|
||||
updateGeometry(m_visibleDimension, visibleSize);
|
||||
}
|
||||
|
||||
void MapView::followCreature(const CreaturePtr& creature)
|
||||
{
|
||||
m_follow = true;
|
||||
m_followingCreature = creature;
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
void MapView::setCameraPosition(const Position& pos)
|
||||
{
|
||||
m_follow = false;
|
||||
m_customCameraPosition = pos;
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
Position MapView::getPosition(const Point& point, const Size& mapSize)
|
||||
{
|
||||
Position cameraPosition = getCameraPosition();
|
||||
|
||||
// if we have no camera, its impossible to get the tile
|
||||
if(!cameraPosition.isValid())
|
||||
return Position();
|
||||
|
||||
Rect srcRect = calcFramebufferSource(mapSize);
|
||||
float sh = srcRect.width() / (float)mapSize.width();
|
||||
float sv = srcRect.height() / (float)mapSize.height();
|
||||
|
||||
Point framebufferPos = Point(point.x * sh, point.y * sv);
|
||||
Point realPos = (framebufferPos + srcRect.topLeft());
|
||||
Point centerOffset = realPos / Otc::TILE_PIXELS;
|
||||
|
||||
Point tilePos2D = getVisibleCenterOffset() - m_drawDimension.toPoint() + centerOffset + Point(2,2);
|
||||
if(tilePos2D.x + cameraPosition.x < 0 && tilePos2D.y + cameraPosition.y < 0)
|
||||
return Position();
|
||||
|
||||
Position position = Position(tilePos2D.x, tilePos2D.y, 0) + cameraPosition;
|
||||
|
||||
if(!position.isValid())
|
||||
return Position();
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
Point MapView::getPositionOffset(const Point& point, const Size& mapSize)
|
||||
{
|
||||
Position cameraPosition = getCameraPosition();
|
||||
|
||||
// if we have no camera, its impossible to get the tile
|
||||
if (!cameraPosition.isValid())
|
||||
return Point(0, 0);
|
||||
|
||||
Rect srcRect = calcFramebufferSource(mapSize);
|
||||
float sh = srcRect.width() / (float)mapSize.width();
|
||||
float sv = srcRect.height() / (float)mapSize.height();
|
||||
|
||||
Point framebufferPos = Point(point.x * sh, point.y * sv);
|
||||
Point realPos = (framebufferPos + srcRect.topLeft());
|
||||
return Point(realPos.x % Otc::TILE_PIXELS, realPos.y % Otc::TILE_PIXELS);
|
||||
}
|
||||
|
||||
void MapView::move(int x, int y)
|
||||
{
|
||||
m_moveOffset.x += x;
|
||||
m_moveOffset.y += y;
|
||||
|
||||
int32_t tmp = m_moveOffset.x / g_sprites.spriteSize();
|
||||
bool requestTilesUpdate = false;
|
||||
if(tmp != 0) {
|
||||
m_customCameraPosition.x += tmp;
|
||||
m_moveOffset.x %= g_sprites.spriteSize();
|
||||
requestTilesUpdate = true;
|
||||
}
|
||||
|
||||
tmp = m_moveOffset.y / g_sprites.spriteSize();
|
||||
if(tmp != 0) {
|
||||
m_customCameraPosition.y += tmp;
|
||||
m_moveOffset.y %= g_sprites.spriteSize();
|
||||
requestTilesUpdate = true;
|
||||
}
|
||||
|
||||
if(requestTilesUpdate)
|
||||
requestVisibleTilesCacheUpdate();
|
||||
}
|
||||
|
||||
Rect MapView::calcFramebufferSource(const Size& destSize, bool inNextFrame)
|
||||
{
|
||||
float scaleFactor = g_sprites.spriteSize()/(float)Otc::TILE_PIXELS;
|
||||
Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * g_sprites.spriteSize();
|
||||
if(isFollowingCreature())
|
||||
drawOffset += m_followingCreature->getWalkOffset(inNextFrame) * scaleFactor;
|
||||
|
||||
Size srcSize = destSize;
|
||||
Size srcVisible = m_visibleDimension * g_sprites.spriteSize();
|
||||
srcSize.scale(srcVisible, Fw::KeepAspectRatio);
|
||||
drawOffset.x += (srcVisible.width() - srcSize.width()) / 2;
|
||||
drawOffset.y += (srcVisible.height() - srcSize.height()) / 2;
|
||||
|
||||
return Rect(drawOffset, srcSize);
|
||||
}
|
||||
|
||||
int MapView::calcFirstVisibleFloor(bool forFading)
|
||||
{
|
||||
int z = 7;
|
||||
// return forced first visible floor
|
||||
if(m_lockedFirstVisibleFloor != -1) {
|
||||
z = m_lockedFirstVisibleFloor;
|
||||
} else {
|
||||
Position cameraPosition = getCameraPosition();
|
||||
|
||||
// this could happens if the player is not known yet
|
||||
if(cameraPosition.isValid()) {
|
||||
// avoid rendering multifloors in far views
|
||||
if(!m_multifloor) {
|
||||
z = cameraPosition.z;
|
||||
} else {
|
||||
// if nothing is limiting the view, the first visible floor is 0
|
||||
int firstFloor = 0;
|
||||
|
||||
// limits to underground floors while under sea level
|
||||
if(cameraPosition.z > Otc::SEA_FLOOR)
|
||||
firstFloor = std::max<int>(cameraPosition.z - Otc::AWARE_UNDEGROUND_FLOOR_RANGE, (int)Otc::UNDERGROUND_FLOOR);
|
||||
|
||||
// loop in 3x3 tiles around the camera
|
||||
for(int ix = -1; ix <= 1 && firstFloor < cameraPosition.z && !forFading; ++ix) {
|
||||
for(int iy = -1; iy <= 1 && firstFloor < cameraPosition.z; ++iy) {
|
||||
Position pos = cameraPosition.translated(ix, iy);
|
||||
|
||||
// process tiles that we can look through, e.g. windows, doors
|
||||
if((ix == 0 && iy == 0) || ((std::abs(ix) != std::abs(iy)) && g_map.isLookPossible(pos))) {
|
||||
Position upperPos = pos;
|
||||
Position coveredPos = pos;
|
||||
|
||||
while(coveredPos.coveredUp() && upperPos.up() && upperPos.z >= firstFloor) {
|
||||
// check tiles physically above
|
||||
TilePtr tile = g_map.getTile(upperPos);
|
||||
if(tile && tile->limitsFloorsView(!g_map.isLookPossible(pos))) {
|
||||
firstFloor = upperPos.z + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// check tiles geometrically above
|
||||
tile = g_map.getTile(coveredPos);
|
||||
if(tile && tile->limitsFloorsView(g_map.isLookPossible(pos))) {
|
||||
firstFloor = coveredPos.z + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
z = firstFloor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// just ensure the that the floor is in the valid range
|
||||
z = stdext::clamp<int>(z, 0, (int)Otc::MAX_Z);
|
||||
return z;
|
||||
}
|
||||
|
||||
int MapView::calcLastVisibleFloor()
|
||||
{
|
||||
if(!m_multifloor)
|
||||
return calcFirstVisibleFloor();
|
||||
|
||||
int z = 7;
|
||||
|
||||
Position cameraPosition = getCameraPosition();
|
||||
// this could happens if the player is not known yet
|
||||
if(cameraPosition.isValid()) {
|
||||
// view only underground floors when below sea level
|
||||
if(cameraPosition.z > Otc::SEA_FLOOR)
|
||||
z = cameraPosition.z + Otc::AWARE_UNDEGROUND_FLOOR_RANGE;
|
||||
else
|
||||
z = Otc::SEA_FLOOR;
|
||||
}
|
||||
|
||||
if(m_lockedFirstVisibleFloor != -1)
|
||||
z = std::max<int>(m_lockedFirstVisibleFloor, z);
|
||||
|
||||
// just ensure the that the floor is in the valid range
|
||||
z = stdext::clamp<int>(z, 0, (int)Otc::MAX_Z);
|
||||
return z;
|
||||
}
|
||||
|
||||
Point MapView::transformPositionTo2D(const Position& position, const Position& relativePosition) {
|
||||
return Point((m_virtualCenterOffset.x + (position.x - relativePosition.x) - (relativePosition.z - position.z)) * g_sprites.spriteSize(),
|
||||
(m_virtualCenterOffset.y + (position.y - relativePosition.y) - (relativePosition.z - position.z)) * g_sprites.spriteSize());
|
||||
}
|
||||
|
||||
|
||||
Position MapView::getCameraPosition()
|
||||
{
|
||||
if (isFollowingCreature()) {
|
||||
return m_followingCreature->getPrewalkingPosition();
|
||||
}
|
||||
|
||||
return m_customCameraPosition;
|
||||
}
|
||||
|
||||
void MapView::setDrawLights(bool enable)
|
||||
{
|
||||
m_drawLight = enable;
|
||||
}
|
||||
|
||||
void MapView::setCrosshair(const std::string& file)
|
||||
{
|
||||
if (file == "")
|
||||
m_crosshair = nullptr;
|
||||
else
|
||||
m_crosshair = g_textures.getTexture(file);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et: */
|
@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MAPVIEW_H
|
||||
#define MAPVIEW_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
#include <framework/graphics/declarations.h>
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include <framework/core/declarations.h>
|
||||
#include "lightview.h"
|
||||
|
||||
// @bindclass
|
||||
class MapView : public LuaObject
|
||||
{
|
||||
public:
|
||||
MapView();
|
||||
~MapView();
|
||||
void drawBackground(const Rect& rect, const TilePtr& crosshairTile = nullptr);
|
||||
void drawForeground(const Rect& rect);
|
||||
void drawTexts(const Rect& rect, const Rect& srcRect);
|
||||
|
||||
private:
|
||||
void drawTileTexts(const Rect& rect, const Rect& srcRect);
|
||||
void updateGeometry(const Size& visibleDimension, const Size& optimizedSize);
|
||||
void updateVisibleTilesCache();
|
||||
void requestVisibleTilesCacheUpdate() { m_mustUpdateVisibleTilesCache = true; }
|
||||
|
||||
protected:
|
||||
void onTileUpdate(const Position& pos);
|
||||
void onMapCenterChange(const Position& pos);
|
||||
|
||||
friend class Map;
|
||||
|
||||
public:
|
||||
// floor visibility related
|
||||
void lockFirstVisibleFloor(int firstVisibleFloor);
|
||||
void unlockFirstVisibleFloor();
|
||||
int getLockedFirstVisibleFloor() { return m_lockedFirstVisibleFloor; }
|
||||
|
||||
void setMultifloor(bool enable) { m_multifloor = enable; requestVisibleTilesCacheUpdate(); }
|
||||
bool isMultifloor() { return m_multifloor; }
|
||||
|
||||
// map dimension related
|
||||
void setVisibleDimension(const Size& visibleDimension);
|
||||
void optimizeForSize(const Size & visibleSize);
|
||||
Size getVisibleDimension() { return m_visibleDimension; }
|
||||
Point getVisibleCenterOffset() { return m_visibleCenterOffset; }
|
||||
int getCachedFirstVisibleFloor() { return m_cachedFirstVisibleFloor; }
|
||||
int getCachedLastVisibleFloor() { return m_cachedLastVisibleFloor; }
|
||||
|
||||
// camera related
|
||||
void followCreature(const CreaturePtr& creature);
|
||||
CreaturePtr getFollowingCreature() { return m_followingCreature; }
|
||||
bool isFollowingCreature() { return m_followingCreature && m_follow; }
|
||||
|
||||
void setCameraPosition(const Position& pos);
|
||||
Position getCameraPosition();
|
||||
|
||||
void setMinimumAmbientLight(float intensity) { m_minimumAmbientLight = intensity; }
|
||||
float getMinimumAmbientLight() { return m_minimumAmbientLight; }
|
||||
|
||||
// drawing related
|
||||
void setDrawFlags(Otc::DrawFlags drawFlags) { m_drawFlags = drawFlags; requestVisibleTilesCacheUpdate(); }
|
||||
Otc::DrawFlags getDrawFlags() { return m_drawFlags; }
|
||||
|
||||
void setDrawTexts(bool enable) { m_drawTexts = enable; }
|
||||
bool isDrawingTexts() { return m_drawTexts; }
|
||||
|
||||
void setDrawNames(bool enable) { m_drawNames = enable; }
|
||||
bool isDrawingNames() { return m_drawNames; }
|
||||
|
||||
void setDrawHealthBars(bool enable) { m_drawHealthBars = enable; }
|
||||
bool isDrawingHealthBars() { return m_drawHealthBars; }
|
||||
|
||||
void setDrawHealthBarsOnTop(bool enable) { m_drawHealthBarsOnTop = enable; }
|
||||
bool isDrawingHealthBarsOnTop() { return m_drawHealthBarsOnTop; }
|
||||
|
||||
void setDrawLights(bool enable);
|
||||
bool isDrawingLights() { return m_drawLight; }
|
||||
|
||||
void setDrawManaBar(bool enable) { m_drawManaBar = enable; }
|
||||
bool isDrawingManaBar() { return m_drawManaBar; }
|
||||
|
||||
void setDrawPlayerBars(bool enable) { m_drawPlayerBars = enable; }
|
||||
|
||||
void move(int x, int y);
|
||||
|
||||
void setAnimated(bool animated) { m_animated = animated; requestVisibleTilesCacheUpdate(); }
|
||||
bool isAnimating() { return m_animated; }
|
||||
|
||||
void setFloorFading(int value) { m_floorFading = value; }
|
||||
void setCrosshair(const std::string& file);
|
||||
|
||||
//void setShader(const PainterShaderProgramPtr& shader, float fadein, float fadeout);
|
||||
//PainterShaderProgramPtr getShader() { return m_shader; }
|
||||
|
||||
Position getPosition(const Point& point, const Size& mapSize);
|
||||
|
||||
Point getPositionOffset(const Point& point, const Size& mapSize);
|
||||
|
||||
MapViewPtr asMapView() { return static_self_cast<MapView>(); }
|
||||
|
||||
private:
|
||||
Rect calcFramebufferSource(const Size& destSize, bool inNextFrame = false);
|
||||
int calcFirstVisibleFloor(bool forFading = false);
|
||||
int calcLastVisibleFloor();
|
||||
Point transformPositionTo2D(const Position& position, const Position& relativePosition);
|
||||
|
||||
stdext::timer m_mapRenderTimer;
|
||||
|
||||
int m_lockedFirstVisibleFloor;
|
||||
int m_cachedFirstVisibleFloor;
|
||||
int m_cachedFirstFadingFloor;
|
||||
int m_cachedLastVisibleFloor;
|
||||
int m_updateTilesPos;
|
||||
int m_floorFading = 500;
|
||||
TexturePtr m_crosshair = nullptr;
|
||||
Size m_drawDimension;
|
||||
Size m_visibleDimension;
|
||||
Size m_optimizedSize;
|
||||
Point m_virtualCenterOffset;
|
||||
Point m_visibleCenterOffset;
|
||||
Point m_moveOffset;
|
||||
Position m_customCameraPosition;
|
||||
Position m_lastCameraPosition;
|
||||
stdext::boolean<true> m_mustUpdateVisibleTilesCache;
|
||||
stdext::boolean<true> m_mustDrawVisibleTilesCache;
|
||||
stdext::boolean<true> m_multifloor;
|
||||
stdext::boolean<true> m_animated;
|
||||
stdext::boolean<true> m_drawTexts;
|
||||
stdext::boolean<true> m_drawNames;
|
||||
stdext::boolean<true> m_drawHealthBars;
|
||||
stdext::boolean<false> m_drawHealthBarsOnTop;
|
||||
stdext::boolean<true> m_drawManaBar;
|
||||
bool m_drawPlayerBars = true;
|
||||
stdext::boolean<true> m_smooth;
|
||||
|
||||
stdext::timer m_fadingFloorTimers[Otc::MAX_Z + 1];
|
||||
|
||||
stdext::boolean<true> m_follow;
|
||||
std::vector<std::pair<TilePtr, bool>> m_cachedVisibleTiles;
|
||||
CreaturePtr m_followingCreature;
|
||||
//PainterShaderProgramPtr m_shader;
|
||||
Otc::DrawFlags m_drawFlags;
|
||||
bool m_drawLight = false;
|
||||
float m_minimumAmbientLight;
|
||||
std::unique_ptr<LightView> m_lightView;
|
||||
TexturePtr m_lightTexture;
|
||||
Timer m_fadeTimer;
|
||||
//PainterShaderProgramPtr m_nextShader;
|
||||
float m_fadeInTime;
|
||||
float m_fadeOutTime;
|
||||
//stdext::boolean<true> m_shaderSwitchDone;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,438 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "minimap.h"
|
||||
#include "tile.h"
|
||||
|
||||
#include <framework/graphics/image.h>
|
||||
#include <framework/graphics/texture.h>
|
||||
#include <framework/graphics/painter.h>
|
||||
#include <framework/graphics/image.h>
|
||||
#include <framework/graphics/framebuffermanager.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include <framework/util/stats.h>
|
||||
|
||||
Minimap g_minimap;
|
||||
|
||||
void MinimapBlock::clean()
|
||||
{
|
||||
m_tiles.fill(MinimapTile());
|
||||
m_texture.reset();
|
||||
m_mustUpdate = false;
|
||||
}
|
||||
|
||||
void MinimapBlock::update()
|
||||
{
|
||||
if(!m_mustUpdate)
|
||||
return;
|
||||
|
||||
ImagePtr image(new Image(Size(MMBLOCK_SIZE, MMBLOCK_SIZE)));
|
||||
|
||||
bool shouldDraw = false;
|
||||
for(int x=0;x<MMBLOCK_SIZE;++x) {
|
||||
for(int y=0;y<MMBLOCK_SIZE;++y) {
|
||||
uint8 c = getTile(x, y).color;
|
||||
Color col = Color::alpha;
|
||||
if(c != 255) {
|
||||
col = Color::from8bit(c);
|
||||
shouldDraw = true;
|
||||
}
|
||||
image->setPixel(x, y, col);
|
||||
}
|
||||
}
|
||||
|
||||
if(shouldDraw) {
|
||||
m_texture = TexturePtr(new Texture(image));
|
||||
} else
|
||||
m_texture.reset();
|
||||
|
||||
m_mustUpdate = false;
|
||||
}
|
||||
|
||||
void MinimapBlock::updateTile(int x, int y, const MinimapTile& tile)
|
||||
{
|
||||
if(m_tiles[getTileIndex(x,y)].color != tile.color)
|
||||
m_mustUpdate = true;
|
||||
|
||||
m_tiles[getTileIndex(x,y)] = tile;
|
||||
}
|
||||
|
||||
void Minimap::init()
|
||||
{
|
||||
}
|
||||
|
||||
void Minimap::terminate()
|
||||
{
|
||||
clean();
|
||||
}
|
||||
|
||||
void Minimap::clean()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
for(int i=0;i<=Otc::MAX_Z;++i)
|
||||
m_tileBlocks[i].clear();
|
||||
}
|
||||
|
||||
void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color)
|
||||
{
|
||||
if(screenRect.isEmpty())
|
||||
return;
|
||||
|
||||
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
||||
g_drawQueue->addFilledRect(screenRect, color);
|
||||
|
||||
if(MMBLOCK_SIZE*scale <= 1 || !mapCenter.isMapPosition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t drawQueueStart = g_drawQueue->size();
|
||||
Point blockOff = getBlockOffset(mapRect.topLeft());
|
||||
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
|
||||
Point start = screenRect.topLeft() -(mapRect.topLeft() - blockOff)*scale - off;
|
||||
|
||||
for(int y = blockOff.y, ys = start.y;ys<screenRect.bottom();y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) {
|
||||
if(y < 0 || y >= 65536)
|
||||
continue;
|
||||
|
||||
for(int x = blockOff.x, xs = start.x;xs<screenRect.right();x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) {
|
||||
if(x < 0 || x >= 65536)
|
||||
continue;
|
||||
|
||||
Position blockPos(x, y, mapCenter.z);
|
||||
if(!hasBlock(blockPos))
|
||||
continue;
|
||||
|
||||
MinimapBlock& block = getBlock(Position(x, y, mapCenter.z));
|
||||
block.update();
|
||||
|
||||
const TexturePtr& tex = block.getTexture();
|
||||
if(tex) {
|
||||
Rect src(0, 0, MMBLOCK_SIZE, MMBLOCK_SIZE);
|
||||
Rect dest(xs, ys, MMBLOCK_SIZE * scale, MMBLOCK_SIZE * scale);
|
||||
|
||||
g_drawQueue->addTexturedRect(dest, tex, src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_drawQueue->setClip(drawQueueStart, screenRect);
|
||||
}
|
||||
|
||||
Point Minimap::getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
|
||||
{
|
||||
if(screenRect.isEmpty() || pos.z != mapCenter.z)
|
||||
return Point(-1,-1);
|
||||
|
||||
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
||||
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
|
||||
Point posoff = (Point(pos.x,pos.y) - mapRect.topLeft())*scale;
|
||||
return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2;
|
||||
}
|
||||
|
||||
Position Minimap::getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale)
|
||||
{
|
||||
if(screenRect.isEmpty())
|
||||
return Position();
|
||||
|
||||
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
||||
Point off = Point((mapRect.size() * scale).toPoint() - screenRect.size().toPoint())/2;
|
||||
Point pos2d = (point - screenRect.topLeft() + off)/scale + mapRect.topLeft();
|
||||
return Position(pos2d.x, pos2d.y, mapCenter.z);
|
||||
}
|
||||
|
||||
Rect Minimap::getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
|
||||
{
|
||||
if(screenRect.isEmpty() || pos.z != mapCenter.z)
|
||||
return Rect();
|
||||
|
||||
int tileSize = 32 * scale;
|
||||
Rect tileRect(0,0,tileSize, tileSize);
|
||||
tileRect.moveCenter(getTilePoint(pos, screenRect, mapCenter, scale));
|
||||
return tileRect;
|
||||
}
|
||||
|
||||
Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale)
|
||||
{
|
||||
int w = screenRect.width() / scale, h = std::ceil(screenRect.height() / scale);
|
||||
Rect mapRect(0,0,w,h);
|
||||
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
|
||||
return mapRect;
|
||||
}
|
||||
|
||||
void Minimap::updateTile(const Position& pos, const TilePtr& tile)
|
||||
{
|
||||
MinimapTile minimapTile;
|
||||
if(tile) {
|
||||
minimapTile.color = tile->getMinimapColorByte();
|
||||
minimapTile.flags |= MinimapTileWasSeen;
|
||||
if(!tile->isWalkable(true))
|
||||
minimapTile.flags |= MinimapTileNotWalkable;
|
||||
if(!tile->isPathable())
|
||||
minimapTile.flags |= MinimapTileNotPathable;
|
||||
minimapTile.speed = std::min<int>((int)std::ceil(tile->getGroundSpeed() / 10.0f), 255);
|
||||
} else {
|
||||
minimapTile.color = 255;
|
||||
minimapTile.flags |= MinimapTileEmpty;
|
||||
minimapTile.speed = 1;
|
||||
}
|
||||
|
||||
if(minimapTile != MinimapTile()) {
|
||||
MinimapBlock& block = getBlock(pos);
|
||||
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
||||
block.updateTile(pos.x - offsetPos.x, pos.y - offsetPos.y, minimapTile);
|
||||
block.justSaw();
|
||||
}
|
||||
}
|
||||
|
||||
const MinimapTile& Minimap::getTile(const Position& pos)
|
||||
{
|
||||
static MinimapTile nulltile;
|
||||
if(pos.z <= Otc::MAX_Z && hasBlock(pos)) {
|
||||
MinimapBlock& block = getBlock(pos);
|
||||
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
||||
return block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y);
|
||||
}
|
||||
return nulltile;
|
||||
}
|
||||
|
||||
std::pair<MinimapBlock_ptr, MinimapTile> Minimap::threadGetTile(const Position& pos) {
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
static MinimapTile nulltile;
|
||||
|
||||
if (pos.z <= Otc::MAX_Z && hasBlock(pos)) {
|
||||
MinimapBlock_ptr block = m_tileBlocks[pos.z][getBlockIndex(pos)];
|
||||
if (block) {
|
||||
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
||||
return std::make_pair(block, block->getTile(pos.x - offsetPos.x, pos.y - offsetPos.y));
|
||||
}
|
||||
}
|
||||
return std::make_pair(nullptr, nulltile);
|
||||
}
|
||||
|
||||
bool Minimap::loadImage(const std::string& fileName, const Position& topLeft, float colorFactor)
|
||||
{
|
||||
if(colorFactor <= 0.01f)
|
||||
colorFactor = 1.0f;
|
||||
|
||||
try {
|
||||
ImagePtr image = Image::load(fileName);
|
||||
|
||||
uint8 waterc = Color::to8bit(std::string("#3300cc"));
|
||||
|
||||
// non pathable colors
|
||||
Color nonPathableColors[] = {
|
||||
std::string("#ffff00"), // yellow
|
||||
};
|
||||
|
||||
// non walkable colors
|
||||
Color nonWalkableColors[] = {
|
||||
std::string("#000000"), // oil, black
|
||||
std::string("#006600"), // trees, dark green
|
||||
std::string("#ff3300"), // walls, red
|
||||
std::string("#666666"), // mountain, grey
|
||||
std::string("#ff6600"), // lava, orange
|
||||
std::string("#00ff00"), // positon
|
||||
std::string("#ccffff"), // ice, very light blue
|
||||
};
|
||||
|
||||
for(int y=0;y<image->getHeight();++y) {
|
||||
for(int x=0;x<image->getWidth();++x) {
|
||||
Color color = *(uint32*)image->getPixel(x,y);
|
||||
uint8 c = Color::to8bit(color * colorFactor);
|
||||
int flags = 0;
|
||||
|
||||
if(c == waterc || color.a() == 0) {
|
||||
flags |= MinimapTileNotWalkable;
|
||||
c = 255; // alpha
|
||||
}
|
||||
|
||||
if(flags != 0) {
|
||||
for(Color &col : nonWalkableColors) {
|
||||
if(col == color) {
|
||||
flags |= MinimapTileNotWalkable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(flags != 0) {
|
||||
for(Color &col : nonPathableColors) {
|
||||
if(col == color) {
|
||||
flags |= MinimapTileNotPathable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(c == 255)
|
||||
continue;
|
||||
|
||||
Position pos(topLeft.x + x, topLeft.y + y, topLeft.z);
|
||||
MinimapBlock& block = getBlock(pos);
|
||||
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
||||
MinimapTile& tile = block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y);
|
||||
if(!(tile.flags & MinimapTileWasSeen)) {
|
||||
tile.color = c;
|
||||
tile.flags = flags;
|
||||
block.mustUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Minimap::saveImage(const std::string& fileName, const Rect& mapRect)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
bool Minimap::loadOtmm(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
FileStreamPtr fin = g_resources.openFile(fileName);
|
||||
if(!fin)
|
||||
stdext::throw_exception("unable to open file");
|
||||
|
||||
uint32 signature = fin->getU32();
|
||||
if(signature != OTMM_SIGNATURE)
|
||||
stdext::throw_exception("invalid OTMM file");
|
||||
|
||||
uint16 start = fin->getU16();
|
||||
uint16 version = fin->getU16();
|
||||
fin->getU32(); // flags
|
||||
|
||||
switch(version) {
|
||||
case 1: {
|
||||
fin->getString(); // description
|
||||
break;
|
||||
}
|
||||
default:
|
||||
stdext::throw_exception("OTMM version not supported");
|
||||
}
|
||||
|
||||
fin->seek(start);
|
||||
|
||||
uint blockSize = MMBLOCK_SIZE * MMBLOCK_SIZE * sizeof(MinimapTile);
|
||||
std::vector<uchar> compressBuffer(compressBound(blockSize));
|
||||
std::vector<uchar> decompressBuffer(blockSize);
|
||||
|
||||
while(true) {
|
||||
Position pos;
|
||||
pos.x = fin->getU16();
|
||||
pos.y = fin->getU16();
|
||||
pos.z = fin->getU8();
|
||||
|
||||
// end of file or file is corrupted
|
||||
if(!pos.isValid() || pos.z >= Otc::MAX_Z+1)
|
||||
break;
|
||||
|
||||
MinimapBlock& block = getBlock(pos);
|
||||
ulong len = fin->getU16();
|
||||
ulong destLen = blockSize;
|
||||
fin->read(compressBuffer.data(), len);
|
||||
int ret = uncompress(decompressBuffer.data(), &destLen, compressBuffer.data(), len);
|
||||
if(ret != Z_OK || destLen != blockSize)
|
||||
break;
|
||||
|
||||
memcpy((uchar*)&block.getTiles(), decompressBuffer.data(), blockSize);
|
||||
block.mustUpdate();
|
||||
block.justSaw();
|
||||
}
|
||||
|
||||
fin->close();
|
||||
return true;
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Minimap::saveOtmm(const std::string& fileName)
|
||||
{
|
||||
try {
|
||||
stdext::timer saveTimer;
|
||||
|
||||
FileStreamPtr fin = g_resources.createFile(fileName);
|
||||
|
||||
//TODO: compression flag with zlib
|
||||
uint32 flags = 0;
|
||||
|
||||
// header
|
||||
fin->addU32(OTMM_SIGNATURE);
|
||||
fin->addU16(0); // data start, will be overwritten later
|
||||
fin->addU16(OTMM_VERSION);
|
||||
fin->addU32(flags);
|
||||
|
||||
// version 1 header
|
||||
fin->addString("OTMM 1.0"); // description
|
||||
|
||||
// go back and rewrite where the map data starts
|
||||
uint32 start = fin->tell();
|
||||
fin->seek(4);
|
||||
fin->addU16(start);
|
||||
fin->seek(start);
|
||||
|
||||
uint blockSize = MMBLOCK_SIZE * MMBLOCK_SIZE * sizeof(MinimapTile);
|
||||
std::vector<uchar> compressBuffer(compressBound(blockSize));
|
||||
const int COMPRESS_LEVEL = 3;
|
||||
|
||||
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
|
||||
for(auto& it : m_tileBlocks[z]) {
|
||||
int index = it.first;
|
||||
MinimapBlock& block = *it.second;
|
||||
if(!block.wasSeen())
|
||||
continue;
|
||||
|
||||
Position pos = getIndexPosition(index, z);
|
||||
fin->addU16(pos.x);
|
||||
fin->addU16(pos.y);
|
||||
fin->addU8(pos.z);
|
||||
|
||||
ulong len = blockSize;
|
||||
int ret = compress2(compressBuffer.data(), &len, (uchar*)&block.getTiles(), blockSize, COMPRESS_LEVEL);
|
||||
VALIDATE(ret == Z_OK);
|
||||
fin->addU16(len);
|
||||
fin->write(compressBuffer.data(), len);
|
||||
}
|
||||
}
|
||||
|
||||
// end of file
|
||||
Position invalidPos;
|
||||
fin->addU16(invalidPos.x);
|
||||
fin->addU16(invalidPos.y);
|
||||
fin->addU8(invalidPos.z);
|
||||
|
||||
fin->flush();
|
||||
|
||||
fin->close();
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("failed to save OTMM minimap: %s", e.what()));
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MINIMAP_H
|
||||
#define MINIMAP_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/graphics/declarations.h>
|
||||
|
||||
enum {
|
||||
MMBLOCK_SIZE = 64,
|
||||
OTMM_SIGNATURE = 0x4D4d544F,
|
||||
OTMM_VERSION = 1
|
||||
};
|
||||
|
||||
enum MinimapTileFlags {
|
||||
MinimapTileWasSeen = 1,
|
||||
MinimapTileNotPathable = 2,
|
||||
MinimapTileNotWalkable = 4,
|
||||
MinimapTileEmpty = 8
|
||||
};
|
||||
|
||||
#pragma pack(push,1) // disable memory alignment
|
||||
struct MinimapTile
|
||||
{
|
||||
MinimapTile() : flags(0), color(255), speed(10) { }
|
||||
uint8 flags;
|
||||
uint8 color;
|
||||
uint8 speed;
|
||||
bool hasFlag(MinimapTileFlags flag) const { return flags & flag; }
|
||||
int getSpeed() const { return speed * 10; }
|
||||
bool operator==(const MinimapTile& other) const { return color == other.color && flags == other.flags && speed == other.speed; }
|
||||
bool operator!=(const MinimapTile& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
class MinimapBlock
|
||||
{
|
||||
public:
|
||||
void clean();
|
||||
void update();
|
||||
void updateTile(int x, int y, const MinimapTile& tile);
|
||||
MinimapTile& getTile(int x, int y) { return m_tiles[getTileIndex(x,y)]; }
|
||||
void resetTile(int x, int y) { m_tiles[getTileIndex(x,y)] = MinimapTile(); }
|
||||
uint getTileIndex(int x, int y) { return ((y % MMBLOCK_SIZE) * MMBLOCK_SIZE) + (x % MMBLOCK_SIZE); }
|
||||
const TexturePtr& getTexture() { return m_texture; }
|
||||
std::array<MinimapTile, MMBLOCK_SIZE * MMBLOCK_SIZE>& getTiles() { return m_tiles; }
|
||||
void mustUpdate() { m_mustUpdate = true; }
|
||||
void justSaw() { m_wasSeen = true; }
|
||||
bool wasSeen() { return m_wasSeen; }
|
||||
private:
|
||||
TexturePtr m_texture;
|
||||
std::array<MinimapTile, MMBLOCK_SIZE * MMBLOCK_SIZE> m_tiles;
|
||||
stdext::boolean<true> m_mustUpdate;
|
||||
stdext::boolean<false> m_wasSeen;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
using MinimapBlock_ptr = std::shared_ptr<MinimapBlock>;
|
||||
|
||||
class Minimap
|
||||
{
|
||||
|
||||
public:
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
void clean();
|
||||
|
||||
void draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color);
|
||||
Point getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale);
|
||||
Position getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale);
|
||||
Rect getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale);
|
||||
|
||||
void updateTile(const Position& pos, const TilePtr& tile);
|
||||
const MinimapTile& getTile(const Position& pos);
|
||||
std::pair<MinimapBlock_ptr, MinimapTile> threadGetTile(const Position& pos);
|
||||
|
||||
bool loadImage(const std::string& fileName, const Position& topLeft, float colorFactor);
|
||||
void saveImage(const std::string& fileName, const Rect& mapRect);
|
||||
bool loadOtmm(const std::string& fileName);
|
||||
void saveOtmm(const std::string& fileName);
|
||||
|
||||
private:
|
||||
Rect calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale);
|
||||
bool hasBlock(const Position& pos) { return m_tileBlocks[pos.z].find(getBlockIndex(pos)) != m_tileBlocks[pos.z].end(); }
|
||||
MinimapBlock& getBlock(const Position& pos) {
|
||||
std::lock_guard<std::mutex> lock(m_lock);
|
||||
auto& ptr = m_tileBlocks[pos.z][getBlockIndex(pos)];
|
||||
if (!ptr)
|
||||
ptr = std::make_shared<MinimapBlock>();
|
||||
return *ptr;
|
||||
}
|
||||
Point getBlockOffset(const Point& pos) { return Point(pos.x - pos.x % MMBLOCK_SIZE,
|
||||
pos.y - pos.y % MMBLOCK_SIZE); }
|
||||
Position getIndexPosition(int index, int z) { return Position((index % (65536 / MMBLOCK_SIZE))*MMBLOCK_SIZE,
|
||||
(index / (65536 / MMBLOCK_SIZE))*MMBLOCK_SIZE, z); }
|
||||
uint getBlockIndex(const Position& pos) { return ((pos.y / MMBLOCK_SIZE) * (65536 / MMBLOCK_SIZE)) + (pos.x / MMBLOCK_SIZE); }
|
||||
std::unordered_map<uint, MinimapBlock_ptr> m_tileBlocks[Otc::MAX_Z+1];
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
extern Minimap g_minimap;
|
||||
|
||||
#endif
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "missile.h"
|
||||
#include "thingtypemanager.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
void Missile::draw(const Point& dest, bool animate, LightView* lightView)
|
||||
{
|
||||
if(m_id == 0 || !animate)
|
||||
return;
|
||||
|
||||
int xPattern = 0, yPattern = 0;
|
||||
if(m_direction == Otc::NorthWest) {
|
||||
xPattern = 0;
|
||||
yPattern = 0;
|
||||
} else if(m_direction == Otc::North) {
|
||||
xPattern = 1;
|
||||
yPattern = 0;
|
||||
} else if(m_direction == Otc::NorthEast) {
|
||||
xPattern = 2;
|
||||
yPattern = 0;
|
||||
} else if(m_direction == Otc::East) {
|
||||
xPattern = 2;
|
||||
yPattern = 1;
|
||||
} else if(m_direction == Otc::SouthEast) {
|
||||
xPattern = 2;
|
||||
yPattern = 2;
|
||||
} else if(m_direction == Otc::South) {
|
||||
xPattern = 1;
|
||||
yPattern = 2;
|
||||
} else if(m_direction == Otc::SouthWest) {
|
||||
xPattern = 0;
|
||||
yPattern = 2;
|
||||
} else if(m_direction == Otc::West) {
|
||||
xPattern = 0;
|
||||
yPattern = 1;
|
||||
} else {
|
||||
xPattern = 1;
|
||||
yPattern = 1;
|
||||
}
|
||||
|
||||
float fraction = m_animationTimer.ticksElapsed() / m_duration;
|
||||
rawGetThingType()->draw(dest + m_delta * fraction, 0, xPattern, yPattern, 0, 0, Color::white, lightView);
|
||||
}
|
||||
|
||||
void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
||||
{
|
||||
m_source = fromPosition;
|
||||
m_destination = toPosition;
|
||||
|
||||
m_direction = fromPosition.getDirectionFromPosition(toPosition);
|
||||
|
||||
m_position = fromPosition;
|
||||
m_delta = Point(toPosition.x - fromPosition.x, toPosition.y - fromPosition.y);
|
||||
m_duration = 150 * std::sqrt(m_delta.length());
|
||||
m_delta *= Otc::TILE_PIXELS;
|
||||
m_animationTimer.restart();
|
||||
|
||||
// schedule removal
|
||||
auto self = asMissile();
|
||||
g_dispatcher.scheduleEvent([self]() { g_map.removeThing(self); }, m_duration);
|
||||
}
|
||||
|
||||
void Missile::setId(uint32 id)
|
||||
{
|
||||
if(!g_things.isValidDatId(id, ThingCategoryMissile))
|
||||
id = 0;
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
const ThingTypePtr& Missile::getThingType()
|
||||
{
|
||||
return g_things.getThingType(m_id, ThingCategoryMissile);
|
||||
}
|
||||
|
||||
ThingType* Missile::rawGetThingType()
|
||||
{
|
||||
return g_things.rawGetThingType(m_id, ThingCategoryMissile);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHOT_H
|
||||
#define SHOT_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <framework/core/timer.h>
|
||||
#include "thing.h"
|
||||
|
||||
// @bindclass
|
||||
class Missile : public Thing
|
||||
{
|
||||
enum {
|
||||
TICKS_PER_FRAME = 75
|
||||
};
|
||||
|
||||
public:
|
||||
void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr);
|
||||
|
||||
void setId(uint32 id);
|
||||
void setPath(const Position& fromPosition, const Position& toPosition);
|
||||
|
||||
uint32 getId() { return m_id; }
|
||||
|
||||
MissilePtr asMissile() { return static_self_cast<Missile>(); }
|
||||
bool isMissile() { return true; }
|
||||
|
||||
const ThingTypePtr& getThingType();
|
||||
ThingType *rawGetThingType();
|
||||
|
||||
Position getSource() { return m_source; }
|
||||
Position getDestination() { return m_destination; }
|
||||
|
||||
private:
|
||||
Timer m_animationTimer;
|
||||
Point m_delta;
|
||||
float m_duration;
|
||||
uint16 m_id;
|
||||
Otc::Direction m_direction;
|
||||
Position m_source, m_destination;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "outfit.h"
|
||||
#include "game.h"
|
||||
#include "spritemanager.h"
|
||||
|
||||
#include <framework/graphics/painter.h>
|
||||
#include <framework/graphics/drawqueue.h>
|
||||
|
||||
Outfit::Outfit()
|
||||
{
|
||||
m_category = ThingCategoryCreature;
|
||||
m_id = 128;
|
||||
m_auxId = 0;
|
||||
resetClothes();
|
||||
}
|
||||
|
||||
void Outfit::draw(Point dest, Otc::Direction direction, uint walkAnimationPhase, bool animate, LightView* lightView)
|
||||
{
|
||||
// direction correction
|
||||
if (m_category != ThingCategoryCreature)
|
||||
direction = Otc::North;
|
||||
else if (direction == Otc::NorthEast || direction == Otc::SouthEast)
|
||||
direction = Otc::East;
|
||||
else if (direction == Otc::NorthWest || direction == Otc::SouthWest)
|
||||
direction = Otc::West;
|
||||
|
||||
auto type = g_things.rawGetThingType(m_category == ThingCategoryCreature ? m_id : m_auxId, m_category);
|
||||
|
||||
int animationPhase = walkAnimationPhase;
|
||||
if (animate && m_category == ThingCategoryCreature) {
|
||||
auto idleAnimator = type->getIdleAnimator();
|
||||
if (idleAnimator) {
|
||||
if (walkAnimationPhase > 0) {
|
||||
animationPhase += idleAnimator->getAnimationPhases() - 1;;
|
||||
} else {
|
||||
animationPhase = idleAnimator->getPhase();
|
||||
}
|
||||
} else if (type->isAnimateAlways()) {
|
||||
int phases = type->getAnimator() ? type->getAnimator()->getAnimationPhases() : type->getAnimationPhases();
|
||||
int ticksPerFrame = 1000 / phases;
|
||||
animationPhase = (g_clock.millis() % (ticksPerFrame * phases)) / ticksPerFrame;
|
||||
}
|
||||
} else if(animate) {
|
||||
int animationPhases = type->getAnimationPhases();
|
||||
int animateTicks = g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::ITEM_TICKS_PER_FRAME_FAST : Otc::ITEM_TICKS_PER_FRAME;
|
||||
|
||||
if (m_category == ThingCategoryEffect) {
|
||||
animationPhases = std::max<int>(1, animationPhases - 2);
|
||||
animateTicks = g_game.getFeature(Otc::GameEnhancedAnimations) ? Otc::INVISIBLE_TICKS_PER_FRAME_FAST : Otc::INVISIBLE_TICKS_PER_FRAME;
|
||||
}
|
||||
|
||||
if (animationPhases > 1)
|
||||
animationPhase = (g_clock.millis() % (animateTicks * animationPhases)) / animateTicks;
|
||||
if (m_category == ThingCategoryEffect)
|
||||
animationPhase = std::min<int>(animationPhase + 1, animationPhases);
|
||||
}
|
||||
|
||||
int zPattern = m_mount > 0 ? std::min<int>(1, type->getNumPatternZ() - 1) : 0;
|
||||
if (zPattern > 0) {
|
||||
int mountAnimationPhase = walkAnimationPhase;
|
||||
auto mountType = g_things.rawGetThingType(m_mount, ThingCategoryCreature);
|
||||
auto idleAnimator = mountType->getIdleAnimator();
|
||||
if (idleAnimator && animate) {
|
||||
if (walkAnimationPhase > 0) {
|
||||
mountAnimationPhase += idleAnimator->getAnimationPhases() - 1;
|
||||
} else {
|
||||
mountAnimationPhase = idleAnimator->getPhase();
|
||||
}
|
||||
}
|
||||
|
||||
dest -= mountType->getDisplacement();
|
||||
mountType->draw(dest, 0, direction, 0, 0, mountAnimationPhase, Color::white, lightView);
|
||||
dest += type->getDisplacement();
|
||||
}
|
||||
|
||||
if (m_aura) {
|
||||
auto auraType = g_things.rawGetThingType(m_aura, ThingCategoryCreature);
|
||||
auraType->draw(dest, 0, direction, 0, 0, 0, Color::white, lightView);
|
||||
}
|
||||
|
||||
if (m_wings && (direction == Otc::South || direction == Otc::West)) {
|
||||
auto wingsType = g_things.rawGetThingType(m_wings, ThingCategoryCreature);
|
||||
wingsType->draw(dest, 0, direction, 0, 0, animationPhase, Color::white, lightView);
|
||||
}
|
||||
|
||||
for (int yPattern = 0; yPattern < type->getNumPatternY(); yPattern++) {
|
||||
if (yPattern > 0 && !(getAddons() & (1 << (yPattern - 1)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type->getLayers() <= 1) {
|
||||
type->draw(dest, 0, direction, yPattern, zPattern, animationPhase, Color::white, lightView);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t colors = m_head + (m_body << 8) + (m_legs << 16) + (m_feet << 24);
|
||||
type->drawOutfit(dest, direction, yPattern, zPattern, animationPhase, colors, Color::white, lightView);
|
||||
}
|
||||
|
||||
if (m_wings && (direction == Otc::North || direction == Otc::East)) {
|
||||
auto wingsType = g_things.rawGetThingType(m_wings, ThingCategoryCreature);
|
||||
wingsType->draw(dest, 0, direction, 0, 0, animationPhase, Color::white, lightView);
|
||||
}
|
||||
}
|
||||
|
||||
void Outfit::draw(const Rect& dest, Otc::Direction direction, uint animationPhase, bool animate)
|
||||
{
|
||||
int size = g_drawQueue->size();
|
||||
draw(Point(0, 0), direction, animationPhase, animate);
|
||||
g_drawQueue->correctOutfit(dest, size);
|
||||
}
|
||||
|
||||
void Outfit::resetClothes()
|
||||
{
|
||||
setHead(0);
|
||||
setBody(0);
|
||||
setLegs(0);
|
||||
setFeet(0);
|
||||
setMount(0);
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef OUTFIT_H
|
||||
#define OUTFIT_H
|
||||
|
||||
#include <framework/util/color.h>
|
||||
#include "thingtypemanager.h"
|
||||
|
||||
class Outfit
|
||||
{
|
||||
public:
|
||||
Outfit();
|
||||
|
||||
static Color getColor(int color)
|
||||
{
|
||||
return Color::getOutfitColor(color);
|
||||
}
|
||||
|
||||
void draw(Point dest, Otc::Direction direction, uint walkAnimationPhase, bool animate = true, LightView* lightView = nullptr);
|
||||
void draw(const Rect& dest, Otc::Direction direction, uint animationPhase, bool animate = true);
|
||||
|
||||
void setId(int id) { m_id = id; }
|
||||
void setAuxId(int id) { m_auxId = id; }
|
||||
void setHead(int head) { m_head = head; }
|
||||
void setBody(int body) { m_body = body; }
|
||||
void setLegs(int legs) { m_legs = legs; }
|
||||
void setFeet(int feet) { m_feet = feet; }
|
||||
void setAddons(int addons) { m_addons = addons; }
|
||||
void setMount(int mount) { m_mount = mount; }
|
||||
void setWings(int wings) { m_wings = wings; }
|
||||
void setAura(int aura) { m_aura = aura; }
|
||||
void setCategory(ThingCategory category) { m_category = category; }
|
||||
|
||||
void resetClothes();
|
||||
|
||||
int getId() const { return m_id; }
|
||||
int getAuxId() const { return m_auxId; }
|
||||
int getHead() const { return m_head; }
|
||||
int getBody() const { return m_body; }
|
||||
int getLegs() const { return m_legs; }
|
||||
int getFeet() const { return m_feet; }
|
||||
int getAddons() const { return m_addons; }
|
||||
int getMount() const { return m_mount; }
|
||||
int getWings() const { return m_wings; }
|
||||
int getAura() const { return m_aura; }
|
||||
ThingCategory getCategory() const { return m_category; }
|
||||
|
||||
private:
|
||||
ThingCategory m_category;
|
||||
int m_id, m_auxId, m_head, m_body, m_legs, m_feet, m_addons, m_mount = 0, m_wings = 0, m_aura = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "player.h"
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include "creature.h"
|
||||
|
||||
// @bindclass
|
||||
class Player : public Creature
|
||||
{
|
||||
public:
|
||||
Player() { }
|
||||
virtual ~Player() { }
|
||||
|
||||
PlayerPtr asPlayer() { return static_self_cast<Player>(); }
|
||||
bool isPlayer() { return true; }
|
||||
};
|
||||
|
||||
#endif
|
@ -1,273 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POSITION_H
|
||||
#define POSITION_H
|
||||
|
||||
#include "const.h"
|
||||
#include <framework/stdext/types.h>
|
||||
#include <framework/const.h>
|
||||
#include <framework/util/point.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Position
|
||||
{
|
||||
public:
|
||||
Position() : x(65535), y(65535), z(255) { }
|
||||
Position(uint16 x, uint16 y, uint8 z) : x(x), y(y), z(z) { }
|
||||
|
||||
Position translatedToDirection(Otc::Direction direction) {
|
||||
Position pos = *this;
|
||||
switch(direction) {
|
||||
case Otc::North:
|
||||
pos.y--;
|
||||
break;
|
||||
case Otc::East:
|
||||
pos.x++;
|
||||
break;
|
||||
case Otc::South:
|
||||
pos.y++;
|
||||
break;
|
||||
case Otc::West:
|
||||
pos.x--;
|
||||
break;
|
||||
case Otc::NorthEast:
|
||||
pos.x++;
|
||||
pos.y--;
|
||||
break;
|
||||
case Otc::SouthEast:
|
||||
pos.x++;
|
||||
pos.y++;
|
||||
break;
|
||||
case Otc::SouthWest:
|
||||
pos.x--;
|
||||
pos.y++;
|
||||
break;
|
||||
case Otc::NorthWest:
|
||||
pos.x--;
|
||||
pos.y--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
Position translatedToReverseDirection(Otc::Direction direction) {
|
||||
Position pos = *this;
|
||||
switch(direction) {
|
||||
case Otc::North:
|
||||
pos.y++;
|
||||
break;
|
||||
case Otc::East:
|
||||
pos.x--;
|
||||
break;
|
||||
case Otc::South:
|
||||
pos.y--;
|
||||
break;
|
||||
case Otc::West:
|
||||
pos.x++;
|
||||
break;
|
||||
case Otc::NorthEast:
|
||||
pos.x--;
|
||||
pos.y++;
|
||||
break;
|
||||
case Otc::SouthEast:
|
||||
pos.x--;
|
||||
pos.y--;
|
||||
break;
|
||||
case Otc::SouthWest:
|
||||
pos.x++;
|
||||
pos.y--;
|
||||
break;
|
||||
case Otc::NorthWest:
|
||||
pos.x++;
|
||||
pos.y++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
std::vector<Position> translatedToDirections(const std::vector<Otc::Direction>& dirs) const {
|
||||
Position lastPos = *this;
|
||||
std::vector<Position> positions;
|
||||
|
||||
if(!lastPos.isValid())
|
||||
return positions;
|
||||
|
||||
positions.push_back(lastPos);
|
||||
|
||||
for(auto dir : dirs) {
|
||||
lastPos = lastPos.translatedToDirection(dir);
|
||||
if(!lastPos.isValid())
|
||||
break;
|
||||
positions.push_back(lastPos);
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
static double getAngleFromPositions(const Position& fromPos, const Position& toPos) {
|
||||
// Returns angle in radians from 0 to 2Pi. -1 means positions are equal.
|
||||
int dx = toPos.x - fromPos.x;
|
||||
int dy = toPos.y - fromPos.y;
|
||||
if(dx == 0 && dy == 0)
|
||||
return -1;
|
||||
|
||||
float angle = std::atan2(dy * -1, dx);
|
||||
if(angle < 0)
|
||||
angle += 2 * Fw::pi;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
double getAngleFromPosition(const Position& position) const {
|
||||
return getAngleFromPositions(*this, position);
|
||||
}
|
||||
|
||||
static Otc::Direction getDirectionFromPositions(const Position& fromPos,
|
||||
const Position& toPos)
|
||||
{
|
||||
float angle = getAngleFromPositions(fromPos, toPos) * RAD_TO_DEC;
|
||||
|
||||
if(angle >= 360 - 22.5 || angle < 0 + 22.5)
|
||||
return Otc::East;
|
||||
else if(angle >= 45 - 22.5 && angle < 45 + 22.5)
|
||||
return Otc::NorthEast;
|
||||
else if(angle >= 90 - 22.5 && angle < 90 + 22.5)
|
||||
return Otc::North;
|
||||
else if(angle >= 135 - 22.5 && angle < 135 + 22.5)
|
||||
return Otc::NorthWest;
|
||||
else if(angle >= 180 - 22.5 && angle < 180 + 22.5)
|
||||
return Otc::West;
|
||||
else if(angle >= 225 - 22.5 && angle < 225 + 22.5)
|
||||
return Otc::SouthWest;
|
||||
else if(angle >= 270 - 22.5 && angle < 270 + 22.5)
|
||||
return Otc::South;
|
||||
else if(angle >= 315 - 22.5 && angle < 315 + 22.5)
|
||||
return Otc::SouthEast;
|
||||
else
|
||||
return Otc::InvalidDirection;
|
||||
}
|
||||
|
||||
Otc::Direction getDirectionFromPosition(const Position& position) const {
|
||||
return getDirectionFromPositions(*this, position);
|
||||
}
|
||||
|
||||
bool isMapPosition() const { return (x >=0 && y >= 0 && z >= 0 && x < 65535 && y < 65535 && z <= Otc::MAX_Z); }
|
||||
bool isValid() const { return !(x == 65535 && y == 65535 && z == 255); }
|
||||
float distance(const Position& pos) const { return sqrt(pow((pos.x - x), 2) + pow((pos.y - y), 2)); }
|
||||
int manhattanDistance(const Position& pos) const { return std::abs(pos.x - x) + std::abs(pos.y - y); }
|
||||
|
||||
void translate(int dx, int dy, short dz = 0) { x += dx; y += dy; z += dz; }
|
||||
Position translated(int dx, int dy, short dz = 0) const { Position pos = *this; pos.x += dx; pos.y += dy; pos.z += dz; return pos; }
|
||||
|
||||
Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); }
|
||||
Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; }
|
||||
Position operator-(const Position& other) const { return Position(x - other.x, y - other.y, z - other.z); }
|
||||
Position& operator-=(const Position& other) { x-=other.x; y-=other.y; z-=other.z; return *this; }
|
||||
// Point conversion(s)
|
||||
Position operator+(const Point& other) const { return Position(x + other.x, y + other.y, z); }
|
||||
Position& operator+=(const Point& other) { x += other.x; y += other.y; return *this; }
|
||||
|
||||
Position& operator=(const Position& other) { x = other.x; y = other.y; z = other.z; return *this; }
|
||||
bool operator==(const Position& other) const { return other.x == x && other.y == y && other.z == z; }
|
||||
bool operator!=(const Position& other) const { return other.x!=x || other.y!=y || other.z!=z; }
|
||||
bool isInRange(const Position& pos, int xRange, int yRange, int zRange = 0) const { return std::abs(x-pos.x) <= xRange && std::abs(y-pos.y) <= yRange && std::abs(z - pos.z) <= zRange; }
|
||||
bool isInRange(const Position& pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const {
|
||||
return (pos.x >= x-minXRange && pos.x <= x+maxXRange && pos.y >= y-minYRange && pos.y <= y+maxYRange && pos.z == z);
|
||||
}
|
||||
// operator less than for std::map
|
||||
bool operator<(const Position& other) const { return x < other.x || y < other.y || z < other.z; }
|
||||
|
||||
bool up(int n = 1) {
|
||||
int nz = z-n;
|
||||
if(nz >= 0 && nz <= Otc::MAX_Z) {
|
||||
z = nz;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool down(int n = 1) {
|
||||
int nz = z+n;
|
||||
if(nz >= 0 && nz <= Otc::MAX_Z) {
|
||||
z = nz;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool coveredUp(int n = 1) {
|
||||
int nx = x+n, ny = y+n, nz = z-n;
|
||||
if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) {
|
||||
x = nx; y = ny; z = nz;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool coveredDown(int n = 1) {
|
||||
int nx = x-n, ny = y-n, nz = z+n;
|
||||
if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) {
|
||||
x = nx; y = ny; z = nz;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string toString()
|
||||
{
|
||||
return std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z);
|
||||
}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
short z;
|
||||
};
|
||||
|
||||
struct PositionHasher {
|
||||
std::size_t operator()(const Position& pos) const {
|
||||
return (((pos.x * 8192) + pos.y) * 16) + pos.z;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Position& pos)
|
||||
{
|
||||
out << (int)pos.x << " " << (int)pos.y << " " << (int)pos.z;
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::istream& operator>>(std::istream& in, Position& pos)
|
||||
{
|
||||
int x, y, z;
|
||||
in >> x >> y >> z;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
pos.z = z;
|
||||
return in;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "protocolcodes.h"
|
||||
|
||||
namespace Proto {
|
||||
|
||||
std::map<uint8, uint8> messageModesMap;
|
||||
|
||||
void buildMessageModesMap(int version) {
|
||||
messageModesMap.clear();
|
||||
|
||||
if(version >= 1094) {
|
||||
messageModesMap[Otc::MessageMana] = 43;
|
||||
}
|
||||
|
||||
if(version >= 1055) { // might be 1054
|
||||
messageModesMap[Otc::MessageNone] = 0;
|
||||
messageModesMap[Otc::MessageSay] = 1;
|
||||
messageModesMap[Otc::MessageWhisper] = 2;
|
||||
messageModesMap[Otc::MessageYell] = 3;
|
||||
messageModesMap[Otc::MessagePrivateFrom] = 4;
|
||||
messageModesMap[Otc::MessagePrivateTo] = 5;
|
||||
messageModesMap[Otc::MessageChannelManagement] = 6;
|
||||
messageModesMap[Otc::MessageChannel] = 7;
|
||||
messageModesMap[Otc::MessageChannelHighlight] = 8;
|
||||
messageModesMap[Otc::MessageSpell] = 9;
|
||||
messageModesMap[Otc::MessageNpcFromStartBlock] = 10;
|
||||
messageModesMap[Otc::MessageNpcFrom] = 11;
|
||||
messageModesMap[Otc::MessageNpcTo] = 12;
|
||||
messageModesMap[Otc::MessageGamemasterBroadcast] = 13;
|
||||
messageModesMap[Otc::MessageGamemasterChannel] = 14;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateFrom] = 15;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateTo] = 16;
|
||||
messageModesMap[Otc::MessageLogin] = 17;
|
||||
messageModesMap[Otc::MessageWarning] = 18; // Admin
|
||||
messageModesMap[Otc::MessageGame] = 19;
|
||||
messageModesMap[Otc::MessageGameHighlight] = 20;
|
||||
messageModesMap[Otc::MessageFailure] = 21;
|
||||
messageModesMap[Otc::MessageLook] = 22;
|
||||
messageModesMap[Otc::MessageDamageDealed] = 23;
|
||||
messageModesMap[Otc::MessageDamageReceived] = 24;
|
||||
messageModesMap[Otc::MessageHeal] = 25;
|
||||
messageModesMap[Otc::MessageExp] = 26;
|
||||
messageModesMap[Otc::MessageDamageOthers] = 27;
|
||||
messageModesMap[Otc::MessageHealOthers] = 28;
|
||||
messageModesMap[Otc::MessageExpOthers] = 29;
|
||||
messageModesMap[Otc::MessageStatus] = 30;
|
||||
messageModesMap[Otc::MessageLoot] = 31;
|
||||
messageModesMap[Otc::MessageTradeNpc] = 32;
|
||||
messageModesMap[Otc::MessageGuild] = 33;
|
||||
messageModesMap[Otc::MessagePartyManagement] = 34;
|
||||
messageModesMap[Otc::MessageParty] = 35;
|
||||
messageModesMap[Otc::MessageBarkLow] = 36;
|
||||
messageModesMap[Otc::MessageBarkLoud] = 37;
|
||||
messageModesMap[Otc::MessageReport] = 38;
|
||||
messageModesMap[Otc::MessageHotkeyUse] = 39;
|
||||
messageModesMap[Otc::MessageTutorialHint] = 40;
|
||||
messageModesMap[Otc::MessageThankyou] = 41;
|
||||
messageModesMap[Otc::MessageMarket] = 42;
|
||||
} else if(version >= 1036) {
|
||||
for(int i = Otc::MessageNone; i <= Otc::MessageBeyondLast; ++i) {
|
||||
if(i >= Otc::MessageNpcTo)
|
||||
messageModesMap[i] = i + 1;
|
||||
else
|
||||
messageModesMap[i] = i;
|
||||
}
|
||||
} else if(version >= 900) {
|
||||
for(int i = Otc::MessageNone; i <= Otc::MessageBeyondLast; ++i)
|
||||
messageModesMap[i] = i;
|
||||
messageModesMap[Otc::MessageNpcFromStartBlock] = 10;
|
||||
messageModesMap[Otc::MessageNpcFrom] = 11;
|
||||
} else if(version >= 861) {
|
||||
messageModesMap[Otc::MessageNone] = 0;
|
||||
messageModesMap[Otc::MessageSay] = 1;
|
||||
messageModesMap[Otc::MessageWhisper] = 2;
|
||||
messageModesMap[Otc::MessageYell] = 3;
|
||||
messageModesMap[Otc::MessageNpcTo] = 4;
|
||||
messageModesMap[Otc::MessageNpcFromStartBlock] = 5;
|
||||
messageModesMap[Otc::MessagePrivateFrom] = 6;
|
||||
messageModesMap[Otc::MessagePrivateTo] = 6;
|
||||
messageModesMap[Otc::MessageChannel] = 7;
|
||||
messageModesMap[Otc::MessageChannelManagement] = 8;
|
||||
messageModesMap[Otc::MessageGamemasterBroadcast] = 9;
|
||||
messageModesMap[Otc::MessageGamemasterChannel] = 10;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateFrom] = 11;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateTo] = 11;
|
||||
messageModesMap[Otc::MessageChannelHighlight] = 12;
|
||||
messageModesMap[Otc::MessageMonsterSay] = 13;
|
||||
messageModesMap[Otc::MessageMonsterYell] = 14;
|
||||
messageModesMap[Otc::MessageWarning] = 15;
|
||||
messageModesMap[Otc::MessageGame] = 16;
|
||||
messageModesMap[Otc::MessageLogin] = 17;
|
||||
messageModesMap[Otc::MessageStatus] = 18;
|
||||
messageModesMap[Otc::MessageLook] = 19;
|
||||
messageModesMap[Otc::MessageFailure] = 20;
|
||||
messageModesMap[Otc::MessageBlue] = 21;
|
||||
messageModesMap[Otc::MessageRed] = 22;
|
||||
} else if(version >= 840) {
|
||||
messageModesMap[Otc::MessageNone] = 0;
|
||||
messageModesMap[Otc::MessageSay] = 1;
|
||||
messageModesMap[Otc::MessageWhisper] = 2;
|
||||
messageModesMap[Otc::MessageYell] = 3;
|
||||
messageModesMap[Otc::MessageNpcTo] = 4;
|
||||
messageModesMap[Otc::MessageNpcFromStartBlock] = 5;
|
||||
messageModesMap[Otc::MessagePrivateFrom] = 6;
|
||||
messageModesMap[Otc::MessagePrivateTo] = 6;
|
||||
messageModesMap[Otc::MessageChannel] = 7;
|
||||
messageModesMap[Otc::MessageChannelManagement] = 8;
|
||||
messageModesMap[Otc::MessageRVRChannel] = 9;
|
||||
messageModesMap[Otc::MessageRVRAnswer] = 10;
|
||||
messageModesMap[Otc::MessageRVRContinue] = 11;
|
||||
messageModesMap[Otc::MessageGamemasterBroadcast] = 12;
|
||||
messageModesMap[Otc::MessageGamemasterChannel] = 13;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateFrom] = 14;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateTo] = 14;
|
||||
messageModesMap[Otc::MessageChannelHighlight] = 15;
|
||||
// 16, 17 ??
|
||||
messageModesMap[Otc::MessageRed] = 18;
|
||||
messageModesMap[Otc::MessageMonsterSay] = 19;
|
||||
messageModesMap[Otc::MessageMonsterYell] = 20;
|
||||
messageModesMap[Otc::MessageWarning] = 21;
|
||||
messageModesMap[Otc::MessageGame] = 22;
|
||||
messageModesMap[Otc::MessageLogin] = 23;
|
||||
messageModesMap[Otc::MessageStatus] = 24;
|
||||
messageModesMap[Otc::MessageLook] = 25;
|
||||
messageModesMap[Otc::MessageFailure] = 26;
|
||||
messageModesMap[Otc::MessageBlue] = 27;
|
||||
} else if(version >= 760) {
|
||||
messageModesMap[Otc::MessageNone] = 0;
|
||||
messageModesMap[Otc::MessageSay] = 1;
|
||||
messageModesMap[Otc::MessageWhisper] = 2;
|
||||
messageModesMap[Otc::MessageYell] = 3;
|
||||
messageModesMap[Otc::MessagePrivateFrom] = 4;
|
||||
messageModesMap[Otc::MessagePrivateTo] = 4;
|
||||
messageModesMap[Otc::MessageChannel] = 5;
|
||||
messageModesMap[Otc::MessageRVRChannel] = 6;
|
||||
messageModesMap[Otc::MessageRVRAnswer] = 7;
|
||||
messageModesMap[Otc::MessageRVRContinue] = 8;
|
||||
messageModesMap[Otc::MessageGamemasterBroadcast] = 9;
|
||||
messageModesMap[Otc::MessageGamemasterChannel] = 10;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateFrom] = 11;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateTo] = 11;
|
||||
messageModesMap[Otc::MessageChannelHighlight] = 12;
|
||||
// 13, 14, 15 ??
|
||||
messageModesMap[Otc::MessageMonsterSay] = 16;
|
||||
messageModesMap[Otc::MessageMonsterYell] = 17;
|
||||
messageModesMap[Otc::MessageWarning] = 18;
|
||||
messageModesMap[Otc::MessageGame] = 19;
|
||||
messageModesMap[Otc::MessageLogin] = 20;
|
||||
messageModesMap[Otc::MessageStatus] = 21;
|
||||
messageModesMap[Otc::MessageLook] = 22;
|
||||
messageModesMap[Otc::MessageFailure] = 23;
|
||||
messageModesMap[Otc::MessageBlue] = 24;
|
||||
messageModesMap[Otc::MessageRed] = 25;
|
||||
}
|
||||
}
|
||||
|
||||
Otc::MessageMode translateMessageModeFromServer(uint8 mode)
|
||||
{
|
||||
auto it = std::find_if(messageModesMap.begin(), messageModesMap.end(), [=] (const std::pair<uint8, uint8>& p) { return p.second == mode; });
|
||||
if(it != messageModesMap.end())
|
||||
return (Otc::MessageMode)it->first;
|
||||
return Otc::MessageInvalid;
|
||||
}
|
||||
|
||||
uint8 translateMessageModeToServer(Otc::MessageMode mode)
|
||||
{
|
||||
if(mode < 0 || mode >= Otc::LastMessage)
|
||||
return Otc::MessageInvalid;
|
||||
auto it = messageModesMap.find(mode);
|
||||
if(it != messageModesMap.end())
|
||||
return it->second;
|
||||
return Otc::MessageInvalid;
|
||||
}
|
||||
|
||||
}
|
@ -1,361 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PROTOCOLCODES_H
|
||||
#define PROTOCOLCODES_H
|
||||
|
||||
#include "global.h"
|
||||
|
||||
namespace Proto {
|
||||
enum LoginServerOpts {
|
||||
LoginServerError = 10,
|
||||
LoginServerMotd = 20,
|
||||
LoginServerUpdateNeeded = 30,
|
||||
LoginServerCharacterList = 100
|
||||
};
|
||||
|
||||
enum ItemOpcode {
|
||||
StaticText = 96,
|
||||
UnknownCreature = 97,
|
||||
OutdatedCreature = 98,
|
||||
Creature = 99
|
||||
};
|
||||
|
||||
enum GameServerOpcodes : uint8
|
||||
{
|
||||
GameServerLoginOrPendingState = 10,
|
||||
GameServerGMActions = 11,
|
||||
GameServerEnterGame = 15,
|
||||
GameServerUpdateNeeded = 17,
|
||||
GameServerLoginError = 20,
|
||||
GameServerLoginAdvice = 21,
|
||||
GameServerLoginWait = 22,
|
||||
GameServerLoginSuccess = 23,
|
||||
GameServerLoginToken = 24,
|
||||
GameServerStoreButtonIndicators = 25, // 1097
|
||||
GameServerPingBack = 29,
|
||||
GameServerPing = 30,
|
||||
GameServerChallenge = 31,
|
||||
GameServerDeath = 40,
|
||||
GameServerSupplyStash = 41,
|
||||
GameServerSpecialContainer = 42,
|
||||
|
||||
// all in game opcodes must be greater than 50
|
||||
GameServerFirstGameOpcode = 50,
|
||||
|
||||
// otclient ONLY
|
||||
GameServerExtendedOpcode = 50,
|
||||
GameServerProgressBar = 59,
|
||||
|
||||
// NOTE: add any custom opcodes in this range
|
||||
// OTClientV8 64-79
|
||||
GameServerNewPing = 64,
|
||||
GameServerChangeMapAwareRange = 66,
|
||||
|
||||
GameServerFeatures = 67,
|
||||
|
||||
GameServerNewCancelWalk = 69,
|
||||
GameServerPredictiveCancelWalk = 70,
|
||||
GameServerWalkId = 71,
|
||||
|
||||
GameServerFloorDescription = 75,
|
||||
|
||||
GameServerProcessesRequest = 80,
|
||||
GameServerDllsRequest = 81,
|
||||
GameServerWindowsRequests = 82,
|
||||
|
||||
GameServerClientCheck = 99,
|
||||
|
||||
// original tibia ONLY
|
||||
GameServerFullMap = 100,
|
||||
GameServerMapTopRow = 101,
|
||||
GameServerMapRightRow = 102,
|
||||
GameServerMapBottomRow = 103,
|
||||
GameServerMapLeftRow = 104,
|
||||
GameServerUpdateTile = 105,
|
||||
GameServerCreateOnMap = 106,
|
||||
GameServerChangeOnMap = 107,
|
||||
GameServerDeleteOnMap = 108,
|
||||
GameServerMoveCreature = 109,
|
||||
GameServerOpenContainer = 110,
|
||||
GameServerCloseContainer = 111,
|
||||
GameServerCreateContainer = 112,
|
||||
GameServerChangeInContainer = 113,
|
||||
GameServerDeleteInContainer = 114,
|
||||
GameServerItemDetail = 118,
|
||||
GameServerSetInventory = 120,
|
||||
GameServerDeleteInventory = 121,
|
||||
GameServerOpenNpcTrade = 122,
|
||||
GameServerPlayerGoods = 123,
|
||||
GameServerCloseNpcTrade = 124,
|
||||
GameServerOwnTrade = 125,
|
||||
GameServerCounterTrade = 126,
|
||||
GameServerCloseTrade = 127,
|
||||
GameServerAmbient = 130,
|
||||
GameServerGraphicalEffect = 131,
|
||||
GameServerTextEffect = 132,
|
||||
GameServerMissleEffect = 133,
|
||||
GameServerMarkCreature = 134,
|
||||
GameServerTrappers = 135,
|
||||
GameServerCreatureHealth = 140,
|
||||
GameServerCreatureLight = 141,
|
||||
GameServerCreatureOutfit = 142,
|
||||
GameServerCreatureSpeed = 143,
|
||||
GameServerCreatureSkull = 144,
|
||||
GameServerCreatureParty = 145,
|
||||
GameServerCreatureUnpass = 146,
|
||||
GameServerCreatureMarks = 147,
|
||||
GameServerPlayerHelpers = 148,
|
||||
GameServerCreatureType = 149,
|
||||
GameServerEditText = 150,
|
||||
GameServerEditList = 151,
|
||||
GameServerNews = 152,
|
||||
GameUnkown154 = 154,
|
||||
GameServerBlessDialog = 155,
|
||||
GameServerBlessings = 156,
|
||||
GameServerPreset = 157,
|
||||
GameServerPremiumTrigger = 158, // 1038
|
||||
GameServerPlayerDataBasic = 159, // 950
|
||||
GameServerPlayerData = 160,
|
||||
GameServerPlayerSkills = 161,
|
||||
GameServerPlayerState = 162,
|
||||
GameServerClearTarget = 163,
|
||||
GameServerPlayerModes = 167,
|
||||
GameServerSpellDelay = 164, // 870
|
||||
GameServerSpellGroupDelay = 165, // 870
|
||||
GameServerMultiUseDelay = 166, // 870
|
||||
GameServerSetStoreDeepLink = 168, // 1097
|
||||
GameServerRestingAreaState = 169,
|
||||
GameServerTalk = 170,
|
||||
GameServerChannels = 171,
|
||||
GameServerOpenChannel = 172,
|
||||
GameServerOpenPrivateChannel = 173,
|
||||
GameServerRuleViolationChannel = 174,
|
||||
GameServerRuleViolationRemove = 175,
|
||||
GameServerRuleViolationCancel = 176,
|
||||
GameServerRuleViolationLock = 177,
|
||||
GameServerOpenOwnChannel = 178,
|
||||
GameServerCloseChannel = 179,
|
||||
GameServerTextMessage = 180,
|
||||
GameServerCancelWalk = 181,
|
||||
GameServerWalkWait = 182,
|
||||
GameServerUnjustifiedStats = 183,
|
||||
GameServerPvpSituations = 184,
|
||||
GameServerHunting = 187,
|
||||
GameServerFloorChangeUp = 190,
|
||||
GameServerFloorChangeDown = 191,
|
||||
GameServerLootContainers = 192,
|
||||
GameServerTournamentLeaderboard = 197,
|
||||
GameServerChooseOutfit = 200,
|
||||
GameServerImpactTracker = 204,
|
||||
GameServerItemsPrices = 205,
|
||||
GameServerSupplyTracker = 206,
|
||||
GameServerLootTracker = 207,
|
||||
GameServerQuestTracker = 208,
|
||||
GameServerKillTracker = 209,
|
||||
GameServerVipAdd = 210,
|
||||
GameServerVipState = 211,
|
||||
GameServerVipLogoutOrGroupData = 212,
|
||||
GameServerCyclopediaNewDetails = 217,
|
||||
GameServerCyclopedia = 218,
|
||||
GameServerTutorialHint = 220,
|
||||
GameServerCyclopediaMapData = 221,
|
||||
GameServerDailyRewardState = 222,
|
||||
GameServerCoinBalance = 223,
|
||||
GameServerStoreError = 224, // 1080
|
||||
GameServerRequestPurchaseData = 225, // 1080
|
||||
GameServerOpenRewardWall = 226,
|
||||
GameServerDailyReward = 228,
|
||||
GameServerDailyRewardHistory = 229,
|
||||
GameServerPreyFreeRolls = 230,
|
||||
GameServerPreyTimeLeft = 231,
|
||||
GameServerPreyData = 232,
|
||||
GameServerPreyPrices = 233,
|
||||
GameServerStoreOfferDescription = 234,
|
||||
GameServerImbuementWindow = 235,
|
||||
GameServerCloseImbuementWindow = 236,
|
||||
GameServerMessageDialog = 237,
|
||||
GameServerResourceBalance = 238,
|
||||
GameServerTime = 239,
|
||||
GameServerQuestLog = 240,
|
||||
GameServerQuestLine = 241,
|
||||
GameServerCoinBalanceUpdate = 242,
|
||||
GameServerChannelEvent = 243, // 910
|
||||
GameServerItemInfo = 244, // 910
|
||||
GameServerPlayerInventory = 245, // 910
|
||||
GameServerMarketEnter = 246, // 944
|
||||
GameServerMarketLeave = 247, // 944
|
||||
GameServerMarketDetail = 248, // 944
|
||||
GameServerMarketBrowse = 249, // 944
|
||||
GameServerModalDialog = 250, // 960
|
||||
GameServerStore = 251, // 1080
|
||||
GameServerStoreOffers = 252, // 1080
|
||||
GameServerStoreTransactionHistory = 253, // 1080
|
||||
GameServerStoreCompletePurchase = 254 // 1080
|
||||
};
|
||||
|
||||
enum ClientOpcodes : uint8
|
||||
{
|
||||
ClientEnterAccount = 1,
|
||||
ClientPendingGame = 10,
|
||||
ClientEnterGame = 15,
|
||||
ClientLeaveGame = 20,
|
||||
ClientPing = 29,
|
||||
ClientPingBack = 30,
|
||||
|
||||
// all in game opcodes must be equal or greater than 50
|
||||
ClientFirstGameOpcode = 50,
|
||||
|
||||
// otclient ONLY
|
||||
ClientExtendedOpcode = 50,
|
||||
|
||||
// NOTE: add any custom opcodes in this range
|
||||
|
||||
// OTClientV8 64-79
|
||||
ClientNewPing = 64,
|
||||
ClientChangeMapAwareRange = 66,
|
||||
|
||||
ClientNewWalk = 69,
|
||||
|
||||
ClientProcessesResponse = 80,
|
||||
ClientDllsResponse = 81,
|
||||
ClientWindowsResponse = 82,
|
||||
|
||||
// original tibia ONLY
|
||||
ClientAutoWalk = 100,
|
||||
ClientWalkNorth = 101,
|
||||
ClientWalkEast = 102,
|
||||
ClientWalkSouth = 103,
|
||||
ClientWalkWest = 104,
|
||||
ClientStop = 105,
|
||||
ClientWalkNorthEast = 106,
|
||||
ClientWalkSouthEast = 107,
|
||||
ClientWalkSouthWest = 108,
|
||||
ClientWalkNorthWest = 109,
|
||||
ClientTurnNorth = 111,
|
||||
ClientTurnEast = 112,
|
||||
ClientTurnSouth = 113,
|
||||
ClientTurnWest = 114,
|
||||
ClientEquipItem = 119, // 910
|
||||
ClientMove = 120,
|
||||
ClientInspectNpcTrade = 121,
|
||||
ClientBuyItem = 122,
|
||||
ClientSellItem = 123,
|
||||
ClientCloseNpcTrade = 124,
|
||||
ClientRequestTrade = 125,
|
||||
ClientInspectTrade = 126,
|
||||
ClientAcceptTrade = 127,
|
||||
ClientRejectTrade = 128,
|
||||
ClientUseItem = 130,
|
||||
ClientUseItemWith = 131,
|
||||
ClientUseOnCreature = 132,
|
||||
ClientRotateItem = 133,
|
||||
ClientCloseContainer = 135,
|
||||
ClientUpContainer = 136,
|
||||
ClientEditText = 137,
|
||||
ClientEditList = 138,
|
||||
ClientWrapableItem = 139,
|
||||
ClientLook = 140,
|
||||
ClientLookCreature = 141,
|
||||
ClientTalk = 150,
|
||||
ClientRequestChannels = 151,
|
||||
ClientJoinChannel = 152,
|
||||
ClientLeaveChannel = 153,
|
||||
ClientOpenPrivateChannel = 154,
|
||||
ClientOpenRuleViolation = 155,
|
||||
ClientCloseRuleViolation = 156,
|
||||
ClientCancelRuleViolation = 157,
|
||||
ClientCloseNpcChannel = 158,
|
||||
ClientChangeFightModes = 160,
|
||||
ClientAttack = 161,
|
||||
ClientFollow = 162,
|
||||
ClientInviteToParty = 163,
|
||||
ClientJoinParty = 164,
|
||||
ClientRevokeInvitation = 165,
|
||||
ClientPassLeadership = 166,
|
||||
ClientLeaveParty = 167,
|
||||
ClientShareExperience = 168,
|
||||
ClientDisbandParty = 169,
|
||||
ClientOpenOwnChannel = 170,
|
||||
ClientInviteToOwnChannel = 171,
|
||||
ClientExcludeFromOwnChannel = 172,
|
||||
ClientCancelAttackAndFollow = 190,
|
||||
ClientUpdateTile = 201,
|
||||
ClientRefreshContainer = 202,
|
||||
ClientBrowseField = 203,
|
||||
ClientSeekInContainer = 204,
|
||||
ClientRequestOutfit = 210,
|
||||
ClientChangeOutfit = 211,
|
||||
ClientMount = 212, // 870
|
||||
ApplyImbuemente = 213,
|
||||
ClearingImbuement = 214,
|
||||
CloseImbuingWindow = 215,
|
||||
ClientAddVip = 220,
|
||||
ClientRemoveVip = 221,
|
||||
ClientEditVip = 222,
|
||||
ClientBugReport = 230,
|
||||
ClientRuleViolation = 231,
|
||||
ClientDebugReport = 232,
|
||||
ClientPreyAction = 235,
|
||||
ClientPreyRequest = 237,
|
||||
ClientTransferCoins = 239, // 1080
|
||||
ClientRequestQuestLog = 240,
|
||||
ClientRequestQuestLine = 241,
|
||||
ClientNewRuleViolation = 242, // 910
|
||||
ClientRequestItemInfo = 243, // 910
|
||||
ClientMarketLeave = 244, // 944
|
||||
ClientMarketBrowse = 245, // 944
|
||||
ClientMarketCreate = 246, // 944
|
||||
ClientMarketCancel = 247, // 944
|
||||
ClientMarketAccept = 248, // 944
|
||||
ClientAnswerModalDialog = 249, // 960
|
||||
ClientOpenStore = 250, // 1080
|
||||
ClientRequestStoreOffers = 251, // 1080
|
||||
ClientBuyStoreOffer = 252, // 1080
|
||||
ClientOpenTransactionHistory = 253, // 1080
|
||||
ClientRequestTransactionHistory = 254 // 1080
|
||||
};
|
||||
|
||||
enum CreatureType {
|
||||
CreatureTypePlayer = 0,
|
||||
CreatureTypeMonster,
|
||||
CreatureTypeNpc,
|
||||
CreatureTypeSummonOwn,
|
||||
CreatureTypeSummonOther,
|
||||
CreatureTypeUnknown = 0xFF
|
||||
};
|
||||
|
||||
enum CreaturesIdRange {
|
||||
PlayerStartId = 0x10000000,
|
||||
PlayerEndId = 0x40000000,
|
||||
MonsterStartId = 0x40000000,
|
||||
MonsterEndId = 0x80000000,
|
||||
NpcStartId = 0x80000000,
|
||||
NpcEndId = 0xffffffff
|
||||
};
|
||||
|
||||
void buildMessageModesMap(int version);
|
||||
Otc::MessageMode translateMessageModeFromServer(uint8 mode);
|
||||
uint8 translateMessageModeToServer(Otc::MessageMode mode);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "protocolgame.h"
|
||||
#include "game.h"
|
||||
#include "player.h"
|
||||
#include "item.h"
|
||||
#include "localplayer.h"
|
||||
|
||||
void ProtocolGame::login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey, const std::string& worldName)
|
||||
{
|
||||
m_accountName = accountName;
|
||||
m_accountPassword = accountPassword;
|
||||
m_authenticatorToken = authenticatorToken;
|
||||
m_sessionKey = sessionKey;
|
||||
m_characterName = characterName;
|
||||
m_worldName = worldName;
|
||||
|
||||
connect(host, port);
|
||||
}
|
||||
|
||||
void ProtocolGame::onConnect()
|
||||
{
|
||||
m_firstRecv = true;
|
||||
Protocol::onConnect();
|
||||
|
||||
m_localPlayer = g_game.getLocalPlayer();
|
||||
|
||||
if (g_game.getFeature(Otc::GameSendWorldName))
|
||||
sendWorldName();
|
||||
|
||||
if (g_game.getFeature(Otc::GamePacketSizeU32))
|
||||
enableBigPackets();
|
||||
|
||||
if(g_game.getFeature(Otc::GameProtocolChecksum))
|
||||
enableChecksum();
|
||||
|
||||
if(!g_game.getFeature(Otc::GameChallengeOnLogin))
|
||||
sendLoginPacket(0, 0);
|
||||
|
||||
recv();
|
||||
}
|
||||
|
||||
void ProtocolGame::onRecv(const InputMessagePtr& inputMessage)
|
||||
{
|
||||
m_recivedPackeds += 1;
|
||||
m_recivedPackedsSize += inputMessage->getMessageSize();
|
||||
if(m_firstRecv) {
|
||||
m_firstRecv = false;
|
||||
|
||||
if(g_game.getFeature(Otc::GameMessageSizeCheck)) {
|
||||
int size = g_game.getFeature(Otc::GamePacketSizeU32) ? inputMessage->getU32() : inputMessage->getU16();
|
||||
if(size != inputMessage->getUnreadSize()) {
|
||||
g_logger.traceError("invalid message size");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parseMessage(inputMessage);
|
||||
recv();
|
||||
}
|
||||
|
||||
void ProtocolGame::onError(const boost::system::error_code& error)
|
||||
{
|
||||
g_game.processConnectionError(error);
|
||||
disconnect();
|
||||
}
|
@ -1,335 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PROTOCOLGAME_H
|
||||
#define PROTOCOLGAME_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "protocolcodes.h"
|
||||
#include <framework/net/protocol.h>
|
||||
#include "creature.h"
|
||||
|
||||
class ProtocolGame : public Protocol
|
||||
{
|
||||
public:
|
||||
void login(const std::string& accountName, const std::string& accountPassword, const std::string& host, uint16 port, const std::string& characterName, const std::string& authenticatorToken, const std::string& sessionKey, const std::string& worldName);
|
||||
void send(const OutputMessagePtr& outputMessage, bool rawPacket = false);
|
||||
|
||||
void sendExtendedOpcode(uint8 opcode, const std::string& buffer);
|
||||
void sendLoginPacket(uint challengeTimestamp, uint8 challengeRandom);
|
||||
void sendWorldName();
|
||||
void sendEnterGame();
|
||||
void sendLogout();
|
||||
void sendPing();
|
||||
void sendPingBack();
|
||||
void sendNewPing(uint32_t pingId, uint16_t localPing, uint16_t fps);
|
||||
void sendAutoWalk(const std::vector<Otc::Direction>& path);
|
||||
void sendWalkNorth();
|
||||
void sendWalkEast();
|
||||
void sendWalkSouth();
|
||||
void sendWalkWest();
|
||||
void sendStop();
|
||||
void sendWalkNorthEast();
|
||||
void sendWalkSouthEast();
|
||||
void sendWalkSouthWest();
|
||||
void sendWalkNorthWest();
|
||||
void sendTurnNorth();
|
||||
void sendTurnEast();
|
||||
void sendTurnSouth();
|
||||
void sendTurnWest();
|
||||
void sendEquipItem(int itemId, int countOrSubType);
|
||||
void sendMove(const Position& fromPos, int itemId, int stackpos, const Position& toPos, int count);
|
||||
void sendInspectNpcTrade(int itemId, int count);
|
||||
void sendBuyItem(int itemId, int subType, int amount, bool ignoreCapacity, bool buyWithBackpack);
|
||||
void sendSellItem(int itemId, int subType, int amount, bool ignoreEquipped);
|
||||
void sendCloseNpcTrade();
|
||||
void sendRequestTrade(const Position& pos, int thingId, int stackpos, uint playerId);
|
||||
void sendInspectTrade(bool counterOffer, int index);
|
||||
void sendAcceptTrade();
|
||||
void sendRejectTrade();
|
||||
void sendUseItem(const Position& position, int itemId, int stackpos, int index);
|
||||
void sendUseItemWith(const Position& fromPos, int itemId, int fromStackPos, const Position& toPos, int toThingId, int toStackPos);
|
||||
void sendUseOnCreature(const Position& pos, int thingId, int stackpos, uint creatureId);
|
||||
void sendRotateItem(const Position& pos, int thingId, int stackpos);
|
||||
void sendWrapableItem(const Position& pos, int thingId, int stackpos);
|
||||
void sendCloseContainer(int containerId);
|
||||
void sendUpContainer(int containerId);
|
||||
void sendEditText(uint id, const std::string& text);
|
||||
void sendEditList(uint id, int doorId, const std::string& text);
|
||||
void sendLook(const Position& position, int thingId, int stackpos);
|
||||
void sendLookCreature(uint creatureId);
|
||||
void sendTalk(Otc::MessageMode mode, int channelId, const std::string& receiver, const std::string& message, const Position& pos, Otc::Direction dir);
|
||||
void sendRequestChannels();
|
||||
void sendJoinChannel(int channelId);
|
||||
void sendLeaveChannel(int channelId);
|
||||
void sendOpenPrivateChannel(const std::string& receiver);
|
||||
void sendOpenRuleViolation(const std::string& reporter);
|
||||
void sendCloseRuleViolation(const std::string& reporter);
|
||||
void sendCancelRuleViolation();
|
||||
void sendCloseNpcChannel();
|
||||
void sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight, Otc::PVPModes pvpMode);
|
||||
void sendAttack(uint creatureId, uint seq);
|
||||
void sendFollow(uint creatureId, uint seq);
|
||||
void sendInviteToParty(uint creatureId);
|
||||
void sendJoinParty(uint creatureId);
|
||||
void sendRevokeInvitation(uint creatureId);
|
||||
void sendPassLeadership(uint creatureId);
|
||||
void sendLeaveParty();
|
||||
void sendShareExperience(bool active);
|
||||
void sendOpenOwnChannel();
|
||||
void sendInviteToOwnChannel(const std::string& name);
|
||||
void sendExcludeFromOwnChannel(const std::string& name);
|
||||
void sendCancelAttackAndFollow();
|
||||
void sendRefreshContainer(int containerId);
|
||||
void sendRequestOutfit();
|
||||
void sendChangeOutfit(const Outfit& outfit);
|
||||
void sendOutfitExtensionStatus(int mount = -1, int wings = -1, int aura = -1, int shader = -1);
|
||||
void sendApplyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm);
|
||||
void sendClearImbuement(uint8_t slot);
|
||||
void sendCloseImbuingWindow();
|
||||
void sendAddVip(const std::string& name);
|
||||
void sendRemoveVip(uint playerId);
|
||||
void sendEditVip(uint playerId, const std::string& description, int iconId, bool notifyLogin);
|
||||
void sendBugReport(const std::string& comment);
|
||||
void sendRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment);
|
||||
void sendDebugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d);
|
||||
void sendRequestQuestLog();
|
||||
void sendRequestQuestLine(int questId);
|
||||
void sendNewNewRuleViolation(int reason, int action, const std::string& characterName, const std::string& comment, const std::string& translation);
|
||||
void sendRequestItemInfo(int itemId, int subType, int index);
|
||||
void sendAnswerModalDialog(uint32 dialog, int button, int choice);
|
||||
void sendBrowseField(const Position& position);
|
||||
void sendSeekInContainer(int cid, int index);
|
||||
void sendBuyStoreOffer(int offerId, int productType, const std::string& name);
|
||||
void sendRequestTransactionHistory(int page, int entriesPerPage);
|
||||
void sendRequestStoreOffers(const std::string& categoryName, int serviceType);
|
||||
void sendOpenStore(int serviceType);
|
||||
void sendTransferCoins(const std::string& recipient, int amount);
|
||||
void sendOpenTransactionHistory(int entiresPerPage);
|
||||
void sendPreyAction(int slot, int actionType, int index);
|
||||
void sendPreyRequest();
|
||||
void sendProcesses();
|
||||
void sendDlls();
|
||||
void sendWindows();
|
||||
|
||||
// otclient only
|
||||
void sendChangeMapAwareRange(int xrange, int yrange);
|
||||
void sendNewWalk(int walkId, int predictionId, const Position& pos, uint8_t flags, const std::vector<Otc::Direction>& path);
|
||||
|
||||
protected:
|
||||
void onConnect();
|
||||
void onRecv(const InputMessagePtr& inputMessage);
|
||||
void onError(const boost::system::error_code& error);
|
||||
|
||||
friend class Game;
|
||||
|
||||
public:
|
||||
void addPosition(const OutputMessagePtr& msg, const Position& position);
|
||||
|
||||
private:
|
||||
void parseStoreButtonIndicators(const InputMessagePtr& msg);
|
||||
void parseSetStoreDeepLink(const InputMessagePtr& msg);
|
||||
void parseRestingAreaState(const InputMessagePtr& msg);
|
||||
void parseStore(const InputMessagePtr& msg);
|
||||
void parseStoreError(const InputMessagePtr& msg);
|
||||
void parseStoreTransactionHistory(const InputMessagePtr& msg);
|
||||
void parseStoreOffers(const InputMessagePtr& msg);
|
||||
void parseCompleteStorePurchase(const InputMessagePtr& msg);
|
||||
void parseRequestPurchaseData(const InputMessagePtr& msg);
|
||||
void parseCoinBalance(const InputMessagePtr& msg);
|
||||
void parseCoinBalanceUpdate(const InputMessagePtr& msg);
|
||||
void parseBlessings(const InputMessagePtr& msg);
|
||||
void parseUnjustifiedStats(const InputMessagePtr& msg);
|
||||
void parsePvpSituations(const InputMessagePtr& msg);
|
||||
void parsePreset(const InputMessagePtr& msg);
|
||||
void parseCreatureType(const InputMessagePtr& msg);
|
||||
void parsePlayerHelpers(const InputMessagePtr& msg);
|
||||
void parseMessage(const InputMessagePtr& msg);
|
||||
void parsePendingGame(const InputMessagePtr& msg);
|
||||
void parseEnterGame(const InputMessagePtr& msg);
|
||||
void parseLogin(const InputMessagePtr& msg);
|
||||
void parseGMActions(const InputMessagePtr& msg);
|
||||
void parseUpdateNeeded(const InputMessagePtr& msg);
|
||||
void parseLoginError(const InputMessagePtr& msg);
|
||||
void parseLoginAdvice(const InputMessagePtr& msg);
|
||||
void parseLoginWait(const InputMessagePtr& msg);
|
||||
void parseLoginToken(const InputMessagePtr& msg);
|
||||
void parsePing(const InputMessagePtr& msg);
|
||||
void parsePingBack(const InputMessagePtr& msg);
|
||||
void parseNewPing(const InputMessagePtr& msg);
|
||||
void parseChallenge(const InputMessagePtr& msg);
|
||||
void parseDeath(const InputMessagePtr& msg);
|
||||
void parseMapDescription(const InputMessagePtr& msg);
|
||||
void parseFloorDescription(const InputMessagePtr& msg);
|
||||
void parseMapMoveNorth(const InputMessagePtr& msg);
|
||||
void parseMapMoveEast(const InputMessagePtr& msg);
|
||||
void parseMapMoveSouth(const InputMessagePtr& msg);
|
||||
void parseMapMoveWest(const InputMessagePtr& msg);
|
||||
void parseUpdateTile(const InputMessagePtr& msg);
|
||||
void parseTileAddThing(const InputMessagePtr& msg);
|
||||
void parseTileTransformThing(const InputMessagePtr& msg);
|
||||
void parseTileRemoveThing(const InputMessagePtr& msg);
|
||||
void parseCreatureMove(const InputMessagePtr& msg);
|
||||
void parseOpenContainer(const InputMessagePtr& msg);
|
||||
void parseCloseContainer(const InputMessagePtr& msg);
|
||||
void parseContainerAddItem(const InputMessagePtr& msg);
|
||||
void parseContainerUpdateItem(const InputMessagePtr& msg);
|
||||
void parseContainerRemoveItem(const InputMessagePtr& msg);
|
||||
void parseAddInventoryItem(const InputMessagePtr& msg);
|
||||
void parseRemoveInventoryItem(const InputMessagePtr& msg);
|
||||
void parseOpenNpcTrade(const InputMessagePtr& msg);
|
||||
void parsePlayerGoods(const InputMessagePtr& msg);
|
||||
void parseCloseNpcTrade(const InputMessagePtr&);
|
||||
void parseWorldLight(const InputMessagePtr& msg);
|
||||
void parseMagicEffect(const InputMessagePtr& msg);
|
||||
void parseAnimatedText(const InputMessagePtr& msg);
|
||||
void parseDistanceMissile(const InputMessagePtr& msg);
|
||||
void parseCreatureMark(const InputMessagePtr& msg);
|
||||
void parseTrappers(const InputMessagePtr& msg);
|
||||
void parseCreatureHealth(const InputMessagePtr& msg);
|
||||
void parseCreatureLight(const InputMessagePtr& msg);
|
||||
void parseCreatureOutfit(const InputMessagePtr& msg);
|
||||
void parseCreatureSpeed(const InputMessagePtr& msg);
|
||||
void parseCreatureSkulls(const InputMessagePtr& msg);
|
||||
void parseCreatureShields(const InputMessagePtr& msg);
|
||||
void parseCreatureUnpass(const InputMessagePtr& msg);
|
||||
void parseEditText(const InputMessagePtr& msg);
|
||||
void parseEditList(const InputMessagePtr& msg);
|
||||
void parsePremiumTrigger(const InputMessagePtr& msg);
|
||||
void parsePreyFreeRolls(const InputMessagePtr& msg);
|
||||
void parsePreyTimeLeft(const InputMessagePtr& msg);
|
||||
void parsePreyData(const InputMessagePtr& msg);
|
||||
void parsePreyPrices(const InputMessagePtr& msg);
|
||||
void parseStoreOfferDescription(const InputMessagePtr& msg);
|
||||
void parsePlayerInfo(const InputMessagePtr& msg);
|
||||
void parsePlayerStats(const InputMessagePtr& msg);
|
||||
void parsePlayerSkills(const InputMessagePtr& msg);
|
||||
void parsePlayerState(const InputMessagePtr& msg);
|
||||
void parsePlayerCancelAttack(const InputMessagePtr& msg);
|
||||
void parsePlayerModes(const InputMessagePtr& msg);
|
||||
void parseSpellCooldown(const InputMessagePtr& msg);
|
||||
void parseSpellGroupCooldown(const InputMessagePtr& msg);
|
||||
void parseMultiUseCooldown(const InputMessagePtr& msg);
|
||||
void parseTalk(const InputMessagePtr& msg);
|
||||
void parseChannelList(const InputMessagePtr& msg);
|
||||
void parseOpenChannel(const InputMessagePtr& msg);
|
||||
void parseOpenPrivateChannel(const InputMessagePtr& msg);
|
||||
void parseOpenOwnPrivateChannel(const InputMessagePtr& msg);
|
||||
void parseCloseChannel(const InputMessagePtr& msg);
|
||||
void parseRuleViolationChannel(const InputMessagePtr& msg);
|
||||
void parseRuleViolationRemove(const InputMessagePtr& msg);
|
||||
void parseRuleViolationCancel(const InputMessagePtr& msg);
|
||||
void parseRuleViolationLock(const InputMessagePtr& msg);
|
||||
void parseOwnTrade(const InputMessagePtr& msg);
|
||||
void parseCounterTrade(const InputMessagePtr& msg);
|
||||
void parseCloseTrade(const InputMessagePtr&);
|
||||
void parseTextMessage(const InputMessagePtr& msg);
|
||||
void parseCancelWalk(const InputMessagePtr& msg);
|
||||
void parseWalkWait(const InputMessagePtr& msg);
|
||||
void parseFloorChangeUp(const InputMessagePtr& msg);
|
||||
void parseFloorChangeDown(const InputMessagePtr& msg);
|
||||
void parseOpenOutfitWindow(const InputMessagePtr& msg);
|
||||
void parseVipAdd(const InputMessagePtr& msg);
|
||||
void parseVipState(const InputMessagePtr& msg);
|
||||
void parseVipLogout(const InputMessagePtr& msg);
|
||||
void parseVipGroupData(const InputMessagePtr& msg);
|
||||
void parseTutorialHint(const InputMessagePtr& msg);
|
||||
void parseCyclopediaMapData(const InputMessagePtr& msg);
|
||||
void parseQuestLog(const InputMessagePtr& msg);
|
||||
void parseQuestLine(const InputMessagePtr& msg);
|
||||
void parseChannelEvent(const InputMessagePtr& msg);
|
||||
void parseItemInfo(const InputMessagePtr& msg);
|
||||
void parsePlayerInventory(const InputMessagePtr& msg);
|
||||
void parseModalDialog(const InputMessagePtr& msg);
|
||||
void parseClientCheck(const InputMessagePtr& msg);
|
||||
void parseGameNews(const InputMessagePtr& msg);
|
||||
void parseMessageDialog(const InputMessagePtr& msg);
|
||||
void parseBlessDialog(const InputMessagePtr& msg);
|
||||
void parseResourceBalance(const InputMessagePtr& msg);
|
||||
void parseServerTime(const InputMessagePtr& msg);
|
||||
void parseQuestTracker(const InputMessagePtr& msg);
|
||||
void parseImbuementWindow(const InputMessagePtr& msg);
|
||||
void parseCloseImbuementWindow(const InputMessagePtr& msg);
|
||||
void parseCyclopediaNewDetails(const InputMessagePtr& msg);
|
||||
void parseCyclopedia(const InputMessagePtr& msg);
|
||||
void parseDailyRewardState(const InputMessagePtr& msg);
|
||||
void parseOpenRewardWall(const InputMessagePtr& msg);
|
||||
void parseDailyReward(const InputMessagePtr& msg);
|
||||
void parseDailyRewardHistory(const InputMessagePtr& msg);
|
||||
void parseKillTracker(const InputMessagePtr& msg);
|
||||
void parseLootContainers(const InputMessagePtr& msg);
|
||||
void parseSupplyStash(const InputMessagePtr& msg);
|
||||
void parseSpecialContainer(const InputMessagePtr& msg);
|
||||
void parseDepotState(const InputMessagePtr& msg);
|
||||
void parseSupplyTracker(const InputMessagePtr& msg);
|
||||
void parseTournamentLeaderboard(const InputMessagePtr& msg);
|
||||
void parseImpactTracker(const InputMessagePtr& msg);
|
||||
void parseItemsPrices(const InputMessagePtr& msg);
|
||||
void parseLootTracker(const InputMessagePtr& msg);
|
||||
void parseItemDetail(const InputMessagePtr& msg);
|
||||
void parseHunting(const InputMessagePtr& msg);
|
||||
void parseExtendedOpcode(const InputMessagePtr& msg);
|
||||
void parseChangeMapAwareRange(const InputMessagePtr& msg);
|
||||
void parseProgressBar(const InputMessagePtr& msg);
|
||||
void parseFeatures(const InputMessagePtr& msg);
|
||||
void parseCreaturesMark(const InputMessagePtr& msg);
|
||||
void parseNewCancelWalk(const InputMessagePtr& msg);
|
||||
void parsePredictiveCancelWalk(const InputMessagePtr& msg);
|
||||
void parseWalkId(const InputMessagePtr& msg);
|
||||
void parseProcessesRequest(const InputMessagePtr& msg);
|
||||
void parseDllsRequest(const InputMessagePtr& msg);
|
||||
void parseWindowsRequest(const InputMessagePtr& msg);
|
||||
|
||||
public:
|
||||
void setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height);
|
||||
int setFloorDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height, int offset, int skip);
|
||||
int setTileDescription(const InputMessagePtr& msg, Position position);
|
||||
|
||||
Outfit getOutfit(const InputMessagePtr& msg, bool ignoreMount = false);
|
||||
ThingPtr getThing(const InputMessagePtr& msg);
|
||||
ThingPtr getMappedThing(const InputMessagePtr & msg);
|
||||
CreaturePtr getCreature(const InputMessagePtr& msg, int type = 0);
|
||||
StaticTextPtr getStaticText(const InputMessagePtr& msg, int type = 0);
|
||||
ItemPtr getItem(const InputMessagePtr& msg, int id = 0, bool hasDescription = true);
|
||||
Position getPosition(const InputMessagePtr& msg);
|
||||
Imbuement getImbuementInfo(const InputMessagePtr& msg);
|
||||
|
||||
int getRecivedPacketsCount() { return m_recivedPackeds; }
|
||||
int getRecivedPacketsSize() { return m_recivedPackedsSize; }
|
||||
|
||||
private:
|
||||
stdext::boolean<false> m_enableSendExtendedOpcode;
|
||||
stdext::boolean<false> m_gameInitialized;
|
||||
stdext::boolean<false> m_mapKnown;
|
||||
stdext::boolean<true> m_firstRecv;
|
||||
std::string m_accountName;
|
||||
std::string m_accountPassword;
|
||||
std::string m_authenticatorToken;
|
||||
std::string m_sessionKey;
|
||||
std::string m_characterName;
|
||||
std::string m_worldName;
|
||||
LocalPlayerPtr m_localPlayer;
|
||||
int m_recivedPackeds = 0;
|
||||
int m_recivedPackedsSize = 0;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "shadermanager.h"
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
ShaderManager g_shaders;
|
||||
|
||||
void ShaderManager::init()
|
||||
{
|
||||
PainterShaderProgram::release();
|
||||
}
|
||||
|
||||
void ShaderManager::terminate()
|
||||
{
|
||||
m_shaders.clear();
|
||||
}
|
||||
|
||||
void ShaderManager::createShader(const std::string& name, std::string vertex, std::string fragment, bool colorMatrix)
|
||||
{
|
||||
if (vertex.find("\n") == std::string::npos) { // file
|
||||
vertex = g_resources.guessFilePath(vertex, "frag");
|
||||
vertex = g_resources.readFileContents(vertex);
|
||||
}
|
||||
if (fragment.find("\n") == std::string::npos) { // file
|
||||
fragment = g_resources.guessFilePath(fragment, "frag");
|
||||
fragment = g_resources.readFileContents(fragment);
|
||||
}
|
||||
|
||||
g_graphicsDispatcher.addEventEx("createShader", [&, name, vertex, fragment, colorMatrix] {
|
||||
auto program = PainterShaderProgram::create(vertex, fragment, colorMatrix);
|
||||
if (program)
|
||||
m_shaders[name] = program;
|
||||
});
|
||||
}
|
||||
|
||||
void ShaderManager::addTexture(const std::string& name, const std::string& file)
|
||||
{
|
||||
g_graphicsDispatcher.addEventEx("addTexture", [&, name, file] {
|
||||
auto program = getShader(name);
|
||||
if (program)
|
||||
program->addMultiTexture(file);
|
||||
});
|
||||
}
|
||||
|
||||
PainterShaderProgramPtr ShaderManager::getShader(const std::string& name)
|
||||
{
|
||||
VALIDATE_GRAPHICS_THREAD();
|
||||
auto it = m_shaders.find(name);
|
||||
if(it != m_shaders.end())
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHADERMANAGER_H
|
||||
#define SHADERMANAGER_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
|
||||
//@bindsingleton g_shaders
|
||||
class ShaderManager
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
void createShader(const std::string& name, std::string vertex, std::string fragment, bool colorMatrix = false);
|
||||
void createOutfitShader(const std::string& name, std::string vertex, std::string fragment)
|
||||
{
|
||||
return createShader(name, vertex, fragment, true);
|
||||
}
|
||||
void addTexture(const std::string& name, const std::string& file);
|
||||
PainterShaderProgramPtr getShader(const std::string& name);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, PainterShaderProgramPtr> m_shaders;
|
||||
};
|
||||
|
||||
|
||||
extern ShaderManager g_shaders;
|
||||
|
||||
#endif
|
||||
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "spritemanager.h"
|
||||
#include "game.h"
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/graphics/image.h>
|
||||
#include <framework/graphics/atlas.h>
|
||||
#include <framework/util/crypt.h>
|
||||
|
||||
SpriteManager g_sprites;
|
||||
|
||||
SpriteManager::SpriteManager()
|
||||
{
|
||||
m_spritesCount = 0;
|
||||
m_signature = 0;
|
||||
}
|
||||
|
||||
void SpriteManager::terminate()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
|
||||
bool SpriteManager::loadSpr(std::string file)
|
||||
{
|
||||
m_spritesCount = 0;
|
||||
m_signature = 0;
|
||||
m_spriteSize = 32;
|
||||
m_loaded = false;
|
||||
m_sprites.clear();
|
||||
|
||||
try {
|
||||
file = g_resources.guessFilePath(file, "spr");
|
||||
|
||||
m_spritesFile = g_resources.openFile(file);
|
||||
|
||||
m_signature = m_spritesFile->getU32();
|
||||
m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16();
|
||||
m_spritesOffset = m_spritesFile->tell();
|
||||
m_loaded = true;
|
||||
g_lua.callGlobalField("g_sprites", "onLoadSpr", file);
|
||||
return true;
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to load sprites from '%s': %s", file, e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteManager::unload()
|
||||
{
|
||||
m_spritesCount = 0;
|
||||
m_signature = 0;
|
||||
m_spritesFile = nullptr;
|
||||
m_sprites.clear();
|
||||
}
|
||||
|
||||
ImagePtr SpriteManager::getSpriteImage(int id)
|
||||
{
|
||||
try {
|
||||
int spriteDataSize = m_spriteSize * m_spriteSize * 4;
|
||||
|
||||
if (id == 0 || !m_spritesFile)
|
||||
return nullptr;
|
||||
|
||||
m_spritesFile->seek(((id - 1) * 4) + m_spritesOffset);
|
||||
|
||||
uint32 spriteAddress = m_spritesFile->getU32();
|
||||
|
||||
// no sprite? return an empty texture
|
||||
if (spriteAddress == 0)
|
||||
return nullptr;
|
||||
|
||||
m_spritesFile->seek(spriteAddress);
|
||||
|
||||
// color key
|
||||
if (m_spriteSize == 32) {
|
||||
m_spritesFile->getU8();
|
||||
m_spritesFile->getU8();
|
||||
m_spritesFile->getU8();
|
||||
}
|
||||
|
||||
uint16 pixelDataSize = m_spritesFile->getU16();
|
||||
|
||||
ImagePtr image(new Image(Size(m_spriteSize, m_spriteSize)));
|
||||
|
||||
uint8* pixels = image->getPixelData();
|
||||
int writePos = 0;
|
||||
int read = 0;
|
||||
bool useAlpha = g_game.getFeature(Otc::GameSpritesAlphaChannel);
|
||||
|
||||
// decompress pixels
|
||||
while (read < pixelDataSize && writePos < spriteDataSize) {
|
||||
uint16 transparentPixels = m_spritesFile->getU16();
|
||||
uint16 coloredPixels = m_spritesFile->getU16();
|
||||
|
||||
writePos += transparentPixels * 4;
|
||||
|
||||
if (useAlpha) {
|
||||
m_spritesFile->read(&pixels[writePos], std::min<uint16>(coloredPixels * 4, spriteDataSize - writePos));
|
||||
writePos += coloredPixels * 4;
|
||||
read += 4 + (4 * coloredPixels);
|
||||
} else {
|
||||
for (int i = 0; i < coloredPixels && writePos < spriteDataSize; i++) {
|
||||
pixels[writePos + 0] = m_spritesFile->getU8();
|
||||
pixels[writePos + 1] = m_spritesFile->getU8();
|
||||
pixels[writePos + 2] = m_spritesFile->getU8();
|
||||
pixels[writePos + 3] = 0xFF;
|
||||
writePos += 4;
|
||||
}
|
||||
read += 4 + (3 * coloredPixels);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
} catch (stdext::exception & e) {
|
||||
g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what()));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SPRITEMANAGER_H
|
||||
#define SPRITEMANAGER_H
|
||||
|
||||
#include <framework/core/declarations.h>
|
||||
#include <framework/graphics/declarations.h>
|
||||
|
||||
//@bindsingleton g_sprites
|
||||
class SpriteManager
|
||||
{
|
||||
enum {
|
||||
SPRITE_SIZE = 32,
|
||||
SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE * 4
|
||||
};
|
||||
|
||||
public:
|
||||
SpriteManager();
|
||||
|
||||
void terminate();
|
||||
|
||||
bool loadSpr(std::string file);
|
||||
void unload();
|
||||
|
||||
#ifdef WITH_ENCRYPTION
|
||||
void saveSpr(std::string fileName);
|
||||
void encryptSprites(std::string fileName);
|
||||
void dumpSprites(std::string dir);
|
||||
#endif
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
int getSpritesCount() { return m_spritesCount; }
|
||||
|
||||
ImagePtr getSpriteImage(int id);
|
||||
bool isLoaded() { return m_loaded; }
|
||||
|
||||
int spriteSize() { return m_spriteSize; }
|
||||
|
||||
private:
|
||||
stdext::boolean<false> m_loaded;
|
||||
uint32 m_signature;
|
||||
int m_spritesCount;
|
||||
int m_spritesOffset;
|
||||
int m_spriteSize = 32;
|
||||
FileStreamPtr m_spritesFile;
|
||||
std::vector<std::vector<uint8_t>> m_sprites;
|
||||
};
|
||||
|
||||
extern SpriteManager g_sprites;
|
||||
|
||||
#endif
|
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "statictext.h"
|
||||
#include "map.h"
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
|
||||
StaticText::StaticText()
|
||||
{
|
||||
m_mode = Otc::MessageNone;
|
||||
m_color = Color::white;
|
||||
m_cachedText.setFont(g_fonts.getFont("verdana-11px-rounded"));
|
||||
m_cachedText.setAlign(Fw::AlignCenter);
|
||||
}
|
||||
|
||||
void StaticText::drawText(const Point& dest, const Rect& parentRect)
|
||||
{
|
||||
Size textSize = m_cachedText.getTextSize();
|
||||
Rect rect = Rect(dest - Point(textSize.width() / 2, textSize.height()) + Point(20, 5), textSize);
|
||||
Rect boundRect = rect;
|
||||
boundRect.bind(parentRect);
|
||||
|
||||
// draw only if the real center is not too far from the parent center, or its a yell
|
||||
//if(g_map.isAwareOfPosition(m_position) || isYell()) {
|
||||
m_cachedText.draw(boundRect, m_color);
|
||||
//}
|
||||
}
|
||||
|
||||
void StaticText::setFont(const std::string& fontName)
|
||||
{
|
||||
m_cachedText.setFont(g_fonts.getFont(fontName));
|
||||
}
|
||||
|
||||
void StaticText::setText(const std::string& text)
|
||||
{
|
||||
m_cachedText.setText(text);
|
||||
}
|
||||
|
||||
bool StaticText::addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text)
|
||||
{
|
||||
return addColoredMessage(name, mode, { text, "" });
|
||||
}
|
||||
|
||||
bool StaticText::addColoredMessage(const std::string& name, Otc::MessageMode mode, const std::vector<std::string>& texts)
|
||||
{
|
||||
if (texts.empty() || texts.size() % 2 != 0)
|
||||
return false;
|
||||
//TODO: this could be moved to lua
|
||||
// first message
|
||||
if (m_messages.size() == 0) {
|
||||
m_name = name;
|
||||
m_mode = mode;
|
||||
}
|
||||
// check if we can really own the message
|
||||
else if (m_name != name || m_mode != mode) {
|
||||
return false;
|
||||
}
|
||||
// too many messages
|
||||
else if (m_messages.size() > 10) {
|
||||
m_messages.pop_front();
|
||||
m_updateEvent->cancel();
|
||||
m_updateEvent = nullptr;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
for (size_t i = 0; i < texts.size(); i += 2) {
|
||||
len += texts[i].length();
|
||||
}
|
||||
|
||||
int delay = std::max<int>(Otc::STATIC_DURATION_PER_CHARACTER * len, Otc::MIN_STATIC_TEXT_DURATION);
|
||||
if (isYell())
|
||||
delay *= 2;
|
||||
|
||||
m_messages.push_back(StaticTextMessage{ texts, g_clock.millis() + delay });
|
||||
compose();
|
||||
|
||||
if (!m_updateEvent)
|
||||
scheduleUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticText::update()
|
||||
{
|
||||
m_messages.pop_front();
|
||||
if(m_messages.empty()) {
|
||||
// schedule removal
|
||||
auto self = asStaticText();
|
||||
g_dispatcher.addEvent([self]() { g_map.removeThing(self); });
|
||||
} else {
|
||||
compose();
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticText::scheduleUpdate()
|
||||
{
|
||||
int delay = std::max<int>(m_messages.front().time - g_clock.millis(), 0);
|
||||
|
||||
auto self = asStaticText();
|
||||
m_updateEvent = g_dispatcher.scheduleEvent([self]() {
|
||||
self->m_updateEvent = nullptr;
|
||||
self->update();
|
||||
}, delay);
|
||||
}
|
||||
|
||||
void StaticText::compose()
|
||||
{
|
||||
//TODO: this could be moved to lua
|
||||
std::vector<std::string> texts;
|
||||
|
||||
if(m_mode == Otc::MessageSay) {
|
||||
texts.push_back(m_name + " says:\n");
|
||||
texts.push_back("#EFEF00");
|
||||
m_color = Color(239, 239, 0);
|
||||
} else if(m_mode == Otc::MessageWhisper) {
|
||||
texts.push_back(m_name + " whispers:\n");
|
||||
texts.push_back("#EFEF00");
|
||||
m_color = Color(239, 239, 0);
|
||||
} else if(m_mode == Otc::MessageYell) {
|
||||
texts.push_back(m_name + " yells:\n");
|
||||
texts.push_back("#EFEF00");
|
||||
m_color = Color(239, 239, 0);
|
||||
} else if(m_mode == Otc::MessageMonsterSay || m_mode == Otc::MessageMonsterYell || m_mode == Otc::MessageSpell
|
||||
|| m_mode == Otc::MessageBarkLow || m_mode == Otc::MessageBarkLoud) {
|
||||
m_color = Color(254, 101, 0);
|
||||
} else if(m_mode == Otc::MessageNpcFrom || m_mode == Otc::MessageNpcFromStartBlock) {
|
||||
texts.push_back(m_name + " says:\n");
|
||||
texts.push_back("#5FF7F7");
|
||||
m_color = Color(95, 247, 247);
|
||||
} else {
|
||||
g_logger.warning(stdext::format("Unknown speak type: %d", m_mode));
|
||||
}
|
||||
|
||||
for(uint i = 0; i < m_messages.size(); ++i) {
|
||||
for (size_t j = 0; j < m_messages[i].texts.size() - 1; j += 2) {
|
||||
texts.push_back(m_messages[i].texts[j]);
|
||||
texts.push_back(m_messages[i].texts[j + 1].empty() ? m_color.toHex() : m_messages[i].texts[j + 1]);
|
||||
}
|
||||
if (texts.size() >= 2 && i < m_messages.size() - 1) {
|
||||
texts[texts.size() - 2] += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
m_cachedText.setColoredText(texts);
|
||||
m_cachedText.wrapText(275);
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef STATICTEXT_H
|
||||
#define STATICTEXT_H
|
||||
|
||||
#include "thing.h"
|
||||
#include <framework/graphics/cachedtext.h>
|
||||
#include <framework/core/timer.h>
|
||||
|
||||
struct StaticTextMessage {
|
||||
std::vector<std::string> texts;
|
||||
ticks_t time;
|
||||
};
|
||||
|
||||
// @bindclass
|
||||
class StaticText : public Thing
|
||||
{
|
||||
public:
|
||||
StaticText();
|
||||
|
||||
void drawText(const Point& dest, const Rect& parentRect);
|
||||
|
||||
std::string getName() { return m_name; }
|
||||
std::string getText() { return m_cachedText.getText(); }
|
||||
Otc::MessageMode getMessageMode() { return m_mode; }
|
||||
std::vector<std::string> getFirstMessage() { return m_messages[0].texts; }
|
||||
|
||||
bool isYell() { return m_mode == Otc::MessageYell || m_mode == Otc::MessageMonsterYell || m_mode == Otc::MessageBarkLoud; }
|
||||
|
||||
void setText(const std::string& text);
|
||||
void setFont(const std::string& fontName);
|
||||
bool addMessage(const std::string& name, Otc::MessageMode mode, const std::string& text);
|
||||
bool addColoredMessage(const std::string& name, Otc::MessageMode mode, const std::vector<std::string>& texts);
|
||||
StaticTextPtr asStaticText() { return static_self_cast<StaticText>(); }
|
||||
bool isStaticText() { return true; }
|
||||
|
||||
void setColor(const Color& color) { m_color = color; }
|
||||
Color getColor() { return m_color; }
|
||||
|
||||
CachedText& getCachedText() { return m_cachedText; }
|
||||
bool hasText() { return m_cachedText.hasText(); }
|
||||
|
||||
private:
|
||||
void update();
|
||||
void scheduleUpdate();
|
||||
void compose();
|
||||
|
||||
stdext::boolean<false> m_yell;
|
||||
std::deque<StaticTextMessage> m_messages;
|
||||
std::string m_name;
|
||||
Otc::MessageMode m_mode;
|
||||
Color m_color;
|
||||
CachedText m_cachedText;
|
||||
ScheduledEventPtr m_updateEvent;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thing.h"
|
||||
#include "spritemanager.h"
|
||||
#include "thingtypemanager.h"
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
#include "game.h"
|
||||
#include <framework/util/stats.h>
|
||||
|
||||
Thing::Thing() :
|
||||
m_datId(0)
|
||||
{
|
||||
g_stats.addThing();
|
||||
}
|
||||
|
||||
Thing::~Thing()
|
||||
{
|
||||
g_stats.removeThing();
|
||||
}
|
||||
|
||||
void Thing::setPosition(const Position& position)
|
||||
{
|
||||
if(m_position == position)
|
||||
return;
|
||||
|
||||
Position oldPos = m_position;
|
||||
m_position = position;
|
||||
onPositionChange(position, oldPos);
|
||||
}
|
||||
|
||||
int Thing::getStackPriority()
|
||||
{
|
||||
// bug fix for old versions
|
||||
if (g_game.getClientVersion() <= 800 && isSplash()) {
|
||||
return 1;
|
||||
}
|
||||
if(isGround())
|
||||
return 0;
|
||||
else if(isGroundBorder())
|
||||
return 1;
|
||||
else if(isOnBottom())
|
||||
return 2;
|
||||
else if(isOnTop())
|
||||
return 3;
|
||||
else if(isCreature())
|
||||
return 4;
|
||||
else // common items
|
||||
return 5;
|
||||
}
|
||||
|
||||
const TilePtr& Thing::getTile()
|
||||
{
|
||||
return g_map.getTile(m_position);
|
||||
}
|
||||
|
||||
ContainerPtr Thing::getParentContainer()
|
||||
{
|
||||
if(m_position.x == 0xffff && m_position.y & 0x40) {
|
||||
int containerId = m_position.y ^ 0x40;
|
||||
return g_game.getContainer(containerId);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Thing::getStackPos()
|
||||
{
|
||||
if(m_position.x == 65535 && isItem()) // is inside a container
|
||||
return m_position.z;
|
||||
else if(const TilePtr& tile = getTile())
|
||||
return tile->getThingStackPos(static_self_cast<Thing>());
|
||||
else {
|
||||
g_logger.traceError("got a thing with invalid stackpos");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const ThingTypePtr& Thing::getThingType()
|
||||
{
|
||||
return g_things.getNullThingType();
|
||||
}
|
||||
|
||||
ThingType* Thing::rawGetThingType()
|
||||
{
|
||||
return g_things.getNullThingType().get();
|
||||
}
|
||||
|
||||
Color Thing::updatedMarkedColor() {
|
||||
if (!m_marked)
|
||||
return Color::white;
|
||||
m_markedColor.setAlpha(0.1f + std::abs(500 - g_clock.millis() % 1000) / 1000.0f); // 0.1-0.6
|
||||
return m_markedColor;
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef THING_H
|
||||
#define THING_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "thingtype.h"
|
||||
#include "thingtypemanager.h"
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include <framework/graphics/drawqueue.h>
|
||||
|
||||
// @bindclass
|
||||
#pragma pack(push,1) // disable memory alignment
|
||||
class Thing : public LuaObject
|
||||
{
|
||||
public:
|
||||
Thing();
|
||||
virtual ~Thing();
|
||||
|
||||
virtual void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr) { }
|
||||
|
||||
virtual void setId(uint32 id) { }
|
||||
void setPosition(const Position& position);
|
||||
|
||||
virtual uint32 getId() { return 0; }
|
||||
Position getPosition() { return m_position; }
|
||||
int getStackPriority();
|
||||
virtual const TilePtr& getTile();
|
||||
ContainerPtr getParentContainer();
|
||||
int getStackPos();
|
||||
|
||||
void setMarked(const std::string& color) {
|
||||
if (color.empty()) {
|
||||
m_marked = false;
|
||||
return;
|
||||
}
|
||||
m_marked = true;
|
||||
m_markedColor = Color(color);
|
||||
}
|
||||
Color updatedMarkedColor();
|
||||
|
||||
virtual bool isItem() { return false; }
|
||||
virtual bool isEffect() { return false; }
|
||||
virtual bool isMissile() { return false; }
|
||||
virtual bool isCreature() { return false; }
|
||||
virtual bool isNpc() { return false; }
|
||||
virtual bool isMonster() { return false; }
|
||||
virtual bool isPlayer() { return false; }
|
||||
virtual bool isLocalPlayer() { return false; }
|
||||
virtual bool isAnimatedText() { return false; }
|
||||
virtual bool isStaticText() { return false; }
|
||||
|
||||
// type shortcuts
|
||||
virtual const ThingTypePtr& getThingType();
|
||||
virtual ThingType *rawGetThingType();
|
||||
Size getSize() { return rawGetThingType()->getSize(); }
|
||||
int getWidth() { return rawGetThingType()->getWidth(); }
|
||||
int getHeight() { return rawGetThingType()->getHeight(); }
|
||||
virtual Point getDisplacement() { return rawGetThingType()->getDisplacement(); }
|
||||
virtual int getDisplacementX() { return rawGetThingType()->getDisplacementX(); }
|
||||
virtual int getDisplacementY() { return rawGetThingType()->getDisplacementY(); }
|
||||
virtual int getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase) { return rawGetThingType()->getExactSize(layer, xPattern, yPattern, zPattern, animationPhase); }
|
||||
int getLayers() { return rawGetThingType()->getLayers(); }
|
||||
int getNumPatternX() { return rawGetThingType()->getNumPatternX(); }
|
||||
int getNumPatternY() { return rawGetThingType()->getNumPatternY(); }
|
||||
int getNumPatternZ() { return rawGetThingType()->getNumPatternZ(); }
|
||||
int getAnimationPhases() { return rawGetThingType()->getAnimationPhases(); }
|
||||
AnimatorPtr getAnimator() { return rawGetThingType()->getAnimator(); }
|
||||
AnimatorPtr getIdleAnimator() { return rawGetThingType()->getIdleAnimator(); }
|
||||
int getGroundSpeed() { return rawGetThingType()->getGroundSpeed(); }
|
||||
int getMaxTextLength() { return rawGetThingType()->getMaxTextLength(); }
|
||||
Light getLight() { return rawGetThingType()->getLight(); }
|
||||
int getMinimapColor() { return rawGetThingType()->getMinimapColor(); }
|
||||
int getLensHelp() { return rawGetThingType()->getLensHelp(); }
|
||||
int getClothSlot() { return rawGetThingType()->getClothSlot(); }
|
||||
int getElevation() { return rawGetThingType()->getElevation(); }
|
||||
bool isGround() { return rawGetThingType()->isGround(); }
|
||||
bool isGroundBorder() { return rawGetThingType()->isGroundBorder(); }
|
||||
bool isOnBottom() { return rawGetThingType()->isOnBottom(); }
|
||||
bool isOnTop() { return rawGetThingType()->isOnTop(); }
|
||||
bool isContainer() { return rawGetThingType()->isContainer(); }
|
||||
bool isStackable() { return rawGetThingType()->isStackable(); }
|
||||
bool isForceUse() { return rawGetThingType()->isForceUse(); }
|
||||
bool isMultiUse() { return rawGetThingType()->isMultiUse(); }
|
||||
bool isWritable() { return rawGetThingType()->isWritable(); }
|
||||
bool isChargeable() { return rawGetThingType()->isChargeable(); }
|
||||
bool isWritableOnce() { return rawGetThingType()->isWritableOnce(); }
|
||||
bool isFluidContainer() { return rawGetThingType()->isFluidContainer(); }
|
||||
bool isSplash() { return rawGetThingType()->isSplash(); }
|
||||
bool isNotWalkable() { return rawGetThingType()->isNotWalkable(); }
|
||||
bool isNotMoveable() { return rawGetThingType()->isNotMoveable(); }
|
||||
bool blockProjectile() { return rawGetThingType()->blockProjectile(); }
|
||||
bool isNotPathable() { return rawGetThingType()->isNotPathable(); }
|
||||
bool isPickupable() { return rawGetThingType()->isPickupable(); }
|
||||
bool isHangable() { return rawGetThingType()->isHangable(); }
|
||||
bool isHookSouth() { return rawGetThingType()->isHookSouth(); }
|
||||
bool isHookEast() { return rawGetThingType()->isHookEast(); }
|
||||
bool isRotateable() { return rawGetThingType()->isRotateable(); }
|
||||
bool hasLight() { return rawGetThingType()->hasLight(); }
|
||||
bool isDontHide() { return rawGetThingType()->isDontHide(); }
|
||||
bool isTranslucent() { return rawGetThingType()->isTranslucent(); }
|
||||
bool hasDisplacement() { return rawGetThingType()->hasDisplacement(); }
|
||||
bool hasElevation() { return rawGetThingType()->hasElevation(); }
|
||||
bool isLyingCorpse() { return rawGetThingType()->isLyingCorpse(); }
|
||||
bool isAnimateAlways() { return rawGetThingType()->isAnimateAlways(); }
|
||||
bool hasMiniMapColor() { return rawGetThingType()->hasMiniMapColor(); }
|
||||
bool hasLensHelp() { return rawGetThingType()->hasLensHelp(); }
|
||||
bool isFullGround() { return rawGetThingType()->isFullGround(); }
|
||||
bool isIgnoreLook() { return rawGetThingType()->isIgnoreLook(); }
|
||||
bool isCloth() { return rawGetThingType()->isCloth(); }
|
||||
bool isMarketable() { return rawGetThingType()->isMarketable(); }
|
||||
bool isUsable() { return rawGetThingType()->isUsable(); }
|
||||
bool isWrapable() { return rawGetThingType()->isWrapable(); }
|
||||
bool isUnwrapable() { return rawGetThingType()->isUnwrapable(); }
|
||||
bool isTopEffect() { return rawGetThingType()->isTopEffect(); }
|
||||
MarketData getMarketData() { return rawGetThingType()->getMarketData(); }
|
||||
|
||||
void hide() { m_hidden = true; }
|
||||
void show() { m_hidden = false; }
|
||||
void setHidden(bool value) { m_hidden = value; }
|
||||
bool isHidden() { return m_hidden; }
|
||||
|
||||
virtual void onPositionChange(const Position& newPos, const Position& oldPos) { }
|
||||
virtual void onAppear() { }
|
||||
virtual void onDisappear() { }
|
||||
|
||||
protected:
|
||||
Position m_position;
|
||||
uint16 m_datId;
|
||||
bool m_marked = false;
|
||||
bool m_hidden = false;
|
||||
Color m_markedColor;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef DATMANAGER_H
|
||||
#define DATMANAGER_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <framework/core/declarations.h>
|
||||
#include "thingtype.h"
|
||||
|
||||
//@bindsingleton g_thingsType
|
||||
class ThingsType
|
||||
{
|
||||
public:
|
||||
|
||||
enum Categories {
|
||||
Item = 0,
|
||||
Creature,
|
||||
Effect,
|
||||
Missile,
|
||||
LastCategory
|
||||
};
|
||||
|
||||
bool load(const std::string& file);
|
||||
void unload();
|
||||
|
||||
bool parseThingType(const FileStreamPtr& fin, ThingType& thingType);
|
||||
|
||||
ThingType *getEmptyThingType() { return &m_emptyThingType; }
|
||||
ThingType *getThingType(uint16 id, Categories category);
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
bool isLoaded() { return m_loaded; }
|
||||
|
||||
uint16 getFirstItemId() { return 100; }
|
||||
uint16 getMaxItemid() { return m_things[Item].size() + 99; }
|
||||
bool isValidItemId(int id) { return id >= getFirstItemId() && id <= getMaxItemid(); }
|
||||
|
||||
private:
|
||||
uint32 m_signature;
|
||||
stdext::boolean<false> m_loaded;
|
||||
ThingTypeList m_things[LastCategory];
|
||||
static ThingType m_emptyThingType;
|
||||
};
|
||||
|
||||
extern ThingsType g_thingsType;
|
||||
|
||||
#endif
|
@ -1,777 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thingtype.h"
|
||||
#include "spritemanager.h"
|
||||
#include "game.h"
|
||||
#include "lightview.h"
|
||||
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/texture.h>
|
||||
#include <framework/graphics/image.h>
|
||||
#include <framework/graphics/texturemanager.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/otml/otml.h>
|
||||
|
||||
ThingType::ThingType()
|
||||
{
|
||||
m_category = ThingInvalidCategory;
|
||||
m_id = 0;
|
||||
m_null = true;
|
||||
m_exactSize = 0;
|
||||
m_realSize = 0;
|
||||
m_animator = nullptr;
|
||||
m_numPatternX = m_numPatternY = m_numPatternZ = 0;
|
||||
m_animationPhases = 0;
|
||||
m_layers = 0;
|
||||
m_elevation = 0;
|
||||
m_opacity = 1.0f;
|
||||
}
|
||||
|
||||
void ThingType::serialize(const FileStreamPtr& fin)
|
||||
{
|
||||
for(int i = 0; i < ThingLastAttr; ++i) {
|
||||
if(!hasAttr((ThingAttr)i))
|
||||
continue;
|
||||
|
||||
int attr = i;
|
||||
if(g_game.getClientVersion() >= 780) {
|
||||
if(attr == ThingAttrChargeable)
|
||||
attr = ThingAttrWritable;
|
||||
else if(attr >= ThingAttrWritable)
|
||||
attr += 1;
|
||||
} else if(g_game.getClientVersion() >= 1000) {
|
||||
if(attr == ThingAttrNoMoveAnimation)
|
||||
attr = 16;
|
||||
else if(attr >= ThingAttrPickupable)
|
||||
attr += 1;
|
||||
}
|
||||
|
||||
fin->addU8(attr);
|
||||
switch(attr) {
|
||||
case ThingAttrDisplacement: {
|
||||
fin->addU16(m_displacement.x);
|
||||
fin->addU16(m_displacement.y);
|
||||
break;
|
||||
}
|
||||
case ThingAttrLight: {
|
||||
Light light = m_attribs.get<Light>(attr);
|
||||
fin->addU16(light.intensity);
|
||||
fin->addU16(light.color);
|
||||
break;
|
||||
}
|
||||
case ThingAttrMarket: {
|
||||
MarketData market = m_attribs.get<MarketData>(attr);
|
||||
fin->addU16(market.category);
|
||||
fin->addU16(market.tradeAs);
|
||||
fin->addU16(market.showAs);
|
||||
fin->addString(market.name);
|
||||
fin->addU16(market.restrictVocation);
|
||||
fin->addU16(market.requiredLevel);
|
||||
break;
|
||||
}
|
||||
case ThingAttrUsable:
|
||||
case ThingAttrElevation:
|
||||
case ThingAttrGround:
|
||||
case ThingAttrWritable:
|
||||
case ThingAttrWritableOnce:
|
||||
case ThingAttrMinimapColor:
|
||||
case ThingAttrCloth:
|
||||
case ThingAttrLensHelp:
|
||||
fin->addU16(m_attribs.get<uint16>(attr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
fin->addU8(ThingLastAttr);
|
||||
|
||||
fin->addU8(m_size.width());
|
||||
fin->addU8(m_size.height());
|
||||
|
||||
if(m_size.width() > 1 || m_size.height() > 1)
|
||||
fin->addU8(m_realSize);
|
||||
|
||||
fin->addU8(m_layers);
|
||||
fin->addU8(m_numPatternX);
|
||||
fin->addU8(m_numPatternY);
|
||||
fin->addU8(m_numPatternZ);
|
||||
fin->addU8(m_animationPhases);
|
||||
|
||||
if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
|
||||
if(m_animationPhases > 1 && m_animator != nullptr) {
|
||||
m_animator->serialize(fin);
|
||||
}
|
||||
}
|
||||
|
||||
for(uint i = 0; i < m_spritesIndex.size(); i++) {
|
||||
if(g_game.getFeature(Otc::GameSpritesU32))
|
||||
fin->addU32(m_spritesIndex[i]);
|
||||
else
|
||||
fin->addU16(m_spritesIndex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin)
|
||||
{
|
||||
m_null = false;
|
||||
m_id = clientId;
|
||||
m_category = category;
|
||||
|
||||
int count = 0, attr = -1;
|
||||
bool done = false;
|
||||
for(int i = 0 ; i < ThingLastAttr;++i) {
|
||||
count++;
|
||||
attr = fin->getU8();
|
||||
if(attr == ThingLastAttr) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(g_game.getClientVersion() >= 1000) {
|
||||
/* In 10.10+ all attributes from 16 and up were
|
||||
* incremented by 1 to make space for 16 as
|
||||
* "No Movement Animation" flag.
|
||||
*/
|
||||
if(attr == 16)
|
||||
attr = ThingAttrNoMoveAnimation;
|
||||
else if(attr > 16)
|
||||
attr -= 1;
|
||||
} else if(g_game.getClientVersion() >= 860) {
|
||||
/* Default attribute values follow
|
||||
* the format of 8.6-9.86.
|
||||
* Therefore no changes here.
|
||||
*/
|
||||
} else if(g_game.getClientVersion() >= 780) {
|
||||
/* In 7.80-8.54 all attributes from 8 and higher were
|
||||
* incremented by 1 to make space for 8 as
|
||||
* "Item Charges" flag.
|
||||
*/
|
||||
if(attr == 8) {
|
||||
m_attribs.set(ThingAttrChargeable, true);
|
||||
continue;
|
||||
} else if(attr > 8)
|
||||
attr -= 1;
|
||||
} else if(g_game.getClientVersion() >= 755) {
|
||||
/* In 7.55-7.72 attributes 23 is "Floor Change". */
|
||||
if(attr == 23)
|
||||
attr = ThingAttrFloorChange;
|
||||
} else if(g_game.getClientVersion() >= 740) {
|
||||
/* In 7.4-7.5 attribute "Ground Border" did not exist
|
||||
* attributes 1-15 have to be adjusted.
|
||||
* Several other changes in the format.
|
||||
*/
|
||||
if(attr > 0 && attr <= 15)
|
||||
attr += 1;
|
||||
else if(attr == 16)
|
||||
attr = ThingAttrLight;
|
||||
else if(attr == 17)
|
||||
attr = ThingAttrFloorChange;
|
||||
else if(attr == 18)
|
||||
attr = ThingAttrFullGround;
|
||||
else if(attr == 19)
|
||||
attr = ThingAttrElevation;
|
||||
else if(attr == 20)
|
||||
attr = ThingAttrDisplacement;
|
||||
else if(attr == 22)
|
||||
attr = ThingAttrMinimapColor;
|
||||
else if(attr == 23)
|
||||
attr = ThingAttrRotateable;
|
||||
else if(attr == 24)
|
||||
attr = ThingAttrLyingCorpse;
|
||||
else if(attr == 25)
|
||||
attr = ThingAttrHangable;
|
||||
else if(attr == 26)
|
||||
attr = ThingAttrHookSouth;
|
||||
else if(attr == 27)
|
||||
attr = ThingAttrHookEast;
|
||||
else if(attr == 28)
|
||||
attr = ThingAttrAnimateAlways;
|
||||
|
||||
/* "Multi Use" and "Force Use" are swapped */
|
||||
if(attr == ThingAttrMultiUse)
|
||||
attr = ThingAttrForceUse;
|
||||
else if(attr == ThingAttrForceUse)
|
||||
attr = ThingAttrMultiUse;
|
||||
}
|
||||
|
||||
switch(attr) {
|
||||
case ThingAttrDisplacement: {
|
||||
if(g_game.getClientVersion() >= 755) {
|
||||
m_displacement.x = fin->getU16();
|
||||
m_displacement.y = fin->getU16();
|
||||
} else {
|
||||
m_displacement.x = 8;
|
||||
m_displacement.y = 8;
|
||||
}
|
||||
m_attribs.set(attr, true);
|
||||
break;
|
||||
}
|
||||
case ThingAttrLight: {
|
||||
Light light;
|
||||
light.intensity = fin->getU16();
|
||||
light.color = fin->getU16();
|
||||
m_attribs.set(attr, light);
|
||||
break;
|
||||
}
|
||||
case ThingAttrMarket: {
|
||||
MarketData market;
|
||||
market.category = fin->getU16();
|
||||
market.tradeAs = fin->getU16();
|
||||
market.showAs = fin->getU16();
|
||||
market.name = fin->getString();
|
||||
market.restrictVocation = fin->getU16();
|
||||
market.requiredLevel = fin->getU16();
|
||||
m_attribs.set(attr, market);
|
||||
break;
|
||||
}
|
||||
case ThingAttrElevation: {
|
||||
m_elevation = fin->getU16();
|
||||
m_attribs.set(attr, m_elevation);
|
||||
break;
|
||||
}
|
||||
case ThingAttrUsable:
|
||||
case ThingAttrGround:
|
||||
case ThingAttrWritable:
|
||||
case ThingAttrWritableOnce:
|
||||
case ThingAttrMinimapColor:
|
||||
case ThingAttrCloth:
|
||||
case ThingAttrLensHelp:
|
||||
m_attribs.set(attr, fin->getU16());
|
||||
break;
|
||||
default:
|
||||
m_attribs.set(attr, true);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
if(!done)
|
||||
stdext::throw_exception(stdext::format("corrupt data (id: %d, category: %d, count: %d, lastAttr: %d)",
|
||||
m_id, m_category, count, attr));
|
||||
|
||||
bool hasFrameGroups = (category == ThingCategoryCreature && g_game.getFeature(Otc::GameIdleAnimations));
|
||||
uint8 groupCount = hasFrameGroups ? fin->getU8() : 1;
|
||||
|
||||
m_animationPhases = 0;
|
||||
int totalSpritesCount = 0;
|
||||
|
||||
std::vector<Size> sizes;
|
||||
std::vector<int> total_sprites;
|
||||
|
||||
for(int i = 0; i < groupCount; ++i) {
|
||||
uint8 frameGroupType = FrameGroupDefault;
|
||||
if(hasFrameGroups)
|
||||
frameGroupType = fin->getU8();
|
||||
|
||||
uint8 width = fin->getU8();
|
||||
uint8 height = fin->getU8();
|
||||
m_size = Size(width, height);
|
||||
sizes.push_back(m_size);
|
||||
if(width > 1 || height > 1) {
|
||||
m_realSize = fin->getU8();
|
||||
m_exactSize = std::min<int>(m_realSize, std::max<int>(width * 32, height * 32));
|
||||
}
|
||||
else
|
||||
m_exactSize = 32;
|
||||
|
||||
m_layers = fin->getU8();
|
||||
m_numPatternX = fin->getU8();
|
||||
m_numPatternY = fin->getU8();
|
||||
if(g_game.getClientVersion() >= 755)
|
||||
m_numPatternZ = fin->getU8();
|
||||
else
|
||||
m_numPatternZ = 1;
|
||||
|
||||
int groupAnimationsPhases = fin->getU8();
|
||||
m_animationPhases += groupAnimationsPhases;
|
||||
|
||||
if(groupAnimationsPhases > 1 && g_game.getFeature(Otc::GameEnhancedAnimations)) {
|
||||
AnimatorPtr animator = AnimatorPtr(new Animator);
|
||||
animator->unserialize(groupAnimationsPhases, fin);
|
||||
|
||||
switch (frameGroupType) {
|
||||
case FrameGroupIdle:
|
||||
m_idleAnimator = animator;
|
||||
break;
|
||||
case FrameGroupMoving:
|
||||
m_animator = animator;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * groupAnimationsPhases;
|
||||
total_sprites.push_back(totalSprites);
|
||||
|
||||
if((totalSpritesCount+totalSprites) > 4096)
|
||||
stdext::throw_exception("a thing type has more than 4096 sprites");
|
||||
|
||||
m_spritesIndex.resize((totalSpritesCount+totalSprites));
|
||||
for(int i = totalSpritesCount; i < (totalSpritesCount+totalSprites); i++)
|
||||
m_spritesIndex[i] = g_game.getFeature(Otc::GameSpritesU32) ? fin->getU32() : fin->getU16();
|
||||
|
||||
totalSpritesCount += totalSprites;
|
||||
}
|
||||
|
||||
if(sizes.size() > 1) {
|
||||
// correction for some sprites
|
||||
for (auto& s : sizes) {
|
||||
m_size.setWidth(std::max<int>(m_size.width(), s.width()));
|
||||
m_size.setHeight(std::max<int>(m_size.height(), s.height()));
|
||||
}
|
||||
size_t expectedSize = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases;
|
||||
if (expectedSize != m_spritesIndex.size()) {
|
||||
std::vector<int> sprites(std::move(m_spritesIndex));
|
||||
m_spritesIndex.clear();
|
||||
m_spritesIndex.reserve(expectedSize);
|
||||
for (size_t i = 0, idx = 0; i < sizes.size(); ++i) {
|
||||
int totalSprites = total_sprites[i];
|
||||
if (m_size == sizes[i]) {
|
||||
for (int j = 0; j < totalSprites; ++j) {
|
||||
m_spritesIndex.push_back(sprites[idx++]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
size_t patterns = (totalSprites / sizes[i].area());
|
||||
for (size_t p = 0; p < patterns; ++p) {
|
||||
for (int x = 0; x < m_size.width(); ++x) {
|
||||
for (int y = 0; y < m_size.height(); ++y) {
|
||||
if (x < sizes[i].width() && y < sizes[i].height()) {
|
||||
m_spritesIndex.push_back(sprites[idx++]);
|
||||
continue;
|
||||
}
|
||||
m_spritesIndex.push_back(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (m_spritesIndex.size() != expectedSize) {
|
||||
// g_logger.warning(stdext::format("Wrong thingtype: %i - %i - %i", clientId, m_spritesIndex.size(), expectedSize));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_idleAnimator && !m_animator) {
|
||||
m_animator = m_idleAnimator;
|
||||
m_idleAnimator = nullptr;
|
||||
}
|
||||
|
||||
m_textures.resize(m_animationPhases);
|
||||
m_texturesFramesRects.resize(m_animationPhases);
|
||||
m_texturesFramesOriginRects.resize(m_animationPhases);
|
||||
m_texturesFramesOffsets.resize(m_animationPhases);
|
||||
|
||||
m_lastUsage = g_clock.seconds();
|
||||
}
|
||||
|
||||
void ThingType::exportImage(std::string fileName)
|
||||
{
|
||||
if (m_null)
|
||||
stdext::throw_exception("cannot export null thingtype");
|
||||
|
||||
if (m_spritesIndex.size() == 0)
|
||||
stdext::throw_exception("cannot export thingtype without sprites");
|
||||
|
||||
size_t spriteSize = g_sprites.spriteSize();
|
||||
|
||||
ImagePtr image(new Image(Size(spriteSize * m_size.width() * m_layers * m_numPatternX, spriteSize * m_size.height() * m_animationPhases * m_numPatternY * m_numPatternZ)));
|
||||
for (int z = 0; z < m_numPatternZ; ++z) {
|
||||
for (int y = 0; y < m_numPatternY; ++y) {
|
||||
for (int x = 0; x < m_numPatternX; ++x) {
|
||||
for (int l = 0; l < m_layers; ++l) {
|
||||
for (int a = 0; a < m_animationPhases; ++a) {
|
||||
for (int w = 0; w < m_size.width(); ++w) {
|
||||
for (int h = 0; h < m_size.height(); ++h) {
|
||||
image->blit(Point(spriteSize * (m_size.width() - w - 1 + m_size.width() * x + m_size.width() * m_numPatternX * l),
|
||||
spriteSize * (m_size.height() - h - 1 + m_size.height() * y + m_size.height() * m_numPatternY * a + m_size.height() * m_numPatternY * m_animationPhases * z)),
|
||||
g_sprites.getSpriteImage(m_spritesIndex[getSpriteIndex(w, h, l, x, y, z, a)]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image->savePNG(fileName);
|
||||
}
|
||||
|
||||
void ThingType::replaceSprites(std::map<uint32_t, ImagePtr>& replacements, std::string fileName)
|
||||
{
|
||||
if (m_null)
|
||||
stdext::throw_exception("cannot export null thingtype");
|
||||
|
||||
if (m_spritesIndex.size() == 0)
|
||||
stdext::throw_exception("cannot export thingtype without sprites");
|
||||
|
||||
size_t spriteSize = g_sprites.spriteSize();
|
||||
|
||||
ImagePtr image = Image::loadPNG(fileName);
|
||||
if (!image)
|
||||
stdext::throw_exception(stdext::format("can't load image from %s", fileName));
|
||||
|
||||
for (int z = 0; z < m_numPatternZ; ++z) {
|
||||
for (int y = 0; y < m_numPatternY; ++y) {
|
||||
for (int x = 0; x < m_numPatternX; ++x) {
|
||||
for (int l = 0; l < m_layers; ++l) {
|
||||
for (int a = 0; a < m_animationPhases; ++a) {
|
||||
for (int w = 0; w < m_size.width(); ++w) {
|
||||
for (int h = 0; h < m_size.height(); ++h) {
|
||||
uint32_t sprite = m_spritesIndex[getSpriteIndex(w, h, l, x, y, z, a)];
|
||||
ImagePtr orgSprite = g_sprites.getSpriteImage(m_spritesIndex[getSpriteIndex(w, h, l, x, y, z, a)]);
|
||||
if (!orgSprite) continue;
|
||||
Point src(spriteSize * (m_size.width() - w - 1 + m_size.width() * x + m_size.width() * m_numPatternX * l),
|
||||
spriteSize * (m_size.height() - h - 1 + m_size.height() * y + m_size.height() * m_numPatternY * a + m_size.height() * m_numPatternY * m_animationPhases * z));
|
||||
src = src * 2;
|
||||
ImagePtr newSprite(new Image(Size(orgSprite->getSize() * 2)));
|
||||
for (int x = 0; x < newSprite->getSize().width(); ++x) {
|
||||
for (int y = 0; y < newSprite->getSize().height(); ++y) {
|
||||
newSprite->setPixel(x, y, image->getPixel(src.x + x, src.y + y));
|
||||
}
|
||||
}
|
||||
replacements[sprite] = newSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThingType::unserializeOtml(const OTMLNodePtr& node)
|
||||
{
|
||||
for(const OTMLNodePtr& node2 : node->children()) {
|
||||
if(node2->tag() == "opacity")
|
||||
m_opacity = node2->value<float>();
|
||||
else if(node2->tag() == "notprewalkable")
|
||||
m_attribs.set(ThingAttrNotPreWalkable, node2->value<bool>());
|
||||
else if(node2->tag() == "image")
|
||||
m_customImage = node2->value();
|
||||
else if(node2->tag() == "full-ground") {
|
||||
if(node2->value<bool>())
|
||||
m_attribs.set(ThingAttrFullGround, true);
|
||||
else
|
||||
m_attribs.remove(ThingAttrFullGround);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThingType::unload()
|
||||
{
|
||||
m_textures.clear();
|
||||
m_texturesFramesRects.clear();
|
||||
m_texturesFramesOriginRects.clear();
|
||||
m_texturesFramesOffsets.clear();
|
||||
|
||||
m_textures.resize(m_animationPhases);
|
||||
m_texturesFramesRects.resize(m_animationPhases);
|
||||
m_texturesFramesOriginRects.resize(m_animationPhases);
|
||||
m_texturesFramesOffsets.resize(m_animationPhases);
|
||||
|
||||
m_loaded = false;
|
||||
}
|
||||
|
||||
|
||||
DrawQueueItem* ThingType::draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color, LightView* lightView)
|
||||
{
|
||||
if (m_null)
|
||||
return nullptr;
|
||||
|
||||
if (animationPhase < 0 || animationPhase >= m_animationPhases)
|
||||
return nullptr;
|
||||
|
||||
const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects.
|
||||
if (!texture)
|
||||
return nullptr;
|
||||
|
||||
uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
|
||||
if (frameIndex >= m_texturesFramesRects[animationPhase].size())
|
||||
return nullptr;
|
||||
|
||||
Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex];
|
||||
Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex];
|
||||
|
||||
Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * Otc::TILE_PIXELS), textureRect.size());
|
||||
|
||||
bool useOpacity = m_opacity < 1.0f;
|
||||
if (useOpacity)
|
||||
color.setAlpha(m_opacity);
|
||||
|
||||
if (lightView && hasLight())
|
||||
lightView->addLight(screenRect.center(), getLight());
|
||||
|
||||
return g_drawQueue->addTexturedRect(screenRect, texture, textureRect, color);
|
||||
}
|
||||
|
||||
DrawQueueItem* ThingType::draw(const Rect& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color)
|
||||
{
|
||||
if (m_null)
|
||||
return nullptr;
|
||||
|
||||
if (animationPhase < 0 || animationPhase >= m_animationPhases)
|
||||
return nullptr;
|
||||
|
||||
const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects.
|
||||
if (!texture)
|
||||
return nullptr;
|
||||
|
||||
uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
|
||||
if (frameIndex >= m_texturesFramesRects[animationPhase].size())
|
||||
return nullptr;
|
||||
|
||||
Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex];
|
||||
Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex];
|
||||
|
||||
bool useOpacity = m_opacity < 1.0f;
|
||||
if (useOpacity)
|
||||
color.setAlpha(m_opacity);
|
||||
|
||||
Size size = m_size * Otc::TILE_PIXELS;
|
||||
if (!size.isValid())
|
||||
return nullptr;
|
||||
|
||||
// size correction for some too big items
|
||||
if ((size.width() > 1 || size.height() > 1) &&
|
||||
textureRect.width() <= Otc::TILE_PIXELS && textureRect.height() <= Otc::TILE_PIXELS) {
|
||||
size = Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS);
|
||||
textureOffset = Point((Otc::TILE_PIXELS - textureRect.width()) / 2,
|
||||
(Otc::TILE_PIXELS - textureRect.height()) / 2);
|
||||
}
|
||||
|
||||
float scale = std::min<float>((float)dest.width() / size.width(), (float)dest.height() / size.height());
|
||||
return g_drawQueue->addTexturedRect(Rect(dest.topLeft() + (textureOffset * scale), textureRect.size() * scale), texture, textureRect, color);
|
||||
}
|
||||
|
||||
void ThingType::drawOutfit(const Point& dest, int xPattern, int yPattern, int zPattern, int animationPhase, int colors, Color color, LightView* lightView)
|
||||
{
|
||||
if (m_null)
|
||||
return;
|
||||
|
||||
if (animationPhase < 0 || animationPhase >= m_animationPhases)
|
||||
return;
|
||||
|
||||
const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects.
|
||||
if (!texture)
|
||||
return;
|
||||
|
||||
uint frameIndex = getTextureIndex(0, xPattern, yPattern, zPattern);
|
||||
uint frameIndex2 = getTextureIndex(1, xPattern, yPattern, zPattern);
|
||||
if (frameIndex >= m_texturesFramesRects[animationPhase].size() || frameIndex2 >= m_texturesFramesRects[animationPhase].size())
|
||||
return;
|
||||
|
||||
Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex];
|
||||
Point textureOffset2 = m_texturesFramesOffsets[animationPhase][frameIndex2];
|
||||
Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex];
|
||||
Rect textureRect2 = m_texturesFramesRects[animationPhase][frameIndex2];
|
||||
Size size = textureRect.size();
|
||||
if (!size.isValid())
|
||||
return;
|
||||
Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * Otc::TILE_PIXELS), textureRect.size());
|
||||
|
||||
bool useOpacity = m_opacity < 1.0f;
|
||||
if (useOpacity)
|
||||
color.setAlpha(m_opacity);
|
||||
|
||||
if (lightView && hasLight())
|
||||
lightView->addLight(screenRect.center(), getLight());
|
||||
|
||||
Point offset = textureOffset - textureOffset2;
|
||||
offset += textureRect2.topLeft() - textureRect.topLeft();
|
||||
g_drawQueue->addOutfit(screenRect, texture, textureRect, offset, colors, color);
|
||||
}
|
||||
|
||||
Rect ThingType::getDrawSize(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
|
||||
{
|
||||
if (m_null)
|
||||
return Rect(0, 0, 1, 1);
|
||||
|
||||
if (animationPhase < 0 || animationPhase >= m_animationPhases)
|
||||
return Rect(0, 0, 1, 1);
|
||||
|
||||
const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects.
|
||||
if (!texture)
|
||||
return Rect(0, 0, 1, 1);
|
||||
|
||||
uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
|
||||
if (frameIndex >= m_texturesFramesRects[animationPhase].size())
|
||||
return Rect(0, 0, 1, 1);
|
||||
|
||||
Point textureOffset = m_texturesFramesOffsets[animationPhase][frameIndex];
|
||||
Rect textureRect = m_texturesFramesRects[animationPhase][frameIndex];
|
||||
return Rect(dest + textureOffset - m_displacement - (m_size.toPoint() - Point(1, 1)) * Otc::TILE_PIXELS, textureRect.size());
|
||||
}
|
||||
|
||||
|
||||
const TexturePtr& ThingType::getTexture(int animationPhase)
|
||||
{
|
||||
m_lastUsage = g_clock.seconds();
|
||||
|
||||
int spriteSize = g_sprites.spriteSize();
|
||||
TexturePtr& animationPhaseTexture = m_textures[animationPhase];
|
||||
if(!animationPhaseTexture) {
|
||||
bool useCustomImage = false;
|
||||
if(animationPhase == 0 && !m_customImage.empty())
|
||||
useCustomImage = true;
|
||||
|
||||
// we don't need layers in common items, they will be pre-drawn
|
||||
int textureLayers = 1;
|
||||
int numLayers = m_layers;
|
||||
if(m_category == ThingCategoryCreature && numLayers >= 2) {
|
||||
// otcv8 optimization from 5 to 2 layers
|
||||
textureLayers = 2;
|
||||
numLayers = 2;
|
||||
}
|
||||
|
||||
int indexSize = textureLayers * m_numPatternX * m_numPatternY * m_numPatternZ;
|
||||
Size textureSize = getBestTextureDimension(m_size.width(), m_size.height(), indexSize);
|
||||
ImagePtr fullImage;
|
||||
|
||||
if(useCustomImage)
|
||||
fullImage = Image::load(m_customImage);
|
||||
else
|
||||
fullImage = ImagePtr(new Image(textureSize * spriteSize));
|
||||
|
||||
m_texturesFramesRects[animationPhase].resize(indexSize);
|
||||
m_texturesFramesOriginRects[animationPhase].resize(indexSize);
|
||||
m_texturesFramesOffsets[animationPhase].resize(indexSize);
|
||||
|
||||
for(int z = 0; z < m_numPatternZ; ++z) {
|
||||
for(int y = 0; y < m_numPatternY; ++y) {
|
||||
for(int x = 0; x < m_numPatternX; ++x) {
|
||||
for(int l = 0; l < numLayers; ++l) {
|
||||
bool spriteMask = (m_category == ThingCategoryCreature && l > 0);
|
||||
int frameIndex = getTextureIndex(l % textureLayers, x, y, z);
|
||||
Point framePos = Point(frameIndex % (textureSize.width() / m_size.width()) * m_size.width(),
|
||||
frameIndex / (textureSize.width() / m_size.width()) * m_size.height()) * spriteSize;
|
||||
|
||||
if (!useCustomImage) {
|
||||
for (int h = 0; h < m_size.height(); ++h) {
|
||||
for (int w = 0; w < m_size.width(); ++w) {
|
||||
uint spriteIndex = getSpriteIndex(w, h, spriteMask ? 1 : l, x, y, z, animationPhase);
|
||||
ImagePtr spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]);
|
||||
if (!spriteImage) {
|
||||
continue;
|
||||
}
|
||||
Point spritePos = Point(m_size.width() - w - 1,
|
||||
m_size.height() - h - 1) * spriteSize;
|
||||
fullImage->blit(framePos + spritePos, spriteImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rect drawRect(framePos + Point(m_size.width(), m_size.height()) * spriteSize - Point(1,1), framePos);
|
||||
for(int x = framePos.x; x < framePos.x + m_size.width() * spriteSize; ++x) {
|
||||
for(int y = framePos.y; y < framePos.y + m_size.height() * spriteSize; ++y) {
|
||||
uint8 *p = fullImage->getPixel(x,y);
|
||||
if(p[3] != 0x00) {
|
||||
drawRect.setTop (std::min<int>(y, (int)drawRect.top()));
|
||||
drawRect.setLeft (std::min<int>(x, (int)drawRect.left()));
|
||||
drawRect.setBottom(std::max<int>(y, (int)drawRect.bottom()));
|
||||
drawRect.setRight (std::max<int>(x, (int)drawRect.right()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_texturesFramesRects[animationPhase][frameIndex] = drawRect;
|
||||
m_texturesFramesOriginRects[animationPhase][frameIndex] = Rect(framePos, Size(m_size.width(), m_size.height()) * spriteSize);// *0.5;
|
||||
m_texturesFramesOffsets[animationPhase][frameIndex] = (drawRect.topLeft() - framePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
animationPhaseTexture = TexturePtr(new Texture(fullImage, true, false, true));
|
||||
m_loaded = true;
|
||||
}
|
||||
return animationPhaseTexture;
|
||||
}
|
||||
|
||||
Size ThingType::getBestTextureDimension(int w, int h, int count)
|
||||
{
|
||||
const int MAX = 32;
|
||||
|
||||
int k = 1;
|
||||
while(k < w)
|
||||
k<<=1;
|
||||
w = k;
|
||||
|
||||
k = 1;
|
||||
while(k < h)
|
||||
k<<=1;
|
||||
h = k;
|
||||
|
||||
int numSprites = w*h*count;
|
||||
VALIDATE(numSprites <= MAX*MAX);
|
||||
VALIDATE(w <= MAX);
|
||||
VALIDATE(h <= MAX);
|
||||
|
||||
Size bestDimension = Size(MAX, MAX);
|
||||
for(int i=w;i<=MAX;i<<=1) {
|
||||
for(int j=h;j<=MAX;j<<=1) {
|
||||
Size candidateDimension = Size(i, j);
|
||||
if(candidateDimension.area() < numSprites)
|
||||
continue;
|
||||
if((candidateDimension.area() < bestDimension.area()) ||
|
||||
(candidateDimension.area() == bestDimension.area() && candidateDimension.width() + candidateDimension.height() < bestDimension.width() + bestDimension.height()))
|
||||
bestDimension = candidateDimension;
|
||||
}
|
||||
}
|
||||
|
||||
return bestDimension;
|
||||
}
|
||||
|
||||
uint ThingType::getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) {
|
||||
uint index =
|
||||
((((((a % m_animationPhases)
|
||||
* m_numPatternZ + z)
|
||||
* m_numPatternY + y)
|
||||
* m_numPatternX + x)
|
||||
* m_layers + l)
|
||||
* m_size.height() + h)
|
||||
* m_size.width() + w;
|
||||
VALIDATE(index < m_spritesIndex.size());
|
||||
return index;
|
||||
}
|
||||
|
||||
uint ThingType::getTextureIndex(int l, int x, int y, int z) {
|
||||
return ((l * m_numPatternZ + z)
|
||||
* m_numPatternY + y)
|
||||
* m_numPatternX + x;
|
||||
}
|
||||
|
||||
int ThingType::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
|
||||
{
|
||||
if(m_null)
|
||||
return 0;
|
||||
|
||||
getTexture(animationPhase); // we must calculate it anyway.
|
||||
int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
|
||||
Size size = m_texturesFramesOriginRects[animationPhase][frameIndex].size() - m_texturesFramesOffsets[animationPhase][frameIndex].toSize();
|
||||
return std::max<int>(size.width(), size.height());
|
||||
}
|
||||
|
||||
void ThingType::setPathable(bool var)
|
||||
{
|
||||
if(var == true)
|
||||
m_attribs.remove(ThingAttrNotPathable);
|
||||
else
|
||||
m_attribs.set(ThingAttrNotPathable, true);
|
||||
}
|
@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef THINGTYPE_H
|
||||
#define THINGTYPE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "animator.h"
|
||||
|
||||
#include <framework/core/declarations.h>
|
||||
#include <framework/otml/declarations.h>
|
||||
#include <framework/graphics/texture.h>
|
||||
#include <framework/graphics/coordsbuffer.h>
|
||||
#include <framework/graphics/drawqueue.h>
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include <framework/net/server.h>
|
||||
|
||||
enum NewDrawType : uint8 {
|
||||
NewDrawNormal = 0,
|
||||
NewDrawMount = 5,
|
||||
NewDrawOutfit = 6,
|
||||
NewDrawOutfitLayers = 7,
|
||||
NewDrawMissle = 10
|
||||
};
|
||||
|
||||
enum FrameGroupType : uint8 {
|
||||
FrameGroupDefault = 0,
|
||||
FrameGroupIdle = FrameGroupDefault,
|
||||
FrameGroupMoving
|
||||
};
|
||||
|
||||
enum ThingCategory : uint8 {
|
||||
ThingCategoryItem = 0,
|
||||
ThingCategoryCreature,
|
||||
ThingCategoryEffect,
|
||||
ThingCategoryMissile,
|
||||
ThingInvalidCategory,
|
||||
ThingLastCategory = ThingInvalidCategory
|
||||
};
|
||||
|
||||
enum ThingAttr : uint8 {
|
||||
ThingAttrGround = 0,
|
||||
ThingAttrGroundBorder = 1,
|
||||
ThingAttrOnBottom = 2,
|
||||
ThingAttrOnTop = 3,
|
||||
ThingAttrContainer = 4,
|
||||
ThingAttrStackable = 5,
|
||||
ThingAttrForceUse = 6,
|
||||
ThingAttrMultiUse = 7,
|
||||
ThingAttrWritable = 8,
|
||||
ThingAttrWritableOnce = 9,
|
||||
ThingAttrFluidContainer = 10,
|
||||
ThingAttrSplash = 11,
|
||||
ThingAttrNotWalkable = 12,
|
||||
ThingAttrNotMoveable = 13,
|
||||
ThingAttrBlockProjectile = 14,
|
||||
ThingAttrNotPathable = 15,
|
||||
ThingAttrPickupable = 16,
|
||||
ThingAttrHangable = 17,
|
||||
ThingAttrHookSouth = 18,
|
||||
ThingAttrHookEast = 19,
|
||||
ThingAttrRotateable = 20,
|
||||
ThingAttrLight = 21,
|
||||
ThingAttrDontHide = 22,
|
||||
ThingAttrTranslucent = 23,
|
||||
ThingAttrDisplacement = 24,
|
||||
ThingAttrElevation = 25,
|
||||
ThingAttrLyingCorpse = 26,
|
||||
ThingAttrAnimateAlways = 27,
|
||||
ThingAttrMinimapColor = 28,
|
||||
ThingAttrLensHelp = 29,
|
||||
ThingAttrFullGround = 30,
|
||||
ThingAttrLook = 31,
|
||||
ThingAttrCloth = 32,
|
||||
ThingAttrMarket = 33,
|
||||
ThingAttrUsable = 34,
|
||||
ThingAttrWrapable = 35,
|
||||
ThingAttrUnwrapable = 36,
|
||||
ThingAttrTopEffect = 37,
|
||||
|
||||
// additional
|
||||
ThingAttrOpacity = 100,
|
||||
ThingAttrNotPreWalkable = 101,
|
||||
|
||||
ThingAttrFloorChange = 252,
|
||||
ThingAttrNoMoveAnimation = 253, // 10.10: real value is 16, but we need to do this for backwards compatibility
|
||||
ThingAttrChargeable = 254, // deprecated
|
||||
ThingLastAttr = 255
|
||||
};
|
||||
|
||||
enum SpriteMask {
|
||||
SpriteMask = 1,
|
||||
};
|
||||
|
||||
struct MarketData {
|
||||
std::string name;
|
||||
int category;
|
||||
uint16 requiredLevel;
|
||||
uint16 restrictVocation;
|
||||
uint16 showAs;
|
||||
uint16 tradeAs;
|
||||
};
|
||||
|
||||
struct StoreCategory {
|
||||
std::string name;
|
||||
std::string description;
|
||||
int state;
|
||||
std::string icon;
|
||||
std::string parent;
|
||||
};
|
||||
|
||||
struct StoreOffer {
|
||||
int id;
|
||||
std::string name;
|
||||
std::string description;
|
||||
int price;
|
||||
int state;
|
||||
std::string icon;
|
||||
};
|
||||
|
||||
struct Imbuement {
|
||||
int id;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string group;
|
||||
int imageId;
|
||||
int duration;
|
||||
bool premiumOnly;
|
||||
std::vector<std::pair<ItemPtr, std::string>> sources;
|
||||
int cost;
|
||||
int successRate;
|
||||
int protectionCost;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
Point pos;
|
||||
uint8_t color = 215;
|
||||
uint8_t intensity = 0;
|
||||
};
|
||||
|
||||
class ThingType : public LuaObject
|
||||
{
|
||||
public:
|
||||
ThingType();
|
||||
|
||||
void unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin);
|
||||
void unserializeOtml(const OTMLNodePtr& node);
|
||||
void unload();
|
||||
|
||||
void serialize(const FileStreamPtr& fin);
|
||||
void exportImage(std::string fileName);
|
||||
void replaceSprites(std::map<uint32_t, ImagePtr>& replacements, std::string fileName);
|
||||
|
||||
DrawQueueItem* draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color = Color::white, LightView* lightView = nullptr);
|
||||
DrawQueueItem* draw(const Rect& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, Color color = Color::white);
|
||||
void drawOutfit(const Point& dest, int xPattern, int yPattern, int zPattern, int animationPhase, int colors, Color color = Color::white, LightView* lightView = nullptr);
|
||||
Rect getDrawSize(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase);
|
||||
|
||||
uint16 getId() { return m_id; }
|
||||
ThingCategory getCategory() { return m_category; }
|
||||
bool isNull() { return m_null; }
|
||||
bool hasAttr(ThingAttr attr) { return m_attribs.has(attr); }
|
||||
bool isLoaded() { return m_loaded; }
|
||||
ticks_t getLastUsage() { return m_lastUsage; }
|
||||
|
||||
Size getSize() { return m_size; }
|
||||
int getWidth() { return m_size.width(); }
|
||||
int getHeight() { return m_size.height(); }
|
||||
int getExactSize(int layer = 0, int xPattern = 0, int yPattern = 0, int zPattern = 0, int animationPhase = 0);
|
||||
int getRealSize() { return m_realSize; }
|
||||
int getLayers() { return m_layers; }
|
||||
int getNumPatternX() { return m_numPatternX; }
|
||||
int getNumPatternY() { return m_numPatternY; }
|
||||
int getNumPatternZ() { return m_numPatternZ; }
|
||||
int getAnimationPhases() { return m_animationPhases; }
|
||||
AnimatorPtr getAnimator() { return m_animator; }
|
||||
AnimatorPtr getIdleAnimator() { return m_idleAnimator; }
|
||||
Point getDisplacement() { return m_displacement; }
|
||||
int getDisplacementX() { return getDisplacement().x; }
|
||||
int getDisplacementY() { return getDisplacement().y; }
|
||||
int getElevation() { return m_elevation; }
|
||||
|
||||
int getGroundSpeed() { return m_attribs.get<uint16>(ThingAttrGround); }
|
||||
int getMaxTextLength() { return m_attribs.has(ThingAttrWritableOnce) ? m_attribs.get<uint16>(ThingAttrWritableOnce) : m_attribs.get<uint16>(ThingAttrWritable); }
|
||||
Light getLight() { return m_attribs.get<Light>(ThingAttrLight); }
|
||||
int getMinimapColor() { return m_attribs.get<uint16>(ThingAttrMinimapColor); }
|
||||
int getLensHelp() { return m_attribs.get<uint16>(ThingAttrLensHelp); }
|
||||
int getClothSlot() { return m_attribs.get<uint16>(ThingAttrCloth); }
|
||||
MarketData getMarketData() { return m_attribs.get<MarketData>(ThingAttrMarket); }
|
||||
bool isGround() { return m_attribs.has(ThingAttrGround); }
|
||||
bool isGroundBorder() { return m_attribs.has(ThingAttrGroundBorder); }
|
||||
bool isOnBottom() { return m_attribs.has(ThingAttrOnBottom); }
|
||||
bool isOnTop() { return m_attribs.has(ThingAttrOnTop); }
|
||||
bool isContainer() { return m_attribs.has(ThingAttrContainer); }
|
||||
bool isStackable() { return m_attribs.has(ThingAttrStackable); }
|
||||
bool isForceUse() { return m_attribs.has(ThingAttrForceUse); }
|
||||
bool isMultiUse() { return m_attribs.has(ThingAttrMultiUse); }
|
||||
bool isWritable() { return m_attribs.has(ThingAttrWritable); }
|
||||
bool isChargeable() { return m_attribs.has(ThingAttrChargeable); }
|
||||
bool isWritableOnce() { return m_attribs.has(ThingAttrWritableOnce); }
|
||||
bool isFluidContainer() { return m_attribs.has(ThingAttrFluidContainer); }
|
||||
bool isSplash() { return m_attribs.has(ThingAttrSplash); }
|
||||
bool isNotWalkable() { return m_attribs.has(ThingAttrNotWalkable); }
|
||||
bool isNotMoveable() { return m_attribs.has(ThingAttrNotMoveable); }
|
||||
bool blockProjectile() { return m_attribs.has(ThingAttrBlockProjectile); }
|
||||
bool isNotPathable() { return m_attribs.has(ThingAttrNotPathable); }
|
||||
bool isPickupable() { return m_attribs.has(ThingAttrPickupable); }
|
||||
bool isHangable() { return m_attribs.has(ThingAttrHangable); }
|
||||
bool isHookSouth() { return m_attribs.has(ThingAttrHookSouth); }
|
||||
bool isHookEast() { return m_attribs.has(ThingAttrHookEast); }
|
||||
bool isRotateable() { return m_attribs.has(ThingAttrRotateable); }
|
||||
bool hasLight() { return m_attribs.has(ThingAttrLight); }
|
||||
bool isDontHide() { return m_attribs.has(ThingAttrDontHide); }
|
||||
bool isTranslucent() { return m_attribs.has(ThingAttrTranslucent); }
|
||||
bool hasDisplacement() { return m_attribs.has(ThingAttrDisplacement); }
|
||||
bool hasElevation() { return m_attribs.has(ThingAttrElevation); }
|
||||
bool isLyingCorpse() { return m_attribs.has(ThingAttrLyingCorpse); }
|
||||
bool isAnimateAlways() { return m_attribs.has(ThingAttrAnimateAlways); }
|
||||
bool hasMiniMapColor() { return m_attribs.has(ThingAttrMinimapColor); }
|
||||
bool hasLensHelp() { return m_attribs.has(ThingAttrLensHelp); }
|
||||
bool isFullGround() { return m_attribs.has(ThingAttrFullGround); }
|
||||
bool isIgnoreLook() { return m_attribs.has(ThingAttrLook); }
|
||||
bool isCloth() { return m_attribs.has(ThingAttrCloth); }
|
||||
bool isMarketable() { return m_attribs.has(ThingAttrMarket); }
|
||||
bool isUsable() { return m_attribs.has(ThingAttrUsable); }
|
||||
bool isWrapable() { return m_attribs.has(ThingAttrWrapable); }
|
||||
bool isUnwrapable() { return m_attribs.has(ThingAttrUnwrapable); }
|
||||
bool isTopEffect() { return m_attribs.has(ThingAttrTopEffect); }
|
||||
|
||||
std::vector<int> getSprites() { return m_spritesIndex; }
|
||||
|
||||
// additional
|
||||
float getOpacity() { return m_opacity; }
|
||||
bool isNotPreWalkable() { return m_attribs.has(ThingAttrNotPreWalkable); }
|
||||
void setPathable(bool var);
|
||||
|
||||
private:
|
||||
const TexturePtr& getTexture(int animationPhase);
|
||||
Size getBestTextureDimension(int w, int h, int count);
|
||||
uint getSpriteIndex(int w, int h, int l, int x, int y, int z, int a);
|
||||
uint getTextureIndex(int l, int x, int y, int z);
|
||||
|
||||
ThingCategory m_category;
|
||||
uint16 m_id;
|
||||
bool m_null;
|
||||
stdext::dynamic_storage<uint8> m_attribs;
|
||||
|
||||
Size m_size;
|
||||
Point m_displacement;
|
||||
AnimatorPtr m_animator;
|
||||
AnimatorPtr m_idleAnimator;
|
||||
int m_animationPhases;
|
||||
int m_exactSize;
|
||||
int m_realSize;
|
||||
int m_numPatternX, m_numPatternY, m_numPatternZ;
|
||||
int m_layers;
|
||||
int m_elevation;
|
||||
float m_opacity;
|
||||
std::string m_customImage;
|
||||
|
||||
std::vector<int> m_spritesIndex;
|
||||
std::vector<TexturePtr> m_textures;
|
||||
std::vector<std::vector<Rect>> m_texturesFramesRects;
|
||||
std::vector<std::vector<Rect>> m_texturesFramesOriginRects;
|
||||
std::vector<std::vector<Point>> m_texturesFramesOffsets;
|
||||
|
||||
bool m_loaded = false;
|
||||
time_t m_lastUsage;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,497 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thingtypemanager.h"
|
||||
#include "spritemanager.h"
|
||||
#include "thing.h"
|
||||
#include "thingtype.h"
|
||||
#include "itemtype.h"
|
||||
#include "creature.h"
|
||||
#include "creatures.h"
|
||||
#include "game.h"
|
||||
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/core/binarytree.h>
|
||||
#include <framework/xml/tinyxml.h>
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/util/stats.h>
|
||||
|
||||
ThingTypeManager g_things;
|
||||
|
||||
void ThingTypeManager::init()
|
||||
{
|
||||
m_nullThingType = ThingTypePtr(new ThingType);
|
||||
m_nullItemType = ItemTypePtr(new ItemType);
|
||||
m_datSignature = 0;
|
||||
m_contentRevision = 0;
|
||||
m_otbMinorVersion = 0;
|
||||
m_otbMajorVersion = 0;
|
||||
m_datLoaded = false;
|
||||
m_xmlLoaded = false;
|
||||
m_otbLoaded = false;
|
||||
for (int i = 0; i < ThingLastCategory; ++i) {
|
||||
m_thingTypes[i].resize(1, m_nullThingType);
|
||||
m_checkIndex[i] = 0;
|
||||
}
|
||||
m_itemTypes.resize(1, m_nullItemType);
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
void ThingTypeManager::terminate()
|
||||
{
|
||||
for(int i = 0; i < ThingLastCategory; ++i)
|
||||
m_thingTypes[i].clear();
|
||||
m_itemTypes.clear();
|
||||
m_reverseItemTypes.clear();
|
||||
m_marketCategories.clear();
|
||||
m_nullThingType = nullptr;
|
||||
m_nullItemType = nullptr;
|
||||
|
||||
if (m_checkEvent) {
|
||||
m_checkEvent->cancel();
|
||||
m_checkEvent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ThingTypeManager::check()
|
||||
{
|
||||
// removes unused textures from memory after 60s, 500 checks / s
|
||||
m_checkEvent = g_dispatcher.scheduleEvent(std::bind(&ThingTypeManager::check, &g_things), 1000);
|
||||
|
||||
for (size_t i = 0; i < ThingLastCategory; ++i) {
|
||||
size_t limit = std::min<size_t>(m_checkIndex[i] + 100, m_thingTypes[i].size());
|
||||
for (size_t j = m_checkIndex[i]; j < limit; ++j) {
|
||||
if (m_thingTypes[i][j]->isLoaded() && m_thingTypes[i][j]->getLastUsage() + 60 < g_clock.seconds()) {
|
||||
m_thingTypes[i][j]->unload();
|
||||
}
|
||||
}
|
||||
m_checkIndex[i] = limit;
|
||||
if (m_checkIndex[i] >= m_thingTypes[i].size()) {
|
||||
m_checkIndex[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_ENCRYPTION
|
||||
void ThingTypeManager::saveDat(std::string fileName)
|
||||
{
|
||||
if(!m_datLoaded)
|
||||
stdext::throw_exception("failed to save, dat is not loaded");
|
||||
|
||||
try {
|
||||
FileStreamPtr fin = g_resources.createFile(fileName);
|
||||
if(!fin)
|
||||
stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
|
||||
|
||||
fin->addU32(m_datSignature);
|
||||
|
||||
for(int category = 0; category < ThingLastCategory; ++category)
|
||||
fin->addU16(m_thingTypes[category].size() - 1);
|
||||
|
||||
for(int category = 0; category < ThingLastCategory; ++category) {
|
||||
uint16 firstId = 1;
|
||||
if(category == ThingCategoryItem)
|
||||
firstId = 100;
|
||||
|
||||
for(uint16 id = firstId; id < m_thingTypes[category].size(); ++id)
|
||||
m_thingTypes[category][id]->serialize(fin);
|
||||
}
|
||||
|
||||
|
||||
fin->flush();
|
||||
fin->close();
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void ThingTypeManager::dumpTextures(std::string dir)
|
||||
{
|
||||
if (dir.empty()) {
|
||||
g_logger.error("Empty dir for sprites dump");
|
||||
return;
|
||||
}
|
||||
g_resources.makeDir(dir);
|
||||
for (int category = 0; category < ThingLastCategory; ++category) {
|
||||
g_resources.makeDir(dir + "/" + std::to_string((int)category));
|
||||
|
||||
uint16 firstId = 1;
|
||||
if (category == ThingCategoryItem)
|
||||
firstId = 100;
|
||||
|
||||
for (uint16 id = firstId; id < m_thingTypes[category].size(); ++id)
|
||||
m_thingTypes[category][id]->exportImage(dir + "/" + std::to_string((int)category) + "/" + std::to_string(id) + ".png");
|
||||
}
|
||||
}
|
||||
|
||||
void ThingTypeManager::replaceTextures(std::string dir) {
|
||||
if (dir.empty()) {
|
||||
g_logger.error("Empty dir for sprites dump");
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<uint32_t, ImagePtr> replacements;
|
||||
for (int category = 0; category < ThingLastCategory; ++category) {
|
||||
uint16 firstId = 1;
|
||||
if (category == ThingCategoryItem)
|
||||
firstId = 100;
|
||||
|
||||
for (uint16 id = firstId; id < m_thingTypes[category].size(); ++id) {
|
||||
std::string fileName = dir + "/" + std::to_string((int)category) + "/" + std::to_string(id) + "_[][x2.000000].png";
|
||||
m_thingTypes[category][id]->replaceSprites(replacements, fileName);
|
||||
}
|
||||
}
|
||||
//g_sprites.saveReplacedSpr(dir + "/sprites.spr", replacements);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool ThingTypeManager::loadDat(std::string file)
|
||||
{
|
||||
m_datLoaded = false;
|
||||
m_datSignature = 0;
|
||||
m_contentRevision = 0;
|
||||
try {
|
||||
file = g_resources.guessFilePath(file, "dat");
|
||||
|
||||
FileStreamPtr fin = g_resources.openFile(file);
|
||||
|
||||
m_datSignature = fin->getU32();
|
||||
m_contentRevision = static_cast<uint16_t>(m_datSignature);
|
||||
|
||||
for(int category = 0; category < ThingLastCategory; ++category) {
|
||||
int count = fin->getU16() + 1;
|
||||
m_thingTypes[category].clear();
|
||||
m_thingTypes[category].resize(count, m_nullThingType);
|
||||
}
|
||||
|
||||
m_marketCategories.clear();
|
||||
for(int category = 0; category < ThingLastCategory; ++category) {
|
||||
uint16 firstId = 1;
|
||||
if(category == ThingCategoryItem)
|
||||
firstId = 100;
|
||||
for(uint16 id = firstId; id < m_thingTypes[category].size(); ++id) {
|
||||
ThingTypePtr type(new ThingType);
|
||||
type->unserialize(id, (ThingCategory)category, fin);
|
||||
m_thingTypes[category][id] = type;
|
||||
if (type->isMarketable()) {
|
||||
auto marketData = type->getMarketData();
|
||||
m_marketCategories.insert(marketData.category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_datLoaded = true;
|
||||
g_lua.callGlobalField("g_things", "onLoadDat", file);
|
||||
return true;
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to read dat '%s': %s'", file, e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ThingTypeManager::loadOtml(std::string file)
|
||||
{
|
||||
try {
|
||||
file = g_resources.guessFilePath(file, "otml");
|
||||
|
||||
OTMLDocumentPtr doc = OTMLDocument::parse(file);
|
||||
for(const OTMLNodePtr& node : doc->children()) {
|
||||
ThingCategory category;
|
||||
if(node->tag() == "creatures")
|
||||
category = ThingCategoryCreature;
|
||||
else if(node->tag() == "items")
|
||||
category = ThingCategoryItem;
|
||||
else if(node->tag() == "effects")
|
||||
category = ThingCategoryEffect;
|
||||
else if(node->tag() == "missiles")
|
||||
category = ThingCategoryMissile;
|
||||
else {
|
||||
throw OTMLException(node, "not a valid thing category");
|
||||
}
|
||||
|
||||
for(const OTMLNodePtr& node2 : node->children()) {
|
||||
uint16 id = stdext::safe_cast<uint16>(node2->tag());
|
||||
ThingTypePtr type = getThingType(id, category);
|
||||
if(!type)
|
||||
throw OTMLException(node2, "thing not found");
|
||||
type->unserializeOtml(node2);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to read dat otml '%s': %s'", file, e.what()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ThingTypeManager::loadOtb(const std::string& file)
|
||||
{
|
||||
try {
|
||||
FileStreamPtr fin = g_resources.openFile(file);
|
||||
|
||||
uint signature = fin->getU32();
|
||||
if (signature != 0)
|
||||
stdext::throw_exception("invalid otb file");
|
||||
|
||||
BinaryTreePtr root = fin->getBinaryTree();
|
||||
root->skip(1); // otb first byte is always 0
|
||||
|
||||
signature = root->getU32();
|
||||
if (signature != 0)
|
||||
stdext::throw_exception("invalid otb file");
|
||||
|
||||
uint8 rootAttr = root->getU8();
|
||||
if (rootAttr == 0x01) { // OTB_ROOT_ATTR_VERSION
|
||||
uint16 size = root->getU16();
|
||||
if (size != 4 + 4 + 4 + 128)
|
||||
stdext::throw_exception("invalid otb root attr version size");
|
||||
|
||||
m_otbMajorVersion = root->getU32();
|
||||
m_otbMinorVersion = root->getU32();
|
||||
root->skip(4); // buildNumber
|
||||
root->skip(128); // description
|
||||
}
|
||||
|
||||
BinaryTreeVec children = root->getChildren();
|
||||
m_reverseItemTypes.clear();
|
||||
m_itemTypes.resize(children.size() + 1, m_nullItemType);
|
||||
m_reverseItemTypes.resize(children.size() + 1, m_nullItemType);
|
||||
|
||||
for (const BinaryTreePtr& node : children) {
|
||||
ItemTypePtr itemType(new ItemType);
|
||||
itemType->unserialize(node);
|
||||
addItemType(itemType);
|
||||
|
||||
uint16 clientId = itemType->getClientId();
|
||||
if (unlikely(clientId >= m_reverseItemTypes.size()))
|
||||
m_reverseItemTypes.resize(clientId + 1);
|
||||
m_reverseItemTypes[clientId] = itemType;
|
||||
}
|
||||
|
||||
m_otbLoaded = true;
|
||||
g_lua.callGlobalField("g_things", "onLoadOtb", file);
|
||||
} catch (std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to load '%s' (OTB file): %s", file, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ThingTypeManager::loadXml(const std::string& file)
|
||||
{
|
||||
try {
|
||||
if(!isOtbLoaded())
|
||||
stdext::throw_exception("OTB must be loaded before XML");
|
||||
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(g_resources.readFileContents(file).c_str());
|
||||
if(doc.Error())
|
||||
stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));
|
||||
|
||||
TiXmlElement* root = doc.FirstChildElement();
|
||||
if(!root || root->ValueTStr() != "items")
|
||||
stdext::throw_exception("invalid root tag name");
|
||||
|
||||
for(TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
|
||||
if(unlikely(element->ValueTStr() != "item"))
|
||||
continue;
|
||||
|
||||
uint16 id = element->readType<uint16>("id");
|
||||
if(id != 0) {
|
||||
std::vector<std::string> s_ids = stdext::split(element->Attribute("id"), ";");
|
||||
for(const std::string& s : s_ids) {
|
||||
std::vector<int32> ids = stdext::split<int32>(s, "-");
|
||||
if(ids.size() > 1) {
|
||||
int32 i = ids[0];
|
||||
while(i <= ids[1])
|
||||
parseItemType(i++, element);
|
||||
} else
|
||||
parseItemType(atoi(s.c_str()), element);
|
||||
}
|
||||
} else {
|
||||
std::vector<int32> begin = stdext::split<int32>(element->Attribute("fromid"), ";");
|
||||
std::vector<int32> end = stdext::split<int32>(element->Attribute("toid"), ";");
|
||||
if(begin[0] && begin.size() == end.size()) {
|
||||
size_t size = begin.size();
|
||||
for(size_t i = 0; i < size; ++i)
|
||||
while(begin[i] <= end[i])
|
||||
parseItemType(begin[i]++, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doc.Clear();
|
||||
m_xmlLoaded = true;
|
||||
g_logger.debug("items.xml read successfully.");
|
||||
} catch(std::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to load '%s' (XML file): %s", file, e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void ThingTypeManager::parseItemType(uint16 serverId, TiXmlElement* elem)
|
||||
{
|
||||
ItemTypePtr itemType = nullptr;
|
||||
|
||||
bool s;
|
||||
int d;
|
||||
|
||||
if(g_game.getClientVersion() < 960) {
|
||||
s = serverId > 20000 && serverId < 20100;
|
||||
d = 20000;
|
||||
} else {
|
||||
s = serverId > 30000 && serverId < 30100;
|
||||
d = 30000;
|
||||
}
|
||||
|
||||
if(s) {
|
||||
serverId -= d;
|
||||
itemType = ItemTypePtr(new ItemType);
|
||||
itemType->setServerId(serverId);
|
||||
addItemType(itemType);
|
||||
} else
|
||||
itemType = getItemType(serverId);
|
||||
|
||||
itemType->setName(elem->Attribute("name"));
|
||||
for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
|
||||
std::string key = attrib->Attribute("key");
|
||||
if(key.empty())
|
||||
continue;
|
||||
|
||||
stdext::tolower(key);
|
||||
if(key == "description")
|
||||
itemType->setDesc(attrib->Attribute("value"));
|
||||
else if(key == "weapontype")
|
||||
itemType->setCategory(ItemCategoryWeapon);
|
||||
else if(key == "ammotype")
|
||||
itemType->setCategory(ItemCategoryAmmunition);
|
||||
else if(key == "armor")
|
||||
itemType->setCategory(ItemCategoryArmor);
|
||||
else if(key == "charges")
|
||||
itemType->setCategory(ItemCategoryCharges);
|
||||
else if(key == "type") {
|
||||
std::string value = attrib->Attribute("value");
|
||||
stdext::tolower(value);
|
||||
|
||||
if(value == "key")
|
||||
itemType->setCategory(ItemCategoryKey);
|
||||
else if(value == "magicfield")
|
||||
itemType->setCategory(ItemCategoryMagicField);
|
||||
else if(value == "teleport")
|
||||
itemType->setCategory(ItemCategoryTeleport);
|
||||
else if(value == "door")
|
||||
itemType->setCategory(ItemCategoryDoor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThingTypeManager::addItemType(const ItemTypePtr& itemType)
|
||||
{
|
||||
uint16 id = itemType->getServerId();
|
||||
if(unlikely(id >= m_itemTypes.size()))
|
||||
m_itemTypes.resize(id + 1, m_nullItemType);
|
||||
m_itemTypes[id] = itemType;
|
||||
}
|
||||
|
||||
const ItemTypePtr& ThingTypeManager::findItemTypeByClientId(uint16 id)
|
||||
{
|
||||
if(id == 0 || id >= m_reverseItemTypes.size())
|
||||
return m_nullItemType;
|
||||
|
||||
if(m_reverseItemTypes[id])
|
||||
return m_reverseItemTypes[id];
|
||||
else
|
||||
return m_nullItemType;
|
||||
}
|
||||
|
||||
const ItemTypePtr& ThingTypeManager::findItemTypeByName(std::string name)
|
||||
{
|
||||
for(const ItemTypePtr& it : m_itemTypes)
|
||||
if(it->getName() == name)
|
||||
return it;
|
||||
return m_nullItemType;
|
||||
}
|
||||
|
||||
ItemTypeList ThingTypeManager::findItemTypesByName(std::string name)
|
||||
{
|
||||
ItemTypeList ret;
|
||||
for(const ItemTypePtr& it : m_itemTypes)
|
||||
if(it->getName() == name)
|
||||
ret.push_back(it);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ItemTypeList ThingTypeManager::findItemTypesByString(std::string name)
|
||||
{
|
||||
ItemTypeList ret;
|
||||
for(const ItemTypePtr& it : m_itemTypes)
|
||||
if(it->getName().find(name) != std::string::npos)
|
||||
ret.push_back(it);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory category)
|
||||
{
|
||||
if(category >= ThingLastCategory || id >= m_thingTypes[category].size()) {
|
||||
g_logger.error(stdext::format("invalid thing type client id %d in category %d", id, category));
|
||||
return m_nullThingType;
|
||||
}
|
||||
return m_thingTypes[category][id];
|
||||
}
|
||||
|
||||
const ItemTypePtr& ThingTypeManager::getItemType(uint16 id)
|
||||
{
|
||||
if(id >= m_itemTypes.size() || m_itemTypes[id] == m_nullItemType) {
|
||||
g_logger.error(stdext::format("invalid thing type, server id: %d", id));
|
||||
return m_nullItemType;
|
||||
}
|
||||
return m_itemTypes[id];
|
||||
}
|
||||
|
||||
ThingTypeList ThingTypeManager::findThingTypeByAttr(ThingAttr attr, ThingCategory category)
|
||||
{
|
||||
ThingTypeList ret;
|
||||
for(const ThingTypePtr& type : m_thingTypes[category])
|
||||
if(type->hasAttr(attr))
|
||||
ret.push_back(type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ItemTypeList ThingTypeManager::findItemTypeByCategory(ItemCategory category)
|
||||
{
|
||||
ItemTypeList ret;
|
||||
for(const ItemTypePtr& type : m_itemTypes)
|
||||
if(type->getCategory() == category)
|
||||
ret.push_back(type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const ThingTypeList& ThingTypeManager::getThingTypes(ThingCategory category)
|
||||
{
|
||||
ThingTypeList ret;
|
||||
if(category >= ThingLastCategory)
|
||||
stdext::throw_exception(stdext::format("invalid thing type category %d", category));
|
||||
return m_thingTypes[category];
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et: */
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef THINGTYPEMANAGER_H
|
||||
#define THINGTYPEMANAGER_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <framework/core/declarations.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
#include "thingtype.h"
|
||||
#include "itemtype.h"
|
||||
|
||||
class ThingTypeManager
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
void terminate();
|
||||
void check();
|
||||
|
||||
bool loadDat(std::string file);
|
||||
bool loadOtml(std::string file);
|
||||
void loadOtb(const std::string& file);
|
||||
void loadXml(const std::string& file);
|
||||
void parseItemType(uint16 id, TiXmlElement *elem);
|
||||
|
||||
#ifdef WITH_ENCRYPTION
|
||||
void saveDat(std::string fileName);
|
||||
void dumpTextures(std::string dir);
|
||||
void replaceTextures(std::string dir);
|
||||
#endif
|
||||
|
||||
void addItemType(const ItemTypePtr& itemType);
|
||||
const ItemTypePtr& findItemTypeByClientId(uint16 id);
|
||||
const ItemTypePtr& findItemTypeByName(std::string name);
|
||||
ItemTypeList findItemTypesByName(std::string name);
|
||||
ItemTypeList findItemTypesByString(std::string str);
|
||||
|
||||
std::set<int> getMarketCategories()
|
||||
{
|
||||
return m_marketCategories;
|
||||
}
|
||||
|
||||
const ThingTypePtr& getNullThingType() { return m_nullThingType; }
|
||||
const ItemTypePtr& getNullItemType() { return m_nullItemType; }
|
||||
|
||||
const ThingTypePtr& getThingType(uint16 id, ThingCategory category);
|
||||
const ItemTypePtr& getItemType(uint16 id);
|
||||
ThingType* rawGetThingType(uint16 id, ThingCategory category) {
|
||||
VALIDATE(id < m_thingTypes[category].size());
|
||||
return m_thingTypes[category][id].get();
|
||||
}
|
||||
ItemType* rawGetItemType(uint16 id) {
|
||||
VALIDATE(id < m_itemTypes.size());
|
||||
return m_itemTypes[id].get();
|
||||
}
|
||||
|
||||
ThingTypeList findThingTypeByAttr(ThingAttr attr, ThingCategory category);
|
||||
ItemTypeList findItemTypeByCategory(ItemCategory category);
|
||||
|
||||
const ThingTypeList& getThingTypes(ThingCategory category);
|
||||
const ItemTypeList& getItemTypes() { return m_itemTypes; }
|
||||
|
||||
uint32 getDatSignature() { return m_datSignature; }
|
||||
uint32 getOtbMajorVersion() { return m_otbMajorVersion; }
|
||||
uint32 getOtbMinorVersion() { return m_otbMinorVersion; }
|
||||
uint16 getContentRevision() { return m_contentRevision; }
|
||||
|
||||
bool isDatLoaded() { return m_datLoaded; }
|
||||
bool isXmlLoaded() { return m_xmlLoaded; }
|
||||
bool isOtbLoaded() { return m_otbLoaded; }
|
||||
|
||||
bool isValidDatId(uint16 id, ThingCategory category) { return id >= 1 && id < m_thingTypes[category].size(); }
|
||||
bool isValidOtbId(uint16 id) { return id >= 1 && id < m_itemTypes.size(); }
|
||||
|
||||
private:
|
||||
ThingTypeList m_thingTypes[ThingLastCategory];
|
||||
ItemTypeList m_reverseItemTypes;
|
||||
ItemTypeList m_itemTypes;
|
||||
std::set<int> m_marketCategories;
|
||||
|
||||
ThingTypePtr m_nullThingType;
|
||||
ItemTypePtr m_nullItemType;
|
||||
|
||||
bool m_datLoaded;
|
||||
bool m_xmlLoaded;
|
||||
bool m_otbLoaded;
|
||||
|
||||
uint32 m_otbMinorVersion;
|
||||
uint32 m_otbMajorVersion;
|
||||
uint32 m_datSignature;
|
||||
uint16 m_contentRevision;
|
||||
|
||||
ScheduledEventPtr m_checkEvent;
|
||||
size_t m_checkIndex[ThingLastCategory];
|
||||
};
|
||||
|
||||
extern ThingTypeManager g_things;
|
||||
|
||||
#endif
|
@ -1,792 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tile.h"
|
||||
#include "item.h"
|
||||
#include "thingtypemanager.h"
|
||||
#include "map.h"
|
||||
#include "game.h"
|
||||
#include "localplayer.h"
|
||||
#include "effect.h"
|
||||
#include "protocolgame.h"
|
||||
#include "lightview.h"
|
||||
#include "spritemanager.h"
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
#include <framework/util/extras.h>
|
||||
#include <framework/core/adaptiverenderer.h>
|
||||
|
||||
Tile::Tile(const Position& position) :
|
||||
m_position(position),
|
||||
m_drawElevation(0),
|
||||
m_minimapColor(0),
|
||||
m_flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Tile::drawBottom(const Point& dest, LightView* lightView)
|
||||
{
|
||||
m_topDraws = 0;
|
||||
m_drawElevation = 0;
|
||||
if (m_fill != Color::alpha) {
|
||||
g_drawQueue->addFilledRect(Rect(dest, Otc::TILE_PIXELS, Otc::TILE_PIXELS), m_fill);
|
||||
return;
|
||||
}
|
||||
|
||||
// bottom things
|
||||
for (const ThingPtr& thing : m_things) {
|
||||
if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
|
||||
break;
|
||||
if (thing->isHidden())
|
||||
continue;
|
||||
|
||||
thing->draw(dest - m_drawElevation, true, lightView);
|
||||
m_drawElevation = std::min<uint8_t>(m_drawElevation + thing->getElevation(), Otc::MAX_ELEVATION);
|
||||
}
|
||||
|
||||
// common items, reverse order
|
||||
int redrawPreviousTopW = 0, redrawPreviousTopH = 0;
|
||||
for (auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
|
||||
const ThingPtr& thing = *it;
|
||||
if (thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->isCreature())
|
||||
break;
|
||||
if (thing->isHidden())
|
||||
continue;
|
||||
|
||||
thing->draw(dest - m_drawElevation, true, lightView);
|
||||
m_drawElevation = std::min<uint8_t>(m_drawElevation + thing->getElevation(), Otc::MAX_ELEVATION);
|
||||
|
||||
if (thing->isLyingCorpse()) {
|
||||
redrawPreviousTopW = std::max<int>(thing->getWidth() - 1, redrawPreviousTopW);
|
||||
redrawPreviousTopH = std::max<int>(thing->getHeight() - 1, redrawPreviousTopH);
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = -redrawPreviousTopW; x <= 0; ++x) {
|
||||
for (int y = -redrawPreviousTopH; y <= 0; ++y) {
|
||||
if (x == 0 && y == 0)
|
||||
continue;
|
||||
if(const TilePtr& tile = g_map.getTile(m_position.translated(x, y)))
|
||||
tile->drawTop(dest + Point(x * Otc::TILE_PIXELS, y * Otc::TILE_PIXELS), lightView);
|
||||
}
|
||||
}
|
||||
|
||||
if (lightView && hasTranslucentLight()) {
|
||||
lightView->addLight(dest + Point(16, 16), 215, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Tile::drawTop(const Point& dest, LightView* lightView)
|
||||
{
|
||||
if (m_fill != Color::alpha)
|
||||
return;
|
||||
if (m_topDraws++ < m_topCorrection)
|
||||
return;
|
||||
|
||||
// walking creatures
|
||||
for (const CreaturePtr& creature : m_walkingCreatures) {
|
||||
if (creature->isHidden())
|
||||
continue;
|
||||
Point creatureDest(dest.x + ((creature->getPrewalkingPosition().x - m_position.x) * Otc::TILE_PIXELS - m_drawElevation),
|
||||
dest.y + ((creature->getPrewalkingPosition().y - m_position.y) * Otc::TILE_PIXELS - m_drawElevation));
|
||||
creature->draw(creatureDest, true, lightView);
|
||||
}
|
||||
|
||||
// creatures
|
||||
std::vector<CreaturePtr> creaturesToDraw;
|
||||
int limit = g_adaptiveRenderer.creaturesLimit();
|
||||
for (auto& thing : m_things) {
|
||||
if (!thing->isCreature() || thing->isHidden())
|
||||
continue;
|
||||
if (limit-- <= 0)
|
||||
break;
|
||||
CreaturePtr creature = thing->static_self_cast<Creature>();
|
||||
if (!creature || creature->isWalking())
|
||||
continue;
|
||||
creature->draw(dest - m_drawElevation, true, lightView);
|
||||
}
|
||||
|
||||
// effects
|
||||
limit = std::min<int>((int)m_effects.size() - 1, g_adaptiveRenderer.effetsLimit());
|
||||
for (int i = limit; i >= 0; --i) {
|
||||
if (m_effects[i]->isHidden())
|
||||
continue;
|
||||
m_effects[i]->draw(dest - m_drawElevation, m_position.x - g_map.getCentralPosition().x, m_position.y - g_map.getCentralPosition().y, true, lightView);
|
||||
}
|
||||
|
||||
// top
|
||||
for (const ThingPtr& thing : m_things) {
|
||||
if (!thing->isOnTop() || thing->isHidden())
|
||||
continue;
|
||||
thing->draw(dest - m_drawElevation, true, lightView);
|
||||
m_drawElevation = std::min<uint8_t>(m_drawElevation + thing->getElevation(), Otc::MAX_ELEVATION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Tile::calculateCorpseCorrection() {
|
||||
m_topCorrection = 0;
|
||||
int redrawPreviousTopW = 0, redrawPreviousTopH = 0;
|
||||
for(auto it = m_things.rbegin(); it != m_things.rend(); ++it) {
|
||||
const ThingPtr& thing = *it;
|
||||
if(!thing->isLyingCorpse()) {
|
||||
continue;
|
||||
}
|
||||
if (thing->isHidden())
|
||||
continue;
|
||||
redrawPreviousTopW = std::max<int>(thing->getWidth() - 1, redrawPreviousTopW);
|
||||
redrawPreviousTopH = std::max<int>(thing->getHeight() - 1, redrawPreviousTopH);
|
||||
}
|
||||
|
||||
for (int x = -redrawPreviousTopW; x <= 0; ++x) {
|
||||
for (int y = -redrawPreviousTopH; y <= 0; ++y) {
|
||||
if (x == 0 && y == 0)
|
||||
continue;
|
||||
if (const TilePtr& tile = g_map.getTile(m_position.translated(x, y)))
|
||||
tile->m_topCorrection += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tile::drawTexts(Point dest)
|
||||
{
|
||||
if (m_timerText && g_clock.millis() < m_timer) {
|
||||
if (m_text && m_text->hasText())
|
||||
dest.y -= 8;
|
||||
m_timerText->setText(stdext::format("%.01f", (m_timer - g_clock.millis()) / 1000.));
|
||||
m_timerText->drawText(dest, Rect(dest.x - 64, dest.y - 64, 128, 128));
|
||||
dest.y += 16;
|
||||
}
|
||||
|
||||
if (m_text && m_text->hasText()) {
|
||||
m_text->drawText(dest, Rect(dest.x - 64, dest.y - 64, 128, 128));
|
||||
}
|
||||
}
|
||||
|
||||
void Tile::clean()
|
||||
{
|
||||
while(!m_things.empty())
|
||||
removeThing(m_things.front());
|
||||
}
|
||||
|
||||
void Tile::addWalkingCreature(const CreaturePtr& creature)
|
||||
{
|
||||
m_walkingCreatures.push_back(creature);
|
||||
}
|
||||
|
||||
void Tile::removeWalkingCreature(const CreaturePtr& creature)
|
||||
{
|
||||
auto it = std::find(m_walkingCreatures.begin(), m_walkingCreatures.end(), creature);
|
||||
if(it != m_walkingCreatures.end())
|
||||
m_walkingCreatures.erase(it);
|
||||
}
|
||||
|
||||
void Tile::addThing(const ThingPtr& thing, int stackPos)
|
||||
{
|
||||
if(!thing)
|
||||
return;
|
||||
|
||||
if(thing->isEffect()) {
|
||||
if(thing->isTopEffect())
|
||||
m_effects.insert(m_effects.begin(), thing->static_self_cast<Effect>());
|
||||
else
|
||||
m_effects.push_back(thing->static_self_cast<Effect>());
|
||||
} else {
|
||||
// priority 854
|
||||
// 0 - ground, --> -->
|
||||
// 1 - ground borders --> -->
|
||||
// 2 - bottom (walls), --> -->
|
||||
// 3 - on top (doors) --> -->
|
||||
// 4 - creatures, from top to bottom <-- -->
|
||||
// 5 - items, from top to bottom <-- <--
|
||||
if(stackPos < 0 || stackPos == 255) {
|
||||
int priority = thing->getStackPriority();
|
||||
|
||||
// -1 or 255 => auto detect position
|
||||
// -2 => append
|
||||
|
||||
bool append;
|
||||
if(stackPos == -2)
|
||||
append = true;
|
||||
else {
|
||||
append = (priority <= 3);
|
||||
|
||||
// newer protocols does not store creatures in reverse order
|
||||
if(g_game.getClientVersion() >= 854 && priority == 4)
|
||||
append = !append;
|
||||
}
|
||||
|
||||
for(stackPos = 0; stackPos < (int)m_things.size(); ++stackPos) {
|
||||
int otherPriority = m_things[stackPos]->getStackPriority();
|
||||
if((append && otherPriority > priority) || (!append && otherPriority >= priority))
|
||||
break;
|
||||
}
|
||||
} else if(stackPos > (int)m_things.size())
|
||||
stackPos = m_things.size();
|
||||
|
||||
m_things.insert(m_things.begin() + stackPos, thing);
|
||||
|
||||
if(m_things.size() > MAX_THINGS)
|
||||
removeThing(m_things[MAX_THINGS]);
|
||||
|
||||
/*
|
||||
// check stack priorities
|
||||
// this code exists to find stackpos bugs faster
|
||||
int lastPriority = 0;
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
int priority = thing->getStackPriority();
|
||||
VALIDATE(lastPriority <= priority);
|
||||
lastPriority = priority;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
thing->setPosition(m_position);
|
||||
thing->onAppear();
|
||||
|
||||
if(thing->isTranslucent())
|
||||
checkTranslucentLight();
|
||||
|
||||
if(g_game.isTileThingLuaCallbackEnabled())
|
||||
callLuaField("onAddThing", thing);
|
||||
}
|
||||
|
||||
bool Tile::removeThing(ThingPtr thing)
|
||||
{
|
||||
if(!thing)
|
||||
return false;
|
||||
|
||||
bool removed = false;
|
||||
|
||||
if(thing->isEffect()) {
|
||||
EffectPtr effect = thing->static_self_cast<Effect>();
|
||||
auto it = std::find(m_effects.begin(), m_effects.end(), effect);
|
||||
if(it != m_effects.end()) {
|
||||
m_effects.erase(it);
|
||||
removed = true;
|
||||
}
|
||||
} else {
|
||||
auto it = std::find(m_things.begin(), m_things.end(), thing);
|
||||
if(it != m_things.end()) {
|
||||
m_things.erase(it);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->isCreature()) {
|
||||
m_lastCreature = thing->getId();
|
||||
}
|
||||
|
||||
thing->onDisappear();
|
||||
|
||||
if(thing->isTranslucent())
|
||||
checkTranslucentLight();
|
||||
|
||||
if (g_game.isTileThingLuaCallbackEnabled() && removed) {
|
||||
callLuaField("onRemoveThing", thing);
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
ThingPtr Tile::getThing(int stackPos)
|
||||
{
|
||||
if(stackPos >= 0 && stackPos < (int)m_things.size())
|
||||
return m_things[stackPos];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EffectPtr Tile::getEffect(uint16 id)
|
||||
{
|
||||
for(const EffectPtr& effect : m_effects)
|
||||
if(effect->getId() == id)
|
||||
return effect;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Tile::hasThing(const ThingPtr& thing)
|
||||
{
|
||||
return std::find(m_things.begin(), m_things.end(), thing) != m_things.end();
|
||||
}
|
||||
|
||||
int Tile::getThingStackPos(const ThingPtr& thing)
|
||||
{
|
||||
for(uint stackpos = 0; stackpos < m_things.size(); ++stackpos)
|
||||
if(thing == m_things[stackpos])
|
||||
return stackpos;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopThing()
|
||||
{
|
||||
if(isEmpty())
|
||||
return nullptr;
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature())
|
||||
return thing;
|
||||
return m_things[m_things.size() - 1];
|
||||
}
|
||||
|
||||
std::vector<ItemPtr> Tile::getItems()
|
||||
{
|
||||
std::vector<ItemPtr> items;
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(!thing->isItem())
|
||||
continue;
|
||||
ItemPtr item = thing->static_self_cast<Item>();
|
||||
items.push_back(item);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
std::vector<CreaturePtr> Tile::getCreatures()
|
||||
{
|
||||
std::vector<CreaturePtr> creatures;
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isCreature())
|
||||
creatures.push_back(thing->static_self_cast<Creature>());
|
||||
}
|
||||
return creatures;
|
||||
}
|
||||
|
||||
ItemPtr Tile::getGround()
|
||||
{
|
||||
ThingPtr firstObject = getThing(0);
|
||||
if(!firstObject)
|
||||
return nullptr;
|
||||
if(firstObject->isGround() && firstObject->isItem())
|
||||
return firstObject->static_self_cast<Item>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Tile::getGroundSpeed()
|
||||
{
|
||||
if (m_speed)
|
||||
return m_speed;
|
||||
int groundSpeed = 100;
|
||||
if(ItemPtr ground = getGround())
|
||||
groundSpeed = ground->getGroundSpeed();
|
||||
return groundSpeed;
|
||||
}
|
||||
|
||||
uint8 Tile::getMinimapColorByte()
|
||||
{
|
||||
uint8 color = 255; // alpha
|
||||
if(m_minimapColor != 0)
|
||||
return m_minimapColor;
|
||||
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())
|
||||
break;
|
||||
uint8 c = thing->getMinimapColor();
|
||||
if(c != 0)
|
||||
color = c;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopLookThing()
|
||||
{
|
||||
if(isEmpty())
|
||||
return nullptr;
|
||||
|
||||
for(uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if(!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()))
|
||||
return thing;
|
||||
}
|
||||
|
||||
return m_things[0];
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopLookThingEx(Point offset)
|
||||
{
|
||||
auto creature = getTopCreatureEx(offset);
|
||||
if (creature)
|
||||
return creature;
|
||||
|
||||
if (isEmpty())
|
||||
return nullptr;
|
||||
|
||||
for (uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()))
|
||||
return thing;
|
||||
}
|
||||
|
||||
return m_things[0];
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopUseThing()
|
||||
{
|
||||
if(isEmpty())
|
||||
return nullptr;
|
||||
|
||||
for(uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (thing->isForceUse() || (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature() && !thing->isSplash()))
|
||||
return thing;
|
||||
}
|
||||
|
||||
for (uint i = m_things.size() - 1; i > 0; --i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (!thing->isSplash() && !thing->isCreature())
|
||||
return thing;
|
||||
}
|
||||
|
||||
return m_things[0];
|
||||
}
|
||||
|
||||
CreaturePtr Tile::getTopCreature()
|
||||
{
|
||||
CreaturePtr creature;
|
||||
for(uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if(thing->isLocalPlayer()) // return local player if there is no other creature
|
||||
creature = thing->static_self_cast<Creature>();
|
||||
else if(thing->isCreature() && !thing->isLocalPlayer())
|
||||
return thing->static_self_cast<Creature>();
|
||||
}
|
||||
if(!creature && !m_walkingCreatures.empty())
|
||||
creature = m_walkingCreatures.back();
|
||||
|
||||
// check for walking creatures in tiles around
|
||||
if(!creature) {
|
||||
for(int xi=-1;xi<=1;++xi) {
|
||||
for(int yi=-1;yi<=1;++yi) {
|
||||
Position pos = m_position.translated(xi, yi);
|
||||
if(pos == m_position)
|
||||
continue;
|
||||
|
||||
const TilePtr& tile = g_map.getTile(pos);
|
||||
if(tile) {
|
||||
for(const CreaturePtr& c : tile->getCreatures()) {
|
||||
if(c->isWalking() && c->getLastStepFromPosition() == m_position && c->getStepProgress() < 0.75f) {
|
||||
creature = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return creature;
|
||||
}
|
||||
|
||||
CreaturePtr Tile::getTopCreatureEx(Point offset)
|
||||
{
|
||||
// hidden
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopMoveThing()
|
||||
{
|
||||
if(isEmpty())
|
||||
return nullptr;
|
||||
|
||||
for(uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()) {
|
||||
if(i > 0 && thing->isNotMoveable())
|
||||
return m_things[i-1];
|
||||
return thing;
|
||||
}
|
||||
}
|
||||
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isCreature())
|
||||
return thing;
|
||||
}
|
||||
|
||||
return m_things[0];
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopMultiUseThing()
|
||||
{
|
||||
if (isEmpty())
|
||||
return nullptr;
|
||||
|
||||
if (CreaturePtr topCreature = getTopCreature())
|
||||
return topCreature;
|
||||
|
||||
for (uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (thing->isForceUse())
|
||||
return thing;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()) {
|
||||
if (i > 0 && thing->isSplash())
|
||||
return m_things[i - 1];
|
||||
return thing;
|
||||
}
|
||||
}
|
||||
|
||||
return m_things.back();
|
||||
}
|
||||
|
||||
ThingPtr Tile::getTopMultiUseThingEx(Point offset)
|
||||
{
|
||||
if (CreaturePtr topCreature = getTopCreatureEx(offset))
|
||||
return topCreature;
|
||||
|
||||
if (isEmpty())
|
||||
return nullptr;
|
||||
|
||||
for (uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (thing->isForceUse() && !thing->isCreature())
|
||||
return thing;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < m_things.size(); ++i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()) {
|
||||
if (i > 0 && thing->isSplash())
|
||||
return m_things[i - 1];
|
||||
return thing;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = m_things.size() - 1; i > 0; --i) {
|
||||
ThingPtr thing = m_things[i];
|
||||
if (!thing->isCreature())
|
||||
return thing;
|
||||
}
|
||||
|
||||
return m_things[0];
|
||||
}
|
||||
|
||||
bool Tile::isWalkable(bool ignoreCreatures)
|
||||
{
|
||||
if(!getGround())
|
||||
return false;
|
||||
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isNotWalkable())
|
||||
return false;
|
||||
|
||||
if(!ignoreCreatures) {
|
||||
if(thing->isCreature()) {
|
||||
CreaturePtr creature = thing->static_self_cast<Creature>();
|
||||
if(!creature->isPassable() && creature->canBeSeen() && !creature->isLocalPlayer())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tile::isPathable()
|
||||
{
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->isNotPathable())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tile::isFullGround()
|
||||
{
|
||||
ItemPtr ground = getGround();
|
||||
if(ground && ground->isFullGround())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::isFullyOpaque()
|
||||
{
|
||||
ThingPtr firstObject = getThing(0);
|
||||
return firstObject && firstObject->isFullGround();
|
||||
}
|
||||
|
||||
bool Tile::isSingleDimension()
|
||||
{
|
||||
if(!m_walkingCreatures.empty())
|
||||
return false;
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->getHeight() != 1 || thing->getWidth() != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tile::isLookPossible()
|
||||
{
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->blockProjectile())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tile::isClickable()
|
||||
{
|
||||
bool hasGround = false;
|
||||
bool hasOnBottom = false;
|
||||
bool hasIgnoreLook = false;
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isGround())
|
||||
hasGround = true;
|
||||
if(thing->isOnBottom())
|
||||
hasOnBottom = true;
|
||||
if((hasGround || hasOnBottom) && !hasIgnoreLook)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::isEmpty()
|
||||
{
|
||||
return m_things.size() == 0;
|
||||
}
|
||||
|
||||
bool Tile::isDrawable()
|
||||
{
|
||||
return !m_things.empty() || !m_walkingCreatures.empty() || !m_effects.empty();
|
||||
}
|
||||
|
||||
bool Tile::mustHookEast()
|
||||
{
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->isHookEast())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::mustHookSouth()
|
||||
{
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->isHookSouth())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::hasCreature()
|
||||
{
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->isCreature())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::hasBlockingCreature()
|
||||
{
|
||||
for (const ThingPtr& thing : m_things)
|
||||
if (thing->isCreature() && !thing->static_self_cast<Creature>()->isPassable() && !thing->isLocalPlayer())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::limitsFloorsView(bool isFreeView)
|
||||
{
|
||||
// ground and walls limits the view
|
||||
ThingPtr firstThing = getThing(0);
|
||||
|
||||
if(isFreeView) {
|
||||
if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || firstThing->isOnBottom()))
|
||||
return true;
|
||||
} else if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || (firstThing->isOnBottom() && firstThing->blockProjectile())))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Tile::canErase()
|
||||
{
|
||||
return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty() && m_flags == 0 && m_minimapColor == 0;
|
||||
}
|
||||
|
||||
int Tile::getElevation()
|
||||
{
|
||||
int elevation = 0;
|
||||
for(const ThingPtr& thing : m_things)
|
||||
if(thing->getElevation() > 0)
|
||||
elevation++;
|
||||
return elevation;
|
||||
}
|
||||
|
||||
bool Tile::hasElevation(int elevation)
|
||||
{
|
||||
return getElevation() >= elevation;
|
||||
}
|
||||
|
||||
void Tile::checkTranslucentLight()
|
||||
{
|
||||
if(m_position.z != Otc::SEA_FLOOR)
|
||||
return;
|
||||
|
||||
Position downPos = m_position;
|
||||
if(!downPos.down())
|
||||
return;
|
||||
|
||||
TilePtr tile = g_map.getOrCreateTile(downPos);
|
||||
if(!tile)
|
||||
return;
|
||||
|
||||
bool translucent = false;
|
||||
for(const ThingPtr& thing : m_things) {
|
||||
if(thing->isTranslucent() || thing->hasLensHelp()) {
|
||||
translucent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(translucent)
|
||||
tile->m_flags |= TILESTATE_TRANSLUECENT_LIGHT;
|
||||
else
|
||||
tile->m_flags &= ~TILESTATE_TRANSLUECENT_LIGHT;
|
||||
}
|
||||
|
||||
void Tile::setText(const std::string& text, Color color)
|
||||
{
|
||||
if (!m_text) {
|
||||
m_text = StaticTextPtr(new StaticText());
|
||||
}
|
||||
m_text->setText(text);
|
||||
m_text->setColor(color);
|
||||
}
|
||||
|
||||
std::string Tile::getText()
|
||||
{
|
||||
return m_text ? m_text->getCachedText().getText() : "";
|
||||
}
|
||||
|
||||
void Tile::setTimer(int time, Color color)
|
||||
{
|
||||
if (time > 60000) {
|
||||
g_logger.warning("Max tile timer value is 300000 (300s)!");
|
||||
return;
|
||||
}
|
||||
m_timer = time + g_clock.millis();
|
||||
if (!m_timerText) {
|
||||
m_timerText = StaticTextPtr(new StaticText());
|
||||
}
|
||||
m_timerText->setColor(color);
|
||||
}
|
||||
|
||||
int Tile::getTimer()
|
||||
{
|
||||
return m_timerText ? std::max<int>(0, m_timer - g_clock.millis()) : 0;
|
||||
}
|
||||
|
||||
void Tile::setFill(Color color)
|
||||
{
|
||||
m_fill = color;
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TILE_H
|
||||
#define TILE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "mapview.h"
|
||||
#include "effect.h"
|
||||
#include "creature.h"
|
||||
#include "item.h"
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include <framework/stdext/time.h>
|
||||
|
||||
enum tileflags_t
|
||||
{
|
||||
TILESTATE_NONE = 0,
|
||||
TILESTATE_PROTECTIONZONE = 1 << 0,
|
||||
TILESTATE_TRASHED = 1 << 1,
|
||||
TILESTATE_OPTIONALZONE = 1 << 2,
|
||||
TILESTATE_NOLOGOUT = 1 << 3,
|
||||
TILESTATE_HARDCOREZONE = 1 << 4,
|
||||
TILESTATE_REFRESH = 1 << 5,
|
||||
|
||||
// internal usage
|
||||
TILESTATE_HOUSE = 1 << 6,
|
||||
TILESTATE_TELEPORT = 1 << 17,
|
||||
TILESTATE_MAGICFIELD = 1 << 18,
|
||||
TILESTATE_MAILBOX = 1 << 19,
|
||||
TILESTATE_TRASHHOLDER = 1 << 20,
|
||||
TILESTATE_BED = 1 << 21,
|
||||
TILESTATE_DEPOT = 1 << 22,
|
||||
TILESTATE_TRANSLUECENT_LIGHT = 1 << 23,
|
||||
|
||||
TILESTATE_LAST = 1 << 24
|
||||
};
|
||||
|
||||
class Tile : public LuaObject
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
MAX_THINGS = 10
|
||||
};
|
||||
|
||||
Tile(const Position& position);
|
||||
|
||||
void calculateCorpseCorrection();
|
||||
|
||||
void drawBottom(const Point& dest, LightView* lightView = nullptr);
|
||||
void drawTop(const Point& dest, LightView* lightView = nullptr);
|
||||
void drawTexts(Point dest);
|
||||
|
||||
public:
|
||||
void clean();
|
||||
|
||||
void addWalkingCreature(const CreaturePtr& creature);
|
||||
void removeWalkingCreature(const CreaturePtr& creature);
|
||||
|
||||
void addThing(const ThingPtr& thing, int stackPos);
|
||||
bool removeThing(ThingPtr thing);
|
||||
ThingPtr getThing(int stackPos);
|
||||
EffectPtr getEffect(uint16 id);
|
||||
bool hasThing(const ThingPtr& thing);
|
||||
int getThingStackPos(const ThingPtr& thing);
|
||||
ThingPtr getTopThing();
|
||||
|
||||
ThingPtr getTopLookThing();
|
||||
ThingPtr getTopLookThingEx(Point offset);
|
||||
ThingPtr getTopUseThing();
|
||||
CreaturePtr getTopCreature();
|
||||
CreaturePtr getTopCreatureEx(Point offset);
|
||||
ThingPtr getTopMoveThing();
|
||||
ThingPtr getTopMultiUseThing();
|
||||
ThingPtr getTopMultiUseThingEx(Point offset);
|
||||
|
||||
const Position& getPosition() { return m_position; }
|
||||
int getDrawElevation() { return m_drawElevation; }
|
||||
std::vector<ItemPtr> getItems();
|
||||
std::vector<CreaturePtr> getCreatures();
|
||||
std::vector<CreaturePtr> getWalkingCreatures() { return m_walkingCreatures; }
|
||||
std::vector<ThingPtr> getThings() { return m_things; }
|
||||
std::vector<EffectPtr> getEffects() { return m_effects; }
|
||||
ItemPtr getGround();
|
||||
int getGroundSpeed();
|
||||
bool isBlocking() { return m_blocking != 0; }
|
||||
uint8 getMinimapColorByte();
|
||||
int getThingCount() { return m_things.size() + m_effects.size(); }
|
||||
bool isPathable();
|
||||
bool isWalkable(bool ignoreCreatures = false);
|
||||
bool isFullGround();
|
||||
bool isFullyOpaque();
|
||||
bool isSingleDimension();
|
||||
bool isLookPossible();
|
||||
bool isClickable();
|
||||
bool isEmpty();
|
||||
bool isDrawable();
|
||||
bool hasTranslucentLight() { return m_flags & TILESTATE_TRANSLUECENT_LIGHT; }
|
||||
bool mustHookSouth();
|
||||
bool mustHookEast();
|
||||
bool hasCreature();
|
||||
bool hasBlockingCreature();
|
||||
bool limitsFloorsView(bool isFreeView = false);
|
||||
bool canErase();
|
||||
int getElevation();
|
||||
bool hasElevation(int elevation = 1);
|
||||
void overwriteMinimapColor(uint8 color) { m_minimapColor = color; }
|
||||
|
||||
void remFlag(uint32 flag) { m_flags &= ~flag; }
|
||||
void setFlag(uint32 flag) { m_flags |= flag; }
|
||||
void setFlags(uint32 flags) { m_flags = flags; }
|
||||
bool hasFlag(uint32 flag) { return (m_flags & flag) == flag; }
|
||||
uint32 getFlags() { return m_flags; }
|
||||
|
||||
void setHouseId(uint32 hid) { m_houseId = hid; }
|
||||
uint32 getHouseId() { return m_houseId; }
|
||||
bool isHouseTile() { return m_houseId != 0 && (m_flags & TILESTATE_HOUSE) == TILESTATE_HOUSE; }
|
||||
|
||||
void select() { m_selected = true; }
|
||||
void unselect() { m_selected = false; }
|
||||
bool isSelected() { return m_selected; }
|
||||
|
||||
TilePtr asTile() { return static_self_cast<Tile>(); }
|
||||
|
||||
void setSpeed(uint16_t speed, uint8_t blocking) {
|
||||
m_speed = speed;
|
||||
m_blocking = blocking;
|
||||
}
|
||||
|
||||
void setText(const std::string& text, Color color);
|
||||
std::string getText();
|
||||
void setTimer(int time, Color color);
|
||||
int getTimer();
|
||||
void setFill(Color color);
|
||||
void resetFill() { m_fill = Color::alpha; }
|
||||
|
||||
private:
|
||||
void checkTranslucentLight();
|
||||
|
||||
std::vector<CreaturePtr> m_walkingCreatures;
|
||||
std::vector<EffectPtr> m_effects; // leave this outside m_things because it has no stackpos.
|
||||
std::vector<ThingPtr> m_things;
|
||||
Position m_position;
|
||||
uint8 m_drawElevation;
|
||||
uint8 m_minimapColor;
|
||||
uint32 m_flags, m_houseId;
|
||||
uint16 m_speed = 0;
|
||||
uint8 m_blocking = 0;
|
||||
|
||||
uint32_t m_lastCreature = 0;
|
||||
int m_topCorrection = 0;
|
||||
int m_topDraws = 0;
|
||||
|
||||
stdext::boolean<false> m_selected;
|
||||
|
||||
ticks_t m_timer = 0;
|
||||
StaticTextPtr m_timerText;
|
||||
StaticTextPtr m_text;
|
||||
Color m_fill = Color::alpha;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "towns.h"
|
||||
|
||||
TownManager g_towns;
|
||||
|
||||
Town::Town(uint32 tid, const std::string& name, const Position& pos)
|
||||
: m_id(tid), m_name(name)
|
||||
{
|
||||
if(pos.isValid())
|
||||
m_pos = pos;
|
||||
}
|
||||
|
||||
TownManager::TownManager()
|
||||
{
|
||||
m_nullTown = TownPtr(new Town);
|
||||
}
|
||||
|
||||
void TownManager::addTown(const TownPtr &town)
|
||||
{
|
||||
if(findTown(town->getId()) == m_towns.end())
|
||||
m_towns.push_back(town);
|
||||
}
|
||||
|
||||
void TownManager::removeTown(uint32 townId)
|
||||
{
|
||||
auto it = findTown(townId);
|
||||
if(it != m_towns.end())
|
||||
m_towns.erase(it);
|
||||
}
|
||||
|
||||
const TownPtr& TownManager::getTown(uint32 townId)
|
||||
{
|
||||
auto it = std::find_if(m_towns.begin(), m_towns.end(),
|
||||
[=] (const TownPtr& town) -> bool { return town->getId() == townId; });
|
||||
if(it != m_towns.end())
|
||||
return *it;
|
||||
return m_nullTown;
|
||||
}
|
||||
|
||||
const TownPtr& TownManager::getTownByName(std::string name)
|
||||
{
|
||||
auto it = std::find_if(m_towns.begin(), m_towns.end(),
|
||||
[=] (const TownPtr& town) -> bool { return town->getName() == name; } );
|
||||
if(it != m_towns.end())
|
||||
return *it;
|
||||
return m_nullTown;
|
||||
}
|
||||
|
||||
TownList::iterator TownManager::findTown(uint32 townId)
|
||||
{
|
||||
return std::find_if(m_towns.begin(), m_towns.end(),
|
||||
[=] (const TownPtr& town) -> bool { return town->getId() == townId; });
|
||||
}
|
||||
|
||||
void TownManager::sort()
|
||||
{
|
||||
m_towns.sort([] (const TownPtr& lhs, const TownPtr& rhs) { return lhs->getName() < rhs->getName(); });
|
||||
}
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TOWNS_H
|
||||
#define TOWNS_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
|
||||
class Town : public LuaObject
|
||||
{
|
||||
public:
|
||||
Town() { }
|
||||
Town(uint32 tid, const std::string& name, const Position& pos=Position());
|
||||
|
||||
void setId(uint32 tid) { m_id = tid; }
|
||||
void setName(const std::string& name) { m_name = name; }
|
||||
void setPos(const Position& pos) { m_pos = pos; }
|
||||
|
||||
uint32 getId() { return m_id; }
|
||||
std::string getName() { return m_name; }
|
||||
Position getPos() { return m_pos; }
|
||||
|
||||
private:
|
||||
uint32 m_id;
|
||||
std::string m_name;
|
||||
Position m_pos; // temple pos
|
||||
};
|
||||
|
||||
class TownManager
|
||||
{
|
||||
public:
|
||||
TownManager();
|
||||
|
||||
void addTown(const TownPtr& town);
|
||||
void removeTown(uint32 townId);
|
||||
const TownPtr& getTown(uint32 townId);
|
||||
const TownPtr& getTownByName(std::string name);
|
||||
|
||||
void sort();
|
||||
TownList getTowns() { return m_towns; }
|
||||
void clear() { m_towns.clear(); m_nullTown = nullptr; }
|
||||
|
||||
private:
|
||||
TownList m_towns;
|
||||
TownPtr m_nullTown;
|
||||
|
||||
protected:
|
||||
TownList::iterator findTown(uint32 townId);
|
||||
};
|
||||
|
||||
extern TownManager g_towns;
|
||||
|
||||
#endif
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uicreature.h"
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/drawqueue.h>
|
||||
|
||||
void UICreature::drawSelf(Fw::DrawPane drawPane)
|
||||
{
|
||||
if(drawPane != Fw::ForegroundPane)
|
||||
return;
|
||||
|
||||
UIWidget::drawSelf(drawPane);
|
||||
|
||||
if(m_creature) {
|
||||
if (m_autoRotating) {
|
||||
auto ticks = (g_clock.millis() % 4000) / 4;
|
||||
Otc::Direction new_dir;
|
||||
if (ticks < 250)
|
||||
{
|
||||
new_dir = Otc::South;
|
||||
}
|
||||
else if (ticks < 500)
|
||||
{
|
||||
new_dir = Otc::East;
|
||||
}
|
||||
else if (ticks < 750)
|
||||
{
|
||||
new_dir = Otc::North;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_dir = Otc::West;
|
||||
}
|
||||
if (new_dir != m_direction) {
|
||||
m_direction = new_dir;
|
||||
m_redraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_creature->getOutfitNumber() != m_outfitNumber) {
|
||||
m_outfitNumber = m_creature->getOutfitNumber();
|
||||
m_redraw = true;
|
||||
}
|
||||
|
||||
m_creature->drawOutfit(getPaddingRect(), m_direction, m_imageColor);
|
||||
}
|
||||
}
|
||||
|
||||
void UICreature::setOutfit(const Outfit& outfit)
|
||||
{
|
||||
if(!m_creature)
|
||||
m_creature = CreaturePtr(new Creature);
|
||||
m_direction = Otc::South;
|
||||
m_creature->setOutfit(outfit);
|
||||
m_redraw = true;
|
||||
}
|
||||
|
||||
void UICreature::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "fixed-creature-size")
|
||||
setFixedCreatureSize(node->value<bool>());
|
||||
else if(node->tag() == "outfit-id") {
|
||||
Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit());
|
||||
outfit.setId(node->value<int>());
|
||||
setOutfit(outfit);
|
||||
}
|
||||
else if(node->tag() == "outfit-head") {
|
||||
Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit());
|
||||
outfit.setHead(node->value<int>());
|
||||
setOutfit(outfit);
|
||||
}
|
||||
else if(node->tag() == "outfit-body") {
|
||||
Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit());
|
||||
outfit.setBody(node->value<int>());
|
||||
setOutfit(outfit);
|
||||
}
|
||||
else if(node->tag() == "outfit-legs") {
|
||||
Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit());
|
||||
outfit.setLegs(node->value<int>());
|
||||
setOutfit(outfit);
|
||||
}
|
||||
else if(node->tag() == "outfit-feet") {
|
||||
Outfit outfit = (m_creature ? m_creature->getOutfit() : Outfit());
|
||||
outfit.setFeet(node->value<int>());
|
||||
setOutfit(outfit);
|
||||
}
|
||||
else if (node->tag() == "scale") {
|
||||
setScale(node->value<float>());
|
||||
}
|
||||
else if (node->tag() == "optimized") {
|
||||
setOptimized(node->value<bool>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UICreature::onGeometryChange(const Rect& oldRect, const Rect& newRect)
|
||||
{
|
||||
UIWidget::onGeometryChange(oldRect, newRect);
|
||||
m_redraw = true;
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UICREATURE_H
|
||||
#define UICREATURE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
#include "creature.h"
|
||||
|
||||
class UICreature : public UIWidget
|
||||
{
|
||||
public:
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
void setCreature(const CreaturePtr& creature) { m_creature = creature; m_redraw = true; }
|
||||
void setFixedCreatureSize(bool fixed) { m_scale = fixed ? 1.0 : 0; m_redraw = true; }
|
||||
void setOutfit(const Outfit& outfit);
|
||||
|
||||
CreaturePtr getCreature() { return m_creature; }
|
||||
bool isFixedCreatureSize() { return m_scale > 0; }
|
||||
|
||||
void setAutoRotating(bool value) { m_autoRotating = value; }
|
||||
void setDirection(Otc::Direction direction) { m_direction = direction; m_redraw = true; }
|
||||
|
||||
void setScale(float scale) { m_scale = scale; m_redraw = true; }
|
||||
float getScale() { return m_scale; }
|
||||
|
||||
void setOptimized(bool value) { m_optimized = value; m_redraw = true; }
|
||||
|
||||
protected:
|
||||
void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
void onGeometryChange(const Rect& oldRect, const Rect& newRect) override;
|
||||
|
||||
CreaturePtr m_creature;
|
||||
stdext::boolean<false> m_autoRotating;
|
||||
stdext::boolean<false> m_redraw;
|
||||
int m_outfitNumber = 0;
|
||||
Otc::Direction m_direction = Otc::South;
|
||||
float m_scale = 1.0;
|
||||
bool m_optimized = false;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uiitem.h"
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
|
||||
UIItem::UIItem()
|
||||
{
|
||||
m_draggable = true;
|
||||
}
|
||||
|
||||
void UIItem::drawSelf(Fw::DrawPane drawPane)
|
||||
{
|
||||
if(drawPane != Fw::ForegroundPane)
|
||||
return;
|
||||
// draw style components in order
|
||||
if(m_backgroundColor.aF() > Fw::MIN_ALPHA) {
|
||||
Rect backgroundDestRect = m_rect;
|
||||
backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left);
|
||||
drawBackground(m_rect);
|
||||
}
|
||||
|
||||
drawImage(m_rect);
|
||||
|
||||
if(m_itemVisible && m_item) {
|
||||
Rect drawRect = getPaddingRect();
|
||||
|
||||
int exactSize = std::max<int>(32, m_item->getExactSize());
|
||||
if(exactSize == 0)
|
||||
return;
|
||||
|
||||
m_item->setColor(m_color);
|
||||
m_item->draw(drawRect);
|
||||
|
||||
if(m_font && m_showCount && (m_item->isStackable() || m_item->isChargeable()) && m_item->getCountOrSubType() > 1) {
|
||||
g_drawQueue->addText(m_font, std::to_string(m_item->getCountOrSubType()), Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight, Color(231, 231, 231));
|
||||
}
|
||||
|
||||
if (m_showId) {
|
||||
g_drawQueue->addText(m_font, std::to_string(m_item->getServerId()), m_rect, Fw::AlignBottomRight, Color(231, 231, 231));
|
||||
}
|
||||
}
|
||||
|
||||
drawBorder(m_rect);
|
||||
drawIcon(m_rect);
|
||||
drawText(m_rect);
|
||||
}
|
||||
|
||||
void UIItem::setItemId(int id)
|
||||
{
|
||||
if (!m_item && id != 0)
|
||||
m_item = Item::create(id);
|
||||
else {
|
||||
// remove item
|
||||
if (id == 0)
|
||||
m_item = nullptr;
|
||||
else
|
||||
m_item->setId(id);
|
||||
}
|
||||
|
||||
callLuaField("onItemChange");
|
||||
}
|
||||
|
||||
void UIItem::setItemCount(int count)
|
||||
{
|
||||
if (m_item)
|
||||
m_item->setCount(count);
|
||||
callLuaField("onItemChange");
|
||||
}
|
||||
void UIItem::setItemSubType(int subType)
|
||||
{
|
||||
if (m_item)
|
||||
m_item->setSubType(subType);
|
||||
callLuaField("onItemChange");
|
||||
}
|
||||
|
||||
void UIItem::setItem(const ItemPtr& item)
|
||||
{
|
||||
m_item = item;
|
||||
callLuaField("onItemChange");
|
||||
}
|
||||
|
||||
void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "item-id")
|
||||
setItemId(node->value<int>());
|
||||
else if(node->tag() == "item-count")
|
||||
setItemCount(node->value<int>());
|
||||
else if(node->tag() == "item-visible")
|
||||
setItemVisible(node->value<bool>());
|
||||
else if(node->tag() == "virtual")
|
||||
setVirtual(node->value<bool>());
|
||||
else if(node->tag() == "show-id")
|
||||
m_showId = node->value<bool>();
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UIITEM_H
|
||||
#define UIITEM_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
#include "item.h"
|
||||
|
||||
class UIItem : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIItem();
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
void setItemId(int id);
|
||||
void setItemCount(int count);
|
||||
void setItemSubType(int subType);
|
||||
void setItemVisible(bool visible) { m_itemVisible = visible; }
|
||||
void setItem(const ItemPtr& item);
|
||||
void setVirtual(bool virt) { m_virtual = virt; }
|
||||
void clearItem() { setItemId(0); }
|
||||
void setShowCount(bool value) { m_showCount = value; }
|
||||
|
||||
int getItemId() { return m_item ? m_item->getId() : 0; }
|
||||
int getItemCount() { return m_item ? m_item->getCount() : 0; }
|
||||
int getItemSubType() { return m_item ? m_item->getSubType() : 0; }
|
||||
int getItemCountOrSubType() { return m_item ? m_item->getCountOrSubType() : 0; }
|
||||
ItemPtr getItem() { return m_item; }
|
||||
bool isVirtual() { return m_virtual; }
|
||||
bool isItemVisible() { return m_itemVisible; }
|
||||
|
||||
protected:
|
||||
void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
|
||||
ItemPtr m_item;
|
||||
stdext::boolean<false> m_virtual;
|
||||
stdext::boolean<true> m_itemVisible;
|
||||
stdext::boolean<false> m_showId;
|
||||
stdext::boolean<true> m_showCount;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uimap.h"
|
||||
#include "game.h"
|
||||
#include "map.h"
|
||||
#include "mapview.h"
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/util/extras.h>
|
||||
#include "localplayer.h"
|
||||
|
||||
UIMap::UIMap()
|
||||
{
|
||||
m_draggable = true;
|
||||
m_mapView = MapViewPtr(new MapView);
|
||||
m_zoom = m_mapView->getVisibleDimension().height();
|
||||
m_keepAspectRatio = true;
|
||||
m_limitVisibleRange = false;
|
||||
m_aspectRatio = m_mapView->getVisibleDimension().ratio();
|
||||
m_maxZoomIn = 3;
|
||||
m_maxZoomOut = 513;
|
||||
m_mapRect.resize(1,1);
|
||||
g_map.addMapView(m_mapView);
|
||||
}
|
||||
|
||||
UIMap::~UIMap()
|
||||
{
|
||||
g_map.removeMapView(m_mapView);
|
||||
}
|
||||
|
||||
bool UIMap::onMouseMove(const Point& mousePos, const Point& mouseMoved)
|
||||
{
|
||||
m_mousePosition = mousePos;
|
||||
return UIWidget::onMouseMove(mousePos, mouseMoved);
|
||||
}
|
||||
|
||||
void UIMap::drawSelf(Fw::DrawPane drawPane)
|
||||
{
|
||||
UIWidget::drawSelf(drawPane);
|
||||
|
||||
if(drawPane == Fw::ForegroundPane) {
|
||||
g_drawQueue->addBoundingRect(m_mapRect.expanded(1), 1, Color::black);
|
||||
g_drawQueue->markMapPosition();
|
||||
} else if(drawPane == Fw::MapBackgroundPane) {
|
||||
m_mapView->drawBackground(m_mapRect, getTile(m_mousePosition));
|
||||
} else if (drawPane == Fw::MapForegroundPane) {
|
||||
m_mapView->drawForeground(m_mapRect);
|
||||
}
|
||||
}
|
||||
|
||||
void UIMap::movePixels(int x, int y)
|
||||
{
|
||||
m_mapView->move(x, y);
|
||||
}
|
||||
|
||||
bool UIMap::setZoom(int zoom)
|
||||
{
|
||||
m_zoom = stdext::clamp<int>(zoom, m_maxZoomIn, m_maxZoomOut);
|
||||
updateVisibleDimension();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UIMap::zoomIn()
|
||||
{
|
||||
int delta = 2;
|
||||
if(m_zoom - delta < m_maxZoomIn)
|
||||
delta--;
|
||||
|
||||
if(m_zoom - delta < m_maxZoomIn)
|
||||
return false;
|
||||
|
||||
m_zoom -= delta;
|
||||
updateVisibleDimension();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UIMap::zoomOut()
|
||||
{
|
||||
int delta = 2;
|
||||
if(m_zoom + delta > m_maxZoomOut)
|
||||
delta--;
|
||||
|
||||
if(m_zoom + delta > m_maxZoomOut)
|
||||
return false;
|
||||
|
||||
m_zoom += 2;
|
||||
updateVisibleDimension();
|
||||
return true;
|
||||
}
|
||||
|
||||
void UIMap::setVisibleDimension(const Size& visibleDimension)
|
||||
{
|
||||
m_mapView->setVisibleDimension(visibleDimension);
|
||||
m_aspectRatio = visibleDimension.ratio();
|
||||
|
||||
if(m_keepAspectRatio)
|
||||
updateMapSize();
|
||||
}
|
||||
|
||||
void UIMap::setKeepAspectRatio(bool enable)
|
||||
{
|
||||
m_keepAspectRatio = enable;
|
||||
if(enable)
|
||||
m_aspectRatio = getVisibleDimension().ratio();
|
||||
updateMapSize();
|
||||
}
|
||||
|
||||
Position UIMap::getPosition(const Point& mousePos)
|
||||
{
|
||||
if (!m_mapRect.contains(mousePos))
|
||||
return Position();
|
||||
|
||||
Point relativeMousePos = mousePos - m_mapRect.topLeft();
|
||||
return m_mapView->getPosition(relativeMousePos, m_mapRect.size());
|
||||
}
|
||||
|
||||
Point UIMap::getPositionOffset(const Point& mousePos)
|
||||
{
|
||||
if (!m_mapRect.contains(mousePos))
|
||||
return Point(0, 0);
|
||||
|
||||
Point relativeMousePos = mousePos - m_mapRect.topLeft();
|
||||
return m_mapView->getPositionOffset(relativeMousePos, m_mapRect.size());
|
||||
}
|
||||
|
||||
TilePtr UIMap::getTile(const Point& mousePos)
|
||||
{
|
||||
Position tilePos = getPosition(mousePos);
|
||||
if(!tilePos.isValid())
|
||||
return nullptr;
|
||||
|
||||
// we must check every floor, from top to bottom to check for a clickable tile
|
||||
TilePtr tile;
|
||||
tilePos.coveredUp(tilePos.z - m_mapView->getCachedFirstVisibleFloor());
|
||||
for(int i = m_mapView->getCachedFirstVisibleFloor(); i <= m_mapView->getCachedLastVisibleFloor(); i++) {
|
||||
tile = g_map.getTile(tilePos);
|
||||
if(tile && tile->isClickable())
|
||||
break;
|
||||
tilePos.coveredDown();
|
||||
}
|
||||
|
||||
if(!tile || !tile->isClickable())
|
||||
return nullptr;
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
void UIMap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "multifloor")
|
||||
setMultifloor(node->value<bool>());
|
||||
else if(node->tag() == "draw-texts")
|
||||
setDrawTexts(node->value<bool>());
|
||||
else if(node->tag() == "draw-lights")
|
||||
setDrawLights(node->value<bool>());
|
||||
else if(node->tag() == "animated")
|
||||
setAnimated(node->value<bool>());
|
||||
}
|
||||
}
|
||||
|
||||
void UIMap::onGeometryChange(const Rect& oldRect, const Rect& newRect)
|
||||
{
|
||||
UIWidget::onGeometryChange(oldRect, newRect);
|
||||
updateMapSize();
|
||||
}
|
||||
|
||||
void UIMap::updateVisibleDimension()
|
||||
{
|
||||
int dimensionHeight = m_zoom;
|
||||
|
||||
float ratio = m_aspectRatio;
|
||||
if(!m_limitVisibleRange && !m_mapRect.isEmpty() && !m_keepAspectRatio)
|
||||
ratio = m_mapRect.size().ratio();
|
||||
|
||||
if(dimensionHeight % 2 == 0)
|
||||
dimensionHeight += 1;
|
||||
int dimensionWidth = m_zoom * ratio;
|
||||
if(dimensionWidth % 2 == 0)
|
||||
dimensionWidth += 1;
|
||||
|
||||
m_mapView->setVisibleDimension(Size(dimensionWidth, dimensionHeight));
|
||||
|
||||
if(m_keepAspectRatio)
|
||||
updateMapSize();
|
||||
|
||||
callLuaField("onVisibleDimensionChange", dimensionWidth, dimensionHeight);
|
||||
}
|
||||
|
||||
void UIMap::updateMapSize()
|
||||
{
|
||||
Rect clippingRect = getPaddingRect();
|
||||
Size mapSize;
|
||||
if(m_keepAspectRatio) {
|
||||
Rect mapRect = clippingRect.expanded(-1);
|
||||
mapSize = Size(m_aspectRatio*m_zoom, m_zoom);
|
||||
mapSize.scale(mapRect.size(), Fw::KeepAspectRatio);
|
||||
} else {
|
||||
mapSize = clippingRect.expanded(-1).size();
|
||||
}
|
||||
|
||||
m_mapRect.resize(mapSize);
|
||||
m_mapRect.moveCenter(clippingRect.center());
|
||||
m_mapView->optimizeForSize(mapSize);
|
||||
|
||||
if(!m_keepAspectRatio)
|
||||
updateVisibleDimension();
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et: */
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UIMAP_H
|
||||
#define UIMAP_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
#include "tile.h"
|
||||
|
||||
#include "mapview.h"
|
||||
|
||||
class UIMap : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIMap();
|
||||
~UIMap();
|
||||
|
||||
bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
|
||||
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
void movePixels(int x, int y);
|
||||
bool setZoom(int zoom);
|
||||
bool zoomIn();
|
||||
bool zoomOut();
|
||||
void followCreature(const CreaturePtr& creature) { m_mapView->followCreature(creature); }
|
||||
|
||||
void setCameraPosition(const Position& pos) { m_mapView->setCameraPosition(pos); }
|
||||
void setMaxZoomIn(int maxZoomIn) { m_maxZoomIn = maxZoomIn; }
|
||||
void setMaxZoomOut(int maxZoomOut) { m_maxZoomOut = maxZoomOut; }
|
||||
void setMultifloor(bool enable) { m_mapView->setMultifloor(enable); }
|
||||
void lockVisibleFloor(int floor) { m_mapView->lockFirstVisibleFloor(floor); }
|
||||
void unlockVisibleFloor() { m_mapView->unlockFirstVisibleFloor(); }
|
||||
void setVisibleDimension(const Size& visibleDimension);
|
||||
void setDrawFlags(Otc::DrawFlags drawFlags) { m_mapView->setDrawFlags(drawFlags); }
|
||||
void setDrawTexts(bool enable) { m_mapView->setDrawTexts(enable); }
|
||||
void setDrawNames(bool enable) { m_mapView->setDrawNames(enable); }
|
||||
void setDrawHealthBars(bool enable) { m_mapView->setDrawHealthBars(enable); }
|
||||
void setDrawHealthBarsOnTop(bool enable) { m_mapView->setDrawHealthBarsOnTop(enable); }
|
||||
void setDrawLights(bool enable) { m_mapView->setDrawLights(enable); }
|
||||
void setDrawManaBar(bool enable) { m_mapView->setDrawManaBar(enable); }
|
||||
void setDrawPlayerBars(bool enable) { m_mapView->setDrawPlayerBars(enable); }
|
||||
void setAnimated(bool enable) { m_mapView->setAnimated(enable); }
|
||||
void setKeepAspectRatio(bool enable);
|
||||
void setMinimumAmbientLight(float intensity) { m_mapView->setMinimumAmbientLight(intensity); }
|
||||
void setLimitVisibleRange(bool limitVisibleRange) { m_limitVisibleRange = limitVisibleRange; updateVisibleDimension(); }
|
||||
void setFloorFading(int value) { m_mapView->setFloorFading(value); }
|
||||
void setCrosshair(const std::string& type) { m_mapView->setCrosshair(type); }
|
||||
bool isMultifloor() { return m_mapView->isMultifloor(); }
|
||||
bool isDrawingTexts() { return m_mapView->isDrawingTexts(); }
|
||||
bool isDrawingNames() { return m_mapView->isDrawingNames(); }
|
||||
bool isDrawingHealthBars() { return m_mapView->isDrawingHealthBars(); }
|
||||
bool isDrawingHealthBarsOnTop() { return m_mapView->isDrawingHealthBarsOnTop(); }
|
||||
bool isDrawingLights() { return m_mapView->isDrawingLights(); }
|
||||
bool isDrawingManaBar() { return m_mapView->isDrawingManaBar(); }
|
||||
bool isAnimating() { return m_mapView->isAnimating(); }
|
||||
bool isKeepAspectRatioEnabled() { return m_keepAspectRatio; }
|
||||
bool isLimitVisibleRangeEnabled() { return m_limitVisibleRange; }
|
||||
|
||||
Size getVisibleDimension() { return m_mapView->getVisibleDimension(); }
|
||||
CreaturePtr getFollowingCreature() { return m_mapView->getFollowingCreature(); }
|
||||
Otc::DrawFlags getDrawFlags() { return m_mapView->getDrawFlags(); }
|
||||
Position getCameraPosition() { return m_mapView->getCameraPosition(); }
|
||||
Position getPosition(const Point& mousePos);
|
||||
Point getPositionOffset(const Point& mousePos);
|
||||
TilePtr getTile(const Point& mousePos);
|
||||
int getMaxZoomIn() { return m_maxZoomIn; }
|
||||
int getMaxZoomOut() { return m_maxZoomOut; }
|
||||
int getZoom() { return m_zoom; }
|
||||
float getMinimumAmbientLight() { return m_mapView->getMinimumAmbientLight(); }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect);
|
||||
|
||||
private:
|
||||
void updateVisibleDimension();
|
||||
void updateMapSize();
|
||||
|
||||
int m_zoom;
|
||||
MapViewPtr m_mapView;
|
||||
Rect m_mapRect;
|
||||
Point m_mousePosition;
|
||||
float m_aspectRatio;
|
||||
bool m_keepAspectRatio;
|
||||
bool m_limitVisibleRange;
|
||||
int m_maxZoomIn;
|
||||
int m_maxZoomOut;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "declarations.h"
|
||||
#include "uimapanchorlayout.h"
|
||||
#include "uiminimap.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
|
||||
int UIPositionAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget)
|
||||
{
|
||||
UIMinimapPtr minimap = hookedWidget->static_self_cast<UIMinimap>();
|
||||
Rect hookedRect = minimap->getTileRect(m_hookedPosition);
|
||||
int point = 0;
|
||||
if(hookedRect.isValid()) {
|
||||
switch(m_hookedEdge) {
|
||||
case Fw::AnchorLeft:
|
||||
point = hookedRect.left();
|
||||
break;
|
||||
case Fw::AnchorRight:
|
||||
point = hookedRect.right();
|
||||
break;
|
||||
case Fw::AnchorTop:
|
||||
point = hookedRect.top();
|
||||
break;
|
||||
case Fw::AnchorBottom:
|
||||
point = hookedRect.bottom();
|
||||
break;
|
||||
case Fw::AnchorHorizontalCenter:
|
||||
point = hookedRect.horizontalCenter();
|
||||
break;
|
||||
case Fw::AnchorVerticalCenter:
|
||||
point = hookedRect.verticalCenter();
|
||||
break;
|
||||
default:
|
||||
// must never happens
|
||||
VALIDATE(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
void UIMapAnchorLayout::addPositionAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge)
|
||||
{
|
||||
if(!anchoredWidget)
|
||||
return;
|
||||
|
||||
VALIDATE(anchoredWidget != getParentWidget());
|
||||
|
||||
UIPositionAnchorPtr anchor(new UIPositionAnchor(anchoredEdge, hookedPosition, hookedEdge));
|
||||
UIAnchorGroupPtr& anchorGroup = m_anchorsGroups[anchoredWidget];
|
||||
if(!anchorGroup)
|
||||
anchorGroup = UIAnchorGroupPtr(new UIAnchorGroup);
|
||||
|
||||
anchorGroup->addAnchor(anchor);
|
||||
|
||||
// layout must be updated because a new anchor got in
|
||||
update();
|
||||
}
|
||||
|
||||
void UIMapAnchorLayout::centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||
{
|
||||
addPositionAnchor(anchoredWidget, Fw::AnchorHorizontalCenter, hookedPosition, Fw::AnchorHorizontalCenter);
|
||||
addPositionAnchor(anchoredWidget, Fw::AnchorVerticalCenter, hookedPosition, Fw::AnchorVerticalCenter);
|
||||
}
|
||||
|
||||
void UIMapAnchorLayout::fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||
{
|
||||
addPositionAnchor(anchoredWidget, Fw::AnchorLeft, hookedPosition, Fw::AnchorLeft);
|
||||
addPositionAnchor(anchoredWidget, Fw::AnchorRight, hookedPosition, Fw::AnchorRight);
|
||||
addPositionAnchor(anchoredWidget, Fw::AnchorTop, hookedPosition, Fw::AnchorTop);
|
||||
addPositionAnchor(anchoredWidget, Fw::AnchorBottom, hookedPosition, Fw::AnchorBottom);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UIMAPANCHORLAYOUT_H
|
||||
#define UIMAPANCHORLAYOUT_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uianchorlayout.h>
|
||||
|
||||
class UIPositionAnchor : public UIAnchor
|
||||
{
|
||||
public:
|
||||
UIPositionAnchor(Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge) :
|
||||
UIAnchor(anchoredEdge, std::string(), hookedEdge), m_hookedPosition(hookedPosition) { }
|
||||
|
||||
UIWidgetPtr getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget) { return parentWidget; }
|
||||
int getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget);
|
||||
|
||||
private:
|
||||
Position m_hookedPosition;
|
||||
};
|
||||
|
||||
class UIMapAnchorLayout : public UIAnchorLayout
|
||||
{
|
||||
public:
|
||||
UIMapAnchorLayout(UIWidgetPtr parentWidget) : UIAnchorLayout(parentWidget) { }
|
||||
|
||||
void addPositionAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge,
|
||||
const Position& hookedPosition, Fw::AnchorEdge hookedEdge);
|
||||
void centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||
void fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif
|
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uiminimap.h"
|
||||
#include "minimap.h"
|
||||
#include "game.h"
|
||||
#include "uimapanchorlayout.h"
|
||||
#include "luavaluecasts_client.h"
|
||||
|
||||
#include <framework/graphics/painter.h>
|
||||
#include "uimapanchorlayout.h"
|
||||
|
||||
UIMinimap::UIMinimap()
|
||||
{
|
||||
m_zoom = 0;
|
||||
m_scale = 1.0f;
|
||||
m_minZoom = -5;
|
||||
m_maxZoom = 5;
|
||||
m_layout = UIMapAnchorLayoutPtr(new UIMapAnchorLayout(static_self_cast<UIWidget>()));
|
||||
}
|
||||
|
||||
void UIMinimap::drawSelf(Fw::DrawPane drawPane)
|
||||
{
|
||||
UIWidget::drawSelf(drawPane);
|
||||
|
||||
if(drawPane != Fw::ForegroundPane)
|
||||
return;
|
||||
|
||||
g_minimap.draw(getPaddingRect(), getCameraPosition(), m_scale, m_color);
|
||||
}
|
||||
|
||||
bool UIMinimap::setZoom(int zoom)
|
||||
{
|
||||
if(zoom == m_zoom)
|
||||
return true;
|
||||
|
||||
if(zoom < m_minZoom || zoom > m_maxZoom)
|
||||
return false;
|
||||
|
||||
int oldZoom = m_zoom;
|
||||
m_zoom = zoom;
|
||||
if(m_zoom < 0)
|
||||
m_scale = 1.0f / (1 << std::abs(zoom));
|
||||
else if(m_zoom > 0)
|
||||
m_scale = 1.0f * (1 << std::abs(zoom));
|
||||
else
|
||||
m_scale = 1;
|
||||
m_layout->update();
|
||||
|
||||
onZoomChange(zoom, oldZoom);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UIMinimap::setCameraPosition(const Position& pos)
|
||||
{
|
||||
Position oldPos = m_cameraPosition;
|
||||
m_cameraPosition = pos;
|
||||
m_layout->update();
|
||||
|
||||
onCameraPositionChange(pos, oldPos);
|
||||
}
|
||||
|
||||
bool UIMinimap::floorUp()
|
||||
{
|
||||
Position pos = getCameraPosition();
|
||||
if(!pos.up())
|
||||
return false;
|
||||
setCameraPosition(pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UIMinimap::floorDown()
|
||||
{
|
||||
Position pos = getCameraPosition();
|
||||
if(!pos.down())
|
||||
return false;
|
||||
setCameraPosition(pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
Point UIMinimap::getTilePoint(const Position& pos)
|
||||
{
|
||||
return g_minimap.getTilePoint(pos, getPaddingRect(), getCameraPosition(), m_scale);
|
||||
}
|
||||
|
||||
Rect UIMinimap::getTileRect(const Position& pos)
|
||||
{
|
||||
return g_minimap.getTileRect(pos, getPaddingRect(), getCameraPosition(), m_scale);
|
||||
}
|
||||
|
||||
Position UIMinimap::getTilePosition(const Point& mousePos)
|
||||
{
|
||||
return g_minimap.getTilePosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale);
|
||||
}
|
||||
|
||||
void UIMinimap::anchorPosition(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge)
|
||||
{
|
||||
UIMapAnchorLayoutPtr layout = m_layout->static_self_cast<UIMapAnchorLayout>();
|
||||
VALIDATE(layout);
|
||||
layout->addPositionAnchor(anchoredWidget, anchoredEdge, hookedPosition, hookedEdge);
|
||||
}
|
||||
|
||||
void UIMinimap::fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||
{
|
||||
UIMapAnchorLayoutPtr layout = m_layout->static_self_cast<UIMapAnchorLayout>();
|
||||
VALIDATE(layout);
|
||||
layout->fillPosition(anchoredWidget, hookedPosition);
|
||||
}
|
||||
|
||||
void UIMinimap::centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||
{
|
||||
UIMapAnchorLayoutPtr layout = m_layout->static_self_cast<UIMapAnchorLayout>();
|
||||
VALIDATE(layout);
|
||||
layout->centerInPosition(anchoredWidget, hookedPosition);
|
||||
}
|
||||
|
||||
void UIMinimap::onZoomChange(int zoom, int oldZoom)
|
||||
{
|
||||
callLuaField("onZoomChange", zoom, oldZoom);
|
||||
}
|
||||
|
||||
void UIMinimap::onCameraPositionChange(const Position& position, const Position& oldPosition)
|
||||
{
|
||||
callLuaField("onCameraPositionChange", position, oldPosition);
|
||||
}
|
||||
|
||||
void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "zoom")
|
||||
setZoom(node->value<int>());
|
||||
else if(node->tag() == "max-zoom")
|
||||
setMaxZoom(node->value<int>());
|
||||
else if(node->tag() == "min-zoom")
|
||||
setMinZoom(node->value<int>());
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UIMINIMAP_H
|
||||
#define UIMINIMAP_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
|
||||
class UIMinimap : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIMinimap();
|
||||
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
bool zoomIn() { return setZoom(m_zoom+1); }
|
||||
bool zoomOut() { return setZoom(m_zoom-1); }
|
||||
|
||||
bool setZoom(int zoom);
|
||||
void setMinZoom(int minZoom) { m_minZoom = minZoom; }
|
||||
void setMaxZoom(int maxZoom) { m_maxZoom = maxZoom; }
|
||||
void setCameraPosition(const Position& pos);
|
||||
bool floorUp();
|
||||
bool floorDown();
|
||||
|
||||
Point getTilePoint(const Position& pos);
|
||||
Rect getTileRect(const Position& pos);
|
||||
Position getTilePosition(const Point& mousePos);
|
||||
|
||||
Position getCameraPosition() { return m_cameraPosition; }
|
||||
int getMinZoom() { return m_minZoom; }
|
||||
int getMaxZoom() { return m_maxZoom; }
|
||||
int getZoom() { return m_zoom; }
|
||||
float getScale() { return m_scale; }
|
||||
|
||||
void anchorPosition(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge);
|
||||
void fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||
void centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||
|
||||
protected:
|
||||
virtual void onZoomChange(int zoom, int oldZoom);
|
||||
virtual void onCameraPositionChange(const Position& position, const Position& oldPosition);
|
||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
||||
Rect m_mapArea;
|
||||
Position m_cameraPosition;
|
||||
float m_scale;
|
||||
int m_zoom;
|
||||
int m_minZoom;
|
||||
int m_maxZoom;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uiprogressrect.h"
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
|
||||
UIProgressRect::UIProgressRect()
|
||||
{
|
||||
m_percent = 0;
|
||||
}
|
||||
|
||||
void UIProgressRect::drawSelf(Fw::DrawPane drawPane)
|
||||
{
|
||||
if(drawPane != Fw::ForegroundPane)
|
||||
return;
|
||||
|
||||
// todo: check +1 to right/bottom
|
||||
// todo: add smooth
|
||||
Rect drawRect = getPaddingRect();
|
||||
|
||||
// 0% - 12.5% (12.5)
|
||||
// triangle from top center, to top right (var x)
|
||||
if(m_percent < 12.5) {
|
||||
Point var = Point(std::max<int>(m_percent - 0.0, 0.0) * (drawRect.right() - drawRect.horizontalCenter()) / 12.5, 0);
|
||||
g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.topRight() + Point(1,0), drawRect.topCenter() + var, m_backgroundColor);
|
||||
}
|
||||
|
||||
// 12.5% - 37.5% (25)
|
||||
// triangle from top right to bottom right (var y)
|
||||
if(m_percent < 37.5) {
|
||||
Point var = Point(0, std::max<int>(m_percent - 12.5, 0.0) * (drawRect.bottom() - drawRect.top()) / 25.0);
|
||||
g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.bottomRight() + Point(1,1), drawRect.topRight() + var + Point(1,0), m_backgroundColor);
|
||||
}
|
||||
|
||||
// 37.5% - 62.5% (25)
|
||||
// triangle from bottom right to bottom left (var x)
|
||||
if(m_percent < 62.5) {
|
||||
Point var = Point(std::max<int>(m_percent - 37.5, 0.0) * (drawRect.right() - drawRect.left()) / 25.0, 0);
|
||||
g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.bottomLeft() + Point(0,1), drawRect.bottomRight() - var + Point(1,1), m_backgroundColor);
|
||||
}
|
||||
|
||||
// 62.5% - 87.5% (25)
|
||||
// triangle from bottom left to top left
|
||||
if(m_percent < 87.5) {
|
||||
Point var = Point(0, std::max<int>(m_percent - 62.5, 0.0) * (drawRect.bottom() - drawRect.top()) / 25.0);
|
||||
g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.topLeft(), drawRect.bottomLeft() - var + Point(0,1), m_backgroundColor);
|
||||
}
|
||||
|
||||
// 87.5% - 100% (12.5)
|
||||
// triangle from top left to top center
|
||||
if(m_percent < 100) {
|
||||
Point var = Point(std::max<int>(m_percent - 87.5, 0.0) * (drawRect.horizontalCenter() - drawRect.left()) / 12.5, 0);
|
||||
g_drawQueue->addFilledTriangle(drawRect.center(), drawRect.topCenter(), drawRect.topLeft() + var, m_backgroundColor);
|
||||
}
|
||||
|
||||
drawImage(m_rect);
|
||||
drawBorder(m_rect);
|
||||
drawIcon(m_rect);
|
||||
drawText(m_rect);
|
||||
}
|
||||
|
||||
void UIProgressRect::setPercent(float percent)
|
||||
{
|
||||
m_percent = stdext::clamp<float>((double)percent, 0.0, 100.0);
|
||||
}
|
||||
|
||||
void UIProgressRect::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "percent")
|
||||
setPercent(node->value<float>());
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UIPROGRESSRECT_H
|
||||
#define UIPROGRESSRECT_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
#include "item.h"
|
||||
|
||||
class UIProgressRect : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIProgressRect();
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
void setPercent(float percent);
|
||||
float getPercent() { return m_percent; }
|
||||
|
||||
protected:
|
||||
void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
|
||||
float m_percent;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uisprite.h"
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/texturemanager.h>
|
||||
#include <client/spritemanager.h>
|
||||
|
||||
UISprite::UISprite() :
|
||||
m_spriteId(0),
|
||||
m_spriteColor(Color::white)
|
||||
{ }
|
||||
|
||||
void UISprite::drawSelf(Fw::DrawPane drawPane)
|
||||
{
|
||||
if(drawPane != Fw::ForegroundPane)
|
||||
return;
|
||||
|
||||
// draw style components in order
|
||||
if(m_backgroundColor.aF() > Fw::MIN_ALPHA) {
|
||||
Rect backgroundDestRect = m_rect;
|
||||
backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left);
|
||||
drawBackground(m_rect);
|
||||
}
|
||||
|
||||
drawImage(m_rect);
|
||||
|
||||
if(m_spriteVisible && m_sprite) {
|
||||
g_drawQueue->addTexturedRect(getPaddingRect(), m_sprite, Rect(Point(0, 0), m_sprite->getSize()), m_spriteColor);
|
||||
}
|
||||
|
||||
drawBorder(m_rect);
|
||||
drawIcon(m_rect);
|
||||
drawText(m_rect);
|
||||
}
|
||||
|
||||
void UISprite::setSpriteId(int id)
|
||||
{
|
||||
if(!g_sprites.isLoaded())
|
||||
return;
|
||||
|
||||
m_spriteId = id;
|
||||
if(id == 0)
|
||||
m_sprite = nullptr;
|
||||
else {
|
||||
ImagePtr image = g_sprites.getSpriteImage(id);
|
||||
if(image)
|
||||
m_sprite = new Texture(image);
|
||||
else
|
||||
m_sprite = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void UISprite::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleName, styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "sprite-id")
|
||||
setSpriteId(node->value<int>());
|
||||
else if(node->tag() == "sprite-visible")
|
||||
setSpriteVisible(node->value<bool>());
|
||||
else if(node->tag() == "sprite-color")
|
||||
setSpriteColor(node->value<Color>());
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UISPRITE_H
|
||||
#define UISPRITE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/ui/uiwidget.h>
|
||||
|
||||
class UISprite : public UIWidget
|
||||
{
|
||||
public:
|
||||
UISprite();
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
void setSpriteId(int id);
|
||||
int getSpriteId() { return m_spriteId; }
|
||||
void clearSprite() { setSpriteId(0); }
|
||||
|
||||
void setSpriteColor(Color color) { m_spriteColor = color; }
|
||||
|
||||
bool isSpriteVisible() { return m_spriteVisible; }
|
||||
void setSpriteVisible(bool visible) { m_spriteVisible = visible; }
|
||||
|
||||
bool hasSprite() { return m_sprite != nullptr; }
|
||||
|
||||
protected:
|
||||
void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||
|
||||
TexturePtr m_sprite;
|
||||
uint16 m_spriteId;
|
||||
Color m_spriteColor;
|
||||
|
||||
stdext::boolean<true> m_spriteVisible;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,301 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_CONST_H
|
||||
#define FRAMEWORK_CONST_H
|
||||
|
||||
#include "stdext/compiler.h"
|
||||
|
||||
#define DEG_TO_RAD (acos(-1)/180.0)
|
||||
#define RAD_TO_DEC (180.0/acos(-1))
|
||||
|
||||
#ifndef BUILD_COMMIT
|
||||
#define BUILD_COMMIT "devel"
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_REVISION
|
||||
#define BUILD_REVISION "0"
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_TYPE
|
||||
#define BUILD_TYPE "unknown"
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_ARCH
|
||||
#if defined(__amd64) || defined(_M_X64)
|
||||
#define BUILD_ARCH "x64"
|
||||
#elif defined(__i386) || defined(_M_IX86) || defined(_X86_)
|
||||
#define BUILD_ARCH "x86"
|
||||
#else
|
||||
#define BUILD_ARCH "unknown"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Fw
|
||||
{
|
||||
static const float pi = 3.14159265;
|
||||
static const float MIN_ALPHA = 0.003f;
|
||||
enum Key : unsigned char {
|
||||
KeyUnknown = 0,
|
||||
KeyEscape = 1,
|
||||
KeyTab = 2,
|
||||
KeyBackspace = 3,
|
||||
//KeyReturn = 4,
|
||||
KeyEnter = 5,
|
||||
KeyInsert = 6,
|
||||
KeyDelete = 7,
|
||||
KeyPause = 8,
|
||||
KeyPrintScreen = 9,
|
||||
KeyHome = 10,
|
||||
KeyEnd = 11,
|
||||
KeyPageUp = 12,
|
||||
KeyPageDown = 13,
|
||||
KeyUp = 14,
|
||||
KeyDown = 15,
|
||||
KeyLeft = 16,
|
||||
KeyRight = 17,
|
||||
KeyNumLock = 18,
|
||||
KeyScrollLock = 19,
|
||||
KeyCapsLock = 20,
|
||||
KeyCtrl = 21,
|
||||
KeyShift = 22,
|
||||
KeyAlt = 23,
|
||||
//KeyAltGr = 24,
|
||||
KeyMeta = 25,
|
||||
KeyMenu = 26,
|
||||
KeySpace = 32, // ' '
|
||||
KeyExclamation = 33, // !
|
||||
KeyQuote = 34, // "
|
||||
KeyNumberSign = 35, // #
|
||||
KeyDollar = 36, // $
|
||||
KeyPercent = 37, // %
|
||||
KeyAmpersand = 38, // &
|
||||
KeyApostrophe = 39, // '
|
||||
KeyLeftParen = 40, // (
|
||||
KeyRightParen = 41, // )
|
||||
KeyAsterisk = 42, // *
|
||||
KeyPlus = 43, // +
|
||||
KeyComma = 44, // ,
|
||||
KeyMinus = 45, // -
|
||||
KeyPeriod = 46, // .
|
||||
KeySlash = 47, // /
|
||||
Key0 = 48, // 0
|
||||
Key1 = 49, // 1
|
||||
Key2 = 50, // 2
|
||||
Key3 = 51, // 3
|
||||
Key4 = 52, // 4
|
||||
Key5 = 53, // 5
|
||||
Key6 = 54, // 6
|
||||
Key7 = 55, // 7
|
||||
Key8 = 56, // 8
|
||||
Key9 = 57, // 9
|
||||
KeyColon = 58, // :
|
||||
KeySemicolon = 59, // ;
|
||||
KeyLess = 60, // <
|
||||
KeyEqual = 61, // =
|
||||
KeyGreater = 62, // >
|
||||
KeyQuestion = 63, // ?
|
||||
KeyAtSign = 64, // @
|
||||
KeyA = 65, // a
|
||||
KeyB = 66, // b
|
||||
KeyC = 67, // c
|
||||
KeyD = 68, // d
|
||||
KeyE = 69, // e
|
||||
KeyF = 70, // f
|
||||
KeyG = 71, // g
|
||||
KeyH = 72, // h
|
||||
KeyI = 73, // i
|
||||
KeyJ = 74, // j
|
||||
KeyK = 75, // k
|
||||
KeyL = 76, // l
|
||||
KeyM = 77, // m
|
||||
KeyN = 78, // n
|
||||
KeyO = 79, // o
|
||||
KeyP = 80, // p
|
||||
KeyQ = 81, // q
|
||||
KeyR = 82, // r
|
||||
KeyS = 83, // s
|
||||
KeyT = 84, // t
|
||||
KeyU = 85, // u
|
||||
KeyV = 86, // v
|
||||
KeyW = 87, // w
|
||||
KeyX = 88, // x
|
||||
KeyY = 89, // y
|
||||
KeyZ = 90, // z
|
||||
KeyLeftBracket = 91, // [
|
||||
KeyBackslash = 92, // '\'
|
||||
KeyRightBracket = 93, // ]
|
||||
KeyCaret = 94, // ^
|
||||
KeyUnderscore = 95, // _
|
||||
KeyGrave = 96, // `
|
||||
KeyLeftCurly = 123, // {
|
||||
KeyBar = 124, // |
|
||||
KeyRightCurly = 125, // }
|
||||
KeyTilde = 126, // ~
|
||||
KeyF1 = 128,
|
||||
KeyF2 = 129,
|
||||
KeyF3 = 130,
|
||||
KeyF4 = 131,
|
||||
KeyF5 = 132,
|
||||
KeyF6 = 134,
|
||||
KeyF7 = 135,
|
||||
KeyF8 = 136,
|
||||
KeyF9 = 137,
|
||||
KeyF10 = 138,
|
||||
KeyF11 = 139,
|
||||
KeyF12 = 140,
|
||||
KeyNumpad0 = 141,
|
||||
KeyNumpad1 = 142,
|
||||
KeyNumpad2 = 143,
|
||||
KeyNumpad3 = 144,
|
||||
KeyNumpad4 = 145,
|
||||
KeyNumpad5 = 146,
|
||||
KeyNumpad6 = 147,
|
||||
KeyNumpad7 = 148,
|
||||
KeyNumpad8 = 149,
|
||||
KeyNumpad9 = 150
|
||||
};
|
||||
|
||||
enum LogLevel {
|
||||
LogDebug = 0,
|
||||
LogInfo,
|
||||
LogWarning,
|
||||
LogError,
|
||||
LogFatal
|
||||
};
|
||||
|
||||
enum AspectRatioMode {
|
||||
IgnoreAspectRatio,
|
||||
KeepAspectRatio,
|
||||
KeepAspectRatioByExpanding
|
||||
};
|
||||
|
||||
enum AlignmentFlag {
|
||||
AlignNone = 0,
|
||||
AlignLeft = 1,
|
||||
AlignRight = 2,
|
||||
AlignTop = 4,
|
||||
AlignBottom = 8,
|
||||
AlignHorizontalCenter = 16,
|
||||
AlignVerticalCenter = 32,
|
||||
AlignTopLeft = AlignTop | AlignLeft, // 5
|
||||
AlignTopRight = AlignTop | AlignRight, // 6
|
||||
AlignBottomLeft = AlignBottom | AlignLeft, // 9
|
||||
AlignBottomRight = AlignBottom | AlignRight, // 10
|
||||
AlignLeftCenter = AlignLeft | AlignVerticalCenter, // 33
|
||||
AlignRightCenter = AlignRight | AlignVerticalCenter, // 34
|
||||
AlignTopCenter = AlignTop | AlignHorizontalCenter, // 20
|
||||
AlignBottomCenter = AlignBottom | AlignHorizontalCenter, // 24
|
||||
AlignCenter = AlignVerticalCenter | AlignHorizontalCenter // 48
|
||||
};
|
||||
|
||||
enum AnchorEdge {
|
||||
AnchorNone = 0,
|
||||
AnchorTop,
|
||||
AnchorBottom,
|
||||
AnchorLeft,
|
||||
AnchorRight,
|
||||
AnchorVerticalCenter,
|
||||
AnchorHorizontalCenter
|
||||
};
|
||||
|
||||
enum FocusReason {
|
||||
MouseFocusReason = 0,
|
||||
KeyboardFocusReason,
|
||||
ActiveFocusReason,
|
||||
OtherFocusReason
|
||||
};
|
||||
|
||||
enum AutoFocusPolicy {
|
||||
AutoFocusNone = 0,
|
||||
AutoFocusFirst,
|
||||
AutoFocusLast
|
||||
};
|
||||
|
||||
enum InputEventType {
|
||||
NoInputEvent = 0,
|
||||
KeyTextInputEvent,
|
||||
KeyDownInputEvent,
|
||||
KeyPressInputEvent,
|
||||
KeyUpInputEvent,
|
||||
MousePressInputEvent,
|
||||
MouseReleaseInputEvent,
|
||||
MouseMoveInputEvent,
|
||||
MouseWheelInputEvent
|
||||
};
|
||||
|
||||
enum MouseButton {
|
||||
MouseNoButton = 0,
|
||||
MouseLeftButton,
|
||||
MouseRightButton,
|
||||
MouseMidButton,
|
||||
MouseTouch
|
||||
};
|
||||
|
||||
enum MouseWheelDirection {
|
||||
MouseNoWheel = 0,
|
||||
MouseWheelUp,
|
||||
MouseWheelDown
|
||||
};
|
||||
|
||||
enum KeyboardModifier {
|
||||
KeyboardNoModifier = 0,
|
||||
KeyboardCtrlModifier = 1,
|
||||
KeyboardAltModifier = 2,
|
||||
KeyboardShiftModifier = 4
|
||||
};
|
||||
|
||||
enum WidgetState {
|
||||
InvalidState = -1,
|
||||
DefaultState = 0,
|
||||
ActiveState = 1,
|
||||
FocusState = 2,
|
||||
HoverState = 4,
|
||||
PressedState = 8,
|
||||
DisabledState = 16,
|
||||
CheckedState = 32,
|
||||
OnState = 64,
|
||||
FirstState = 128,
|
||||
MiddleState = 256,
|
||||
LastState = 512,
|
||||
AlternateState = 1024,
|
||||
DraggingState = 2048,
|
||||
HiddenState = 4096,
|
||||
MobileState = 8192,
|
||||
LastWidgetState = 16384
|
||||
};
|
||||
|
||||
enum DrawPane {
|
||||
ForegroundPane = 1,
|
||||
MapBackgroundPane = 2,
|
||||
MapForegroundPane = 3,
|
||||
};
|
||||
|
||||
#ifdef FW_SQL
|
||||
enum DatabaseEngine {
|
||||
DatabaseNone = 0,
|
||||
DatabaseMySQL
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,91 +0,0 @@
|
||||
#include <framework/core/logger.h>
|
||||
#include <framework/core/graphicalapplication.h>
|
||||
#include <framework/stdext/format.h>
|
||||
#include <framework/util/extras.h>
|
||||
|
||||
#include "adaptiverenderer.h"
|
||||
|
||||
AdaptiveRenderer g_adaptiveRenderer;
|
||||
|
||||
void AdaptiveRenderer::newFrame() {
|
||||
auto now = stdext::millis();
|
||||
m_frames.push_back(now);
|
||||
while (m_frames.front() + 5000 < now) {
|
||||
m_frames.pop_front();
|
||||
}
|
||||
|
||||
if (m_forcedSpeed >= 0 && m_forcedSpeed <= 4) {
|
||||
m_speed = m_forcedSpeed;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_update + 5000 > now)
|
||||
return;
|
||||
|
||||
m_update = stdext::millis();
|
||||
|
||||
if (m_speed < 1)
|
||||
m_speed = 1;
|
||||
|
||||
int maxFps = std::min<int>(100, std::max<int>(10, g_app.getMaxFps() < 10 ? 100 : g_app.getMaxFps()));
|
||||
if (m_speed >= 2 && maxFps > 60) { // fix for forced vsync
|
||||
maxFps = 60;
|
||||
}
|
||||
|
||||
if (m_frames.size() < maxFps * (4.0f - m_speed * 0.3f) && m_speed != RenderSpeeds - 1) {
|
||||
m_speed += 1;
|
||||
}
|
||||
if (m_frames.size() > maxFps * (4.5f - m_speed * 0.1f) && m_speed > 1) {
|
||||
m_speed -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void AdaptiveRenderer::refresh() {
|
||||
m_update = stdext::millis();
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::effetsLimit() {
|
||||
static int limits[RenderSpeeds] = { 20, 10, 7, 4, 2 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::creaturesLimit() {
|
||||
static int limits[RenderSpeeds] = { 20, 10, 7, 5, 3 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::itemsLimit() {
|
||||
static int limits[RenderSpeeds] = { 20, 10, 7, 5, 3 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::mapRenderInterval() {
|
||||
static int limits[RenderSpeeds] = { 0, 10, 20, 50, 100 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::textsLimit() {
|
||||
static int limits[RenderSpeeds] = { 1000, 50, 30, 15, 5 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::creaturesRenderInterval() {
|
||||
// not working yet
|
||||
static int limits[RenderSpeeds] = { 0, 0, 10, 15, 20 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
bool AdaptiveRenderer::allowFading() {
|
||||
return m_speed <= 2;
|
||||
}
|
||||
|
||||
int AdaptiveRenderer::foregroundUpdateInterval() {
|
||||
static int limits[RenderSpeeds] = { 0, 20, 40, 50, 60 };
|
||||
return limits[m_speed];
|
||||
}
|
||||
|
||||
std::string AdaptiveRenderer::getDebugInfo() {
|
||||
std::stringstream ss;
|
||||
ss << "Frames: " << m_frames.size() << "|" << m_speed << "|" << m_forcedSpeed;
|
||||
return ss.str();
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
#ifndef ADAPTIVERENDERER_H
|
||||
#define ADAPTIVERENDERER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
constexpr int RenderSpeeds = 5;
|
||||
|
||||
class AdaptiveRenderer {
|
||||
public:
|
||||
void newFrame();
|
||||
|
||||
void refresh();
|
||||
|
||||
int effetsLimit();
|
||||
|
||||
int creaturesLimit();
|
||||
|
||||
int itemsLimit();
|
||||
|
||||
int textsLimit();
|
||||
|
||||
int mapRenderInterval();
|
||||
|
||||
int creaturesRenderInterval();
|
||||
|
||||
|
||||
bool allowFading();
|
||||
|
||||
int getLevel() {
|
||||
return m_speed;
|
||||
}
|
||||
|
||||
int foregroundUpdateInterval();
|
||||
|
||||
std::string getDebugInfo();
|
||||
|
||||
void setForcedLevel(int value) {
|
||||
m_forcedSpeed = value;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_forcedSpeed = -1;
|
||||
int m_speed = 0;
|
||||
time_t m_update = 0;
|
||||
std::list<time_t> m_frames;
|
||||
};
|
||||
|
||||
extern AdaptiveRenderer g_adaptiveRenderer;
|
||||
|
||||
#endif
|
@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "application.h"
|
||||
#include <csignal>
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/modulemanager.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/core/configmanager.h>
|
||||
#include "asyncdispatcher.h"
|
||||
#include <framework/luaengine/luainterface.h>
|
||||
#include <framework/platform/crashhandler.h>
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/http/http.h>
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <locale>
|
||||
|
||||
#ifdef FW_NET
|
||||
#include <framework/net/connection.h>
|
||||
#ifdef FW_PROXY
|
||||
#include <extras/proxy/proxy.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void exitSignalHandler(int sig)
|
||||
{
|
||||
static bool signaled = false;
|
||||
switch(sig) {
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
if(!signaled && !g_app.isStopping() && !g_app.isTerminated()) {
|
||||
signaled = true;
|
||||
g_dispatcher.addEvent(std::bind(&Application::close, &g_app));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Application::Application()
|
||||
{
|
||||
m_appName = "application";
|
||||
m_appCompactName = "app";
|
||||
m_appVersion = "none";
|
||||
m_charset = "cp1252";
|
||||
m_stopping = false;
|
||||
#ifdef ANDROID
|
||||
m_mobile = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::init(std::vector<std::string>& args)
|
||||
{
|
||||
// capture exit signals
|
||||
signal(SIGTERM, exitSignalHandler);
|
||||
signal(SIGINT, exitSignalHandler);
|
||||
|
||||
// setup locale
|
||||
std::locale::global(std::locale());
|
||||
|
||||
// process args encoding
|
||||
g_platform.processArgs(args);
|
||||
|
||||
g_asyncDispatcher.init();
|
||||
|
||||
std::string startupOptions;
|
||||
for(uint i=1;i<args.size();++i) {
|
||||
const std::string& arg = args[i];
|
||||
startupOptions += " ";
|
||||
startupOptions += arg;
|
||||
}
|
||||
if(startupOptions.length() > 0)
|
||||
g_logger.info(stdext::format("Startup options: %s", startupOptions));
|
||||
|
||||
m_startupOptions = startupOptions;
|
||||
|
||||
// mobile testing
|
||||
if (startupOptions.find("-mobile") != std::string::npos)
|
||||
m_mobile = true;
|
||||
|
||||
// initialize configs
|
||||
g_configs.init();
|
||||
|
||||
// initialize lua
|
||||
g_lua.init();
|
||||
registerLuaFunctions();
|
||||
|
||||
#ifdef FW_PROXY
|
||||
// initalize proxy
|
||||
g_proxy.init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::deinit()
|
||||
{
|
||||
g_lua.callGlobalField("g_app", "onTerminate");
|
||||
|
||||
// run modules unload events
|
||||
g_modules.unloadModules();
|
||||
g_modules.clear();
|
||||
|
||||
// release remaining lua object references
|
||||
g_lua.collectGarbage();
|
||||
|
||||
// poll remaining events
|
||||
poll();
|
||||
|
||||
// disable dispatcher events
|
||||
g_dispatcher.shutdown();
|
||||
}
|
||||
|
||||
void Application::terminate()
|
||||
{
|
||||
#ifdef FW_NET
|
||||
// terminate network
|
||||
Connection::terminate();
|
||||
#endif
|
||||
|
||||
// release configs
|
||||
g_configs.terminate();
|
||||
|
||||
// release resources
|
||||
g_resources.terminate();
|
||||
|
||||
// terminate script environment
|
||||
g_lua.terminate();
|
||||
|
||||
#ifdef FW_PROXY
|
||||
// terminate proxy
|
||||
g_proxy.terminate();
|
||||
#endif
|
||||
|
||||
m_terminated = true;
|
||||
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
}
|
||||
|
||||
void Application::poll()
|
||||
{
|
||||
#ifdef FW_NET
|
||||
Connection::poll();
|
||||
#endif
|
||||
|
||||
g_dispatcher.poll();
|
||||
|
||||
// poll connection again to flush pending write
|
||||
#ifdef FW_NET
|
||||
Connection::poll();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::exit()
|
||||
{
|
||||
g_lua.callGlobalField<bool>("g_app", "onExit");
|
||||
m_stopping = true;
|
||||
}
|
||||
|
||||
void Application::quick_exit()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
::quick_exit(0);
|
||||
#else
|
||||
::exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Application::close()
|
||||
{
|
||||
if(!g_lua.callGlobalField<bool>("g_app", "onClose"))
|
||||
exit();
|
||||
}
|
||||
|
||||
void Application::restart()
|
||||
{
|
||||
#ifndef ANDROID
|
||||
boost::process::child c(g_resources.getBinaryName());
|
||||
std::error_code ec2;
|
||||
if (c.wait_for(std::chrono::seconds(1), ec2)) {
|
||||
g_logger.fatal("Updater restart error. Please restart application");
|
||||
}
|
||||
c.detach();
|
||||
quick_exit();
|
||||
#else
|
||||
exit();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string Application::getOs()
|
||||
{
|
||||
#if defined(ANDROID)
|
||||
return "android";
|
||||
#elif defined(WIN32)
|
||||
return "windows";
|
||||
#elif defined(__APPLE__)
|
||||
return "mac";
|
||||
#elif __linux
|
||||
return "linux";
|
||||
#else
|
||||
return "unknown";
|
||||
#endif
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
#include <framework/global.h>
|
||||
|
||||
//@bindsingleton g_app
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
Application();
|
||||
virtual ~Application() {}
|
||||
|
||||
virtual void init(std::vector<std::string>& args);
|
||||
virtual void deinit();
|
||||
virtual void terminate();
|
||||
virtual void run() = 0;
|
||||
virtual void poll();
|
||||
virtual void exit();
|
||||
virtual void quick_exit();
|
||||
virtual void close();
|
||||
void restart();
|
||||
|
||||
void setName(const std::string& name) { m_appName = name; }
|
||||
void setCompactName(const std::string& compactName) { m_appCompactName = compactName; }
|
||||
void setVersion(const std::string& version) { m_appVersion = version; }
|
||||
|
||||
bool isRunning() { return m_running; }
|
||||
bool isStopping() { return m_stopping; }
|
||||
bool isTerminated() { return m_terminated; }
|
||||
const std::string& getName() { return m_appName; }
|
||||
const std::string& getCompactName() { return m_appCompactName; }
|
||||
const std::string& getVersion() { return m_appVersion; }
|
||||
|
||||
std::string getCharset() { return m_charset; }
|
||||
std::string getBuildCompiler() { return BUILD_COMPILER; }
|
||||
std::string getBuildDate() { return std::string(__DATE__); }
|
||||
std::string getBuildRevision() { return BUILD_REVISION; }
|
||||
std::string getBuildCommit() { return BUILD_COMMIT; }
|
||||
std::string getBuildType() { return BUILD_TYPE; }
|
||||
std::string getBuildArch() { return BUILD_ARCH; }
|
||||
std::string getAuthor() { return "otclient.ovh"; }
|
||||
std::string getOs();
|
||||
std::string getStartupOptions() { return m_startupOptions; }
|
||||
|
||||
bool isMobile()
|
||||
{
|
||||
return m_mobile;
|
||||
}
|
||||
|
||||
protected:
|
||||
void registerLuaFunctions();
|
||||
|
||||
std::string m_charset;
|
||||
std::string m_appName;
|
||||
std::string m_appCompactName;
|
||||
std::string m_appVersion;
|
||||
std::string m_startupOptions;
|
||||
stdext::boolean<false> m_running;
|
||||
stdext::boolean<false> m_stopping;
|
||||
stdext::boolean<false> m_terminated;
|
||||
stdext::boolean<false> m_mobile;
|
||||
};
|
||||
|
||||
#ifdef FW_GRAPHICS
|
||||
#include "graphicalapplication.h"
|
||||
#else
|
||||
#include "consoleapplication.h"
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "asyncdispatcher.h"
|
||||
|
||||
AsyncDispatcher g_asyncDispatcher;
|
||||
|
||||
void AsyncDispatcher::init()
|
||||
{
|
||||
spawn_thread();
|
||||
}
|
||||
|
||||
void AsyncDispatcher::terminate()
|
||||
{
|
||||
stop();
|
||||
m_tasks.clear();
|
||||
}
|
||||
|
||||
void AsyncDispatcher::spawn_thread()
|
||||
{
|
||||
m_running = true;
|
||||
m_threads.push_back(std::thread(std::bind(&AsyncDispatcher::exec_loop, this)));
|
||||
}
|
||||
|
||||
void AsyncDispatcher::stop()
|
||||
{
|
||||
m_mutex.lock();
|
||||
m_running = false;
|
||||
m_condition.notify_all();
|
||||
m_mutex.unlock();
|
||||
for(std::thread& thread : m_threads)
|
||||
thread.join();
|
||||
m_threads.clear();
|
||||
};
|
||||
|
||||
void AsyncDispatcher::exec_loop() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
while(true) {
|
||||
while(m_tasks.size() == 0 && m_running)
|
||||
m_condition.wait(lock);
|
||||
|
||||
if(!m_running)
|
||||
return;
|
||||
|
||||
std::function<void()> task = m_tasks.front();
|
||||
m_tasks.pop_front();
|
||||
|
||||
lock.unlock();
|
||||
task();
|
||||
lock.lock();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user