Ir para conteúdo

Pesquisar na Comunidade

Mostrando resultados para as tags ''magus''.



Mais opções de pesquisa

  • Pesquisar por Tags

    Digite tags separadas por vírgulas
  • Pesquisar por Autor

Tipo de Conteúdo


Fóruns

  • A Cidade OTBR
    • OTServ Brasil
    • Atendimento
    • Taverna
  • Projetos Open Source
    • Canary
    • OTServBR-Global
    • Mehah OTClient
    • MyAAC
  • OpenTibia
    • Notícias e Discussões
    • Suporte - Dúvidas, Bugs, Erros
    • Downloads
    • Tutoriais
    • Show-Off
  • Outros
    • Design

Encontrado 5 registros

  1. Abra o arquivo data/creaturescripts/scripts/firstitems.lua, apague o que tem lá e adicione: local firstItems = { [0] = { -- No-vocation (sem vocação) 2398, -- Mace 2512, -- Wooden Shield 2649, -- Leather Legs 2170, -- Silver Amulet 2461, -- Leather Helmet 2467, -- Leather Armor 2643, -- Leather Boots }, [1] = { --Sorcerer 2525, -- Shield 2190, -- Weapon 2661, -- Necklace 2457, -- Helmet 2463, -- Armor 2647, -- Legs 2643 -- Boots }, [2] = { --Druid 2525, -- Shield 2182, -- Weapon 2661, -- Necklace 2457, -- Helmet 2463, -- Armor 2647, -- Legs 2643 -- Boots }, [3] = { --Paladin 2455, -- Weapon {2543,100}, -- Ammunition,Count 2661, -- Necklace 2457, -- Helmet 2463, -- Armor 2647, -- Legs 2643 -- Boots }, [4] = { --Knight 2383, -- Weapon (Sword) 2428, -- Weapon (Axe) 2422, -- Weapon (Club) 2525, -- Shield 2661, -- Necklace 2457, -- Helmet 2463, -- Armor 2647, -- Legs 2643 -- Boots } } function onLogin(cid) if getPlayerStorageValue(cid, 30001) <= 0 then local bag = doPlayerAddItem(cid, 1988, 1) -- Backpack doAddContainerItem(bag, 2554, 1) -- Shovel doAddContainerItem(bag, 2120, 1) -- Rope local mergeidx = getPlayerVocation(cid) for k,v in ipairs(firstItems[mergeidx]) do local isArray = type(v) == "table" doPlayerAddItem(cid, (isArray and v[1] or v), (isArray and v[2] or 1)) end setPlayerStorageValue(cid, 30001, 1) end return TRUE end O que vem configurado é um Plate Set (Leather Set no caso de sem vocação), caso queria mudar altere na primeira variável. Somente verifique se o novo jogador terá capacidade suficiente para aguentar todos os equips, caso não tenha alguns podem cair no chão. Esse é o script quando o jogador loga pela primeira vez e recebe seus primeiros itens. Valeu Makaveli pelo toque da vocação 0.
  2. Global Storage melhorado

    Com este script, você pode: Salvar dados para serem utilizados mais tarde em outros scripts, independente se é talk/movement/creature/etc; Salvar tabelas e valores boleanos com a função bônus gstorage.serialize(); Converter os dados, caso sejam tabelas ou boleanos, com gstorage.unserialize(); Optar por ser um global storage que salva após o desligamento do pc ou não. Funções: gstorage.add(id, valor) gstorage.get(id) gstorage.serialize(var) gstorage.unserialize(var) [spoiler=Alguns exemplos] --Talkaction local str = 'Mensagem gerada num talkaction.' gstorage.add(1, str) --Creature Script print(gstorage.get(1)) -- Mensagem gerada num talkaction. -- Movement local corrida = {['1st'] = 'Magus', ['2nd'] = 'Skyen Hasus', ['3rd'] = 'Mock']} gstorage.add(2, gstorage.serialize(corrida)) -- NPC local t = gstorage.unserialize(gstorage.get(2)) doNPCsay(cid, "O primeiro lugar foi: "..t['1st']) Instalação: Crie um arquivo chamado gstorage.lua na pasta data/lib e adicione: gstorage = { _VERSION = "1.0", __construct = function(dbsave) if(luasql == nil) then assert(package.loadlib("sqlite3.dll", "luaopen_luasql_sqlite3")) () end genv = assert(luasql.sqlite3()) gcon = assert(genv:connect(dbsave and 'store.s3db' or ':memory:')) assert(gcon:execute[[ CREATE TABLE IF NOT EXISTS stores( id int(11), value varchar(999) ) ]]) end, add = function(id, value) local cur = gcon:execute(string.format([[ SELECT id FROM stores WHERE id = %d]], id) ) local exists = cur:fetch() cur:close() if (exists) then return gcon:execute(string.format([[ UPDATE stores SET value = '%s' WHERE id = %d]], value, id) ) else return gcon:execute(string.format([[ INSERT INTO stores (id,value) VALUES (%d,'%s')]], id, value) ) end end, get = function(id) local cur = assert(gcon:execute(string.format([[ SELECT value FROM stores WHERE id = %d]], id) )) local ret = cur:fetch() cur:close() return ret end, serialize = function(o) local function subtable(t) local arr = string.char(123) for i, v in pairs(t) do arr = arr .. string.format('[%s] = ', type(i) == 'number' and i or '"'..i..'"') if (type(v) == 'table') then arr = arr .. subtable(v) .. string.char(44) elseif (type(v) == 'function' or type(v) == 'thread' or type(v) == 'userdata') then error('You cannot encode function, thread or userdata.') else arr = arr .. string.format('%s,', type(v) == 'number' and v or '"'..v..'"') end end return arr:sub(1,arr:len()-1)..string.char(125) end if(type(o) == 'boolean') then return o and 'b:true' or 'b:false' elseif(type(o) == 'table') then return subtable(o) elseif (type(o) == 'function' or type(o) == 'thread' or type(o) == 'userdata') then error('You cannot encode function, thread or userdata.') else return o end end, unserialize = function(o) if (type(o) ~= 'string') then return o elseif(o == 'b:true') then return true elseif(o == 'b:false') then return false elseif(o:find('{.+}')) then return assert(loadstring(string.format("local t = %s return t", o))) () -- Obrigado pela dica Skyen Hasus! else return o end end, } gstorage.__construct() -- Se não quiser perder os stores depois de reiniciar o pc, coloque true na função [..__construct(true)] Adicione em data.lua, no final: dofile(getDataDir() .. "lib/gstorage.lua") Adicionado
  3. Encriptando senhas para maior segurança!

    Dicas de segurança Um pouco de segurança nunca é demais, não é? Ainda mais se tratando de um servidor pessoal, aonde muitos de vocês trabalham bastante para torná-lo popular e forte contra ataques DDoS ou hackers. Uma dica bem válida de segurança é a encriptação das senhas dos jogadores utilizando hashs, que resulta em um processo unidirecional (não existe decriptação). Existem vários algorítmos que geram tais hashs, os otservs atuais apresentam suporte a dois deles: MD5 e SHA-1. A diferença entre os dois está no tamanho de bits da saída (da encriptação), onde o primeiro resulta em uma saída de 128 bits enquanto o segundo em uma saída de 160 bits. Sendo assim, SHA-1 se torna mais eficiente do que o MD5 pois a possibilidade de colisão de hashs (duas hashs iguais com combinações de letras diferentes) é muito menor; mas dificilmente essa vulnerabilidade seria um problema para o nosso quesito, já que a quantidade de dados encriptados não seria elevada. Vantagens? Um exemplo de vantagem é usar a encriptação para impedir qualquer ladrão de cookies que utilize ataques comuns como cross-site scripting (XSS) de decifrar as senhas. Outro exemplo é se qualquer hacker obtiver um acesso somente-leitura ao banco de dados - ficará a ver navios. Porém a segurança vem com um custo: senhas não poderão ser recuperadas, apenas trocadas. Perceba que no próprio sistema do fórum se você perder a senha, ele lhe dará um link para resetá-la. Isso porque estão todas encriptadas com esse método. Conheço um site que decripta, hahah sou foda... Na verdade, o que esses sites que dizem decriptar as hashs fazem nada mais é do que lhe informar hashs que eles tenham salvas no banco de dados deles. O site www.cmd5.com, por exemplo, tem mais de 4 TB de hashs MD5 no banco de dados mas não consegue identificar (por exemplo) "myp4ssw0rd" encriptada, isso porque senhas utilizam combinações de caracteres muito inesperadas e são enésimas possibilidades. Utilizando no OT Há uma variável passwordType no config.lua que está configurada como plain, significa que ele está reconhecendo as senhas como elas mesmas. Para utilizar o SHA-1 ou MD5, primeiro basta apenas alterar a variável para sha1 ou md5. O problema é agora, caso o seu site não tenha uma opção para encriptar essas senhas, você terá que modificá-lo manualmente. Vou usar como exemplo o site da OTNet (não possui também): Na parte de login, encriptar o $_POST enviado para comparação (linha 3.400, index.php): $pass = sha1($_POST['pass']); E na parte de criar a conta, encriptar a senha enviada ao banco de dados (linha 3.594, index.php): mysql_query("INSERT INTO `accounts` (`name`, `password`, `creationdata`, `premdays`, `email`, `key`, `activated`) VALUES ('".$post[0]."', '".sha1($post[1])."', '".time()."', '".$freePremmy."', '".escape_string($post[4])."', '$rk', '$activated')"); [spoiler=+ Infos]Caso seu servidor já tenha várias contas, você pode usar a consulta SQL abaixo para encriptar todas as senhas em SHA-1, mas lembre-se que essa ação é irreversível. UPDATE `accounts` SET `password` = sha1(password) Nota: se você prefere usar md5, apenas troque todos sha1() do exemplo para md5(). Outras dicas de segurança Aproveito para deixar outras dicas para vocês. [spoiler=Protegendo o phpMyAdmin]Ao instalar o Xampp por exemplo, o phpMyAdmin (local aonde ficará o banco de dados do servidor caso for MySQL) estará desprotegido contra invasões. Para protegê-lo de modo eficaz faça o seguinte: Clique no link "Privilégios", que fica um pouco baixo do campo de criação de banco de dados. Clicando lá, uma lista com os usuários irá aparecer. Clique no ícone de edição do usuário root. Nesta página, não altere nada, somente crie uma senha para tal usuário. Clique no Executar que está na abaixo destes campos. Sua senha foi criada/alterada! Agora, você precisa alterar o método de autenticação do phpMyAdmin. Para fazê-lo, vá até a pasta phpMyAdmin do webservidor (fica acima de htdocs) e abra o arquivo config.inc.php com algum editor de texto. Você achará uma variável com estes dados: $cfg['Servers'][$i]['auth_type'] = 'config'; Mude-a para: $cfg['Servers'][$i]['auth_type'] = 'http'; Salve o arquivo. Pronto! Seu banco de dados estará totalmente protegido contra invasões, para acessá-lo basta usar o login "root" e a senha que você definiu. [spoiler=Protegendo contra XSS]Cross-site scripting (XSS), resumidamente, é o ato de injetar códigos html em querystrings ou campos de comentários desprotegidos, consequentemente sendo possível injetar códigos javascript - o que pode ser muito inseguro. Para se proteger disso você pode simplesmente usar a função strip_tags() do php ou qualquer expressão regular para remover tags comprometedoras. Um exemplo simples: $_GET = array_map('strip_tags', $_GET); $_POST = array_map('strip_tags', $_POST); $_COOKIE = array_map('strip_tags', $_COOKIE); $_GET, $_POST e $_COOKIE são arrays globais que guardam informações enviadas em formulários (POST), querystrings (GET) e cookies, famoso GPC. A função array_map(), como o nome já diz, irá mapear todos os elementos do array aplicando a função strip_tags() neles. Assim, se você enviar algo como: ?charactername=<b>Magus</b> ele não deixará a busca em negrito. Você também pode usar algo como: // Página de busca (exemplo) $meuchar = $_REQUEST['personagem']; if ereg("<\w+>", $meuchar) { exit("Ação não permitida."); } Aí vai da criatividade. É isso ^^
  4. Algumas funções

    utf8Encode Sintaxe: utf8Encode( string str ) Funciona da mesma maneira que utf8_encode. Valor retornado: Retorna a string encodada para UTF-8. [spoiler=Exemplo de Uso] local str = utf8Encode("Vamos lá caçar!") print(str) -- Vamos l& #225; ca& #231;ar& #33; function utf8Encode(str) return string.gsub(str, "([^ %w])", function (s) return ""..s:byte()..";" end) end utf8Decode Sintaxe: utf8Decode( string str ) Funciona da mesma maneira que utf8_decode. Valor retornado: Retorna a string decodada de UTF-8 para ISO-8859-1. [spoiler=Exemplo de Uso] local str = utf8Decode("Vamos l& #225; ca& #231;ar& #33;") print(str) -- Vamos lá caçar! function utf8Decode(str) return string.gsub(str, "(%d+);", function(s) return s:char() end) end DoPlayerAddDepotItem Sintaxe: doPlayerAddDepotItem( int cid , mixed item [, mixed count ] ) A função adiciona o item e quantidade especificadas no depot do jogador cid, sendo que ambos item e quantidade podem ser inteiros ou tabela (array). O único contra da função é que é necessário que o jogador seja kickado, após ele voltar os itens estarão disponíveis. Valor retornado: Retorna true em sucesso e false em falha. [spoiler=Exemplo de Uso] local Item = 2400 --Magic Sword if (doPlayerAddDepotItem(cid, Item) == TRUE) then Mensagem("Item adicionado com sucesso!") else Mensagem("Houve um erro ao adicionar o item!") end local Item = {2400, 2148, 2152, 2160} -- Magic Sword, Gold Coin, Platinum Coin, Crystal Coin local Qtdade = {1, 100, 10, 5} -- Count respectivo à ordem dos itens acima doPlayerAddDepotItem(cid, Item, Qtdade) function doPlayerAddDepotItem(cid, item, count) local item,count,pid = type(item)=="table" and item or {item},type(count)=="table" and count or {(count or 1)},getPlayerGUID(cid) doRemoveCreature(cid) for k,v in ipairs(item) do local ls = db.getResult("SELECT `sid` FROM `player_depotitems` WHERE `player_id` = "..pid.." ORDER BY `sid` DESC LIMIT 1") return db.executeQuery("INSERT INTO `player_depotitems` (`player_id`, `sid`, `pid`, `itemtype`, `count`, `attributes`) VALUES ("..pid..", "..(ls:getDataInt("sid")+1)..", 101, "..v..", "..count[k]..", '"..(count[k] > 1 and string.format("%x",count[k]) or '').."')") or false end end getInstantSpells Sintaxe: getInstantSpells([ int vocid ] ) Parecida com getPlayerInstantSpellsInfo(), porém procura todas as spells por vocação, não jogador. Se vocid não for definida, irá retornar todas as spells do servidor. Valor retornado: Retorna uma tabela com todas as magias encontradas e as seguintes chaves (words, name, level, mlevel, mana, manapercent) em sucesso ou table nil em falha. [spoiler=Exemplo de Uso]TalkAction !spellsorcerer function onSay(cid) local text = "" for k,v in ipairs(getInstantSpells(1)) do --Aqui vc configura o id da vocação text = text..v.name.."\nWords: "..v.words.."\nLevel: "..v.level.."\nMana: "..(v.mana == 0 and v.manapercent.."%" or v.mana).."\n\n" end doShowTextDialog(cid, 2175, string.trim(text)) end function getInstantSpells(voc) local voc = voc and (getVocationInfo(voc).name or nil) or nil local spell = io.open(getDataDir().."/spells/spells.xml") local r,cts = {},spell:read("*a") for t,name,xml in string.gmatch(cts,'<(%a+) name="(.-)".->(.-)</[^s]') do if (t ~= "rune") then vocs = {""} for voc in string.gmatch(xml,'"(.-)"') do table.insert(vocs,voc) end if (isInArray(vocs,voc)) then table.insert(r,getInstantSpellInfo(name)) end end end spell:close() return r end setPlayerRecoveryKey Sintaxe: setPlayerRecoveryKey( int cid ) Define uma nova Recovery Key para o jogador cid, e não define RKs repetidas. Valor retornado: Retorna a string da nova recovery key em sucesso ou false em falha. [spoiler=Exemplo de Uso]Talk !NewRK function onSay(cid, words, param, channel) if (getPlayerStorageValue(cid, 78789) == -1) then local newRK = setPlayerRecoveryKey(cid) if (newRK) then Message("RK alterada com sucesso! Sua nova rk é: "..newRK) setPlayerStorageValue(cid, 78789, 1) else Message("Houve um erro ao setar a rk!") end else Message("Você já trocou de RK!") end end function setPlayerRecoveryKey(cid) local wd,newrk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789","" for i = 0, 15 do tmp = math.random(1,#wd) newrk = newrk..string.sub(wd,tmp,tmp) end local newrk = string.gsub(newrk, "(....)", "%1-", 3) local keyexists = db.getResult("SELECT * FROM `accounts` WHERE `key` = '"..newrk.."'") if (keyexists:getID() ~= -1) then return setPlayerRecoveryKey(cid) end return db.executeQuery("UPDATE `accounts` SET `key` = '"..newrk.."' WHERE `id` = "..getPlayerAccountId(cid)) and newrk or false end Espero que seja útil! Abraços.
  5. Summon Portal "City

    Summon Portal "City Invoque um portal e nunca se perca! Olá, Este script tem a intenção de agir como uma spell (magia) do servidor, mas como eu fiz ele por TalkActions, postei nesta seção. Requerimentos Organizar coordenadas nos arquivos; OTScriptLIB v0.2 (funções isStrInArray() e setTimer()) por Colex. Nota: Não é necessário um servidor que possua a função doCreateTeleport(), portanto funciona em qualquer um com SVNs mais antigas (Evolutions, por exemplo). Função Ao ser usado, primeiramente, ele verifica se o jogador pode utilizar a magia (vocação), se tem nível e mana suficiente, se os parâmetros foram dados corretamente e se nenhum outro portal está aberto. Depois, um efeito da criação do portal aparecerá, este efeito dura 5 segundos (padrão) e após isto o portal é finalmente criado, na frente do personagem. Todos podem entrar no portal, porém, ele é automaticamente fechado dentro de 10 segundos (isto pode ser mudado). Você também pode, com outro comando, salvar uma posição, para depois utilizar um portal para te levar a este local, útil para salvar locais de caças etc, quando você precisa voltar para a cidade ou quando morre. Nota: somente dá para salvar posições em campos abertos (posição Z = 7). Digamos que, é praticamente a mesma função da magia Portal do jogo Ragnarök (fiz baseado nela mesmo) dos sacerdotes. Script O script utiliza TalkActions e Movements, porém, é mais simples do que vocês imaginam. TalkActions: summonportal.lua function onSay(cid, words, param) city = {"Save", "Venore", "Carlin", "Thais"} -- Cidades disponíveis para teleporte (save = ponto salvo; não mude). popen = 5 --Tempo para o portal abrir (em segundos). ptime = 10 -- Tempo para o portal fechar (em segundos). pvoc = {1,2,5,6} --Ids das vocações que podem invocar portais (altere de acordo com os padrões dados). plevel = 20 --Nível mínimo necessário para poder invocar portais. pmana = 300 --Mana necessária para poder invocar portais. -- Função isStrInArray() e setTimer() por Colex - OTScriptLIB. if (words == "Save Portal") then ppos = getPlayerPosition(cid) if (not isStrInArray(getPlayerVocation(cid), pvoc) or getPlayerLevel(cid) < plevel) then doPlayerSendCancel(cid,"Sorry, only mages above level "..plevel.." can set portal points.") elseif (ppos.z ~= 7) then doPlayerSendCancel(cid,"Sorry, you can not point a portal to this position.") elseif (getTilePzInfo(ppos) == 1) then doPlayerSendCancel(cid,"Sorry, you can not point a portal to a protected position.") else setPlayerStorageValue(cid, 7889, ppos.x) setPlayerStorageValue(cid, 7890, ppos.y) setPlayerStorageValue(cid, 7891, ppos.z) doPlayerSendCancel(cid, "Position saved. You can summon a portal to this position at any time.") end elseif (words == "Summon Portal") then if (not isStrInArray(getPlayerVocation(cid), pvoc) or getPlayerLevel(cid) < plevel) then doPlayerSendCancel(cid,"Sorry, only mages above level "..plevel.." can use this magic.") elseif (getPlayerMana(cid) < pmana) then doPlayerSendCancel(cid,"You do not have enough mana.") elseif (param == '') then str = "Disponible Places: " for i = 1,#city do if (i == #city) then str = str..city[i].."." else str = str..city[i]..", " end end doPlayerSendCancel(cid,str) elseif (not isStrInArray(param, city)) then doPlayerSendCancel(cid,"This place does not exists or it can not be accessed by a portal.") elseif (checkevent ~= nil) then doPlayerSendCancel(cid,"You have to wait until a other portal is closed to summon another one.") else ppos = getPlayerPosition(cid) if (getPlayerLookDir(cid) == 0) then teleportPos = {x = ppos.x, y = ppos.y-1, z = ppos.z, stackpos = 1} elseif (getPlayerLookDir(cid) == 1) then teleportPos = {x = ppos.x+1, y = ppos.y, z = ppos.z, stackpos = 1} elseif (getPlayerLookDir(cid) == 2) then teleportPos = {x = ppos.x, y = ppos.y+1, z = ppos.z, stackpos = 1} elseif (getPlayerLookDir(cid) == 3) then teleportPos = {x = ppos.x-1, y = ppos.y, z = ppos.z, stackpos = 1} end if (getThingfromPos(teleportPos).uid == 0) then stopevent = nil doPlayerSay(cid,"Portal !!",1) doPlayerAddMana(cid,-pmana) doSendMagicEffect(ppos, 13) funceffect = function() doSendMagicEffect(teleportPos, 31) end effectevent = setTimer("funceffect", 400, {teleportPos}) checkevent = addEvent(function() enableTimer(effectevent, false) tuid = doCreateItem(1387, 1, teleportPos) if (param == city[1]) then if (getPlayerStorageValue(cid,7889)) then setGlobalStorageValue(9889, cid) doSetItemActionId(tuid,7889) else doPlayerSendCancel(cid, "You do not have any saved position to point a portal.") end elseif (param == city[2]) then doSetItemActionId(tuid,7890) elseif (param == city[3]) then doSetItemActionId(tuid,7891) elseif (param == city[4]) then doSetItemActionId(tuid,7892) end addEvent(function() doRemoveItem(getThingfromPos(teleportPos).uid,1) checkevent = nil end, (ptime*1000), {teleportPos}) end, (popen*1000), {teleportPos, cid, city}) else doPlayerSendCancel(cid, "You can not summon a portal here.") end end end end talkactions.xml <talkaction words="Summon Portal" script="summonportal.lua" /> <talkaction words="Save Portal" script="summonportal.lua" /> Movements: summonportal.lua function onStepIn(cid, item, pos) if (item.actionid == 7889) then tuid = getGlobalStorageValue(9889) topos = {x = getPlayerStorageValue(tuid,7889), y = getPlayerStorageValue(tuid,7890), z = getPlayerStorageValue(tuid,7891)} doTeleportThing(cid, topos) doSendMagicEffect(topos,10) elseif (item.actionid == 7890) then --Venore topos = {x = 1000, y = 1000, z = 7} doTeleportThing(cid, topos) doSendMagicEffect(topos,10) elseif (item.actionid == 7891) then --Carlin topos = {x = 1000, y = 1000, z = 8} doTeleportThing(cid, topos) doSendMagicEffect(topos,10) elseif (item.actionid == 7892) then --Thais topos = {x = 987, y = 1006, z = 8} doTeleportThing(cid, topos) doSendMagicEffect(topos,10) end end movements.xml <movevent event="StepIn" actionid="7889" script="summonportal.lua" /> <movevent event="StepIn" actionid="7890" script="summonportal.lua" /> <movevent event="StepIn" actionid="7891" script="summonportal.lua" /> <movevent event="StepIn" actionid="7892" script="summonportal.lua" /> Como usar Primeiro de tudo, não se esqueça de entrar no tópico do OTScriptLIB, baixá-lo e adicioná-lo ao seu servidor. Após isto, abra o arquivo summonglobal.lua (TalkAction) e edite as variáveis com comentários como desejar. A variável city serve somente para você colocar o nome de suas cidades, que serão os parâmetros usados para invocar o portal. Se no seu servidor tem mais cidades, adicione o nome dela na variável city, e também mais uma linha desta: elseif (param == city[4]) then doSetItemActionId(tuid,7893) Somando mais um número na função doSetItemActionId() e seguindo os padrões da linguagem. Para editar as coordenadas que seus jogadores serão teleportados ao pisar no portal, abra o arquivo summonglobal.lua (Movement) e edite as variáveis topos de cada if. Cada actionid é representada por umas das cidades encontradas no outro arquivo. Se você adicionou mais uma cidade, também adicione mais umas linhas neste arquivo, somando mais um número no item.actionid e seguindo os padrões da linguagem: elseif (item.actionid == 7893) then topos = {x = 987, y = 1006, z = 8} doTeleportThing(cid, topos) doSendMagicEffect(topos,10) É bem simples, se você seguir os passos dados corretamente não tem como errar. Comandos Summon Portal - Informa todos os locais disponíveis para a criação de um portal. Save Portal - Salva suas coordenadas atuais, para serem usadas no invocamento de um portal específico. Summon Portal "Save - Invoca um portal para teleportá-lo até seu ponto de portal, coordenadas geradas pelo "Save Portal". Summon Portal "City - Invoca um portal para as demais localidades disponíveis; cada parâmetro especificado apontará para localidades diferentes. Outros Nada mais a adicionar. Se você tem dúvidas, sugestões, ou encontrou algum erro, poste aqui. Também não posso garantir que o inglês usado no script esteja 100% correto! Abraços! ;]
×