Skulls 331 Postado Janeiro 12, 2016 Share Postado Janeiro 12, 2016 (editado) Fala galera, tudo bem? Semana passada abri uma dúvida perguntando se alguém conhecia algum jeito de players compartilharem o mesmo espaço no mapa sem interagirem entre si, como se fossem duas dimensões separadas. Ninguém soube me dar uma solução que fizesse exatamente isso, porém, o Danihcv me deu uma luz sugerindo que eu fizesse algo próximo de um instanciador de mapa. Ou seja, uma forma de clonar automaticamente um pedaço do mapa desejado sem ter que criar mil vezes no map editor. Ainda estou trabalhando na automação do mesmo - pretendo fazer um sistema, sem ser talkaction, que sempre que for necessário ele instancia uma novo espaço para aquele mesmo mapa. Esta é uma primeira versão, feita em talkaction pois achei melhor de trabalhar num primeiro momento e testar todas as funções que eu queria adicionar, ela faz basicamente cópia de uma área do mapa. Pro projeto que eu pensei para esse sistema é suficiente que ele suporte somente mapas do mesmo tamanho e, portanto, foquei em atender esse requisito. Ainda sim, é possível trabalhar com mapas de tamanhos diferentes, desde que eles fiquem em linhas diferentes. Vamos lá Primeiramente, eu fiz um banco de funções que foram utilizadas ou serão úteis mais para frente. Em lib, crie um arquivo chamado cloneMap.lua e adicione o código abaixo: --Número de tiles por linha 2*side+1 function getNextCloneTile(emptySpaceBeginPos, side, i) local d = 2*side + 1 local y = i%d local x = math.floor(i/d) return {x = emptySpaceBeginPos.x + x, y = emptySpaceBeginPos.y + y, z = emptySpaceBeginPos.z} end function deleteTile(pos) doCleanTile(pos,true) local tmp = getThingFromPos(pos) if(tmp.uid ~= 0) then if(isCreature(tmp.uid)) then return doRemoveCreature(tmp.uid) else return doRemoveItem(tmp.uid, math.min(math.max(1, tmp.type), 1)) end end end function clearArea(center, side) for k, tile in pairs(getArea(center, side, side)) do if(getTileThingByPos(tile).itemid ~= 0) then deleteTile(tile) end end end function cloneMap(center, side, emptySpaceBeginPos) for k, tile in pairs(getArea(center, side, side)) do for i=0, 1 do tile.stackpos = i local tmp = getThingFromPos(tile) if tmp.uid ~= 0 then local nextTile = getNextCloneTile(emptySpaceBeginPos, side, k-1) if isCreature(tmp.uid) == true then local creature = getCreatureName(tmp.uid) doCreateMonster(creature, nextTile) else local item_id = tmp.itemid doCreateItem(tmp.itemid, 1, nextTile) end end end end return true end function cloneMultiDimensionalMaps(center, side, emptySpaceBeginPos, dim) for i = 0, dim do cloneMap(center, side, {x = emptySpaceBeginPos.x, y = emptySpaceBeginPos.y, z = emptySpaceBeginPos.z - i}) end end As funções estão todas funcionando, porém algumas não foram utilizadas nessa versão, ficam de bônus pra vocês. Depois disso, vá em talkactions.xml adicione a tag: <talkaction words="!clonemap" event="script" value="cmap.lua"/> Feito isso, crie dentro de scripts um arquivo chamado cmap.lua e adicione o código abaixo: local config = { map = {center = {x = 102, y = 182, z = 7}, side = 5}, emptySpaceBeginPos = {x = 84, y = 247, z = 7}, storages = {x = 5546, y = 5547, z = 5548}, safe_dist = 15 } --params {1 CenterX, 2 CenterY, 3 CenterZ, 4 Side, 5 Dimensions} --!clonemap CenterX CenterY CenterZ Side Dimensions function onSay(cid, words, param) if getPlayerGroupId(cid) == 6 then if(getGlobalStorageValue(config.storages.x) == -1) then setGlobalStorageValue(config.storages.x, config.emptySpaceBeginPos.x) end if(getGlobalStorageValue(config.storages.y) == -1) then setGlobalStorageValue(config.storages.y, config.emptySpaceBeginPos.y) end if(getGlobalStorageValue(config.storages.z) == -1) then setGlobalStorageValue(config.storages.z, config.emptySpaceBeginPos.z) end local data = string.split(param) if data then if #data < 5 then doPlayerSendCancel(cid, "!clonemap needs 5 parameters: x, y, z, side and dimensions") return false else if tonumber(data[1]) ~= nil and tonumber(data[2]) ~= nil and tonumber(data[3]) ~= nil and tonumber(data[4]) ~= nil and tonumber(data[5]) ~= nil then local pos = {x = getGlobalStorageValue(config.storages.x), y = getGlobalStorageValue(config.storages.y), z = getGlobalStorageValue(config.storages.z)} if (pos.x + config.safe_dist + 2*data[4]) > 2048 then if((pos.y + config.safe_dist + 2*data[4]) > 2048) then doPlayerSendCancel(cid, "Your free area is full.") return false end pos.x = config.emptySpaceBeginPos.x pos.y = pos.y + config.safe_dist + 2*data[4] end cloneMultiDimensionalMaps({x = data[1], y = data[2], z = data[3]}, data[4], pos, (data[5] - 1)) setGlobalStorageValue(config.storages.x, pos.x + config.safe_dist + 2*data[4]) setGlobalStorageValue(config.storages.y, pos.y) else doPlayerSendCancel(cid, "!clonemap parameters must be numbers.") return false end end else doPlayerSendCancel(cid, "You must define at least 5 parameters to !clonemap.") return false end else doPlayerSendCancel(cid, "You must be a GOD to cast !clonemap.") return false end --clearArea({x = config.emptySpaceBeginPos.x + config.map.side, y = config.emptySpaceBeginPos.y + config.map.side, z = 7}, config.map.side) end Por último, vá em globalevents/scripts e abra o arquivo start.lua. Dentro da função onStartup(), antes do return true, adicione as 3 linhas a seguir: setGlobalStorageValue(5546, -1) setGlobalStorageValue(5547, -1) setGlobalStorageValue(5548, -1) Pronto. Agora algumas configurações que você deve fazer de acordo com seu mapa: emptySpaceBeginPos - É a posição no mapa onde começa a área vazia que você determinou para a criação das instâncias (Canto superior esquerdo da área, ela cresce para direita até o fim do mapa e depois para baixo e se encerra quando o mapa acaba). Storages - Storages globais onde serão armazenadas os próximos valores X, Y e Z a serem utilizados. (A progressão no eixo z ainda não foi implementada, mas a lógica é a mesma). safe_dist - É a distância entre os mapas, você pode variar de acordo com a utilização que vai dar ao mapa. Feito isso, está pronto para utilizar o Instanciador de Mapas V1.0. Como funciona: !clonemap CenterX CenterY CenterZ Side Floors Centers (X, Y e Z) são as coordenadas centrais do seu mapa (e Z é o floor mais baixo do mapa, caso ele seja multi floor, isto é o floor de valor mais alto - ex, se o seu mapa vai de z=7 até z =10, use CenterZ = 10). Side é a distância entre o centro e uma das bordas (Caso o mapa não seja quadrado, basta usar a maior distância. É possível implementar usando a mesma lógica um SideX e SideY, mas eu não tive tempo de fazê-lo). Floors é o número de andares que tem o seu mapa, se ele ocupa só um andar floor = 1, 2 floor = 2 e assim por diante. Bom é isso, espero que gostem e que seja útil para vocês. Agora vou empenhar no sistema completo, assim que terminar eu posto a versão 2.0 do instanciador com muito mais recursos. Algumas Imagens OBSERVAÇÃO IMPORTANTEQuando você utilizar o comando ingame, esteja longe da área onde o mapa será criado, senão o seu cliente irá debugar. Nada acontece, na verdade, acho que é algum problema do cliente, assim que você abre o tibia novamente tudo se estabiliza, mas é chato ficar re-abrindo então evite isso.\ Grande abraço. ps: Lembrando, novamente dos Créditos ao Danihcv pela ideia, sem o brainstorm por ele promovido no meu tópico isso não seria possível Editado Janeiro 12, 2016 por Skulls Link para o comentário Compartilhar em outros sites More sharing options...
Administrador Administrador 1435 Postado Janeiro 12, 2016 Administrador Share Postado Janeiro 12, 2016 Genial cara! Mais genial ainda você querer compartilhar. :biggrin: :biggrin: Link para o comentário Compartilhar em outros sites More sharing options...
Skulls 331 Postado Janeiro 12, 2016 Autor Share Postado Janeiro 12, 2016 Genial cara! Mais genial ainda você querer compartilhar. :biggrin: :biggrin: Valeu Daniel! Passei da minha época já, hoje em dia faço por hobbie quando to atoa. Tenho uma pequena ideia em mente, vou tocando ela devagarzinho em sigilo, mas o sistemas que a envolvem eu vou compartilhando com vocês! @Topic Adicionei algumas imagens e fixei um bug estranho. Link para o comentário Compartilhar em outros sites More sharing options...
Danihcv 335 Postado Janeiro 12, 2016 Share Postado Janeiro 12, 2016 (editado) Esperando pra ver a versão final. shausahuashu (y) *ps: os créditos são pra vc, isso sim. Vc que desenvolveu o script. sahusahusa Editado Janeiro 12, 2016 por Danihcv Link para o comentário Compartilhar em outros sites More sharing options...
Skulls 331 Postado Janeiro 12, 2016 Autor Share Postado Janeiro 12, 2016 (editado) Esperando pra ver a versão final. shausahuashu (y) *ps: os créditos são pra vc, isso sim. Vc que desenvolveu o script. sahusahusa Po calma, to te dando os créditos da ideia. Ta certo, eu fiz. Mas o que é o mundo sem as ideias? hahaha Se tudo der certo acho que esse mes sai a v2.0, inclusive se quiser me ajudar a pensar em funcionalidades para o mesmo, estou aberto à sugestões obs: Editei pra adicionar um reset nos storages toda vez que o server for iniciado, isso impede que o server salve com várias instâncias criadas e a posição '0' mude de lugar. Editado Janeiro 12, 2016 por Skulls Link para o comentário Compartilhar em outros sites More sharing options...
BananaFight 196 Postado Janeiro 18, 2016 Share Postado Janeiro 18, 2016 (editado) Amigo, recomendo fazer isso pela source, você cria esses espaços com o RME, e carrega eles em uma lista de instancias, assim quando precisar não fica criando esses tiles, e se torna muito mais simples e pratico. Vou explicar detalhadamente o que você precisa fazer. 1° Criar um vetor ( Recomendo std::map ) de mapas do tibia 2° Criar um método em c++ que carrega esses maps e insere ele no vetor 3° criar um método que transporta o player para o seu map 4° criar um método que salve a oldPos do players, para quando ele deslogar / morrer, ele voltar pro map principal. com um conhecimento razoável em c++ é possível fazer isso, porem acho que pode ser um pouco trabalhoso. Com esse sistema você pode criar mapas para dungeons, houses etc, e sem contar que você pode transportar vários players para esses locais. Editado Janeiro 18, 2016 por BananaFight Link para o comentário Compartilhar em outros sites More sharing options...
Skulls 331 Postado Janeiro 19, 2016 Autor Share Postado Janeiro 19, 2016 Bom cara obrigado pela dica, mas não pretendo mexer na source por enquanto. Abraços, Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados