Skulls 331 Posted January 12, 2016 Report Share Posted January 12, 2016 (edited) 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 Edited January 12, 2016 by Skulls Link to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/ Share on other sites More sharing options...
Administrador Administrador 1435 Posted January 12, 2016 Administrador Report Share Posted January 12, 2016 Genial cara! Mais genial ainda você querer compartilhar. :biggrin: :biggrin: Link to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/#findComment-1680895 Share on other sites More sharing options...
Skulls 331 Posted January 12, 2016 Author Report Share Posted January 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 to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/#findComment-1680896 Share on other sites More sharing options...
Danihcv 335 Posted January 12, 2016 Report Share Posted January 12, 2016 (edited) 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 Edited January 12, 2016 by Danihcv Link to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/#findComment-1680897 Share on other sites More sharing options...
Skulls 331 Posted January 12, 2016 Author Report Share Posted January 12, 2016 (edited) 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. Edited January 12, 2016 by Skulls Link to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/#findComment-1680902 Share on other sites More sharing options...
BananaFight 196 Posted January 18, 2016 Report Share Posted January 18, 2016 (edited) 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. Edited January 18, 2016 by BananaFight Link to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/#findComment-1682053 Share on other sites More sharing options...
Skulls 331 Posted January 19, 2016 Author Report Share Posted January 19, 2016 Bom cara obrigado pela dica, mas não pretendo mexer na source por enquanto. Abraços, Link to comment https://xtibia.com/forum/topic/238745-instanciando-mapas-v10/#findComment-1682174 Share on other sites More sharing options...
Recommended Posts