Moderador Este é um post popular. Yomee 1.296 Postado 4 de Fevereiro Moderador Este é um post popular. Compartilhar Postado 4 de Fevereiro LINK DE DOWNLOAD DO MODULE: Spoiler This is the hidden content, please Entre ou Cadastre-se SCAN: This is the hidden content, please Entre ou Cadastre-se ------------------------------------------------------------------------------------------------------------ 📜 Implementação do Opcode no Servidor Se você ainda não implementou suporte para Opcode no lado do servidor, será necessário adicioná-lo na sua source para que o script do partyicons funcione corretamente. 📌 Siga este tutorial e adicione o suporte à sua source do TFS 1.x+: This is the hidden content, please Entre ou Cadastre-se : This is the hidden content, please Entre ou Cadastre-se ⚠️ Atenção: Não sou responsável por possíveis danos à sua source. Faça as alterações por sua conta e risco. ------------------------------------------------------------------------------------------------------------ Este módulo ajuda você a acompanhar os membros do seu grupo, mostrando-os no minimapa. (testei o mesmo no tfs 1.4.2) Primeiramente, vamos baixar o arquivo "game_partyIcons", onde está o module (sim, esse é configurado na parte do servidor também). Esses 4arquivos precisam está na pasta "game_partyIcons" que vocês adicionaram na pasta "mods" do seu cliente. Spoiler Após isso, precisamos ativar a feature "GameExtendedOpcode" no seu cliente. Então, vá até modules/game_things/things.lua e procure por "function load()". Logo após essa linha, vocês adicionarão "g_game.enableFeature(GameExtendedOpcode)", ficando assim. Spoiler -- PARTE DO CLIENTE FINALIZADA -- Agora vamos para o servidor. Acessem este diretório do seu servidor: data/creaturescripts/scripts Criem um arquivo chamado "partyUpdate.lua" e adicionem este código. Spoiler local OPCODE_PARTY = 160 function onThink(creature, interval) local _data = {name = creature:getName(), pos = creature:getPosition()} local leader = creature:getParty():getLeader() local party = creature:getParty() if (#party:getMembers() > 0) then for _, member in ipairs(party:getMembers()) do member:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "update", player = _data})) end end if (creature ~= leader) then leader:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "update", player = _data})) end return true end Depois, vá até data/creaturescripts/creaturescripts.xml e adicione esta linha. Spoiler <event type="think" name="partyUpdate" interval="3000" script="partyUpdate.lua" /> Agora, vá até data/events/events.xml e deixe o arquivo igual ao meu. (A única alteração será no final, mudando enabled="0" para "1".) Spoiler Depois, vá até data/events/scripts/party.lua (faça um backup do seu party.lua antes). Em seguida, adicione este código dentro do arquivo. Spoiler local OPCODE_PARTY = 160 function Party:onJoin(player) -- PARTY ICON START -- scuffed workaround because members only get populated after we returned true :/ local _members = {} local leader = self:getLeader() table.insert(_members, {name = player:getName(), vocation = player:getVocation():getClientId(), pos = player:getPosition()}) for _, member in ipairs(self:getMembers()) do table.insert(members, {name = member:getName(), vocation = member:getVocation():getClientId(), pos = member:getPosition()}) end table.insert(_members, {name = leader:getName(), vocation = leader:getVocation():getClientId(), pos = leader:getPosition()}) player:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "join", members = _members})) leader:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "join", members = _members})) for _, member in ipairs(self:getMembers()) do member:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "join", members = _members})) end player:registerEvent("partyUpdate") if #self:getMembers() == 0 then leader:registerEvent("partyUpdate") end -- PARTY ICON END return true end function Party:onLeave(player) -- PARTY ICON START local members = self:getMembers() for _, member in ipairs(members) do member:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "leave", name = player:getName()})) end self:getLeader():sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "leave", name = player:getName()})) player:unregisterEvent("partyUpdate") -- PARTY ICON END return true end function Party:onDisband() -- PARTY ICON START local members = self:getMembers() for _, member in ipairs(members) do member:sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "leave", name = member:getName()})) member:unregisterEvent("partyUpdate") end self:getLeader():sendExtendedOpcode(OPCODE_PARTY, json.encode({type = "leave", name = self:getLeader():getName()})) self:getLeader():unregisterEvent("partyUpdate") -- PARTY ICON END return true end function Party:onShareExperience(exp) local sharedExperienceMultiplier = 1.20 --20% local vocationsIds = {} local vocationId = self:getLeader():getVocation():getBase():getId() if vocationId ~= VOCATION_NONE then table.insert(vocationsIds, vocationId) end for _, member in ipairs(self:getMembers()) do vocationId = member:getVocation():getBase():getId() if not table.contains(vocationsIds, vocationId) and vocationId ~= VOCATION_NONE then table.insert(vocationsIds, vocationId) end end local size = #vocationsIds if size > 1 then sharedExperienceMultiplier = 1.0 + ((size * (5 * (size - 1) + 10)) / 100) end return (exp * sharedExperienceMultiplier) / (#self:getMembers() + 1) end Agora, para finalizar, vá até data/lib/lib.lua e adicione esta linha no arquivo. Spoiler dofile('data/lib/core/json.lua') Depois disso, vá até data/lib/core, crie um arquivo chamado json.lua e adicione este código nele. Spoiler -- -- 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) -- This is the hidden content, please Entre ou Cadastre-se 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 Pronto! Ao abrirem o cliente e formarem uma party entre dois membros, vocês verão esse resultado no minimapa. LINK ORIGINAL DO MODULE: This is the hidden content, please Entre ou Cadastre-se 58 3 2 3 Link para o comentário https://tibiadevs.com/forums/topic/873-game_partyicons/ Compartilhar em outros sites Mais opções de compartilhamento...
chakoo2002 60 Postado 4 de Fevereiro Compartilhar Postado 4 de Fevereiro bro XD <event type="think" name="partyUpdate" interval="3000" script="partyUpdate.lua" /> wtf is this, why onThink? Link para o comentário https://tibiadevs.com/forums/topic/873-game_partyicons/#findComment-4570 Compartilhar em outros sites Mais opções de compartilhamento...
lopas 0 Postado 5 de Fevereiro Compartilhar Postado 5 de Fevereiro I think he ment globalevent not creaturescript Link para o comentário https://tibiadevs.com/forums/topic/873-game_partyicons/#findComment-4575 Compartilhar em outros sites Mais opções de compartilhamento...
Moderador Yomee 1.296 Postado 5 de Fevereiro Autor Moderador Compartilhar Postado 5 de Fevereiro 17 horas atrás, chakoo2002 disse: bro XD <event type="think" name="partyUpdate" interval="3000" script="partyUpdate.lua" /> wtf is this, why onThink? <globalevent name="partyUpdate" interval="3000" script="partyUpdate.lua" /> or <event type="party" name="partyUpdate" script="partyUpdate.lua" /> :D Link para o comentário https://tibiadevs.com/forums/topic/873-game_partyicons/#findComment-4579 Compartilhar em outros sites Mais opções de compartilhamento...
lopas 0 Postado 6 de Fevereiro Compartilhar Postado 6 de Fevereiro prety sure <event type="party" name="partyUpdate" script="partyUpdate.lua" /> is a wors pick dou to amount of resource it will use same for globalevent the script is just not optimmal Link para o comentário https://tibiadevs.com/forums/topic/873-game_partyicons/#findComment-4582 Compartilhar em outros sites Mais opções de compartilhamento...
Posts Recomendados
Crie uma conta ou entre para comentar
Você precisar ser um membro para fazer um comentário
Criar uma conta
Crie uma nova conta em nossa comunidade. É fácil!
Crie uma nova contaEntrar
Já tem uma conta? Faça o login.
Entrar Agora