diff --git a/api/stats.php b/api/stats.php
deleted file mode 100644
index 48859a1..0000000
--- a/api/stats.php
+++ /dev/null
@@ -1,13 +0,0 @@
-uid) {
- die();
-}
-
-if($json->uid) {
- file_put_contents("stats/".($json->uid).".log", "\n".$data."\n", FILE_APPEND);
-}
-
-echo "OK";
-?>
\ No newline at end of file
diff --git a/api/status.php b/api/status.php
deleted file mode 100644
index 2b1a20e..0000000
--- a/api/status.php
+++ /dev/null
@@ -1,26 +0,0 @@
-([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);
-?>
\ No newline at end of file
diff --git a/api/updater.php b/api/updater.php
deleted file mode 100644
index f59e4f3..0000000
--- a/api/updater.php
+++ /dev/null
@@ -1,69 +0,0 @@
- "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));
-
-?>
\ No newline at end of file
diff --git a/api/updater_advanced.php b/api/updater_advanced.php
deleted file mode 100644
index 62a3710..0000000
--- a/api/updater_advanced.php
+++ /dev/null
@@ -1,77 +0,0 @@
- "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));
-
-?>
\ No newline at end of file
diff --git a/otclient_linux b/otclient_linux
deleted file mode 100644
index 9842843..0000000
Binary files a/otclient_linux and /dev/null differ
diff --git a/run_android.bat b/run_android.bat
deleted file mode 100644
index b407fa1..0000000
--- a/run_android.bat
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/server/README.md b/server/README.md
deleted file mode 100644
index 378f01c..0000000
--- a/server/README.md
+++ /dev/null
@@ -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')
diff --git a/server/json.lua b/server/json.lua
deleted file mode 100644
index 22cbb47..0000000
--- a/server/json.lua
+++ /dev/null
@@ -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
diff --git a/server/shop/shop.lua b/server/shop/shop.lua
deleted file mode 100644
index ebb9dfb..0000000
--- a/server/shop/shop.lua
+++ /dev/null
@@ -1,362 +0,0 @@
--- BETA VERSION, net tested yet
--- Instruction:
--- creaturescripts.xml
--- 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
\ No newline at end of file
diff --git a/src/README.md b/src/README.md
deleted file mode 100644
index 516d531..0000000
--- a/src/README.md
+++ /dev/null
@@ -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)
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
deleted file mode 100644
index dc51557..0000000
--- a/src/client/CMakeLists.txt
+++ /dev/null
@@ -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")
diff --git a/src/client/animatedtext.cpp b/src/client/animatedtext.cpp
deleted file mode 100644
index 3a33384..0000000
--- a/src/client/animatedtext.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-#include
-
-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(m_cachedText.getText());
- int otherNumber = stdext::safe_cast(other->getCachedText().getText());
- m_cachedText.setText(std::to_string(number + otherNumber));
- return true;
- } catch(...) {}
- return false;
-}
diff --git a/src/client/animatedtext.h b/src/client/animatedtext.h
deleted file mode 100644
index ead95dd..0000000
--- a/src/client/animatedtext.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-#include
-
-// @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(); }
- 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
diff --git a/src/client/animator.cpp b/src/client/animator.cpp
deleted file mode 100644
index 15bcadb..0000000
--- a/src/client/animator.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
-* Copyright (c) 2010-2017 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
-#include
-#include
-#include
-
-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(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(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;
-}
diff --git a/src/client/animator.h b/src/client/animator.h
deleted file mode 100644
index 61676b4..0000000
--- a/src/client/animator.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-* Copyright (c) 2010-2017 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
-#include
-
-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 > m_phaseDurations;
-
- int m_currentDuration;
- AnimationDirection m_currentDirection;
- int m_currentLoop;
-
- ticks_t m_lastPhaseTicks;
- bool m_isComplete;
-
- int m_phase;
-};
-
-#endif
diff --git a/src/client/client.cpp b/src/client/client.cpp
deleted file mode 100644
index 54d9103..0000000
--- a/src/client/client.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-#include
-#include "game.h"
-#include "map.h"
-#include "shadermanager.h"
-#include "spritemanager.h"
-#include "minimap.h"
-#include
-
-Client g_client;
-
-void Client::init(std::vector& 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();
-}
diff --git a/src/client/client.h b/src/client/client.h
deleted file mode 100644
index bba39d4..0000000
--- a/src/client/client.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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& args);
- void terminate();
- void registerLuaFunctions();
-};
-
-extern Client g_client;
-
-#endif
diff --git a/src/client/const.h b/src/client/const.h
deleted file mode 100644
index 6a1eafc..0000000
--- a/src/client/const.h
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
diff --git a/src/client/container.cpp b/src/client/container.cpp
deleted file mode 100644
index f6df471..0000000
--- a/src/client/container.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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& 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));
-}
diff --git a/src/client/container.h b/src/client/container.h
deleted file mode 100644
index 49d12ee..0000000
--- a/src/client/container.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-
-// @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 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& 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 m_items;
-};
-
-#endif
diff --git a/src/client/creature.cpp b/src/client/creature.cpp
deleted file mode 100644
index d47f221..0000000
--- a/src/client/creature.cpp
+++ /dev/null
@@ -1,1150 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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 "creature.h"
-#include "thingtypemanager.h"
-#include "localplayer.h"
-#include "map.h"
-#include "tile.h"
-#include "item.h"
-#include "game.h"
-#include "effect.h"
-#include "luavaluecasts_client.h"
-#include "lightview.h"
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include "spritemanager.h"
-
-#include
-#include
-
-std::array Creature::m_speedFormula = { -1,-1,-1 };
-
-Creature::Creature() : Thing()
-{
- m_id = 0;
- m_healthPercent = 100;
- m_manaPercent = -1;
- m_speed = 200;
- m_direction = Otc::South;
- m_walkDirection = Otc::South;
- m_walkAnimationPhase = 0;
- m_walkedPixels = 0;
- m_skull = Otc::SkullNone;
- m_shield = Otc::ShieldNone;
- m_emblem = Otc::EmblemNone;
- m_type = Proto::CreatureTypeUnknown;
- m_icon = Otc::NpcIconNone;
- m_lastStepDirection = Otc::InvalidDirection;
- m_footLastStep = 0;
- m_nameCache.setFont(g_fonts.getFont("verdana-11px-rounded"));
- m_nameCache.setAlign(Fw::AlignTopCenter);
- m_footStep = 0;
- //m_speedFormula.fill(-1);
- m_outfitColor = Color::white;
- m_progressBarPercent = 0;
- m_progressBarUpdateEvent = nullptr;
- g_stats.addCreature();
-}
-
-Creature::~Creature()
-{
- g_stats.removeCreature();
-}
-
-void Creature::draw(const Point& dest, bool animate, LightView* lightView)
-{
- if (!canBeSeen())
- return;
-
- Point creatureCenter = dest + m_walkOffset - getDisplacement() + Point(Otc::TILE_PIXELS / 2, Otc::TILE_PIXELS / 2);
- drawBottomWidgets(creatureCenter, m_walking ? m_walkDirection : m_direction);
-
- Point animationOffset = animate ? m_walkOffset : Point(0, 0);
- if (m_outfit.getCategory() != ThingCategoryCreature)
- animationOffset -= getDisplacement();
-
- if (m_showTimedSquare && animate) {
- g_drawQueue->addBoundingRect(Rect(dest + (animationOffset - getDisplacement() + 2), Size(28, 28)), 2, m_timedSquareColor);
- }
-
- if (m_showStaticSquare && animate) {
- g_drawQueue->addBoundingRect(Rect(dest + (animationOffset - getDisplacement()), Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS)), 2, m_staticSquareColor);
- }
-
- size_t drawQueueSize = g_drawQueue->size();
- m_outfit.draw(dest + animationOffset, m_walking ? m_walkDirection : m_direction, m_walkAnimationPhase, true, lightView);
- if (m_marked) {
- g_drawQueue->setMark(drawQueueSize, updatedMarkedColor());
- }
-
- drawTopWidgets(creatureCenter, m_walking ? m_walkDirection : m_direction);
-
- Light light = rawGetThingType()->getLight();
- if (m_light.intensity != light.intensity || m_light.color != light.color)
- light = m_light;
-
- // local player always have a minimum light in complete darkness
- if (isLocalPlayer()) {
- light.intensity = std::max(light.intensity, 2);
- if (light.color == 0 || light.color > 215)
- light.color = 215;
- }
-
- if(lightView)
- lightView->addLight(creatureCenter, light);
-}
-
-void Creature::drawOutfit(const Rect& destRect, Otc::Direction direction, const Color& color)
-{
- if (direction == Otc::InvalidDirection)
- direction = m_direction;
-
- m_outfit.draw(destRect, direction, 0, false);
-}
-
-void Creature::drawInformation(const Point& point, bool useGray, const Rect& parentRect, int drawFlags)
-{
- if (m_healthPercent < 1) // creature is dead
- return;
-
- Color fillColor = Color(96, 96, 96);
-
- if (!useGray)
- fillColor = m_informationColor;
-
- // calculate main rects
- Rect backgroundRect = Rect(point.x + m_informationOffset.x - (13.5), point.y + m_informationOffset.y, 27, 4);
- backgroundRect.bind(parentRect);
-
- //debug
- if (g_extras.debugWalking) {
- int footDelay = (getStepDuration(true)) / 3;
- int footAnimPhases = getWalkAnimationPhases() - 1;
- m_nameCache.setText(stdext::format("%i %i %i %i %i\n %i %i\n%i %i %i\n%i %i %i %i %i",
- (int)m_stepDuration, (int)getStepDuration(true), getStepDuration(false), (int)m_walkedPixels, (int)m_walkTimer.ticksElapsed(),
- (int)m_walkOffset.x, (int)m_walkOffset.y,
- (int)m_speed, (int)getTile()->getGroundSpeed(), (int)g_game.getWalkId(),
- (int)(g_clock.millis() - m_footLastStep), (int)footDelay, (int)footAnimPhases, (int)m_walkAnimationPhase, (int)stdext::millis()));
- }
-
- Size nameSize = m_nameCache.getTextSize();
- Rect textRect = Rect(point.x + m_informationOffset.x - nameSize.width() / 2.0, point.y + m_informationOffset.y - 12, nameSize);
- textRect.bind(parentRect);
-
- // distance them
- uint32 offset = 12;
- if (isLocalPlayer()) {
- offset *= 2;
- }
-
- if (textRect.top() == parentRect.top())
- backgroundRect.moveTop(textRect.top() + offset);
- if (backgroundRect.bottom() == parentRect.bottom())
- textRect.moveTop(backgroundRect.top() - offset);
-
- // health rect is based on background rect, so no worries
- Rect healthRect = backgroundRect.expanded(-1);
- healthRect.setWidth((m_healthPercent / 100.0) * 25);
-
- // draw
- if (g_game.getFeature(Otc::GameBlueNpcNameColor) && isNpc() && m_healthPercent == 100 && !useGray)
- fillColor = Color(0x66, 0xcc, 0xff);
-
- if (drawFlags & Otc::DrawBars && (!isNpc() || !g_game.getFeature(Otc::GameHideNpcNames))) {
- g_drawQueue->addFilledRect(backgroundRect, Color::black);
- g_drawQueue->addFilledRect(healthRect, fillColor);
-
- if (drawFlags & Otc::DrawManaBar) {
- int manaPercent = m_manaPercent;
- if (isLocalPlayer()) {
- LocalPlayerPtr player = g_game.getLocalPlayer();
- if (player) {
- double maxMana = player->getMaxMana();
- if (maxMana == 0) {
- manaPercent = 100;
- } else {
- manaPercent = (player->getMana() * 100) / maxMana;
- }
- }
- }
- if (manaPercent >= 0) {
- backgroundRect.moveTop(backgroundRect.bottom());
- g_drawQueue->addFilledRect(backgroundRect, Color::black);
-
- Rect manaRect = backgroundRect.expanded(-1);
- manaRect.setWidth(((float)manaPercent / 100.f) * 25);
- g_drawQueue->addFilledRect(manaRect, Color::blue);
- }
- }
-
- if (getProgressBarPercent()) {
- backgroundRect.moveTop(backgroundRect.bottom());
-
- g_drawQueue->addFilledRect(backgroundRect, Color::black);
-
- Rect progressBarRect = backgroundRect.expanded(-1);
- double maxBar = 100;
- progressBarRect.setWidth(getProgressBarPercent() / (maxBar * 1.0) * 25);
-
- g_drawQueue->addFilledRect(progressBarRect, Color::white);
- }
- }
-
- if (drawFlags & Otc::DrawNames) {
- m_nameCache.draw(textRect, fillColor);
-
- if (m_text) {
- auto extraTextSize = m_text->getCachedText().getTextSize();
- Rect extraTextRect = Rect(point.x + m_informationOffset.x - extraTextSize.width() / 2.0, point.y + m_informationOffset.y + 15, extraTextSize);
- m_text->drawText(extraTextRect.center(), extraTextRect);
- }
- }
-
- if (!(drawFlags & Otc::DrawIcons))
- return;
-
- if (m_skull != Otc::SkullNone && m_skullTexture) {
- Rect skullRect = Rect(backgroundRect.x() + 13.5 + 12, backgroundRect.y() + 5, m_skullTexture->getSize());
- g_drawQueue->addTexturedRect(skullRect, m_skullTexture, Rect(0, 0, m_skullTexture->getSize()));
- }
- if (m_shield != Otc::ShieldNone && m_shieldTexture && m_showShieldTexture) {
- Rect shieldRect = Rect(backgroundRect.x() + 13.5, backgroundRect.y() + 5, m_shieldTexture->getSize());
- g_drawQueue->addTexturedRect(shieldRect, m_shieldTexture, Rect(0, 0, m_shieldTexture->getSize()));
- }
- if (m_emblem != Otc::EmblemNone && m_emblemTexture) {
- Rect emblemRect = Rect(backgroundRect.x() + 13.5 + 12, backgroundRect.y() + 16, m_emblemTexture->getSize());
- g_drawQueue->addTexturedRect(emblemRect, m_emblemTexture, Rect(0, 0, m_emblemTexture->getSize()));
- }
- if (m_type != Proto::CreatureTypeUnknown && m_typeTexture) {
- Rect typeRect = Rect(backgroundRect.x() + 13.5 + 12 + 12, backgroundRect.y() + 16, m_typeTexture->getSize());
- g_drawQueue->addTexturedRect(typeRect, m_typeTexture, Rect(0, 0, m_typeTexture->getSize()));
- }
- if (m_icon != Otc::NpcIconNone && m_iconTexture) {
- Rect iconRect = Rect(backgroundRect.x() + 13.5 + 12, backgroundRect.y() + 5, m_iconTexture->getSize());
- g_drawQueue->addTexturedRect(iconRect, m_iconTexture, Rect(0, 0, m_iconTexture->getSize()));
- }
-}
-
-bool Creature::isInsideOffset(Point offset)
-{
- // for worse precision:
- // Rect rect(getDrawOffset() - (m_walking ? m_walkOffset : Point(0,0)), Size(Otc::TILE_PIXELS - getDisplacementY(), Otc::TILE_PIXELS - getDisplacementX()));
- Rect rect(getDrawOffset() - m_walkOffset - getDisplacement(), Size(Otc::TILE_PIXELS, Otc::TILE_PIXELS));
- return rect.contains(offset);
-}
-
-bool Creature::canShoot(int distance)
-{
- return getTile() ? getTile()->canShoot(distance) : false;
-}
-
-void Creature::turn(Otc::Direction direction)
-{
- setDirection(direction);
- callLuaField("onTurn", direction);
-}
-
-void Creature::walk(const Position& oldPos, const Position& newPos)
-{
- if (oldPos == newPos)
- return;
-
- // get walk direction
- m_lastStepDirection = oldPos.getDirectionFromPosition(newPos);
- m_lastStepFromPosition = oldPos;
- m_lastStepToPosition = newPos;
-
- // set current walking direction
- setDirection(m_lastStepDirection);
- m_walkDirection = m_direction;
-
- // starts counting walk
- m_walking = true;
- m_walkTimer.restart();
- m_walkedPixels = 0;
-
- if (m_walkFinishAnimEvent) {
- m_walkFinishAnimEvent->cancel();
- m_walkFinishAnimEvent = nullptr;
- }
-
- // starts updating walk
- nextWalkUpdate();
-}
-
-void Creature::stopWalk()
-{
- if (!m_walking)
- return;
-
- // stops the walk right away
- terminateWalk();
-}
-
-void Creature::jump(int height, int duration)
-{
- if (!m_jumpOffset.isNull())
- return;
-
- m_jumpTimer.restart();
- m_jumpHeight = height;
- m_jumpDuration = duration;
-
- updateJump();
-}
-
-void Creature::updateJump()
-{
- int t = m_jumpTimer.ticksElapsed();
- double a = -4 * m_jumpHeight / (m_jumpDuration * m_jumpDuration);
- double b = +4 * m_jumpHeight / (m_jumpDuration);
-
- double height = a * t * t + b * t;
- int roundHeight = stdext::round(height);
- int halfJumpDuration = m_jumpDuration / 2;
-
- // schedules next update
- if (m_jumpTimer.ticksElapsed() < m_jumpDuration) {
- m_jumpOffset = PointF(height, height);
-
- int diff = 0;
- if (m_jumpTimer.ticksElapsed() < halfJumpDuration)
- diff = 1;
- else if (m_jumpTimer.ticksElapsed() > halfJumpDuration)
- diff = -1;
-
- int nextT, i = 1;
- do {
- nextT = stdext::round((-b + std::sqrt(std::max(b * b + 4 * a * (roundHeight + diff * i), 0.0)) * diff) / (2 * a));
- ++i;
-
- if (nextT < halfJumpDuration)
- diff = 1;
- else if (nextT > halfJumpDuration)
- diff = -1;
- } while (nextT - m_jumpTimer.ticksElapsed() == 0 && i < 3);
-
- auto self = static_self_cast();
- g_dispatcher.scheduleEvent([self] {
- self->updateJump();
- }, nextT - m_jumpTimer.ticksElapsed());
- } else
- m_jumpOffset = PointF(0, 0);
-}
-
-void Creature::onPositionChange(const Position& newPos, const Position& oldPos)
-{
- callLuaField("onPositionChange", newPos, oldPos);
-}
-
-void Creature::onAppear()
-{
- // cancel any disappear event
- if (m_disappearEvent) {
- m_disappearEvent->cancel();
- m_disappearEvent = nullptr;
- }
-
- // creature appeared the first time or wasn't seen for a long time
- if (m_removed) {
- stopWalk();
- m_removed = false;
- callLuaField("onAppear");
- // walk
- } else if (m_oldPosition != m_position && m_oldPosition.isInRange(m_position, 1, 1) && m_allowAppearWalk) {
- m_allowAppearWalk = false;
- walk(m_oldPosition, m_position);
- callLuaField("onWalk", m_oldPosition, m_position);
- // teleport
- } else if (m_oldPosition != m_position) {
- stopWalk();
- callLuaField("onDisappear");
- callLuaField("onAppear");
- } // else turn
-}
-
-void Creature::onDisappear()
-{
- if (m_disappearEvent)
- m_disappearEvent->cancel();
-
- m_oldPosition = m_position;
-
- // a pair onDisappear and onAppear events are fired even when creatures walks or turns,
- // so we must filter
- auto self = static_self_cast();
- m_disappearEvent = g_dispatcher.addEvent([self] {
- self->m_removed = true;
- self->stopWalk();
-
- self->callLuaField("onDisappear");
-
- // invalidate this creature position
- if (!self->isLocalPlayer())
- self->setPosition(Position());
- self->m_oldPosition = Position();
- self->m_disappearEvent = nullptr;
- self->clearWidgets();
- });
-}
-
-void Creature::onDeath()
-{
- callLuaField("onDeath");
-}
-
-int Creature::getWalkAnimationPhases()
-{
- if (!getAnimator())
- return getAnimationPhases();
- return getAnimator()->getAnimationPhases() + (g_game.getFeature(Otc::GameIdleAnimations) ? 1 : 0);
-}
-
-void Creature::updateWalkAnimation(int totalPixelsWalked)
-{
- // update outfit animation
- if (m_outfit.getCategory() != ThingCategoryCreature)
- return;
-
- int footAnimPhases = getWalkAnimationPhases() - 1;
- // TODO, should be /2 for <= 810
- int footDelay = getStepDuration(true);
- if (footAnimPhases > 0) {
- footDelay = ((getStepDuration(true) + 20) / (g_game.getFeature(Otc::GameFasterAnimations) ? footAnimPhases * 2 : footAnimPhases));
- }
- if (!g_game.getFeature(Otc::GameFasterAnimations))
- footDelay += 10;
- if (footDelay < 20)
- footDelay = 20;
-
- // Since mount is a different outfit we need to get the mount animation phases
- if (m_outfit.getMount() != 0) {
- ThingType* type = g_things.rawGetThingType(m_outfit.getMount(), m_outfit.getCategory());
- footAnimPhases = std::min(footAnimPhases, type->getAnimationPhases() - 1);
- }
-
- if (footAnimPhases == 0) {
- m_walkAnimationPhase = 0;
- } else if (g_clock.millis() >= m_footLastStep + footDelay && totalPixelsWalked < 32) {
- m_footStep++;
- m_walkAnimationPhase = 1 + (m_footStep % footAnimPhases);
- m_footLastStep = (g_clock.millis() - m_footLastStep) > footDelay * 1.5 ? g_clock.millis() : m_footLastStep + footDelay;
- } else if (m_walkAnimationPhase == 0 && totalPixelsWalked < 32) {
- m_walkAnimationPhase = 1 + (m_footStep % footAnimPhases);
- }
-
- if (totalPixelsWalked == 32 && !m_walkFinishAnimEvent) {
- auto self = static_self_cast();
- m_walkFinishAnimEvent = g_dispatcher.scheduleEvent([self] {
- self->m_footStep = 0;
- self->m_walkAnimationPhase = 0;
- self->m_walkFinishAnimEvent = nullptr;
- }, 50);
- }
-
-}
-
-void Creature::updateWalkOffset(int totalPixelsWalked, bool inNextFrame)
-{
- 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 = 32 - totalPixelsWalked;
- else if (m_walkDirection == Otc::South || m_walkDirection == Otc::SouthEast || m_walkDirection == Otc::SouthWest)
- walkOffset.y = totalPixelsWalked - 32;
-
- if (m_walkDirection == Otc::East || m_walkDirection == Otc::NorthEast || m_walkDirection == Otc::SouthEast)
- walkOffset.x = totalPixelsWalked - 32;
- else if (m_walkDirection == Otc::West || m_walkDirection == Otc::NorthWest || m_walkDirection == Otc::SouthWest)
- walkOffset.x = 32 - totalPixelsWalked;
-}
-
-void Creature::updateWalkingTile()
-{
- // determine new walking tile
- TilePtr newWalkingTile;
- Rect virtualCreatureRect(Otc::TILE_PIXELS + (m_walkOffset.x - getDisplacementX()),
- Otc::TILE_PIXELS + (m_walkOffset.y - getDisplacementY()),
- Otc::TILE_PIXELS, Otc::TILE_PIXELS);
- for (int xi = -1; xi <= 1 && !newWalkingTile; ++xi) {
- for (int yi = -1; yi <= 1 && !newWalkingTile; ++yi) {
- Rect virtualTileRect((xi + 1) * Otc::TILE_PIXELS, (yi + 1) * Otc::TILE_PIXELS, Otc::TILE_PIXELS, Otc::TILE_PIXELS);
-
- // only render creatures where bottom right is inside tile rect
- if (virtualTileRect.contains(virtualCreatureRect.bottomRight())) {
- newWalkingTile = g_map.getOrCreateTile(getPrewalkingPosition().translated(xi, yi, 0));
- }
- }
- }
-
- if (newWalkingTile != m_walkingTile) {
- if (m_walkingTile)
- m_walkingTile->removeWalkingCreature(static_self_cast());
- if (newWalkingTile) {
- newWalkingTile->addWalkingCreature(static_self_cast());
-
- // recache visible tiles in map views
- if (newWalkingTile->isEmpty())
- g_map.notificateTileUpdate(newWalkingTile->getPosition());
- }
- m_walkingTile = newWalkingTile;
- }
-}
-
-void Creature::nextWalkUpdate()
-{
- // remove any previous scheduled walk updates
- if (m_walkUpdateEvent)
- m_walkUpdateEvent->cancel();
-
- // do the update
- updateWalk();
-
- // schedules next update
- if (m_walking) {
- auto self = static_self_cast();
- m_walkUpdateEvent = g_dispatcher.scheduleEvent([self] {
- self->m_walkUpdateEvent = nullptr;
- self->nextWalkUpdate();
- }, getStepDuration(true) / 32);
- }
-}
-
-void Creature::updateWalk()
-{
- float walkTicksPerPixel = ((float)(getStepDuration(true) + 10)) / 32.0f;
- int totalPixelsWalked = std::min(m_walkTimer.ticksElapsed() / walkTicksPerPixel, 32.0f);
- int totalPixelsWalkedInNextFrame = std::min((m_walkTimer.ticksElapsed() + 15) / walkTicksPerPixel, 32.0f);
-
- // needed for paralyze effect
- m_walkedPixels = std::max(m_walkedPixels, totalPixelsWalked);
- int walkedPixelsInNextFrame = std::max(m_walkedPixels, totalPixelsWalkedInNextFrame);
-
- // update walk animation and offsets
- updateWalkAnimation(totalPixelsWalked);
- updateWalkOffset(m_walkedPixels);
- updateWalkOffset(walkedPixelsInNextFrame, true);
- updateWalkingTile();
-
- // terminate walk
- if (m_walking && m_walkTimer.ticksElapsed() >= getStepDuration())
- terminateWalk();
-}
-
-void Creature::terminateWalk()
-{
- // remove any scheduled walk update
- if (m_walkUpdateEvent) {
- m_walkUpdateEvent->cancel();
- m_walkUpdateEvent = nullptr;
- }
-
- if (m_walkingTile) {
- m_walkingTile->removeWalkingCreature(static_self_cast());
- m_walkingTile = nullptr;
- }
-
- m_walking = false;
- m_walkedPixels = 0;
- m_walkOffset = Point(0, 0);
- m_walkOffsetInNextFrame = Point(0, 0);
-
- // reset walk animation states
- if (!m_walkFinishAnimEvent) {
- auto self = static_self_cast();
- m_walkFinishAnimEvent = g_dispatcher.scheduleEvent([self] {
- self->m_footStep = 0;
- self->m_walkAnimationPhase = 0;
- self->m_walkFinishAnimEvent = nullptr;
- }, 50);
- }
-}
-
-void Creature::setName(const std::string& name)
-{
- m_nameCache.setText(name);
- m_name = name;
-}
-
-void Creature::setHealthPercent(uint8 healthPercent)
-{
- if (healthPercent > 100)
- healthPercent = 100;
-
- if (!m_useCustomInformationColor) {
- if (healthPercent > 92)
- m_informationColor = Color(0x00, 0xBC, 0x00);
- else if (healthPercent > 60)
- m_informationColor = Color(0x50, 0xA1, 0x50);
- else if (healthPercent > 30)
- m_informationColor = Color(0xA1, 0xA1, 0x00);
- else if (healthPercent > 8)
- m_informationColor = Color(0xBF, 0x0A, 0x0A);
- else if (healthPercent > 3)
- m_informationColor = Color(0x91, 0x0F, 0x0F);
- else
- m_informationColor = Color(0x85, 0x0C, 0x0C);
- }
-
- bool changed = m_healthPercent != healthPercent;
- m_healthPercent = healthPercent;
- if (changed) {
- callLuaField("onHealthPercentChange", healthPercent);
- }
-
- if (healthPercent <= 0)
- onDeath();
-}
-
-void Creature::setDirection(Otc::Direction direction)
-{
- VALIDATE(direction != Otc::InvalidDirection);
- m_direction = direction;
-}
-
-void Creature::setOutfit(const Outfit& outfit)
-{
- Outfit oldOutfit = m_outfit;
- if (outfit.getCategory() != ThingCategoryCreature) {
- if (!g_things.isValidDatId(outfit.getAuxId(), outfit.getCategory()))
- return;
- m_outfit.setAuxId(outfit.getAuxId());
- m_outfit.setCategory(outfit.getCategory());
- } else {
- if (outfit.getId() > 0 && !g_things.isValidDatId(outfit.getId(), ThingCategoryCreature))
- return;
- m_outfit = outfit;
- }
- m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed.
-
- callLuaField("onOutfitChange", m_outfit, oldOutfit);
-}
-
-void Creature::setOutfitColor(const Color& color, int duration)
-{
- if (m_outfitColorUpdateEvent) {
- m_outfitColorUpdateEvent->cancel();
- m_outfitColorUpdateEvent = nullptr;
- }
-
- if (duration > 0) {
- Color delta = (color - m_outfitColor) / (float)duration;
- m_outfitColorTimer.restart();
- updateOutfitColor(m_outfitColor, color, delta, duration);
- } else
- m_outfitColor = color;
-}
-
-void Creature::updateOutfitColor(Color color, Color finalColor, Color delta, int duration)
-{
- if (m_outfitColorTimer.ticksElapsed() < duration) {
- m_outfitColor = color + delta * m_outfitColorTimer.ticksElapsed();
-
- auto self = static_self_cast();
- m_outfitColorUpdateEvent = g_dispatcher.scheduleEvent([=] {
- self->updateOutfitColor(color, finalColor, delta, duration);
- }, 100);
- } else {
- m_outfitColor = finalColor;
- }
-}
-
-void Creature::setSpeed(uint16 speed)
-{
- uint16 oldSpeed = m_speed;
- m_speed = speed;
-
- // speed can change while walking (utani hur, paralyze, etc..)
- if (m_walking)
- nextWalkUpdate();
-
- callLuaField("onSpeedChange", m_speed, oldSpeed);
-}
-
-void Creature::setBaseSpeed(double baseSpeed)
-{
- if (m_baseSpeed != baseSpeed) {
- double oldBaseSpeed = m_baseSpeed;
- m_baseSpeed = baseSpeed;
-
- callLuaField("onBaseSpeedChange", baseSpeed, oldBaseSpeed);
- }
-}
-
-void Creature::setSkull(uint8 skull)
-{
- m_skull = skull;
- callLuaField("onSkullChange", m_skull);
-}
-
-void Creature::setShield(uint8 shield)
-{
- m_shield = shield;
- callLuaField("onShieldChange", m_shield);
-}
-
-void Creature::setEmblem(uint8 emblem)
-{
- m_emblem = emblem;
- callLuaField("onEmblemChange", m_emblem);
-}
-
-void Creature::setType(uint8 type)
-{
- m_type = type;
- callLuaField("onTypeChange", m_type);
-}
-
-void Creature::setIcon(uint8 icon)
-{
- m_icon = icon;
- callLuaField("onIconChange", m_icon);
-}
-
-void Creature::setSkullTexture(const std::string& filename)
-{
- m_skullTexture = g_textures.getTexture(filename);
-}
-
-void Creature::setShieldTexture(const std::string& filename, bool blink)
-{
- m_shieldTexture = g_textures.getTexture(filename);
- m_showShieldTexture = true;
-
- if (blink && !m_shieldBlink) {
- auto self = static_self_cast();
- g_dispatcher.scheduleEvent([self]() {
- self->updateShield();
- }, SHIELD_BLINK_TICKS);
- }
-
- m_shieldBlink = blink;
-}
-
-void Creature::setEmblemTexture(const std::string& filename)
-{
- m_emblemTexture = g_textures.getTexture(filename);
-}
-
-void Creature::setTypeTexture(const std::string& filename)
-{
- m_typeTexture = g_textures.getTexture(filename);
-}
-
-void Creature::setIconTexture(const std::string& filename)
-{
- m_iconTexture = g_textures.getTexture(filename);
-}
-
-void Creature::setSpeedFormula(double speedA, double speedB, double speedC)
-{
- m_speedFormula[Otc::SpeedFormulaA] = speedA;
- m_speedFormula[Otc::SpeedFormulaB] = speedB;
- m_speedFormula[Otc::SpeedFormulaC] = speedC;
-}
-
-bool Creature::hasSpeedFormula()
-{
- return m_speedFormula[Otc::SpeedFormulaA] != -1 && m_speedFormula[Otc::SpeedFormulaB] != -1
- && m_speedFormula[Otc::SpeedFormulaC] != -1;
-}
-
-void Creature::addTimedSquare(uint8 color)
-{
- m_showTimedSquare = true;
- m_timedSquareColor = Color::from8bit(color);
-
- // schedule removal
- auto self = static_self_cast();
- g_dispatcher.scheduleEvent([self]() {
- self->removeTimedSquare();
- }, VOLATILE_SQUARE_DURATION);
-}
-
-
-void Creature::updateShield()
-{
- m_showShieldTexture = !m_showShieldTexture;
-
- if (m_shield != Otc::ShieldNone && m_shieldBlink) {
- auto self = static_self_cast();
- g_dispatcher.scheduleEvent([self]() {
- self->updateShield();
- }, SHIELD_BLINK_TICKS);
- } else if (!m_shieldBlink)
- m_showShieldTexture = true;
-}
-
-Point Creature::getDrawOffset()
-{
- Point drawOffset;
- if (m_walking) {
- if (m_walkingTile)
- drawOffset -= Point(1, 1) * m_walkingTile->getDrawElevation();
- drawOffset += m_walkOffset;
- } else {
- const TilePtr& tile = getTile();
- if (tile)
- drawOffset -= Point(1, 1) * tile->getDrawElevation();
- }
- return drawOffset;
-}
-
-int Creature::getStepDuration(bool ignoreDiagonal, Otc::Direction dir)
-{
- int speed = m_speed;
- if (speed < 1)
- return 0;
-
- if (g_game.getFeature(Otc::GameNewSpeedLaw))
- speed *= 2;
-
- int groundSpeed = 0;
- Position tilePos;
-
- if (dir == Otc::InvalidDirection)
- tilePos = m_lastStepToPosition;
- else
- tilePos = getPrewalkingPosition(true).translatedToDirection(dir);
-
- if (!tilePos.isValid())
- tilePos = getPrewalkingPosition(true);
-
- const TilePtr& tile = g_map.getTile(tilePos);
- if (tile) {
- groundSpeed = tile->getGroundSpeed();
- if (groundSpeed == 0)
- groundSpeed = 150;
- }
-
- int interval = 1000;
- if (groundSpeed > 0 && speed > 0)
- interval = 1000 * groundSpeed;
-
- if (g_game.getFeature(Otc::GameNewSpeedLaw) && hasSpeedFormula()) {
- int formulatedSpeed = 1;
- if (speed > -m_speedFormula[Otc::SpeedFormulaB]) {
- formulatedSpeed = std::max(1, (int)floor((m_speedFormula[Otc::SpeedFormulaA] * log((speed / 2)
- + m_speedFormula[Otc::SpeedFormulaB]) + m_speedFormula[Otc::SpeedFormulaC]) + 0.5));
- }
- interval = std::floor(interval / (double)formulatedSpeed);
- } else
- interval /= speed;
-
- if (g_game.getClientVersion() >= 900 && !g_game.getFeature(Otc::GameNewWalking))
- interval = std::ceil((float)interval / (float)g_game.getServerBeat()) * g_game.getServerBeat();
-
- float factor = 3;
- if (g_game.getClientVersion() <= 810)
- factor = 2;
-
- interval = std::max(interval, g_game.getServerBeat());
-
- if (!ignoreDiagonal && (m_lastStepDirection == Otc::NorthWest || m_lastStepDirection == Otc::NorthEast ||
- m_lastStepDirection == Otc::SouthWest || m_lastStepDirection == Otc::SouthEast))
- interval *= factor;
-
- if (!isServerWalking() && g_game.getFeature(Otc::GameSlowerManualWalking)) {
- interval += 25;
- }
- if (isServerWalking() && g_game.getFeature(Otc::GameNewWalking) && m_stepDuration > 0) // just use server value
- {
- interval = m_stepDuration;
- }
-
- return interval;
-}
-
-Point Creature::getDisplacement()
-{
- if (m_outfit.getCategory() == ThingCategoryEffect)
- return Point(8, 8);
- else if (m_outfit.getCategory() == ThingCategoryItem)
- return Point(0, 0);
-
- if (m_outfit.getMount() != 0) {
- auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature);
- return datType->getDisplacement();
- }
-
- return Thing::getDisplacement();
-}
-
-int Creature::getDisplacementX()
-{
- if (m_outfit.getCategory() == ThingCategoryEffect)
- return 8;
- else if (m_outfit.getCategory() == ThingCategoryItem)
- return 0;
-
- if (m_outfit.getMount() != 0) {
- auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature);
- return datType->getDisplacementX();
- }
-
- return Thing::getDisplacementX();
-}
-
-int Creature::getDisplacementY()
-{
- if (m_outfit.getCategory() == ThingCategoryEffect)
- return 8;
- else if (m_outfit.getCategory() == ThingCategoryItem)
- return 0;
-
- if (m_outfit.getMount() != 0) {
- auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature);
- if (datType) {
- return datType->getDisplacementY();
- }
- }
-
- return Thing::getDisplacementY();
-}
-
-int Creature::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
-{
- int exactSize = 0;
-
- animationPhase = 0;
- xPattern = Otc::South;
-
- zPattern = 0;
- if (m_outfit.getMount() != 0)
- zPattern = 1;
-
- for (yPattern = 0; yPattern < getNumPatternY(); yPattern++) {
- if (yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern - 1))))
- continue;
-
- for (layer = 0; layer < getLayers(); ++layer)
- exactSize = std::max(exactSize, Thing::getExactSize(layer, xPattern, yPattern, zPattern, animationPhase));
- }
-
- return exactSize;
-}
-
-const ThingTypePtr& Creature::getThingType()
-{
- return g_things.getThingType(m_outfit.getId(), ThingCategoryCreature);
-}
-
-ThingType* Creature::rawGetThingType()
-{
- return g_things.rawGetThingType(m_outfit.getId(), ThingCategoryCreature);
-}
-
-void Creature::setText(const std::string& text, const Color& color)
-{
- if (!m_text) {
- m_text = StaticTextPtr(new StaticText());
- }
- m_text->setText(text);
- m_text->setColor(color);
-}
-
-std::string Creature::getText()
-{
- if (!m_text) {
- return "";
- }
- return m_text->getText();
-}
-
-
-// widgets
-void Creature::addTopWidget(const UIWidgetPtr& widget)
-{
- if (!widget) return;
- if (std::find(m_topWidgets.begin(), m_topWidgets.end(), widget) == m_topWidgets.end()) {
- m_topWidgets.push_back(widget);
- }
-}
-
-void Creature::addBottomWidget(const UIWidgetPtr& widget)
-{
- if (!widget) return;
- if (std::find(m_bottomWidgets.begin(), m_bottomWidgets.end(), widget) == m_bottomWidgets.end()) {
- m_bottomWidgets.push_back(widget);
- }
-}
-
-void Creature::addDirectionalWidget(const UIWidgetPtr& widget)
-{
- if (!widget) return;
- if (std::find(m_directionalWidgets.begin(), m_directionalWidgets.end(), widget) == m_directionalWidgets.end()) {
- m_directionalWidgets.push_back(widget);
- }
-}
-
-void Creature::removeTopWidget(const UIWidgetPtr& widget)
-{
- auto it = std::remove(m_topWidgets.begin(), m_topWidgets.end(), widget);
- while(it != m_topWidgets.end()) {
- (*it)->destroy();
- it = m_topWidgets.erase(it);
- }
-}
-
-void Creature::removeBottomWidget(const UIWidgetPtr& widget)
-{
- auto it = std::remove(m_bottomWidgets.begin(), m_bottomWidgets.end(), widget);
- while (it != m_topWidgets.end()) {
- (*it)->destroy();
- it = m_bottomWidgets.erase(it);
- }
-}
-
-void Creature::removeDirectionalWidget(const UIWidgetPtr& widget)
-{
- auto it = m_directionalWidgets.erase(std::remove(m_directionalWidgets.begin(), m_directionalWidgets.end(), widget));
- while (it != m_topWidgets.end()) {
- (*it)->destroy();
- it = m_directionalWidgets.erase(it);
- }
-
-}
-
-std::list Creature::getTopWidgets()
-{
- return m_topWidgets;
-}
-
-std::list Creature::getBottomWidgets()
-{
- return m_bottomWidgets;
-}
-
-std::list Creature::getDirectionalWdigets()
-{
- return m_directionalWidgets;
-}
-
-void Creature::clearWidgets()
-{
- clearTopWidgets();
- clearBottomWidgets();
- clearDirectionalWidgets();
-}
-
-void Creature::clearTopWidgets()
-{
- for (auto& widget : m_topWidgets) {
- widget->destroy();
- }
- m_topWidgets.clear();
-}
-
-void Creature::clearBottomWidgets()
-{
- for (auto& widget : m_bottomWidgets) {
- widget->destroy();
- }
- m_bottomWidgets.clear();
-}
-
-void Creature::clearDirectionalWidgets()
-{
- for (auto& widget : m_directionalWidgets) {
- widget->destroy();
- }
- m_directionalWidgets.clear();
-}
-
-void Creature::drawTopWidgets(const Point& dest, const Otc::Direction direction)
-{
- if (direction == Otc::North || direction == Otc::West) {
- for (auto& widget : m_directionalWidgets) {
- Rect dest_rect = widget->getRect();
- dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height());
- widget->setRect(dest_rect);
- widget->draw(dest_rect, Fw::ForegroundPane);
- }
- }
- for (auto& widget : m_topWidgets) {
- Rect dest_rect = widget->getRect();
- dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height());
- widget->setRect(dest_rect);
- widget->draw(dest_rect, Fw::ForegroundPane);
- }
-}
-
-void Creature::drawBottomWidgets(const Point& dest, const Otc::Direction direction)
-{
- for (auto& widget : m_bottomWidgets) {
- Rect dest_rect = widget->getRect();
- dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height());
- widget->setRect(dest_rect);
- widget->draw(dest_rect, Fw::ForegroundPane);
- }
-
- if (direction == Otc::South || direction == Otc::East) {
- for (auto& widget : m_directionalWidgets) {
- Rect dest_rect = widget->getRect();
- dest_rect = Rect(dest - Point(dest_rect.width() / 2, dest_rect.height() / 2), dest_rect.width(), dest_rect.height());
- widget->setRect(dest_rect);
- widget->draw(dest_rect, Fw::ForegroundPane);
- }
- }
-}
-
-void Creature::setProgressBar(uint32 duration, bool ltr)
-{
- if (m_progressBarUpdateEvent) {
- m_progressBarUpdateEvent->cancel();
- m_progressBarUpdateEvent = nullptr;
- }
-
- if (duration > 0) {
- m_progressBarTimer.restart();
- updateProgressBar(duration, ltr);
- } else
- m_progressBarPercent = 0;
-
- callLuaField("onProgressBarStart", duration, ltr);
-}
-
-void Creature::updateProgressBar(uint32 duration, bool ltr)
-{
- if (m_progressBarTimer.ticksElapsed() < duration) {
- if (ltr)
- m_progressBarPercent = abs(m_progressBarTimer.ticksElapsed() / static_cast(duration) * 100);
- else
- m_progressBarPercent = abs((m_progressBarTimer.ticksElapsed() / static_cast(duration) * 100) - 100);
-
- auto self = static_self_cast();
- m_progressBarUpdateEvent = g_dispatcher.scheduleEvent([=] {
- self->updateProgressBar(duration, ltr);
- }, 50);
- } else {
- m_progressBarPercent = 0;
- }
- callLuaField("onProgressBarUpdate", m_progressBarPercent, duration, ltr);
-}
diff --git a/src/client/creature.h b/src/client/creature.h
deleted file mode 100644
index dcfab7c..0000000
--- a/src/client/creature.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-#include
-#include
-#include
-#include
-
- // @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 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 getTopWidgets();
- std::list getBottomWidgets();
- std::list 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 m_showShieldTexture;
- stdext::boolean m_shieldBlink;
- stdext::boolean m_passable;
- Color m_timedSquareColor;
- Color m_staticSquareColor;
- Color m_nameColor;
- stdext::boolean m_showTimedSquare;
- stdext::boolean m_showStaticSquare;
- stdext::boolean 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 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 m_walking;
- stdext::boolean 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 m_bottomWidgets;
- std::list m_directionalWidgets;
- std::list 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
diff --git a/src/client/creatures.cpp b/src/client/creatures.cpp
deleted file mode 100644
index 8ec8c20..0000000
--- a/src/client/creatures.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-
-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("centerx");
- centerPos.y = node->readType("centery");
- centerPos.z = node->readType("centerz");
-
- setCenterPos(centerPos);
- setRadius(node->readType("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("spawntime"));
- Otc::Direction dir = Otc::North;
- int16 dir_ = cNode->readType("direction");
- if(dir_ >= Otc::East && dir_ <= Otc::West)
- dir = (Otc::Direction)dir_;
- cType->setDirection(dir);
-
- Position placePos;
- placePos.x = centerPos.x + cNode->readType("x");
- placePos.y = centerPos.y + cNode->readType("y");
- placePos.z = cNode->readType("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 Spawn::getCreatures()
-{
- std::vector 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("type");
- if(type > 0) {
- out.setCategory(ThingCategoryCreature);
- out.setId(type);
- } else {
- out.setCategory(ThingCategoryItem);
- out.setAuxId(attrib->readType("typeex"));
- }
-
- {
- out.setHead(attrib->readType(("head")));
- out.setBody(attrib->readType(("body")));
- out.setLegs(attrib->readType(("legs")));
- out.setFeet(attrib->readType(("feet")));
- out.setAddons(attrib->readType(("addons")));
- out.setMount(attrib->readType(("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 CreatureManager::getSpawns()
-{
- std::vector spawns;
- for (auto p : m_spawns)
- spawns.push_back(p.second);
- return spawns;
-}
-
-/* vim: set ts=4 sw=4 et: */
diff --git a/src/client/creatures.h b/src/client/creatures.h
deleted file mode 100644
index 6a64f6a..0000000
--- a/src/client/creatures.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#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(SpawnAttrRadius); }
-
- void setCenterPos(const Position& pos) { m_attribs.set(SpawnAttrCenter, pos); }
- Position getCenterPos() { return m_attribs.get(SpawnAttrCenter); }
-
- std::vector 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 m_attribs;
- std::unordered_map 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(CreatureAttrSpawnTime); }
-
- void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); }
- std::string getName() { return m_attribs.get(CreatureAttrName); }
-
- void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); }
- Outfit getOutfit() { return m_attribs.get(CreatureAttrOutfit); }
-
- void setDirection(Otc::Direction dir) { m_attribs.set(CreatureAttrDir, dir); }
- Otc::Direction getDirection() { return m_attribs.get(CreatureAttrDir); }
-
- void setRace(CreatureRace race) { m_attribs.set(CreatureAttrRace, race); }
- CreatureRace getRace() { return m_attribs.get(CreatureAttrRace); }
-
- CreaturePtr cast();
-
-private:
- stdext::dynamic_storage 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 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& getCreatures() { return m_creatures; }
-
-protected:
- void internalLoadCreatureBuffer(TiXmlElement* elem, const CreatureTypePtr& m);
-
-private:
- std::vector m_creatures;
- std::unordered_map m_spawns;
- stdext::boolean m_loaded, m_spawnLoaded;
- CreatureTypePtr m_nullCreature;
-};
-
-extern CreatureManager g_creatures;
-
-#endif
diff --git a/src/client/declarations.h b/src/client/declarations.h
deleted file mode 100644
index ffd46cf..0000000
--- a/src/client/declarations.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-
-// 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 MapViewPtr;
-typedef stdext::shared_object_ptr LightViewPtr;
-typedef stdext::shared_object_ptr TilePtr;
-typedef stdext::shared_object_ptr ThingPtr;
-typedef stdext::shared_object_ptr- ItemPtr;
-typedef stdext::shared_object_ptr ContainerPtr;
-typedef stdext::shared_object_ptr CreaturePtr;
-typedef stdext::shared_object_ptr MonsterPtr;
-typedef stdext::shared_object_ptr NpcPtr;
-typedef stdext::shared_object_ptr PlayerPtr;
-typedef stdext::shared_object_ptr LocalPlayerPtr;
-typedef stdext::shared_object_ptr EffectPtr;
-typedef stdext::shared_object_ptr MissilePtr;
-typedef stdext::shared_object_ptr AnimatedTextPtr;
-typedef stdext::shared_object_ptr StaticTextPtr;
-typedef stdext::shared_object_ptr AnimatorPtr;
-typedef stdext::shared_object_ptr ThingTypePtr;
-typedef stdext::shared_object_ptr ItemTypePtr;
-typedef stdext::shared_object_ptr HousePtr;
-typedef stdext::shared_object_ptr TownPtr;
-typedef stdext::shared_object_ptr CreatureTypePtr;
-typedef stdext::shared_object_ptr SpawnPtr;
-
-typedef std::vector ThingList;
-typedef std::vector ThingTypeList;
-typedef std::vector ItemTypeList;
-typedef std::list HouseList;
-typedef std::list TownList;
-typedef std::list ItemList;
-typedef std::list TileList;
-typedef std::vector ItemVector;
-typedef std::unordered_map TileMap;
-typedef std::unordered_map CreatureMap;
-typedef std::unordered_map SpawnMap;
-
-// net
-class ProtocolLogin;
-class ProtocolGame;
-
-typedef stdext::shared_object_ptr ProtocolGamePtr;
-typedef stdext::shared_object_ptr ProtocolLoginPtr;
-
-// ui
-class UIItem;
-class UICreature;
-class UIMap;
-class UIMinimap;
-class UIProgressRect;
-class UIMapAnchorLayout;
-class UIPositionAnchor;
-class UISprite;
-
-typedef stdext::shared_object_ptr UIItemPtr;
-typedef stdext::shared_object_ptr UICreaturePtr;
-typedef stdext::shared_object_ptr UISpritePtr;
-typedef stdext::shared_object_ptr UIMapPtr;
-typedef stdext::shared_object_ptr UIMinimapPtr;
-typedef stdext::shared_object_ptr UIProgressRectPtr;
-typedef stdext::shared_object_ptr UIMapAnchorLayoutPtr;
-typedef stdext::shared_object_ptr UIPositionAnchorPtr;
-
-#endif
diff --git a/src/client/effect.cpp b/src/client/effect.cpp
deleted file mode 100644
index b650e90..0000000
--- a/src/client/effect.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-
-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)(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);
-}
diff --git a/src/client/effect.h b/src/client/effect.h
deleted file mode 100644
index 2399499..0000000
--- a/src/client/effect.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-#include
-#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(); }
- 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
diff --git a/src/client/game.cpp b/src/client/game.cpp
deleted file mode 100644
index 410dba0..0000000
--- a/src/client/game.cpp
+++ /dev/null
@@ -1,1648 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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 "game.h"
-#include "localplayer.h"
-#include "map.h"
-#include "tile.h"
-#include "creature.h"
-#include "container.h"
-#include "statictext.h"
-#include
-#include
-#include
-#include "luavaluecasts_client.h"
-#include "protocolgame.h"
-#include "protocolcodes.h"
-
-#include
-
-Game g_game;
-
-Game::Game()
-{
- m_protocolVersion = 0;
- m_clientCustomOs = -1;
- m_clientVersion = 0;
- m_online = false;
- m_denyBotCall = false;
- m_dead = false;
- m_serverBeat = 50;
- m_seq = 0;
- m_ping = -1;
- m_pingDelay = 1000;
- m_newPingDelay = 250;
- m_canReportBugs = false;
- m_fightMode = Otc::FightBalanced;
- m_chaseMode = Otc::DontChase;
- m_pvpMode = Otc::WhiteDove;
- m_safeFight = true;
-}
-
-void Game::init()
-{
- resetGameStates();
-}
-
-void Game::terminate()
-{
- resetGameStates();
- m_protocolGame = nullptr;
-}
-
-void Game::resetGameStates()
-{
- m_online = false;
- m_denyBotCall = false;
- m_dead = false;
- m_serverBeat = 50;
- m_seq = 0;
- m_ping = -1;
- m_canReportBugs = false;
- m_fightMode = Otc::FightBalanced;
- m_chaseMode = Otc::DontChase;
- m_pvpMode = Otc::WhiteDove;
- m_safeFight = true;
- m_followingCreature = nullptr;
- m_attackingCreature = nullptr;
- m_localPlayer = nullptr;
- m_pingSent = 0;
- m_pingReceived = 0;
- m_walkId = 0;
- m_walkPrediction = 0;
- m_coins = 0;
- m_transferableCoins = 0;
- m_newPingIds.clear();
- m_unjustifiedPoints = UnjustifiedPoints();
-
- for(auto& it : m_containers) {
- const ContainerPtr& container = it.second;
- if(container)
- container->onClose();
- }
-
- if(m_pingEvent) {
- m_pingEvent->cancel();
- m_pingEvent = nullptr;
- }
-
- if (m_newPingEvent) {
- m_newPingEvent->cancel();
- m_newPingEvent = nullptr;
- }
-
- if(m_checkConnectionEvent) {
- m_checkConnectionEvent->cancel();
- m_checkConnectionEvent = nullptr;
- }
-
- m_containers.clear();
- m_vips.clear();
- m_gmActions.clear();
- g_map.resetAwareRange();
-}
-
-void Game::processConnectionError(const boost::system::error_code& ec)
-{
- // connection errors only have meaning if we still have a protocol
- if(m_protocolGame) {
- // eof = end of file, a clean disconnect
- if(ec != asio::error::eof)
- g_lua.callGlobalField("g_game", "onConnectionError", ec.message(), ec.value());
-
- processDisconnect();
- }
-}
-
-void Game::processDisconnect()
-{
- if(isOnline())
- processGameEnd();
-
- if(m_protocolGame) {
- m_protocolGame->disconnect();
- m_protocolGame = nullptr;
- }
-}
-
-void Game::processUpdateNeeded(const std::string& signature)
-{
- g_lua.callGlobalField("g_game", "onUpdateNeeded", signature);
-}
-
-void Game::processLoginError(const std::string& error)
-{
- g_lua.callGlobalField("g_game", "onLoginError", error);
-}
-
-void Game::processLoginAdvice(const std::string& message)
-{
- g_lua.callGlobalField("g_game", "onLoginAdvice", message);
-}
-
-void Game::processLoginWait(const std::string& message, int time)
-{
- g_lua.callGlobalField("g_game", "onLoginWait", message, time);
-}
-
-void Game::processLoginToken(bool unknown)
-{
- g_lua.callGlobalField("g_game", "onLoginToken", unknown);
-}
-
-void Game::processLogin()
-{
- g_lua.callGlobalField("g_game", "onLogin");
-}
-
-void Game::processPendingGame()
-{
- m_localPlayer->setPendingGame(true);
- g_lua.callGlobalField("g_game", "onPendingGame");
- m_protocolGame->sendEnterGame();
-}
-
-void Game::processEnterGame()
-{
- m_localPlayer->setPendingGame(false);
- g_lua.callGlobalField("g_game", "onEnterGame");
-}
-
-void Game::processGameStart()
-{
- m_online = true;
-
- // synchronize fight modes with the server
- m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode);
-
- // NOTE: the entire map description and local player information is not known yet (bot call is allowed here)
- enableBotCall();
- g_lua.callGlobalField("g_game", "onGameStart");
- disableBotCall();
-
- if (g_game.getFeature(Otc::GameExtendedClientPing)) {
- m_newPingEvent = g_dispatcher.scheduleEvent([] {
- g_game.newPing();
- }, m_newPingDelay);
- }
- if(g_game.getFeature(Otc::GameClientPing)) {
- m_pingEvent = g_dispatcher.scheduleEvent([] {
- g_game.ping();
- }, m_pingDelay);
- }
-
- m_checkConnectionEvent = g_dispatcher.cycleEvent([this] {
- if(!g_game.isConnectionOk() && !m_connectionFailWarned) {
- g_lua.callGlobalField("g_game", "onConnectionFailing", true);
- m_connectionFailWarned = true;
- } else if(g_game.isConnectionOk() && m_connectionFailWarned) {
- g_lua.callGlobalField("g_game", "onConnectionFailing", false);
- m_connectionFailWarned = false;
- }
- }, 1000);
-}
-
-void Game::processGameEnd()
-{
- m_online = false;
- g_lua.callGlobalField("g_game", "onGameEnd");
-
- if(m_connectionFailWarned) {
- g_lua.callGlobalField("g_game", "onConnectionFailing", false);
- m_connectionFailWarned = false;
- }
-
- // reset game state
- resetGameStates();
-
- m_worldName = "";
- m_characterName = "";
-
- // clean map creatures
- g_map.cleanDynamicThings();
-}
-
-void Game::processDeath(int deathType, int penality)
-{
- m_dead = true;
- m_localPlayer->stopWalk();
-
- g_lua.callGlobalField("g_game", "onDeath", deathType, penality);
-}
-
-void Game::processGMActions(const std::vector& actions)
-{
- m_gmActions = actions;
- g_lua.callGlobalField("g_game", "onGMActions", actions);
-}
-
-void Game::processPlayerHelpers(int helpers)
-{
- g_lua.callGlobalField("g_game", "onPlayerHelpersUpdate", helpers);
-}
-
-void Game::processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode)
-{
- m_fightMode = fightMode;
- m_chaseMode = chaseMode;
- m_safeFight = safeMode;
- m_pvpMode = pvpMode;
-
- g_lua.callGlobalField("g_game", "onFightModeChange", fightMode);
- g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode);
- g_lua.callGlobalField("g_game", "onSafeFightChange", safeMode);
- g_lua.callGlobalField("g_game", "onPVPModeChange", pvpMode);
-}
-
-void Game::processPing()
-{
- g_lua.callGlobalField("g_game", "onPing");
- enableBotCall();
- m_protocolGame->sendPingBack();
- disableBotCall();
-}
-
-void Game::processPingBack()
-{
- m_pingReceived++;
-
- if (!g_game.getFeature(Otc::GameExtendedClientPing)) {
- if (m_pingReceived == m_pingSent)
- m_ping = m_pingTimer.elapsed_millis();
-
- g_lua.callGlobalField("g_game", "onPingBack", m_ping);
- }
-
- m_pingEvent = g_dispatcher.scheduleEvent([] {
- g_game.ping();
- }, m_pingDelay);
-}
-
-void Game::processNewPing(uint32_t pingId)
-{
- auto it = m_newPingIds.find(pingId);
-
- if (it == m_newPingIds.end())
- return;
-
- m_ping = it->second.elapsed_millis();
- g_lua.callGlobalField("g_game", "onPingBack", m_ping);
-}
-
-void Game::processTextMessage(Otc::MessageMode mode, const std::string& text)
-{
- g_lua.callGlobalField("g_game", "onTextMessage", mode, text);
-}
-
-void Game::processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos)
-{
- g_lua.callGlobalField("g_game", "onTalk", name, level, mode, text, channelId, pos);
-}
-
-void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex)
-{
- ContainerPtr previousContainer = getContainer(containerId);
- ContainerPtr container = ContainerPtr(new Container(containerId, capacity, name, containerItem, hasParent, isUnlocked, hasPages, containerSize, firstIndex));
- m_containers[containerId] = container;
- container->onAddItems(items);
-
- // we might want to close a container here
- enableBotCall();
- container->onOpen(previousContainer);
- disableBotCall();
-
- if(previousContainer)
- previousContainer->onClose();
-}
-
-void Game::processCloseContainer(int containerId)
-{
- ContainerPtr container = getContainer(containerId);
- if(!container) {
- return;
- }
-
- m_containers[containerId] = nullptr;
- container->onClose();
-}
-
-void Game::processContainerAddItem(int containerId, const ItemPtr& item, int slot)
-{
- ContainerPtr container = getContainer(containerId);
- if(!container) {
- return;
- }
-
- container->onAddItem(item, slot);
-}
-
-void Game::processContainerUpdateItem(int containerId, int slot, const ItemPtr& item)
-{
- ContainerPtr container = getContainer(containerId);
- if(!container) {
- return;
- }
-
- container->onUpdateItem(slot, item);
-}
-
-void Game::processContainerRemoveItem(int containerId, int slot, const ItemPtr& lastItem)
-{
- ContainerPtr container = getContainer(containerId);
- if(!container) {
- return;
- }
-
- container->onRemoveItem(slot, lastItem);
-}
-
-void Game::processInventoryChange(int slot, const ItemPtr& item)
-{
- if(item)
- item->setPosition(Position(65535, slot, 0));
-
- m_localPlayer->setInventoryItem((Otc::InventorySlot)slot, item);
-}
-
-void Game::processChannelList(const std::vector >& channelList)
-{
- g_lua.callGlobalField("g_game", "onChannelList", channelList);
-}
-
-void Game::processOpenChannel(int channelId, const std::string& name)
-{
- g_lua.callGlobalField("g_game", "onOpenChannel", channelId, name);
-}
-
-void Game::processOpenPrivateChannel(const std::string& name)
-{
- g_lua.callGlobalField("g_game", "onOpenPrivateChannel", name);
-}
-
-void Game::processOpenOwnPrivateChannel(int channelId, const std::string& name)
-{
- g_lua.callGlobalField("g_game", "onOpenOwnPrivateChannel", channelId, name);
-}
-
-void Game::processCloseChannel(int channelId)
-{
- g_lua.callGlobalField("g_game", "onCloseChannel", channelId);
-}
-
-void Game::processRuleViolationChannel(int channelId)
-{
- g_lua.callGlobalField("g_game", "onRuleViolationChannel", channelId);
-}
-
-void Game::processRuleViolationRemove(const std::string& name)
-{
- g_lua.callGlobalField("g_game", "onRuleViolationRemove", name);
-}
-
-void Game::processRuleViolationCancel(const std::string& name)
-{
- g_lua.callGlobalField("g_game", "onRuleViolationCancel", name);
-}
-
-void Game::processRuleViolationLock()
-{
- g_lua.callGlobalField("g_game", "onRuleViolationLock");
-}
-
-void Game::processVipAdd(uint id, const std::string& name, uint status, const std::string& description, int iconId, bool notifyLogin)
-{
- m_vips[id] = Vip(name, status, description, iconId, notifyLogin);
- g_lua.callGlobalField("g_game", "onAddVip", id, name, status, description, iconId, notifyLogin);
-}
-
-void Game::processVipStateChange(uint id, uint status)
-{
- if (m_vips.find(id) == m_vips.end()) return;
- std::get<1>(m_vips[id]) = status;
- g_lua.callGlobalField("g_game", "onVipStateChange", id, status);
-}
-
-void Game::processTutorialHint(int id)
-{
- g_lua.callGlobalField("g_game", "onTutorialHint", id);
-}
-
-void Game::processAddAutomapFlag(const Position& pos, int icon, const std::string& message)
-{
- g_lua.callGlobalField("g_game", "onAddAutomapFlag", pos, icon, message);
-}
-
-void Game::processRemoveAutomapFlag(const Position& pos, int icon, const std::string& message)
-{
- g_lua.callGlobalField("g_game", "onRemoveAutomapFlag", pos, icon, message);
-}
-
-void Game::processOpenOutfitWindow(const Outfit& currentOutfit, const std::vector >& outfitList,
- const std::vector >& mountList)
-{
- // create virtual creature outfit
- CreaturePtr virtualOutfitCreature = CreaturePtr(new Creature);
- virtualOutfitCreature->setDirection(Otc::South);
-
- Outfit outfit = currentOutfit;
- outfit.setMount(0);
- virtualOutfitCreature->setOutfit(outfit);
-
- // creature virtual mount outfit
- CreaturePtr virtualMountCreature = nullptr;
- if(getFeature(Otc::GamePlayerMounts))
- {
- virtualMountCreature = CreaturePtr(new Creature);
- virtualMountCreature->setDirection(Otc::South);
-
- Outfit mountOutfit;
- mountOutfit.setId(0);
-
- int mount = currentOutfit.getMount();
- if(mount > 0)
- mountOutfit.setId(mount);
-
- virtualMountCreature->setOutfit(mountOutfit);
- }
-
- g_lua.callGlobalField("g_game", "onOpenOutfitWindow", virtualOutfitCreature, outfitList, virtualMountCreature, mountList);
-}
-
-void Game::processOpenNpcTrade(const std::vector >& items)
-{
- g_lua.callGlobalField("g_game", "onOpenNpcTrade", items);
-}
-
-void Game::processPlayerGoods(uint64_t money, const std::vector >& goods)
-{
- g_lua.callGlobalField("g_game", "onPlayerGoods", money, goods);
-}
-
-void Game::processCloseNpcTrade()
-{
- g_lua.callGlobalField("g_game", "onCloseNpcTrade");
-}
-
-void Game::processOwnTrade(const std::string& name, const std::vector& items)
-{
- g_lua.callGlobalField("g_game", "onOwnTrade", name, items);
-}
-
-void Game::processCounterTrade(const std::string& name, const std::vector& items)
-{
- g_lua.callGlobalField("g_game", "onCounterTrade", name, items);
-}
-
-void Game::processCloseTrade()
-{
- g_lua.callGlobalField("g_game", "onCloseTrade");
-}
-
-void Game::processEditText(uint id, int itemId, int maxLength, const std::string& text, const std::string& writer, const std::string& date)
-{
- g_lua.callGlobalField("g_game", "onEditText", id, itemId, maxLength, text, writer, date);
-}
-
-void Game::processEditList(uint id, int doorId, const std::string& text)
-{
- g_lua.callGlobalField("g_game", "onEditList", id, doorId, text);
-}
-
-void Game::processQuestLog(const std::vector >& questList)
-{
- g_lua.callGlobalField("g_game", "onQuestLog", questList);
-}
-
-void Game::processQuestLine(int questId, const std::vector >& questMissions)
-{
- g_lua.callGlobalField("g_game", "onQuestLine", questId, questMissions);
-}
-
-void Game::processModalDialog(uint32 id, std::string title, std::string message, std::vector > buttonList, int enterButton, int escapeButton, std::vector > choiceList, bool priority)
-{
- g_lua.callGlobalField("g_game", "onModalDialog", id, title, message, buttonList, enterButton, escapeButton, choiceList, priority);
-}
-
-void Game::processAttackCancel(uint seq)
-{
- if(seq == 0 || m_seq == seq)
- cancelAttack();
-}
-
-void Game::processWalkCancel(Otc::Direction direction)
-{
- m_localPlayer->cancelWalk(direction);
-}
-
-void Game::processNewWalkCancel(Otc::Direction dir)
-{
- m_walkId += 1;
- m_localPlayer->cancelNewWalk(dir);
-}
-
-void Game::processPredictiveWalkCancel(const Position& pos, Otc::Direction dir)
-{
- m_walkPrediction += 1;
- if (m_localPlayer->predictiveCancelWalk(pos, m_walkPrediction, dir)) {
- m_walkId += 1;
- }
-}
-
-void Game::processWalkId(uint32_t walkId)
-{
- m_walkId = std::max(m_walkId, walkId); // fixes desync
-}
-
-void Game::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)
-{
- if(m_protocolGame || isOnline())
- stdext::throw_exception("Unable to login into a world while already online or logging.");
-
- if(m_protocolVersion == 0)
- stdext::throw_exception("Must set a valid game protocol version before logging.");
-
- // reset the new game state
- resetGameStates();
-
- m_localPlayer = LocalPlayerPtr(new LocalPlayer);
- m_localPlayer->setName(characterName);
-
- m_protocolGame = ProtocolGamePtr(new ProtocolGame);
- m_protocolGame->login(account, password, worldHost, (uint16)worldPort, characterName, authenticatorToken, sessionKey);
- m_characterName = characterName;
- m_worldName = worldName;
-}
-
-void Game::cancelLogin()
-{
- // send logout even if the game has not started yet, to make sure that the player doesn't stay logged there
- if(m_protocolGame)
- m_protocolGame->sendLogout();
-
- g_lua.callGlobalField("g_game", "onLogout");
- processDisconnect();
-}
-
-void Game::forceLogout()
-{
- if(!isOnline())
- return;
-
- g_lua.callGlobalField("g_game", "onLogout");
- m_protocolGame->sendLogout();
- processDisconnect();
-}
-
-void Game::safeLogout()
-{
- if(!isOnline())
- return;
-
- g_lua.callGlobalField("g_game", "onLogout");
- m_protocolGame->sendLogout();
-}
-
-void Game::autoWalk(const std::vector& dirs, Position startPos)
-{
- if(!canPerformGameAction())
- return;
-
- if (dirs.size() == 0)
- return;
-
- // protocol limits walk path
- if((!g_game.getFeature(Otc::GameNewWalking) || dirs.size() > 4097) && dirs.size() > 127) {
- g_logger.error("Auto walk path too great");
- return;
- }
-
- if (g_extras.debugWalking) {
- g_logger.info(stdext::format("[%i] Game::autoWalk", (int)g_clock.millis()));
- }
-
- // must cancel follow before any new walk
- if (isFollowing()) {
- cancelFollow();
- }
-
- auto it = dirs.begin();
- Otc::Direction direction = *it;
-
- uint8_t flags = 0x04; // auto walk flag
-
- TilePtr toTile = g_map.getTile(startPos.translatedToDirection(direction));
- if(startPos == m_localPlayer->getPrewalkingPosition() && toTile && toTile->isWalkable() && !m_localPlayer->isWalking() && m_localPlayer->canWalk(direction, true)) {
- m_localPlayer->preWalk(direction);
- m_localPlayer->startServerWalking();
- flags |= 0x01; // prewalk flag
- }
-
- g_lua.callGlobalField("g_game", "onAutoWalk", dirs);
-
- if (g_game.getFeature(Otc::GameNewWalking))
- m_protocolGame->sendNewWalk(m_walkId, m_walkPrediction, startPos, flags, dirs);
- else
- m_protocolGame->sendAutoWalk(dirs);
-}
-
-void Game::walk(Otc::Direction direction, bool withPreWalk)
-{
- m_denyBotCall = false;
- if (!canPerformGameAction()) {
- m_denyBotCall = true;
- return;
- }
- if (g_extras.debugWalking) {
- g_logger.info(stdext::format("[%i] Game::walk", (int)g_clock.millis()));
- }
-
- g_lua.callGlobalField("g_game", "onWalk", direction, withPreWalk);
-
- if (g_game.getFeature(Otc::GameNewWalking)) {
- //hidden
- return;
- }
-
- switch(direction) {
- case Otc::North:
- m_protocolGame->sendWalkNorth();
- break;
- case Otc::East:
- m_protocolGame->sendWalkEast();
- break;
- case Otc::South:
- m_protocolGame->sendWalkSouth();
- break;
- case Otc::West:
- m_protocolGame->sendWalkWest();
- break;
- case Otc::NorthEast:
- m_protocolGame->sendWalkNorthEast();
- break;
- case Otc::SouthEast:
- m_protocolGame->sendWalkSouthEast();
- break;
- case Otc::SouthWest:
- m_protocolGame->sendWalkSouthWest();
- break;
- case Otc::NorthWest:
- m_protocolGame->sendWalkNorthWest();
- break;
- default:
- break;
- }
- m_denyBotCall = true;
-}
-
-void Game::turn(Otc::Direction direction)
-{
- m_denyBotCall = false;
- if (!canPerformGameAction()) {
- m_denyBotCall = true;
- return;
- }
-
- if (g_game.getFeature(Otc::GameNewWalking)) {
- m_localPlayer->setDirection(direction);
- }
-
- switch(direction) {
- case Otc::North:
- m_protocolGame->sendTurnNorth();
- break;
- case Otc::East:
- m_protocolGame->sendTurnEast();
- break;
- case Otc::South:
- m_protocolGame->sendTurnSouth();
- break;
- case Otc::West:
- m_protocolGame->sendTurnWest();
- break;
- default:
- break;
- }
- m_denyBotCall = true;
-}
-
-void Game::stop()
-{
- if (g_extras.debugWalking) {
- g_logger.info(stdext::format("[%i] Game::stop", (int)g_clock.millis()));
- }
-
- m_denyBotCall = false;
- if (!canPerformGameAction()) {
- m_denyBotCall = true;
- return;
- }
-
- if(isFollowing())
- cancelFollow(); // can change m_denyBotCall
- m_denyBotCall = false;
-
- m_protocolGame->sendStop();
- m_denyBotCall = true;
-}
-
-void Game::look(const ThingPtr& thing, bool isBattleList)
-{
- if(!canPerformGameAction() || !thing)
- return;
-
- if(thing->isCreature() && isBattleList && m_protocolVersion >= 961)
- m_protocolGame->sendLookCreature(thing->getId());
- else
- m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackPos());
-}
-
-void Game::move(const ThingPtr& thing, const Position& toPos, int count)
-{
- if (count <= 0)
- count = 1;
-
- if (!canPerformGameAction() || !thing || thing->getPosition() == toPos)
- return;
-
- uint id = thing->getId();
- if (thing->isCreature()) {
- CreaturePtr creature = thing->static_self_cast();
- id = Proto::Creature;
- }
-
- m_protocolGame->sendMove(thing->getPosition(), id, thing->getStackPos(), toPos, count);
-}
-
-void Game::moveRaw(const Position& pos, int id, int stackpos, const Position& toPos, int count)
-{
- if (!canPerformGameAction())
- return;
-
- m_protocolGame->sendMove(pos, id, stackpos, toPos, count);
-}
-
-void Game::moveToParentContainer(const ThingPtr& thing, int count)
-{
- if(!canPerformGameAction() || !thing || count <= 0)
- return;
-
- Position position = thing->getPosition();
- move(thing, Position(position.x, position.y, 254), count);
-}
-
-void Game::rotate(const ThingPtr& thing)
-{
- if(!canPerformGameAction() || !thing)
- return;
-
- m_protocolGame->sendRotateItem(thing->getPosition(), thing->getId(), thing->getStackPos());
-}
-
-void Game::wrap(const ThingPtr& thing)
-{
- if (!canPerformGameAction() || !thing)
- return;
-
- m_protocolGame->sendWrapableItem(thing->getPosition(), thing->getId(), thing->getStackPos());
-}
-
-void Game::use(const ThingPtr& thing)
-{
- if(!canPerformGameAction() || !thing)
- return;
-
- Position pos = thing->getPosition();
- if(!pos.isValid()) // virtual item
- pos = Position(0xFFFF, 0, 0); // inventory item
-
- // some items, e.g. parcel, are not set as containers but they are.
- // always try to use these items in free container slots.
- m_protocolGame->sendUseItem(pos, thing->getId(), thing->getStackPos(), findEmptyContainerId());
-
- g_lua.callGlobalField("g_game", "onUse", pos, thing->getId(), thing->getStackPos(), 0);
-}
-
-void Game::useInventoryItem(int itemId, int subType)
-{
- if(!canPerformGameAction() || !g_things.isValidDatId(itemId, ThingCategoryItem))
- return;
-
- Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
-
- m_protocolGame->sendUseItem(pos, itemId, 0, subType);
-
- g_lua.callGlobalField("g_game", "onUse", pos, itemId, 0, subType);
-}
-
-void Game::useWith(const ItemPtr& item, const ThingPtr& toThing, int subType)
-{
- if(!canPerformGameAction() || !item || !toThing)
- return;
-
- Position pos = item->getPosition();
- if(!pos.isValid()) // virtual item
- pos = Position(0xFFFF, 0, 0); // means that is an item in inventory
-
- if(toThing->isCreature() && g_game.getProtocolVersion() >= 780)
- m_protocolGame->sendUseOnCreature(pos, item->getId(), subType ? subType : item->getStackPos(), toThing->getId());
- else
- m_protocolGame->sendUseItemWith(pos, item->getId(), subType ? subType : item->getStackPos(), toThing->getPosition(), toThing->getId(), toThing->getStackPos());
-
- g_lua.callGlobalField("g_game", "onUseWith", pos, item->getId(), toThing, subType);
-}
-
-void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing, int subType)
-{
- if(!canPerformGameAction() || !toThing)
- return;
-
- Position pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
-
- if(toThing->isCreature())
- m_protocolGame->sendUseOnCreature(pos, itemId, subType, toThing->getId());
- else
- m_protocolGame->sendUseItemWith(pos, itemId, subType, toThing->getPosition(), toThing->getId(), toThing->getStackPos());
-
- g_lua.callGlobalField("g_game", "onUseWith", pos, itemId, toThing, subType);
-}
-
-ItemPtr Game::findItemInContainers(uint itemId, int subType)
-{
- for(auto& it : m_containers) {
- const ContainerPtr& container = it.second;
-
- if(container) {
- ItemPtr item = container->findItemById(itemId, subType);
- if(item != nullptr)
- return item;
- }
- }
- return nullptr;
-}
-
-int Game::open(const ItemPtr& item, const ContainerPtr& previousContainer)
-{
- if(!canPerformGameAction() || !item)
- return -1;
-
- int id = 0;
- if(!previousContainer)
- id = findEmptyContainerId();
- else
- id = previousContainer->getId();
-
- m_protocolGame->sendUseItem(item->getPosition(), item->getId(), item->getStackPos(), id);
- return id;
-}
-
-void Game::openParent(const ContainerPtr& container)
-{
- if(!canPerformGameAction() || !container)
- return;
-
- m_protocolGame->sendUpContainer(container->getId());
-}
-
-void Game::close(const ContainerPtr& container)
-{
- if(!canPerformGameAction() || !container)
- return;
-
- m_protocolGame->sendCloseContainer(container->getId());
-}
-
-void Game::refreshContainer(const ContainerPtr& container)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRefreshContainer(container->getId());
-}
-
-void Game::attack(CreaturePtr creature, bool cancel)
-{
- if(!canPerformGameAction() || creature == m_localPlayer)
- return;
-
- // cancel when attacking again
- if(creature && creature == m_attackingCreature)
- creature = nullptr;
-
- if(creature && isFollowing())
- cancelFollow();
-
- setAttackingCreature(creature);
- m_localPlayer->stopAutoWalk();
-
- if(m_protocolVersion >= 963) {
- if(creature)
- m_seq = creature->getId();
- } else
- m_seq++;
-
- if(!cancel)
- m_protocolGame->sendAttack(creature ? creature->getId() : 0, m_seq);
-}
-
-void Game::follow(CreaturePtr creature)
-{
- m_denyBotCall = false;
- if (!canPerformGameAction() || creature == m_localPlayer) {
- m_denyBotCall = true;
- return;
- }
-
- // cancel when following again
- if(creature && creature == m_followingCreature)
- creature = nullptr;
-
- if(creature && isAttacking())
- cancelAttack();
-
- setFollowingCreature(creature);
- m_localPlayer->stopAutoWalk();
-
- if(m_protocolVersion >= 963) {
- if(creature)
- m_seq = creature->getId();
- } else
- m_seq++;
-
- m_protocolGame->sendFollow(creature ? creature->getId() : 0, m_seq);
- m_denyBotCall = true;
-}
-
-void Game::cancelAttackAndFollow()
-{
- if(!canPerformGameAction())
- return;
-
- if(isFollowing())
- setFollowingCreature(nullptr);
- if(isAttacking())
- setAttackingCreature(nullptr);
-
- m_localPlayer->stopAutoWalk();
-
- m_protocolGame->sendCancelAttackAndFollow();
-
- g_lua.callGlobalField("g_game", "onCancelAttackAndFollow");
-}
-
-void Game::talk(const std::string& message)
-{
- if(!canPerformGameAction() || message.empty())
- return;
-
- talkChannel(Otc::MessageSay, 0, message);
-}
-
-void Game::talkChannel(Otc::MessageMode mode, int channelId, const std::string& message)
-{
- if(!canPerformGameAction() || message.empty())
- return;
-
- m_protocolGame->sendTalk(mode, channelId, "", message, m_localPlayer->getPosition(), m_localPlayer->getDirection());
-}
-
-void Game::talkPrivate(Otc::MessageMode mode, const std::string& receiver, const std::string& message)
-{
- if(!canPerformGameAction() || receiver.empty() || message.empty())
- return;
- m_protocolGame->sendTalk(mode, 0, receiver, message, m_localPlayer->getPosition(), m_localPlayer->getDirection());
-}
-
-void Game::openPrivateChannel(const std::string& receiver)
-{
- if(!canPerformGameAction() || receiver.empty())
- return;
- m_protocolGame->sendOpenPrivateChannel(receiver);
-}
-
-void Game::requestChannels()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestChannels();
-}
-
-void Game::joinChannel(int channelId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendJoinChannel(channelId);
-}
-
-void Game::leaveChannel(int channelId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendLeaveChannel(channelId);
-}
-
-void Game::closeNpcChannel()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendCloseNpcChannel();
-}
-
-void Game::openOwnChannel()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendOpenOwnChannel();
-}
-
-void Game::inviteToOwnChannel(const std::string& name)
-{
- if(!canPerformGameAction() || name.empty())
- return;
- m_protocolGame->sendInviteToOwnChannel(name);
-}
-
-void Game::excludeFromOwnChannel(const std::string& name)
-{
- if(!canPerformGameAction() || name.empty())
- return;
- m_protocolGame->sendExcludeFromOwnChannel(name);
-}
-
-void Game::partyInvite(int creatureId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendInviteToParty(creatureId);
-}
-
-void Game::partyJoin(int creatureId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendJoinParty(creatureId);
-}
-
-void Game::partyRevokeInvitation(int creatureId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRevokeInvitation(creatureId);
-}
-
-void Game::partyPassLeadership(int creatureId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendPassLeadership(creatureId);
-}
-
-void Game::partyLeave()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendLeaveParty();
-}
-
-void Game::partyShareExperience(bool active)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendShareExperience(active);
-}
-
-void Game::requestOutfit()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestOutfit();
-}
-
-void Game::changeOutfit(const Outfit& outfit)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendChangeOutfit(outfit);
-}
-
-void Game::addVip(const std::string& name)
-{
- if(!canPerformGameAction() || name.empty())
- return;
- m_protocolGame->sendAddVip(name);
-}
-
-void Game::removeVip(int playerId)
-{
- if(!canPerformGameAction())
- return;
-
- auto it = m_vips.find(playerId);
- if(it == m_vips.end())
- return;
- m_vips.erase(it);
- m_protocolGame->sendRemoveVip(playerId);
-}
-
-void Game::editVip(int playerId, const std::string& description, int iconId, bool notifyLogin)
-{
- if(!canPerformGameAction())
- return;
-
- auto it = m_vips.find(playerId);
- if(it == m_vips.end())
- return;
-
- std::get<2>(m_vips[playerId]) = description;
- std::get<3>(m_vips[playerId]) = iconId;
- std::get<4>(m_vips[playerId]) = notifyLogin;
-
- if(getFeature(Otc::GameAdditionalVipInfo))
- m_protocolGame->sendEditVip(playerId, description, iconId, notifyLogin);
-}
-
-void Game::setChaseMode(Otc::ChaseModes chaseMode)
-{
- if(!canPerformGameAction())
- return;
- if(m_chaseMode == chaseMode)
- return;
- m_chaseMode = chaseMode;
- m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode);
- g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode);
-}
-
-void Game::setFightMode(Otc::FightModes fightMode)
-{
- if(!canPerformGameAction())
- return;
- if(m_fightMode == fightMode)
- return;
- m_fightMode = fightMode;
- m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode);
- g_lua.callGlobalField("g_game", "onFightModeChange", fightMode);
-}
-
-void Game::setSafeFight(bool on)
-{
- if(!canPerformGameAction())
- return;
- if(m_safeFight == on)
- return;
- m_safeFight = on;
- m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode);
- g_lua.callGlobalField("g_game", "onSafeFightChange", on);
-}
-
-void Game::setPVPMode(Otc::PVPModes pvpMode)
-{
- if(!canPerformGameAction())
- return;
- if(!getFeature(Otc::GamePVPMode))
- return;
- if(m_pvpMode == pvpMode)
- return;
- m_pvpMode = pvpMode;
- m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode);
- g_lua.callGlobalField("g_game", "onPVPModeChange", pvpMode);
-}
-
-void Game::setUnjustifiedPoints(UnjustifiedPoints unjustifiedPoints)
-{
- if(!canPerformGameAction())
- return;
- if(!getFeature(Otc::GameUnjustifiedPoints))
- return;
- if(m_unjustifiedPoints == unjustifiedPoints)
- return;
-
- m_unjustifiedPoints = unjustifiedPoints;
- g_lua.callGlobalField("g_game", "onUnjustifiedPointsChange", unjustifiedPoints);
-}
-
-void Game::setOpenPvpSituations(int openPvpSituations)
-{
- if(!canPerformGameAction())
- return;
- if(m_openPvpSituations == openPvpSituations)
- return;
-
- m_openPvpSituations = openPvpSituations;
- g_lua.callGlobalField("g_game", "onOpenPvpSituationsChange", openPvpSituations);
-}
-
-
-void Game::inspectNpcTrade(const ItemPtr& item)
-{
- if(!canPerformGameAction() || !item)
- return;
- m_protocolGame->sendInspectNpcTrade(item->getId(), item->getCount());
-}
-
-void Game::buyItem(const ItemPtr& item, int amount, bool ignoreCapacity, bool buyWithBackpack)
-{
- if(!canPerformGameAction() || !item)
- return;
- m_protocolGame->sendBuyItem(item->getId(), item->getCountOrSubType(), amount, ignoreCapacity, buyWithBackpack);
-}
-
-void Game::sellItem(const ItemPtr& item, int amount, bool ignoreEquipped)
-{
- if(!canPerformGameAction() || !item)
- return;
- m_protocolGame->sendSellItem(item->getId(), item->getCountOrSubType(), amount, ignoreEquipped);
-}
-
-void Game::closeNpcTrade()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendCloseNpcTrade();
-}
-
-void Game::requestTrade(const ItemPtr& item, const CreaturePtr& creature)
-{
- if(!canPerformGameAction() || !item || !creature)
- return;
- m_protocolGame->sendRequestTrade(item->getPosition(), item->getId(), item->getStackPos(), creature->getId());
-}
-
-void Game::inspectTrade(bool counterOffer, int index)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendInspectTrade(counterOffer, index);
-}
-
-void Game::acceptTrade()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendAcceptTrade();
-}
-
-void Game::rejectTrade()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRejectTrade();
-}
-
-void Game::editText(uint id, const std::string& text)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendEditText(id, text);
-}
-
-void Game::editList(uint id, int doorId, const std::string& text)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendEditList(id, doorId, text);
-}
-
-void Game::openRuleViolation(const std::string& reporter)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendOpenRuleViolation(reporter);
-}
-
-void Game::closeRuleViolation(const std::string& reporter)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendCloseRuleViolation(reporter);
-}
-
-void Game::cancelRuleViolation()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendCancelRuleViolation();
-}
-
-void Game::reportBug(const std::string& comment)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendBugReport(comment);
-}
-
-void Game::reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRuleViolation(target, reason, action, comment, statement, statementId, ipBanishment);
-}
-
-void Game::debugReport(const std::string& a, const std::string& b, const std::string& c, const std::string& d)
-{
- m_protocolGame->sendDebugReport(a, b, c, d);
-}
-
-void Game::requestQuestLog()
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestQuestLog();
-}
-
-void Game::requestQuestLine(int questId)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestQuestLine(questId);
-}
-
-void Game::equipItem(const ItemPtr& item)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendEquipItem(item->getId(), item->getCountOrSubType());
-}
-
-void Game::mount(bool mount)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendOutfitExtensionStatus(mount ? 1 : 0);
-}
-
-void Game::setOutfitExtensions(int mount, int wings, int aura, int shader)
-{
- if (!canPerformGameAction())
- return;
- m_protocolGame->sendOutfitExtensionStatus(mount, wings, aura, shader);
-}
-
-void Game::requestItemInfo(const ItemPtr& item, int index)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestItemInfo(item->getId(), item->getSubType(), index);
-}
-
-void Game::answerModalDialog(uint32 dialog, int button, int choice)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendAnswerModalDialog(dialog, button, choice);
-}
-
-void Game::browseField(const Position& position)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendBrowseField(position);
-}
-
-void Game::seekInContainer(int cid, int index)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendSeekInContainer(cid, index);
-}
-
-void Game::buyStoreOffer(int offerId, int productType, const std::string& name)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendBuyStoreOffer(offerId, productType, name);
-}
-
-void Game::requestTransactionHistory(int page, int entriesPerPage)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestTransactionHistory(page, entriesPerPage);
-}
-
-void Game::requestStoreOffers(const std::string& categoryName, int serviceType)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendRequestStoreOffers(categoryName, serviceType);
-}
-
-void Game::openStore(int serviceType)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendOpenStore(serviceType);
-}
-
-void Game::transferCoins(const std::string& recipient, int amount)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendTransferCoins(recipient, amount);
-}
-
-void Game::openTransactionHistory(int entriesPerPage)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendOpenTransactionHistory(entriesPerPage);
-}
-
-void Game::preyAction(int slot, int actionType, int index)
-{
- if (!canPerformGameAction())
- return;
- m_protocolGame->sendPreyAction(slot, actionType, index);
-}
-
-void Game::preyRequest()
-{
- if (!canPerformGameAction())
- return;
- m_protocolGame->sendPreyRequest();
-}
-
-
-void Game::applyImbuement(uint8_t slot, uint32_t imbuementId, bool protectionCharm)
-{
- if (!canPerformGameAction())
- return;
- m_protocolGame->sendApplyImbuement(slot, imbuementId, protectionCharm);
-}
-
-void Game::clearImbuement(uint8_t slot)
-{
- if (!canPerformGameAction())
- return;
- m_protocolGame->sendClearImbuement(slot);
-}
-
-void Game::closeImbuingWindow()
-{
- if (!canPerformGameAction())
- return;
- m_protocolGame->sendCloseImbuingWindow();
-}
-
-void Game::ping()
-{
- if(!m_protocolGame || !m_protocolGame->isConnected())
- return;
-
- if(m_pingReceived != m_pingSent)
- return;
-
- m_denyBotCall = false;
- m_protocolGame->sendPing();
- m_denyBotCall = true;
- m_pingSent++;
- m_pingTimer.restart();
-}
-
-void Game::newPing()
-{
- if(!m_protocolGame || !m_protocolGame->isConnected())
- return;
-
- static uint32_t pingId = 1;
- pingId += 1;
- m_newPingIds[pingId] = stdext::timer();
-
- m_protocolGame->sendNewPing(pingId, (int16_t)m_ping, (int16_t)g_app.getFps());
- m_newPingEvent = g_dispatcher.scheduleEvent([] {
- g_game.newPing();
- }, m_newPingDelay);
-}
-
-void Game::changeMapAwareRange(int xrange, int yrange)
-{
- if(!canPerformGameAction())
- return;
- m_protocolGame->sendChangeMapAwareRange(xrange, yrange);
-}
-
-bool Game::checkBotProtection()
-{
- if (getFeature(Otc::GameBotProtection)) {
- // accepts calls comming from a stacktrace containing only C++ functions,
- // if the stacktrace contains a lua function, then only accept if the engine is processing an input event
- if (m_denyBotCall && g_lua.isInCppCallback() && !g_app.isOnInputEvent() && !g_dispatcher.isBotSafe()) {
- g_logger.error(g_lua.traceback("caught a lua call to a bot protected game function, the call was cancelled"));
- return false;
- }
- }
-
- return true;
-}
-
-bool Game::canPerformGameAction()
-{
- // we can only perform game actions if we meet these conditions:
- // - the game is online
- // - the local player exists
- // - the local player is not dead
- // - we have a game protocol
- // - the game protocol is connected
- // - its not a bot action
- return m_online && m_localPlayer && !m_localPlayer->isDead() && !m_dead && m_protocolGame && m_protocolGame->isConnected() && checkBotProtection();
-}
-
-void Game::setProtocolVersion(int version)
-{
- if(m_protocolVersion == version)
- return;
-
- if(isOnline())
- stdext::throw_exception("Unable to change protocol version while online");
-
- m_protocolVersion = version;
-
- Proto::buildMessageModesMap(version);
-
- g_lua.callGlobalField("g_game", "onProtocolVersionChange", version);
-}
-
-void Game::setClientVersion(int version)
-{
- if(isOnline())
- stdext::throw_exception("Unable to change client version while online");
-
- m_clientVersion = version;
- g_lua.callGlobalField("g_game", "onClientVersionChange", version);
-}
-
-void Game::setAttackingCreature(const CreaturePtr& creature)
-{
- if(creature != m_attackingCreature) {
- CreaturePtr oldCreature = m_attackingCreature;
- m_attackingCreature = creature;
-
- g_lua.callGlobalField("g_game", "onAttackingCreatureChange", creature, oldCreature);
- }
-}
-
-void Game::setFollowingCreature(const CreaturePtr& creature)
-{
- CreaturePtr oldCreature = m_followingCreature;
- m_followingCreature = creature;
-
- g_lua.callGlobalField("g_game", "onFollowingCreatureChange", creature, oldCreature);
-}
-
-std::string Game::formatCreatureName(const std::string& name)
-{
- std::string formatedName = name;
- if(getFeature(Otc::GameFormatCreatureName) && name.length() > 0) {
- bool upnext = true;
- for(uint i=0;i= 0)
- return m_clientCustomOs;
-
- if(g_app.getOs() == "windows")
- return 20;
- if(g_app.getOs() == "mac")
- return 22;
- if (g_app.getOs() == "android")
- return 23;
- if (g_app.getOs() == "ios")
- return 24;
- return 21; // linux
-}
diff --git a/src/client/game.h b/src/client/game.h
deleted file mode 100644
index b1863ab..0000000
--- a/src/client/game.h
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-
-#include
-
-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 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& 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& 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 >& 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 >& outfitList,
- const std::vector >& mountList);
-
- // npc trade
- void processOpenNpcTrade(const std::vector >& items);
- void processPlayerGoods(uint64_t money, const std::vector >& goods);
- void processCloseNpcTrade();
-
- // player trade
- void processOwnTrade(const std::string& name, const std::vector& items);
- void processCounterTrade(const std::string& name, const std::vector& 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 >& questList);
- void processQuestLine(int questId, const std::vector >& questMissions);
-
- // modal dialogs >= 970
- void processModalDialog(uint32 id, std::string title, std::string message, std::vector > buttonList, int enterButton, int escapeButton, std::vector > 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& 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 getContainers() { return m_containers; }
- std::map 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 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 m_containers;
- std::map 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 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 m_gmActions;
- std::string m_characterName;
- std::string m_worldName;
- std::bitset 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
diff --git a/src/client/global.h b/src/client/global.h
deleted file mode 100644
index fd1b413..0000000
--- a/src/client/global.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-
-// widely used headers
-#include "const.h"
-#include "position.h"
-
-#endif
diff --git a/src/client/houses.cpp b/src/client/houses.cpp
deleted file mode 100644
index 8a71cd9..0000000
--- a/src/client/houses.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2010-2017 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
-
-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("rent"));
- setSize(elem->readType("size"));
- setTownId(elem->readType("townid"));
- m_isGuildHall = elem->readType("guildhall");
-
- Position entryPos;
- entryPos.x = elem->readType("entryx");
- entryPos.y = elem->readType("entryy");
- entryPos.z = elem->readType("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