Ir para conteúdo

Tfs - xadrez in-game


Poccnn

Posts Recomendados

Como e sabido de muitos, dificilmente se faz scripts para ot serve em simulação poo em lua.

 

Eu estava entediado jogando ot e resolvi jogar xadrez com aquelas peças de xadres que tem no jogo. Então me veio a ideia de por ordem nas peças,  fazer com que elas só se movimentem caso seja o movimento correta dela. Eis a oportunidade para eu aprender simulação de poo em lua.

 

 

Bem o script não está terminado, falta muita coisa, mas já é um começo. Gostaria da ajuda de vocês para me orientar na melhor forma de fazer o script.

Eu ainda estou aprendendo simulação de poo em lua,  então orientações nessa área são bem vindas.

Sugestões e críticas construtivas são bem vindas também. 

 

Xadrez.lua

Spoiler

   --[=[ 
      ################################################################################################################ 
      ##                                                         LIVRARIA (LIB) DO SISTEMA DE XADREZ                                                                     ## 
      ##                                                         CRIADO E DESENVOLVIDO POR: Marcryzius.                                                               ## 
      ##                                                       DATA DE CONCLUSÃO DA LIB: 15/JUNHO/2016                                                            ## 
      ##                                                   LIVRARIA ABERTA PARA TODOS QUE QUEIRAM USA-LA.                                                      ## 
      ##                                                                  AGRADECIMENTOS: Dalvorsn.                                                                           ## 
      ################################################################################################################ 
   MUITA COISA FOI MODIFICADO OU REMOVIDO: 
   REMOVIDO: 
      > CONVERSÃO DA POSIÇÃO (AGORA É USADO A POSIÇÃO REAL DO OBJETO). 
   MODIFICADO: 
      > TODAS AS FUNÇÕES DE MOVIMENTOS DAS PEÇAS QUE AGORA RETORNAM APENAS AS POSIÇÕES VALIDAS. 
      > FUNÇÃO GETPOSITIONS FOI REFEITA, AGORA ELA ESTA APENAS SELECIONANDO AS POSIÇÕES VALIDAS PARA A PEÇA EM QUESTÃO. 
   TRANSPORTADO: 
      > TODAS AS FUNÇÕES DE VALIDAÇÃO, ATUALIZAÇÃO, RETORNO E ETC, FORAM PARA MAIN (MOTOR DO SISTEMA). 
   TODO: 
      *OS EFEITOS SOMENTE APARECEM QUANDO UMA PEÇA É MOVIMENTADA PARA UMA POSIÇÃO INVALIDA. 
      *O SISTEMA DE CHECK SOMENTE FUNCIONA QUANDO UMA PEÇA INIMIGA MOVIMENTAR-SE E TIVER A OPORTUNIDADE DE ELIMINAR O REI. 
      *AS JOGADAS SÃO LIVRES, OU SEJA, NÃO ESPERA O OUTRO TIME JOGAR PARA QUE ELE POSSA MOVER SUA PEÇA. 
      *NÃO HÁ IMPLEMENTAÇÃO DE JOGADORES, PORTANTO, TODOS QUE MOVEREM AS PEÇAS SERÃO TIDOS COMO JOGADORES. 
      *SOMENTE HA DUAS FORMAS DE CARREGAR O JOGO, A PRIMEIRA: QUANDO O JOGO AINDA NÃO TIVER SIDO CARREGADO, A SEGUNDA: ELEIMINANDO O REI. 
         >> CASO QUEIRA IMPLEMENTAR OUTRA FORMA DE CARREGAR O JOGO, USE A FUNÇÃO loadTabulero(). 
         >> SUGIRO MODIFICAR AS PEÇAS (ITEM EDITOR) PARA IMPEDIR OS PLAYERS DE COLOCAREM NA BAG ELAS. 
   ]=] 


   GAME = {} 
   XADREZ = {} 
   _init = nil 
   pos_tabulero = {x=1105,y=1071,z=8} --Posição externa no noroeste do tabulero. 
   setmetatable(GAME,{__index = XADREZ}) 

 

local _castle =  function (self,item) -- Novo sistema implementado. Testado. Ok. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {0,1,2,3}, 8,item) 
   end 

 

local _knight = function(self,item) -- Novo sistema implementado. Testado. Ok. 
   local positions = {} 
   local piece_pos,piece_atual = self:getAntPos(),self:getAtualPos() 
      for _, mod_ in pairs({{x = -1, y = -2}, {x = -1, y = 2}, {x = 1, y = -2}, {x = 1, y = 2},{x = -2, y = -1}, {x = -2, y = 1}, {x = 2, y = 1}, {x = 2, y = -1}}) do 
      local posi = {x=piece_pos.x+mod_.x,y=piece_pos.y+mod_.y,z=pos_tabulero.z, stackpos = 255} 
      local si = {x=piece_pos.x+mod_.x,y=piece_pos.y+mod_.y,z=pos_tabulero.z, stackpos = 2} 
      local get,getsi = getThingFromPos(posi), getThingFromPos(si) 
         if not(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid) and get.actionid ~= item.actionid)then 
            if(getsi.itemid == 0 or not(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid)))then 
               if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
                  table.insert(positions,posi) 
               end 
            elseif(isInArray(GAME:getPiecesEnemy(item.itemid),getsi.itemid))then 
               if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
                  table.insert(positions,posi) 
               end 
            end 
         end 
      end 
      return positions 
   end 

 

local _bispo = function (self,item) -- Novo sistema implementado. Testado. Ok. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {4,5,6,7}, 8,item) 
   end 

 

local _queen = function (self,item) -- Novo sistema implementado. Testado. Ok. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {0,1,2,3,4,5,6,7}, 8,item) 
   end 

 

local _king = function (self,item) -- Novo sistema implementado. Testado. Incompleto. 
-- Falta adicionar a função que muda a posição do king e do castle simultaneamente. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {0,1,2,3,4,5,6,7}, 1,item) 
   end 

 

local _pawn = function (self,item) -- Novo sistema implementado. Testado. Incompleto. 
-- Falta adicionar uma forma de eliminar o pawn inimigo pela diagonal quando ele saltar duas casas (primeiro movimento da peça). 
   local positions = {} 
   local get_type = self:getType() 
   local piece_pos = self:getAntPos() 
   local det = get_type < 0 and -1 or 1-- negativo é para o norte e positivo para o sul 
      --nese caso ele faz um movimento na vertical. 
      -- impede que ele passe por cima de outra peça em seu primeiro movimento (no caso, seria duas casas). 
   local posi,pos_back = {x=piece_pos.x,y=piece_pos.y+det,z=pos_tabulero.z, stackpos = 2},{x=piece_pos.x,y=piece_pos.y+det,z=pos_tabulero.z, stackpos = 255} 
   local get,getback = getThingFromPos(posi),getThingFromPos(pos_back) 
      if not(get.itemid > 2625 and get.itemid < 2638 and item.actionid ~= get.actionid)then 
         if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
            if(get_type < -1 or get_type > 1)then 
               if(getback.itemid > 0 and item.actionid == getback.actionid or isCreature(getback.uid)) or getback.itemid == 0 then 
                  table.insert(positions,{x=piece_pos.x,y=piece_pos.y+get_type,z=pos_tabulero.z}) 
               end 
            end 
            if not(getback.itemid > 2625 and getback.itemid < 2638 and item.actionid ~= getback.actionid)then 
               table.insert(positions,{x=piece_pos.x,y=piece_pos.y+det,z=pos_tabulero.z}) 
            end 
         end 
      end 
      --nesse caso ele faz um movimento na diagonal. 
      for pp = -1,1,2 do 
      local posi = {x=piece_pos.x+pp,y=piece_pos.y+(get_type < 0 and -1 or 1),z=pos_tabulero.z, stackpos = 255} 
      local pos = {x=piece_pos.x+pp,y=piece_pos.y+(get_type < 0 and -1 or 1),z=pos_tabulero.z, stackpos = 2} 
      local get,geti = getThingFromPos(pos),getThingFromPos(posi) 
         if not(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid))then 
            if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid) or isInArray(GAME:getPiecesEnemy(item.itemid),geti.itemid))then 
               if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
                  table.insert(positions, posi) 
               end 
            end 
         end 
      end 
      return positions 
   end 

 

-- FUNCOES DO JOGO (GAME) -- 

-- Carrega as peças com suas funções e cria os objetos e os põe in-game 


function GAME:loadTabulero() 
_init = true 
-- CLEAN 
   GAME:cleanTabulero() 
-- CASTLES 
   GAME:addIngamePieces(_castle,{1,8},2627,1) -- white piece's 
   GAME:addIngamePieces(_castle,{1,8},2633,8) -- black piece's 
-- KNIGHTS 
   GAME:addIngamePieces(_knight,{2,7},2628,1) -- white piece's 
   GAME:addIngamePieces(_knight,{2,7},2634,8) -- black piece's 
-- BISHOPS 
   GAME:addIngamePieces(_bispo,{3,6},2629,1) -- white piece's 
   GAME:addIngamePieces(_bispo,{3,6},2635,8) -- black piece's 
--PAWN 
   for Y = 2,7,5 do 
      for X = 1,8 do 
      local piece = doCreateItemEx(Y == 2 and 2626 or 2632, 1) 
         doItemSetAttribute(piece, "aid", piece) -- necessario para identificar o objeto 
         doTileAddItemEx({x=pos_tabulero.x+X,y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 
         local st = XADREZ:getPiece(piece,{}) 
         st:setMoveFunc(_pawn) 
         st:setType(Y == 2 and 2 or -2) 
         st:setAntPos(X,Y) 
         st:setId(Y == 2 and 2626 or 2632) 
      end 
   end 
-- QUEEN E KING 
   for Y = 1,8,7 do 
      for id = 0,1 do 
      local piece = doCreateItemEx(Y == 1 and 2630+id or 2636+id, 1) 
         doItemSetAttribute(piece, "aid", piece) 
         doTileAddItemEx({x=pos_tabulero.x+(4+id),y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 
         local st = XADREZ:getPiece(piece,{}) 
         st:setMoveFunc(id == 0 and _queen or _king) 
         st:setType(Y == 1 and 1 or -1) 
         st:setAntPos(4+id,Y) 
         st:setId(Y == 1 and 2630+id or 2636+id) 
      end 
   end 
   self['white'] = nil 
   self['black'] = nil 
  _init = false 
   return false 
end 

 

-- remove as peças do tabulero. 
function GAME:cleanTabulero() 
   for X = 1,8 do 
      for Y = 1,8 do 
         local get = getThingFromPos({x=pos_tabulero.x+X,y=pos_tabulero.y+Y,z=pos_tabulero.z, stackpos = 1}) 
            if(type(get) == 'table' and get.itemid > 2625 and get.itemid < 2638)then 
               doRemoveItem(get.uid) 
            end 
      end 
   end 
   return true 
end 

 

-- retorna a peça (in game) para o seu lugar. 
function GAME:backMove(self,item) 
   local getPos = self:getAntPos() 
   doTeleportThing(item.uid,{x=getPos.x,y=getPos.y,z=pos_tabulero.z}) -- removido o parametro da posição do tabulero. 
end 

 

-- verifica a possibilidade de haver um check no rei inimigo. 
function GAME:getCheck(self,item) 
local positions = self:getMoveFunc(item) 
   for _, posi in pairs(positions) do 
   local get = getThingFromPos({x=posi.x,y=posi.y,z=pos_tabulero.z, stackpos = 255}) 
      if(get.itemid == 2631 or get.itemid == 2637)then 
         doSendAnimatedText(posi,"Check",10) 
         doSendMagicEffect(posi, 55) 
      end 
   end 
end 

 

-- verifica a possivel eliminação de peças adversarias. 
function GAME:killEnemy(posAtual,pieceid) 
local get,kill = getThingFromPos({x=posAtual.x,y=posAtual.y,z=pos_tabulero.z, stackpos = 2})-- removido o parametro da posição do tabulero. 
   -- não retorna a peça caso seja uma criatura 
   if(isCreature(getThingFromPos({x=posAtual.x,y=posAtual.y,z=pos_tabulero.z, stackpos = 255}).uid))then-- removido o parametro da posição do tabulero. 
      return true 
   -- Retorna a peça caso o item seja do mesmo grupo 
   elseif(isInArray(GAME:getPiecesFriends(pieceid),get.itemid)) and get.itemid > 0 then 
      return false 
   -- Eliminação de peças. 
   elseif(get.itemid > 0)then 
      if(get.itemid == 2631 or get.itemid == 2637)then -- caso seja um rei eliminado, carrega o jogo denovo. 
         doSendAnimatedText({x=pos_tabulero.x+3,y=pos_tabulero.y+4,z=pos_tabulero.z},"Winner",10) 
         doSendAnimatedText({x=pos_tabulero.x+4,y=pos_tabulero.y+4,z=pos_tabulero.z},(get.itemid == 2631 and "Black" or "White"),10) 
         doSendAnimatedText({x=pos_tabulero.x+5,y=pos_tabulero.y+4,z=pos_tabulero.z},"pieces!",10) 
         doRemoveItem(get.uid) 
         GAME:loadTabulero() 
         return true 
      end 
      local get = getThingFromPos({x=posAtual.x,y=posAtual.y,z=pos_tabulero.z, stackpos = 2})-- removido o parametro da posição do tabulero. 
      if(get.itemid > 0 and get.itemid ~= pieceid)then 
         doRemoveItem(get.uid) 
         kill = true 
      end 
   end 
   return kill 
end 

 

-- constrói os movimentos validos. 
function GAME:getPositions(atual,dirs,distance,item) -- Refeito. Testado. Ok. 
local positions = {} 
   for _, dir in pairs(dirs)do 
      for dist = 1, distance do 
        local pos = getPositionByDirection(atual, dir, dist) 
      pos.stackpos = 255 
      local get,id = getThingFromPos(pos),getTileInfo(pos).itemid 
         if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid) or get.itemid == 0 or isCreature(get.uid))then 
            if(id == 966 or id == 965)then table.insert(positions,pos) end 
            if(get.itemid > 100)then break end 
         elseif(get.itemid > 100 and item.actionid == get.actionid)then 
            pos.stackpos = 2 
            local get = getThingFromPos(pos) 
            if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid) or get.itemid == 0)then 
               if(id == 966 or id == 965)then 
                  table.insert(positions,pos) 
               end 
            else 
               break 
            end 
         elseif(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid))then 
            break 
         end 
      end 
   end 
   return positions 
end 

 

--   retorna uma tabela contendo as peças inimigas do 'pieceid' (id do item) enviado. 
function GAME:getPiecesEnemy(pieceid) 
local black,white = {2632,2633,2634,2635,2636,2637},{2626,2627,2628,2629,2630,2631} 
   if(isInArray(black,pieceid))then 
      return white 
   elseif(isInArray(white,pieceid))then 
      return black 
   end 
   return {} 
end 

 

-- retorna uma tabela contendo as peças do mesmo grupo do 'pieceid' (id do item) enviado. 
function GAME:getPiecesFriends(pieceid) 
local black,white = {2632,2633,2634,2635,2636,2637},{2626,2627,2628,2629,2630,2631} 
   if(isInArray(black,pieceid))then 
      return black 
   elseif(isInArray(white,pieceid))then 
      return white 
   end 
   return {} 
end 

 

-- essa função foi criada para quando o 'pawn' chegar a posição final do lado inimigo, seja substituido (transformado) em outro item (do mesmo grupo dele) 
-- levando em consideração a posição de sua chegada. Ex: se ele chegar na posição onde existia um cavaleiro, ele será transformado em um cavaleiro. 
function GAME:getPieceIdInPosByItemId(id,x) 
local x = x > 8 and x-pos_tabulero.x or x 
local items = { 
   [2632] = {2633,2634,2635,2636,2636,2635,2634,2633},-- black 
   [2626] = {2627,2628,2629,2630,2630,2629,2628,2627}, -- white 

   return items[id][x] 
end 

 

-- transforma o 'pawn' em outra peça. 
function GAME:upDateItem(item) 
--[[ 
   ESSA FUNÇÃO FAZ COM QUE OS PEOES (PAWN) AO CHEGAR NA POSIÇÃO INIMIGA, SEJA SUBSTITUIDO PELA  EQUIVALENTE A POSIÇÃO DE SUA CHEGADA. 
]]-- 
local pos = item:getAtualPos() 
local newid = GAME:getPieceIdInPosByItemId(item:getId(),pos.x) 
local nome = { 
   _castle = {2627,2633}, 
   _knight = {2628,2634}, 
   _bispo = {2629,2635}, 
   _queen = {2630,2636} 

   doTransformItem(getThingFromPos({x=pos.x,y=pos.y,z=pos_tabulero.z, stackpos = 1}).uid,newid)-- removido o parametro da posição do tabulero. 
   for k,v in pairs(nome) do 
      if(isInArray(v,newid))then 
      local move = k == '_castle' and _castle or k == '_knight' and _knight or k == '_bispo' and _bispo or _queen 
         item:setMoveFunc(move) 
         item:setType(0) 
         item:setAntPos(pos.x,pos.y) 
         item:setAtualPos(pos.x,pos.y) 
         item:setId(newid) 
         break 
      end 
   end 
end 

-- adiciona as peças no jogo (in-game). 
function GAME:addIngamePieces(func,wb,id,posi) 
   for pos = wb[1],wb[2],(wb[2]-wb[1]) do 
   local piece = doCreateItemEx(id, 1) 
      doItemSetAttribute(piece, "aid", piece) -- necessario para identificar o objeto 
      doTileAddItemEx({x=pos_tabulero.x+pos,y=pos_tabulero.y+posi,z=pos_tabulero.z},piece) 
      local st = XADREZ:getPiece(piece,{}) 
      st:setMoveFunc(func) 
      st:setType(pos <= 2 and 1 or -1) 
      st:setAntPos(pos,posi) 
      st:setAtualPos(pos,posi) 
      st:setId(id) 
   end 
   return true 
end 

 

-- adiciona um jogador ao grupo com o nome dele. 
function GAME:addPlayerGroupByName(nome,grupo) 
   self[grupo] = nome 
end 

-- pega o nome do jogador pelo grupo (black ou white). 
function GAME:getPlayerNameByGroup(grupo) 
   return self[grupo] 
end 

 

-- pega o nome do grupo (black ou white) pelo nome do jogador, desde que esteja cadastrado. 
function GAME:getGroupByPlayerName(nome) 
   for k,v in pairs(self) do 
      if(type(v) == 'string' and v == nome)then 
         return k 
      end 
   end 
end 

 

-- pega o nome do grupo da peça pelo id dela. 
function GAME:getGroupNameById(id) 
   if(isInArray({2632,2633,2634,2635,2636,2637},id))then 
      return 'black' 
   elseif(isInArray({2626,2627,2628,2629,2630,2631},id))then 
      return 'white' 
   end 
end 

 

-- FUNÇÕES DOS OBJETOS (PEÇAS) -- 
-- pega o objeto ou cria ele, caso não exista. 
function XADREZ:getPiece(uid,str) 
   if(self.__call)then 
      return self.__call(self,uid) 
   elseif(str)then 
   local obj = {} 
      obj.id = str.id or 0 
      obj.type_move = str.type_move or 0 
      obj.ant_pos = str.ant_pos or {x=0,y=0} 
      obj.move = str.move or nil 
      setmetatable(obj,self) 
      self.__index = self 
      self.__call = function(self,uid) 
         if uid and not self[uid] then 
            self[uid] = {__index = obj} 
            setmetatable(self[uid], self[uid]) 
            self[uid].uid = uid 
            return self[uid] 
         elseif(self[uid])then 
            return self[uid] 
         end 
      end 
      return self.__call(self,uid) 
   end 
end 

 

-- seta o id (itemid) no objeto (não interfere no id da peça in-game). 
function XADREZ:setId(id) 
   self.id = id 
end 

 

-- pega o id (itemid) declarado no objeto. 
function XADREZ:getId() 
   return self.id 
end 

 

-- type é algo requisitado apenas por 'pawn' que necessita saber se é seu primeiro movimento. 
function XADREZ:setType(value) 
   self.type_move = value 
end 

 

-- pega o type declarado no objeto. 
function XADREZ:getType() 
   return self.type_move 
end 

 

-- apenas usa os parâmetros x e y. 
function XADREZ:setAtualPos(x,y) 
   if(type(x) == 'table')then 
      x,y  = x.x or 0,x.y or 0 
   end 
   self.atual_pos = {x=x,y=y} 
end 

 

--retorna  a tabela com a posição real (in-game) do objeto. retorna apenas os parâmetros x e y. 
function XADREZ:getAtualPos() 
   return self.atual_pos 
end 

 

-- posição anterior da peça, para caso ela precise retornar para sua posição anterior. 
function XADREZ:setAntPos(x,y) 
   if(type(x) == 'table')then 
      x,y = x.x or 0,x.y or 0 
   end 
   self.ant_pos.x = x 
   self.ant_pos.y = y 
end 

 

-- retorna uma tabela com a posição real (in-game) da peça, usando apenas os parâmetros x e y. 
function XADREZ:getAntPos() 
   return self.ant_pos 
end 

 

-- função principal do objeto, onde é verificado suas posições validas para ser movimentado. 
function XADREZ:setMoveFunc(func) 
   self.move = func 
end 

 

-- retorna uma tabela contendo todas as posições validas para o obejto. 
function XADREZ:getMoveFunc(item) 
   return self.move(self,item) 
end 
 

 

 

Motor do sistema:

movements.xml adicione:

Spoiler

<!-- xadrez -->
    <movevent type="RemoveItem"  fromid="2626" toid="2637" event="script" value="xadrez_poo.lua"/>
    <movevent type="AddItem" tileitem="1"  itemid="965;966" event="script" value="xadrez_poo.lua"/>
    

 

movements/scripts/xadrez_poo.lua, adicione:

Spoiler

dofile(getDataDir() .. 'lib/xadrez.lua') --lib

-- FUNÇÕES REQUERIDAS
function doComparePositions(position, positionEx)
    return position.x == positionEx.x and position.y == positionEx.y
end

local function sendEffect(tab)
--tab, seria uma tabela de posições onde serão postos os efeitos.
if type(tab) ~= 'table' then return end
    for _,pos in pairs(tab) do
        doSendMagicEffect(pos, 56)
    end
end

-- EXECUÇÃO DO  SISTEMA IN-GAME
local next_group = ''
local player_solo = false

local function main(item,pos,cid)
local piece,check = XADREZ:getPiece(item.actionid),false

    if(piece)then
    local group = GAME:getGroupNameById(item.itemid)
    local nome_do_proximo_da_vez = GAME:getPlayerNameByGroup(next_group)
        if not(nome_do_proximo_da_vez)then
            if(GAME:getGroupByPlayerName(getCreatureName(cid)))then
                player_solo = true
            end
            GAME:addPlayerGroupByName(getCreatureName(cid),group)
        elseif not(nome_do_proximo_da_vez == getCreatureName(cid))then
            doPlayerSendCancel(cid,"Não é sua vez de jogar.")
            GAME:backMove(piece,item)
            return
        elseif not(GAME:getGroupByPlayerName(getCreatureName(cid)) == group) and not player_solo then
            doPlayerSendCancel(cid,"Voce não pode jogar as pecas do seu adversario.")
            GAME:backMove(piece,item)
            return
        elseif not(group == tostring(next_group))then
            doPlayerSendCancel(cid,"Não é a vez desse grupo jogar.")
            GAME:backMove(piece,item)
            return        
        end
        
        next_group = group == 'white' and 'black' or 'white'
        piece:setAtualPos(pos.x,pos.y)
        
        local positions = piece:getMoveFunc(item)
        for _, posi in pairs(positions) do
            if(doComparePositions(pos,posi))then 
            local get = getThingFromPos({x=posi.x,y=posi.y,z=pos_tabulero.z, stackpos = 2})
                if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid)) and get.itemid > 0 then
                    GAME:killEnemy(pos,item.itemid)
                end
                if(piece:getId() == 2626 or piece:getId() == 2632)then
                    if(pos.y-pos_tabulero.y == (piece:getType() < 0 and 1 or 8))then GAME:upDateItem(piece) end
                end                
                check = true
                piece:setType(piece:getType() < 0 and -1 or 1)
            end
        end
        if not(check)then
            doPlayerSendCancel(cid,"movimento invalido.")
            GAME:backMove(piece,item)
            if(#positions > 0 )then sendEffect(positions) end
        else 
            piece:setAntPos(pos.x,pos.y)
            GAME:getCheck(piece,item)
        end
    end
end

function onAddItem(item,tile,pos,cid)
    if not(isPlayer(cid))then return end
    main(item,pos,cid) -- chama a função principal
end

function onRemoveItem(item, tile, pos, cid)
    if(_init == nil)then 
        doSendAnimatedText(pos,"Load Game!",10)            
        GAME:loadTabulero()
    end

    if not(isPlayer(cid))then return end

    local piece = XADREZ:getPiece(item.actionid)
    if(piece)then
        piece:setAntPos(pos.x,pos.y)
    end
end

 

Editado por Poccnn
Link para o comentário
Compartilhar em outros sites

Implantei uma função para o pawn (peão). Quando ele chegava ao final da área inimiga, ele ficava lá parado - pois os peões não podem se movimentar para trás, então fiz com que ao chegarem lá, eles se tornariam outra peça; a peça no caso seria a da posição em que o pawn chegou - menos no caso do rei.

 

Adicionei essa sentença ao código do pawn.

Citar

if(pawn:getAtualPos().y == (det < 0 and 1 or 8))then GAME:upDateItem(item.actionid) end

 

Criei essas duas funções para que ela possa mudar de tipo de peça.

Citar

function GAME:getPieceIdInPosByItemId(id,x) 
local items = { 
   [2632] = {2633,2634,2635,2636,2637,2635,2634,2633},-- black 
   [2626] = {2627,2628,2629,2630,2631,2629,2628,2627}, -- white 

   return items[id][x] 
end 

function GAME:upDateItem(aid) 
local item = XADREZ:getPiece(aid) 
local pos = item:getAtualPos() 
local newid = GAME:getPieceIdInPosByItemId(item:getId(),pos.x) 
local nome = { 
   _castle = {2627,2633}, 
   _knight = {2628,2634}, 
   _bispo = {2629,2635}, 
   _queen = {2630,2636} 

   doTransformItem(getThingFromPos({x=pos_tabulero.x+pos.x,y=pos_tabulero.y+pos.y,z=pos_tabulero.z, stackpos = 1}).uid,newid) 
   for k,v in pairs(nome) do 
      if(isInArray(v,newid))then 
      local move = k == '_castle' and _castle or k == '_knight' and _knight or k == '_bispo' and _bispo or _queen 
         item:setMoveFunc(move.move) 
         item:setType(0) 
         item:setAntPos(pos.x,pos.y) 
         item:setAtualPos(pos.x,pos.y) 
         item:setId(newid) 
         break 
      end 
   end 
end 

 

E desmenbrei as estruturas das peças, menos o do rei e do pawn que não são necessários. 

 

Spoiler


local _castle = { 
   id = 0, 
   type_move = 0, 
   ant_pos = {x=0,y=0}, 
   move = function (item) 
   local piece = XADREZ:getPiece(item.actionid) 
   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 
      if(posAtual.y-mtr.y == 0 and posAtual.x-mtr.x ~= 0)then 
         for pos = mtr.x,posAtual.x,(mtr.x > posAtual.x and -1 or 1) do 
            if not(pos == posAtual.x)then 
            local get = getThingFromPos({x=pos_tabulero.x+pos,y=pos_tabulero.y+mtr.y,z=pos_tabulero.z, stackpos = 255}) 
               if(get and get.itemid > 2625 and get.itemid < 2638)then 
                  GAME:backMove(item) 
                  return false 
               end 
            end 
         end 
      -- Eliminação de peças 
      if(GAME:killEnemy(posAtual,item.itemid))then 
         return true 
      end 
      elseif(posAtual.x-mtr.x == 0 and posAtual.y-mtr.y ~= 0)then 
         for pos = mtr.y,posAtual.y,(mtr.y > posAtual.y and -1 or 1) do 
            if not(pos == posAtual.y)then 
            local get = getThingFromPos({x=pos_tabulero.x+mtr.x,y=pos_tabulero.y+pos,z=pos_tabulero.z, stackpos = 255}) 
               if(get and get.itemid > 2625 and get.itemid < 2638)then 
                  GAME:backMove(item) 
                  return false 
               end 
            end 
         end 
         -- Eliminação de peças
         if(GAME:killEnemy(posAtual,item.itemid))then 
            return true 
         end 
      end 
      GAME:backMove(item) 
      return false 
   end 

local _knight = { 
   id = 0, 
   type_move = 0, 
   ant_pos = {x=0,y=0}, 
   move = function (item) 
   local piece = XADREZ:getPiece(item.actionid) 
   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 
      if(posAtual.x-mtr.x ~= 0 and posAtual.y-mtr.y ~= 0)then 
         if(posAtual.x-mtr.x == 1 or posAtual.x-mtr.x == -1)then 
            -- nese caso ele faz um movimento na vertical. 
            if(posAtual.y-mtr.y == 2 or posAtual.y-mtr.y == -2)then 
               -- Eliminação de peças
               if(GAME:killEnemy(posAtual,item.itemid))then 
                  return true 
               end 
            end 
         elseif(posAtual.y-mtr.y == 1 or posAtual.y-mtr.y == -1)then 
            -- nesse caso ele faz um movimento na horizontal. 
            if(posAtual.x-mtr.x == 2 or posAtual.x-mtr.x == -2)then 
               -- Eliminação de peças
               if(GAME:killEnemy(posAtual,item.itemid))then 
                  return true 
               end 
            end 
         end 
      end 
      GAME:backMove(item) 
      return false 
   end 

local _bispo = { 
   id = 0, 
   type_move = 0, 
   ant_pos = {x=0,y=0}, 
   move = function (item) 
   local piece = XADREZ:getPiece(item.actionid) 
   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 
      if(posAtual.x-mtr.x ~= 0 and posAtual.y-mtr.y ~= 0)then 
         if(posAtual.x-mtr.x == posAtual.y-mtr.y or posAtual.x-mtr.x == -(posAtual.y-mtr.y))then 
            for _,pos in pairs(GAME:getPositions(mtr,posAtual)) do 
               if not(pos.x == posAtual.x or pos.x == mtr.x)then 
               local get = getThingFromPos({x=pos_tabulero.x+(pos.x),y=pos_tabulero.y+(pos.y),z=pos_tabulero.z, stackpos = 255}) 
                  if(get and get.itemid > 2625 and get.itemid < 2638)then 
                     GAME:backMove(item) 
                     return false 
                  end 
               end 
            end 
            -- Eliminação de peças
            if(GAME:killEnemy(posAtual,item.itemid))then 
               return true 
            end 
         end 
      end 
      GAME:backMove(item) 
      return false 
   end 

local _queen = { 
   id = 0, 
   type_move = 0, 
   ant_pos = {x=0,y=0}, 
   move = function (item) 
   local piece = XADREZ:getPiece(item.actionid) 
   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 
      if(posAtual.y-mtr.y == 0 and posAtual.x-mtr.x ~= 0)then 
         for pos = mtr.x,posAtual.x,(mtr.x > posAtual.x and -1 or 1) do 
            if not(pos == posAtual.x)then 
            local get = getThingFromPos({x=pos_tabulero.x+pos,y=pos_tabulero.y+mtr.y,z=pos_tabulero.z, stackpos = 255}) 
               if(get and get.itemid > 2625 and get.itemid < 2638)then 
                  GAME:backMove(item) 
                  return false 
               end 
            end 
         end 
      elseif(posAtual.x-mtr.x == 0 and posAtual.y-mtr.y ~= 0)then 
         for pos = mtr.y,posAtual.y,(mtr.y > posAtual.y and -1 or 1) do 
            if not(pos == posAtual.y)then 
            local get = getThingFromPos({x=pos_tabulero.x+mtr.x,y=pos_tabulero.y+pos,z=pos_tabulero.z, stackpos = 255}) 
               if(get and get.itemid > 2625 and get.itemid < 2638)then 
                  GAME:backMove(item) 
                  return false 
               end 
            end 
         end 
      elseif(posAtual.x-mtr.x ~= 0 and posAtual.y-mtr.y ~= 0)then 
         if(posAtual.x-mtr.x == posAtual.y-mtr.y or posAtual.x-mtr.x == -(posAtual.y-mtr.y))then 
            for _,pos in pairs(getPositions(mtr,posAtual)) do 
               if not(pos.x == posAtual.x or pos.x == mtr.x)then 
               local get = getThingFromPos({x=pos_tabulero.x+(pos.x),y=pos_tabulero.y+(pos.y),z=pos_tabulero.z, stackpos = 255}) 
                  if(get and get.itemid > 2625 and get.itemid < 2638)then 
                     GAME:backMove(item) 
                     return false 
                  end 
               end 
            end 
            -- Eliminação de peças ou retorno a posição anterior (quando a peça no caso é do mesmo grupo). 
            if(GAME:killEnemy(posAtual,item.itemid))then 
               return true 
            end 
         end 
         GAME:backMove(item) 
         return false 
      end 
      -- Eliminação de peças ou retorno a posição anterior (quando a peça no caso é do mesmo grupo). 
      if(GAME:killEnemy(posAtual,item.itemid))then 
         return true 
      end 
      GAME:backMove(item) 
      return false 
   end 

 

 

Pretendo atualizar esse sistema, fazendo com que o player possa escolher a peça. 

Link para o comentário
Compartilhar em outros sites

Eu fiz algo parecido com isso a um bom tempo atras, não cheguei a completar, acho que tinha ficado faltando o check ou check mate nao sei, vou ver se acho o code aqui

 

#edit

achei

http://pastebin.com/xw2YTWuT

 

O movimento era por arrasto, tu da look na peça e ele mostra as possiveis jogadas pra peça, ve se ajuda em algo

Editado por dalvorsn
Link para o comentário
Compartilhar em outros sites

Obrigado Dalvorsn, concerteza irá ajudar.

Vou estudar esse método que você fez.

Só de dar uma pequena analisada no código,  já me chamou atenção alguns métodos. 

 

Link para o comentário
Compartilhar em outros sites

Estou fazendo diversas mudanças que são necessários; substituindo, eliminando e adaptando funções, além de ter que re-ordenar o script. Mas, tudo isso é necessário, para esse novo método que estou fazendo. O script ficará mais simples, eficiente e com mais funções. Seria a base certa para criar um motor, na qual o player poderá jogar contra a maquina.

 

Uma prévia de como está ficando o sistema. 

xadrez_demonstracao_posicoes_validas_do_knight2.png

 

xadrez_demonstracao_posicoes_validas_do_knight.png

 

Obrigado Dalvorsn por sua ajuda.

xadrez_demonstracao_posicoes_validas_do_knight2.thumb.png.35de6f81d98bf693f534727516c03570.png

xadrez_demonstracao_posicoes_validas_do_knight.thumb.png.9a9538f855e8a396fe85d45c8b451369.png

Link para o comentário
Compartilhar em outros sites

Ainda não é a versão final - ainda falta terminar o motor, mas a lib já está pronta e testada, espero não ter mais que modificar nada na lib enquanto termino de ajustar o motor.

 

Spoiler

   --[=[ 
      ################################################################################################################ 
      ##                                                         LIVRARIA (LIB) DO SISTEMA DE XADREZ                                                                     ## 
      ##                                                         CRIADO E DESENVOLVIDO POR: Marcryzius.                                                               ## 
      ##                                                       DATA DE CONCLUSÃO DA LIB: 15/JUNHO/2016                                                            ## 
      ##                                                   LIVRARIA ABERTA PARA TODOS QUE QUEIRAM USÁ-LA.                                                      ## 
      ##                                                                  AGRADECIMENTOS: Dalvorsn.                                                                           ## 
      ################################################################################################################ 
   MUITA COISA FOI MODIFICADO OU REMOVIDO: 
   REMOVIDO: 
      > CONVERSÃO DA POSIÇÃO (AGORA É USADO A POSIÇÃO REAL DO OBJETO). 
   MODIFICADO: 
      > TODAS AS FUNÇÕES DE MOVIMENTOS DAS PEÇAS QUE AGORA RETORNAM APENAS AS POSIÇÕES VALIDAS. 
      > FUNÇÃO GETPOSITIONS FOI REFEITA, AGORA ELA ESTÁ APENAS SELECIONANDO AS POSIÇÕES VALIDAS PARA A PEÇA EM QUESTÃO. 
   TRANSPORTADO: 
      > TODAS AS FUNÇÕES DE VALIDAÇÃO, ATUALIZAÇÃO, RETORNO E ETC, FORAM PARA MAIN (MOTOR DO SISTEMA). 
   TODO: 
      *OS EFEITOS SOMENTE APARECEM QUANDO UMA PEÇA É MOVIMENTADA PARA UMA POSIÇÃO INVALIDA. 
      *O SISTEMA DE CHECK SOMENTE FUNCIONA QUANDO UMA PEÇA INIMIGA MOVIMENTAR-SE E TIVER A OPORTUNIDADE DE ELIMINAR O REI. 
      *AS JOGADAS SÃO LIVRES, OU SEJA, NÃO ESPERA O OUTRO TIME JOGAR PARA QUE ELE POSSA MOVER SUA PEÇA. 
      *NÃO HÁ IMPLEMENTAÇÃO DE JOGADORES, PORTANTO, TODOS QUE MOVEREM AS PEÇAS SERÃO TIDOS COMO JOGADORES. 
      *SÓ HÁ DUAS FORMAS DE CARREGAR O JOGO, A PRIMEIRA: QUANDO O JOGO AINDA NÃO TIVER SIDO CARREGADO, A SEGUNDA: ELEIMINANDO O REI. 
         >> CASO QUEIRA IMPLEMENTAR OUTRA FORMA DE CARREGAR O JOGO, USE A FUNÇÃO loadTabulero(). 
         >> SUGIRO MODIFICAR AS PEÇAS (ITEM EDITOR) PARA IMPEDIR OS PLAYERS DE COLOCAREM NA BAG A PEÇA. 
   ]=] 
   GAME = {} 
   XADREZ = {} 
   _init = nil 
   pos_tabulero = {x=1105,y=1071,z=8} --Posição externa no noroeste do tabulero. 
   setmetatable(GAME,{__index = XADREZ}) 

local _castle =  function (self,item) -- Novo sistema implementado. Testado. Ok. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {0,1,2,3}, 8,item) 
   end 

local _knight = function(self,item) -- Novo sistema implementado. Testado. Ok. 
   local positions = {} 
   local piece_pos,piece_atual = self:getAntPos(),self:getAtualPos() 
      for _, mod_ in pairs({{x = -1, y = -2}, {x = -1, y = 2}, {x = 1, y = -2}, {x = 1, y = 2},{x = -2, y = -1}, {x = -2, y = 1}, {x = 2, y = 1}, {x = 2, y = -1}}) do 
      local posi = {x=piece_pos.x+mod_.x,y=piece_pos.y+mod_.y,z=pos_tabulero.z, stackpos = 255} 
      local si = {x=piece_pos.x+mod_.x,y=piece_pos.y+mod_.y,z=pos_tabulero.z, stackpos = 2} 
      local get,getsi = getThingFromPos(posi), getThingFromPos(si) 
         if not(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid) and get.actionid ~= item.actionid)then 
            if(getsi.itemid == 0 or not(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid)))then 
               if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
                  table.insert(positions,posi) 
               end 
            elseif(isInArray(GAME:getPiecesEnemy(item.itemid),getsi.itemid))then 
               if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
                  table.insert(positions,posi) 
               end 
            end 
         end 
      end 
      return positions 
   end 

local _bispo = function (self,item) -- Novo sistema implementado. Testado. Ok. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {4,5,6,7}, 8,item) 
   end 

local _queen = function (self,item) -- Novo sistema implementado. Testado. Ok. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {0,1,2,3,4,5,6,7}, 8,item) 
   end 

local _king = function (self,item) -- Novo sistema implementado. Testado. Incompleto. 
-- Falta adicionar a função que muda a posição do king e do castle simutaneamente. 
   local piece_pos = self:getAntPos() 
      return GAME:getPositions({x=piece_pos.x,y=piece_pos.y,z=pos_tabulero.z}, {0,1,2,3,4,5,6,7}, 1,item) 
   end 
local _pawn = function (self,item) -- Novo sistema implementado. Testado. Incompleto. 
-- Falta adicionar uma forma de eliminar o pawn inimigo pela diagonal quando ele saltar duas casas (primeiro movimento da peça). 
   local positions = {} 
   local get_type = self:getType() 
   local piece_pos = self:getAntPos() 
   local det = get_type < 0 and -1 or 1-- negativo é para o norte e positivo para o sul 
      --nese caso ele faz um movimento na vertical. 
      -- impede que ele passe por cima de outra peça em seu primeiro movimento (no caso, seria duas casas). 
   local posi,pos_back = {x=piece_pos.x,y=piece_pos.y+det,z=pos_tabulero.z, stackpos = 2},{x=piece_pos.x,y=piece_pos.y+det,z=pos_tabulero.z, stackpos = 255} 
   local get,getback = getThingFromPos(posi),getThingFromPos(pos_back) 
      if not(get.itemid > 2625 and get.itemid < 2638 and item.actionid ~= get.actionid)then 
         if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
            if(get_type < -1 or get_type > 1)then 
               if(getback.itemid > 0 and item.actionid == getback.actionid or isCreature(getback.uid)) or getback.itemid == 0 then 
                  table.insert(positions,{x=piece_pos.x,y=piece_pos.y+get_type,z=pos_tabulero.z}) 
               end 
            end 
            if not(getback.itemid > 2625 and getback.itemid < 2638 and item.actionid ~= getback.actionid)then 
               table.insert(positions,{x=piece_pos.x,y=piece_pos.y+det,z=pos_tabulero.z}) 
            end 
         end 
      end 
      --nesse caso ele faz um movimento na diagonal. 
      for pp = -1,1,2 do 
      local posi = {x=piece_pos.x+pp,y=piece_pos.y+(get_type < 0 and -1 or 1),z=pos_tabulero.z, stackpos = 255} 
      local pos = {x=piece_pos.x+pp,y=piece_pos.y+(get_type < 0 and -1 or 1),z=pos_tabulero.z, stackpos = 2} 
      local get,geti = getThingFromPos(pos),getThingFromPos(posi) 
         if not(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid))then 
            if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid) or isInArray(GAME:getPiecesEnemy(item.itemid),geti.itemid))then 
               if(getTileInfo(posi).itemid == 966 or getTileInfo(posi).itemid == 965)then 
                  table.insert(positions, posi) 
               end 
            end 
         end 
      end 
      return positions 
   end 

-- FUNCOES DO JOGO (GAME) -- 

-- Carrega as peças com suas funções e cria os objetos e os põe in-game 
function GAME:loadTabulero() 
_init = true 
-- CLEAN 
   GAME:cleanTabulero() 
-- CASTLES 
   GAME:addIngamePieces(_castle,{1,8},2627,1) -- white piece's 
   GAME:addIngamePieces(_castle,{1,8},2633,8) -- black piece's 
-- KNIGHTS 
   GAME:addIngamePieces(_knight,{2,7},2628,1) -- white piece's 
   GAME:addIngamePieces(_knight,{2,7},2634,8) -- black piece's 
-- BISHOPS 
   GAME:addIngamePieces(_bispo,{3,6},2629,1) -- white piece's 
   GAME:addIngamePieces(_bispo,{3,6},2635,8) -- black piece's 
--PAWN 
   for Y = 2,7,5 do 
      for X = 1,8 do 
      local piece = doCreateItemEx(Y == 2 and 2626 or 2632, 1) 
         doItemSetAttribute(piece, "aid", piece) -- necessario para identificar o objeto 
         doTileAddItemEx({x=pos_tabulero.x+X,y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 
         local st = XADREZ:getPiece(piece,{}) 
         st:setMoveFunc(_pawn) 
         st:setType(Y == 2 and 2 or -2) 
         st:setAntPos(X,Y) 
         st:setId(Y == 2 and 2626 or 2632) 
      end 
   end 
-- QUEEN E KING 
   for Y = 1,8,7 do 
      for id = 0,1 do 
      local piece = doCreateItemEx(Y == 1 and 2630+id or 2636+id, 1) 
         doItemSetAttribute(piece, "aid", piece) 
         doTileAddItemEx({x=pos_tabulero.x+(4+id),y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 
         local st = XADREZ:getPiece(piece,{}) 
         st:setMoveFunc(id == 0 and _queen or _king) 
         st:setType(Y == 1 and 1 or -1) 
         st:setAntPos(4+id,Y) 
         st:setId(Y == 1 and 2630+id or 2636+id) 
      end 
   end 
  _init = false 
   return false 
end 

-- remove as peças do tabulero. 
function GAME:cleanTabulero() 
   for X = 1,8 do 
      for Y = 1,8 do 
         local get = getThingFromPos({x=pos_tabulero.x+X,y=pos_tabulero.y+Y,z=pos_tabulero.z, stackpos = 1}) 
            if(type(get) == 'table' and get.itemid > 2625 and get.itemid < 2638)then 
               doRemoveItem(get.uid) 
            end 
      end 
   end 
   return true 
end 

-- retorna a peça (in game) para o seu lugar. 
function GAME:backMove(self,item) 
   local getPos = self:getAntPos() 
   doTeleportThing(item.uid,{x=getPos.x,y=getPos.y,z=pos_tabulero.z}) -- removido o parametro da posição do tabulero. 
end 

-- verifica a possibilidade de haver um check no rei inimigo. 
function GAME:getCheck(self,item) 
local positions = self:getMoveFunc(item) 
   for _, posi in pairs(positions) do 
   local get = getThingFromPos({x=posi.x,y=posi.y,z=pos_tabulero.z, stackpos = 255}) 
      if(get.itemid == 2631 or get.itemid == 2637)then 
         doSendAnimatedText(posi,"Check",10) 
         doSendMagicEffect(posi, 55) 
      end 
   end 
end 

-- verifica a possivel eliminação de peças adversarias. 
function GAME:killEnemy(posAtual,pieceid) 
local get,kill = getThingFromPos({x=posAtual.x,y=posAtual.y,z=pos_tabulero.z, stackpos = 2})-- removido o parametro da posição do tabulero. 
   -- não retorna a peça caso seja uma criatura 
   if(isCreature(getThingFromPos({x=posAtual.x,y=posAtual.y,z=pos_tabulero.z, stackpos = 255}).uid))then-- removido o parametro da posição do tabulero. 
      return true 
   -- Retorna a peça caso o item seja do mesmo grupo 
   elseif not(isInArray(GAME:getPiecesEnemy(pieceid),get.itemid)) and get.itemid > 0 then 
      return false 
   -- Eliminação de peças. 
   elseif(get.itemid > 0)then 
      if(get.itemid == 2631 or get.itemid == 2637)then -- caso seja um rei eliminado, carrega o jogo denovo. 
         doSendAnimatedText({x=pos_tabulero.x+3,y=pos_tabulero.y+4,z=pos_tabulero.z},"Winner",10) 
         doSendAnimatedText({x=pos_tabulero.x+4,y=pos_tabulero.y+4,z=pos_tabulero.z},(get.itemid == 2631 and "Black" or "White"),10) 
         doSendAnimatedText({x=pos_tabulero.x+5,y=pos_tabulero.y+4,z=pos_tabulero.z},"pieces!",10) 
         doRemoveItem(get.uid) 
         GAME:loadTabulero() 
         return true 
      end 
      local get = getThingFromPos({x=posAtual.x,y=posAtual.y,z=pos_tabulero.z, stackpos = 2})-- removido o parametro da posição do tabulero. 
      if(get.itemid > 0 and get.itemid ~= pieceid)then 
         doRemoveItem(get.uid) 
         kill = true 
      end 
   end 
   return kill 
end 

-- constrói os movimentos validos. 
function GAME:getPositions(atual,dirs,distance,item) -- Refeito. Testado. Ok. 
local positions = {} 
   for _, dir in pairs(dirs)do 
      for dist = 1, distance do 
        local pos = getPositionByDirection(atual, dir, dist) 
      pos.stackpos = 255 
      local get,id = getThingFromPos(pos),getTileInfo(pos).itemid 
         if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid) or get.itemid == 0 or isCreature(get.uid))then 
            if(id == 966 or id == 965)then table.insert(positions,pos) end 
            if(get.itemid > 100)then break end 
         elseif(get.itemid > 100 and item.actionid == get.actionid)then 
            pos.stackpos = 2 
            local get = getThingFromPos(pos) 
            if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid) or get.itemid == 0)then 
               if(id == 966 or id == 965)then 
                  table.insert(positions,pos) 
               end 
            else 
               break 
            end 
         elseif(isInArray(GAME:getPiecesFriends(item.itemid),get.itemid))then 
            break 
         end 
      end 
   end 
   return positions 
end 

--   retorna uma tabela contendo as peças inimigas do 'pieceid' (id do item) enviado. 
function GAME:getPiecesEnemy(pieceid) 
local black,white = {2632,2633,2634,2635,2636,2637},{2626,2627,2628,2629,2630,2631} 
   if(isInArray(black,pieceid))then 
      return white 
   elseif(isInArray(white,pieceid))then 
      return black 
   end 
   return {} 
end 

-- retorna uma tabela contendo as peças do mesmo grupo do 'pieceid' (id do item) enviado. 
function GAME:getPiecesFriends(pieceid) 
local black,white = {2632,2633,2634,2635,2636,2637},{2626,2627,2628,2629,2630,2631} 
   if(isInArray(black,pieceid))then 
      return black 
   elseif(isInArray(white,pieceid))then 
      return white 
   end 
   return {} 
end 

-- essa função foi criada para quando o 'pawn' chegar a posição final do lado inimigo, seja substituido (transformado) em outro item (do mesmo grupo dele) 
-- levando em consideração a posição de sua chegada. Ex: se ele chegar na posição onde existia um cavaleiro, ele será transformado em um cavaleiro. 
function GAME:getPieceIdInPosByItemId(id,x) 
local x = x > 8 and x-pos_tabulero.x or x 
local items = { 
   [2632] = {2633,2634,2635,2636,2636,2635,2634,2633},-- black 
   [2626] = {2627,2628,2629,2630,2630,2629,2628,2627}, -- white 

   return items[id][x] 
end 

-- transforma o 'pawn' em outra peça. 
function GAME:upDateItem(item) 
--[[ 
   ESSA FUNÇÃO FAZ COM QUE OS PAWN'S AO CHEGAR NA POSIÇÃO INIMIGA, SEJA SUBSTITUIDO PELA PEÇA EQUIVALENTE A POSIÇÃO DE SUA CHEGADA. 
]]-- 
local pos = item:getAtualPos() 
local newid = GAME:getPieceIdInPosByItemId(item:getId(),pos.x) 
local nome = { 
   _castle = {2627,2633}, 
   _knight = {2628,2634}, 
   _bispo = {2629,2635}, 
   _queen = {2630,2636} 

   doTransformItem(getThingFromPos({x=pos.x,y=pos.y,z=pos_tabulero.z, stackpos = 1}).uid,newid)-- removido o parametro da posição do tabulero. 
   for k,v in pairs(nome) do 
      if(isInArray(v,newid))then 
      local move = k == '_castle' and _castle or k == '_knight' and _knight or k == '_bispo' and _bispo or _queen 
         item:setMoveFunc(move) 
         item:setType(0) 
         item:setAntPos(pos.x,pos.y) 
         item:setAtualPos(pos.x,pos.y) 
         item:setId(newid) 
         break 
      end 
   end 
end 

-- adiciona as peças no jogo (in-game). 
function GAME:addIngamePieces(func,wb,id,posi) 
   for pos = wb[1],wb[2],(wb[2]-wb[1]) do 
   local piece = doCreateItemEx(id, 1) 
      doItemSetAttribute(piece, "aid", piece) -- necessario para identificar o objeto 
      doTileAddItemEx({x=pos_tabulero.x+pos,y=pos_tabulero.y+posi,z=pos_tabulero.z},piece) 
      local st = XADREZ:getPiece(piece,{}) 
      st:setMoveFunc(func) 
      st:setType(pos <= 2 and 1 or -1) 
      st:setAntPos(pos,posi) 
      st:setAtualPos(pos,posi) 
      st:setId(id) 
   end 
   return true 
end 

-- FUNÇÕES DOS OBJETOS (PEÇAS) -- 
-- pega o objeto ou cria ele, caso não exista. 
function XADREZ:getPiece(uid,str) 
   if(self.__call)then 
      return self.__call(self,uid) 
   elseif(str)then 
   local obj = {} 
      obj.id = str.id or 0 
      obj.type_move = str.type_move or 0 
      obj.ant_pos = str.ant_pos or {x=0,y=0} 
      obj.move = str.move or nil 
      setmetatable(obj,self) 
      self.__index = self 
      self.__call = function(self,uid) 
         if uid and not self[uid] then 
            self[uid] = {__index = obj} 
            setmetatable(self[uid], self[uid]) 
            self[uid].uid = uid 
            return self[uid] 
         elseif(self[uid])then 
            return self[uid] 
         end 
      end 
      return self.__call(self,uid) 
   end 
end 

-- seta o id (itemid) no objeto (não interfere no id da peça in-game). 
function XADREZ:setId(id) 
   self.id = id 
end 

-- pega o id (itemid) declarado no objeto. 
function XADREZ:getId() 
   return self.id 
end 

-- type é algo requisitado apenas por 'pawn' que necessita saber se é seu primeiro movimento. 
function XADREZ:setType(value) 
   self.type_move = value 
end 

-- pega o type declarado no objeto. 
function XADREZ:getType() 
   return self.type_move 
end 

-- apenas usa os parâmetros x e y. 
function XADREZ:setAtualPos(x,y) 
   if(type(x) == 'table')then 
      x,y  = x.x or 0,x.y or 0 
   end 
   self.atual_pos = {x=x,y=y} 
end 

--retorna  a tabela com a posição real (in-game) do objeto. usado muito para saber a posição atual do objeto. retorna apenas os parâmetros x e y. 
function XADREZ:getAtualPos() 
   return self.atual_pos 
end 

-- posição anterior da peça, para caso ela precise retornar para sua posição anterior. 
function XADREZ:setAntPos(x,y) 
   if(type(x) == 'table')then 
      x,y = x.x or 0,x.y or 0 
   end 
   self.ant_pos.x = x 
   self.ant_pos.y = y 
end 

-- retorna uma tabela com a posição real (in-game) da peça, usando apenas os parâmetros x e y. 
function XADREZ:getAntPos() 
   return self.ant_pos 
end 

-- função principal do objeto, onde é verificado suas posições validas para ser movimentado. 
function XADREZ:setMoveFunc(func) 
   self.move = func 
end 

-- retorna uma tabela contendo todas as posições validas para o obejto. 
function XADREZ:getMoveFunc(item) 
   return self.move(self,item) 
end 
 

 

Ps: está formatado em utf8, converta ele para ansi antes de usá-lo.

Link para o comentário
Compartilhar em outros sites

  • 2 weeks later...

Depois de um bom tempo sem dedicar a esse script, voltei e fiz algumas funções.

 

Essa é a função principal que gerencia tudo.

Futuramente, pretendo fazer um modo com que o player jogue contra a maquina.

 

O que foi feito?

- foi criado uma forma de cadastrar jogadores.

- foi criado um modo de ordenar a vez de jogar de cada grupo.

- foi criado um modo de bloquear a jogada indevida de um jogador.

 

Citar

 
-- FUNÇÕES REQUERIDAS 
function doComparePositions(position, positionEx) 
   return position.x == positionEx.x and position.y == positionEx.y 
end 

local function sendEffect(tab) 
--tab, seria uma tabela de posições onde serão postos o efeito. 
if type(tab) ~= 'table' then return end 
   for _,pos in pairs(tab) do 
      doSendMagicEffect(pos, 56) 
   end 
end 

 

-- EXECUÇÃO DO  SISTEMA IN-GAME 
local next_group = '' 
local player_solo = false 

local function main(item,pos,cid) 
local piece,check = XADREZ:getPiece(item.actionid),false 

   if(piece)then 
   local group = GAME:getGroupNameById(item.itemid) 
   local nome_do_proximo_da_vez = GAME:getPlayerNameByGroup(next_group) 
      if not(nome_do_proximo_da_vez)then 
      -- faz uma verificação se ja existe um grupo para tal jogador; se existir, então ele está jogando solo. 
         if(GAME:getGroupByPlayerName(getCreatureName(cid)))then 
            player_solo = true 
         end 
         -- mesmo ele jogando solo, se faz necessario setar o grupo opositor a ele. 
         GAME:addPlayerGroupByName(getCreatureName(cid),group) 
      elseif not(nome_do_proximo_da_vez == getCreatureName(cid))then 
         doPlayerSendCancel(cid,"Não é sua vez de jogar.") 
         GAME:backMove(piece,item) 
         return 
      elseif not(GAME:getGroupByPlayerName(getCreatureName(cid)) == group) and not player_solo then 
         doPlayerSendCancel(cid,"Voce não pode jogar as pecas do seu adversario.") 
         GAME:backMove(piece,item) 
         return 
      elseif not(group == tostring(next_group))then 
         doPlayerSendCancel(cid,"Não é a vez desse grupo jogar.") 
         GAME:backMove(piece,item) 
         return 
      end 
      next_group = group == 'white' and 'black' or 'white' 
      piece:setAtualPos(pos.x,pos.y) 
      local positions = piece:getMoveFunc(item) 
      for _, posi in pairs(positions) do 
         if(doComparePositions(pos,posi))then 
         local get = getThingFromPos({x=posi.x,y=posi.y,z=pos_tabulero.z, stackpos = 2}) 
            if(isInArray(GAME:getPiecesEnemy(item.itemid),get.itemid)) and get.itemid > 0 then 
               GAME:killEnemy(pos,item.itemid) 
            end 
            if(piece:getId() == 2626 or piece:getId() == 2632)then 
            -- verifica se o pawn chegou ao final do lado inimigo, fazendo com que seja transformado em outra peça do mesmo grupo dele. 
               if(pos.y-pos_tabulero.y == (piece:getType() < 0 and 1 or 8))then GAME:upDateItem(piece) end 
            end 
            check = true 
            piece:setType(piece:getType() < 0 and -1 or 1) 
         end 
      end 
      if not(check)then 
         doPlayerSendCancel(cid,"movimento invalido.") 
         GAME:backMove(piece,item) 
         -- caso haja meios para ele se mover, envia os efeitos nas posições validas. 
         if(#positions > 0 )then sendEffect(positions) end 
      else 
         piece:setAntPos(pos.x,pos.y) 
         GAME:getCheck(piece,item) -- verifica se há algum rei em check. 
      end 
   end 
end 

 

 

Aqui estão as funções implementadas.

Citar

-- adiciona um jogador ao grupo com o nome dele. 
function GAME:addPlayerGroupByName(nome,grupo) 
   self[grupo] = nome 
end 

-- pega o nome do jogador pelo grupo (black ou white). 
function GAME:getPlayerNameByGroup(grupo) 
   return self[grupo] 
end 

-- pega o nome do grupo (black ou white) pelo nome do jogador, desde que esteja cadastrado. 
function GAME:getGroupByPlayerName(nome) 
   for k,v in pairs(self) do 
      if(type(v) == 'string' and v == nome)then 
         return k 
      end 
   end 
end 

-- pega o nome do grupo da peça pelo id dela. 
function GAME:getGroupNameById(id) 
   if(isInArray({2632,2633,2634,2635,2636,2637},id))then 
      return 'black' 
   elseif(isInArray({2626,2627,2628,2629,2630,2631},id))then 
      return 'white' 
   end 
end 

-- remove o nome do player do grupo

function GAME:removePlayerName(nome)

   for k,v in pairs(self) do

       if type(v) == 'string' and v == nome then

          self[k] = nil

       end

   end

end

 

Segue algumas imagens da execução do sistema in-game.

tentou jogar denovo.png

 

o god tentou jogar a peca do adversario.png

 

578229f2e314a_ogodtentoujogarapecadoadversario.thumb.png.b49737257a5b11e07dfd64069faaf28d.png

57822a4c7d4b1_tentoujogardenovo.thumb.png.7803a0de490eee119372f69dfd2d526b.png

Link para o comentário
Compartilhar em outros sites

  • 2 months later...

Cara que maneiro! eu ja joguei xadrez com um amigo meu no tibia, estavamos cansados de caçar e tudo mais, mas é raro eu ver alguém jogando algo nos tabuleiros tibianos, com esse sistema, um xadrez (melhor) correto da até mais vontade de jogar, atraindo os players... até podendo dar uma bonificação para quem ganhar a partida...

Link para o comentário
Compartilhar em outros sites

  • 7 months later...
Em 06/06/2016 at 10:27, Poccnn disse:

Como e sabido de muitos, dificilmente se faz scripts para ot serve em simulação poo em lua.

 

Eu estava entediado jogando ot e resolvi jogar xadrez com aquelas peças de xadres que tem no jogo. Então me veio a ideia de por ordem nas peças,  fazer com que elas só movimento caso seja o movimento correta dela. Eis a oportunidade para eu aprender simulação de poo em lua.

 

 

Bem o script não está terminado, falta muita coisa, mas já é um começo. Gostaria da ajuda de vocês para me orientar na melhor forma de fazer o script.

Eu ainda estou aprendendo simulação de poo em lua,  então orientações nessa área são bem vindas.

Sugestões e críticas construtivas são bem vindas também. 

 

Xadrez.lua

  Mostrar conteúdo oculto

dofile(getDataDir() .. 'lib/xadrez_lib.lua') --lib 

--[[ 

   SISTEMA FUNCIONANDO SEM NENHUM ERRO APARENTE 

   ÚLTIMA MODIFICAÇÃO: SÁBADO,  4 DE JUNHO DE 2016 ÀS 20:54 

   FALTA: 

   > TESTAR O SISTEMA AFUNDO. 

   > OPTIMIZAR O SISTEMA. 

   > CRIAR ALGUMAS FUNÇÕES QUE FALTAM EM ALGUMAS PEÇAS. 

]] 

function GAME:loadCastles() 

local castle = { 

   id = 0, 

   type_move = 0, 

   ant_pos = {x=0,y=0}, 

   move = function (item) 

-- mtr > posição de retorno = {x=numero de retorno (1 a 8), y=numero de retorno (1 a 8)} 

-- posAtual > é apenas a distancia entre o valor declarada na variavel pos_tabulero menos a posição atual do objeto "in map" equivalente. {x= 1 a 8,y=1 a 8} 

   local piece = XADREZ:getPiece(item.actionid) 

   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 

      if(posAtual.y-mtr.y == 0 and posAtual.x-mtr.x ~= 0)then 

         for pos = mtr.x,posAtual.x,(mtr.x > posAtual.x and -1 or 1) do 

            if not(pos == posAtual.x)then 

            local get = getThingFromPos({x=pos_tabulero.x+pos,y=pos_tabulero.y+mtr.y,z=pos_tabulero.z, stackpos = 255}) 

               if(get and get.itemid > 2625 and get.itemid < 2638)then 

                  GAME:backMove(item) 

                  return false 

               end 

            end 

         end 

      -- Eliminação de peças. 

      if(GAME:killEnemy(posAtual,item.itemid))then 

         return true 

      end 

      elseif(posAtual.x-mtr.x == 0 and posAtual.y-mtr.y ~= 0)then 

         for pos = mtr.y,posAtual.y,(mtr.y > posAtual.y and -1 or 1) do 

            if not(pos == posAtual.y)then 

            local get = getThingFromPos({x=pos_tabulero.x+mtr.x,y=pos_tabulero.y+pos,z=pos_tabulero.z, stackpos = 255}) 

               if(get and get.itemid > 2625 and get.itemid < 2638)then 

                  GAME:backMove(item) 

                  return false 

               end 

            end 

         end 

         -- Eliminação de peças. 

         if(GAME:killEnemy(posAtual,item.itemid))then 

            return true 

         end 

      end 

      GAME:backMove(item) 

      return false 

   end 

   -- adiciona in-game as peças 

   GAME:addIngamePieces(castle,{1,8},2627,1) -- white piece's 

   GAME:addIngamePieces(castle,{1,8},2633,8) -- black piece's 

   return true 

end 

function GAME:loadKnights() 

local knight = { 

   id = 0, 

   type_move = 0, 

   ant_pos = {x=0,y=0}, 

   move = function (item) 

   -- mtr > posição de retorno = {x=numero de retorno (1 a 8), y=numero de retorno (1 a 8)} 

   -- posAtual > é apenas a distancia entre o valor declarada na variavel pos_tabulero menos a posição atual do objeto "in map" equivalente. {x= 1 a 8,y=1 a 8} 

   local piece = XADREZ:getPiece(item.actionid) 

   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 

      if(posAtual.x-mtr.x ~= 0 and posAtual.y-mtr.y ~= 0)then 

         if(posAtual.x-mtr.x == 1 or posAtual.x-mtr.x == -1)then 

            -- nese caso ele faz um movimento na vertical. 

            if(posAtual.y-mtr.y == 2 or posAtual.y-mtr.y == -2)then 

               -- Eliminação de peças

               if(GAME:killEnemy(posAtual,item.itemid))then 

                  return true 

               end 

            end 

         elseif(posAtual.y-mtr.y == 1 or posAtual.y-mtr.y == -1)then 

            -- nesse caso ele faz um movimento na horizontal. 

            if(posAtual.x-mtr.x == 2 or posAtual.x-mtr.x == -2)then 

               -- Eliminação de peças

               if(GAME:killEnemy(posAtual,item.itemid))then 

                  return true 

               end 

            end 

         end 

      end 

      GAME:backMove(item) 

      return false 

   end 

   -- adiciona in-game as peças

   GAME:addIngamePieces(knight,{2,7},2628,1) -- white piece's 

   GAME:addIngamePieces(knight,{2,7},2634,8) -- black piece's 

   return true 

end 

function GAME:loadBishops() 

local bispo = { 

   id = 0, 

   type_move = 0, 

   ant_pos = {x=0,y=0}, 

   move = function (item) 

   -- mtr > posição de retorno = {x=numero de retorno (1 a 8), y=numero de retorno (1 a 8)} 

   -- posAtual > é apenas a distancia entre o valor declarada na variavel pos_tabulero menos a posição atual do objeto "in map" equivalente. {x= 1 a 8,y=1 a 8} 

   local piece = XADREZ:getPiece(item.actionid) 

   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 

      if(posAtual.x-mtr.x ~= 0 and posAtual.y-mtr.y ~= 0)then 

         if(posAtual.x-mtr.x == posAtual.y-mtr.y or posAtual.x-mtr.x == -(posAtual.y-mtr.y))then 

            for _,pos in pairs(getPositions(mtr,posAtual)) do 

               if not(pos.x == posAtual.x or pos.x == mtr.x)then 

               local get = getThingFromPos({x=pos_tabulero.x+(pos.x),y=pos_tabulero.y+(pos.y),z=pos_tabulero.z, stackpos = 255}) 

                  if(get and get.itemid > 2625 and get.itemid < 2638)then 

                     GAME:backMove(item) 

                     return false 

                  end 

               end 

            end 

            -- Eliminação de peças 

            if(GAME:killEnemy(posAtual,item.itemid))then 

               return true 

            end 

         end 

      end 

      GAME:backMove(item) 

      return false 

   end 

   GAME:addIngamePieces(bispo,{3,6},2629,1) -- white piece's 

   GAME:addIngamePieces(bispo,{3,6},2635,8) -- black piece's 

   return true 

end 

function GAME:loadQueens() 

local queen = { 

   id = 0, 

   type_move = 0, 

   ant_pos = {x=0,y=0}, 

   move = function (item) 

-- mtr > posição de retorno = {x=numero de retorno (1 a 8), y=numero de retorno (1 a 8)} 

-- posAtual > é apenas a distancia entre o valor declarada na variavel pos_tabulero menos a posição atual do objeto "in map" equivalente. {x= 1 a 8,y=1 a 8} 

   local piece = XADREZ:getPiece(item.actionid) 

   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 

      if(posAtual.y-mtr.y == 0 and posAtual.x-mtr.x ~= 0)then 

         for pos = mtr.x,posAtual.x,(mtr.x > posAtual.x and -1 or 1) do 

            if not(pos == posAtual.x)then 

            local get = getThingFromPos({x=pos_tabulero.x+pos,y=pos_tabulero.y+mtr.y,z=pos_tabulero.z, stackpos = 255}) 

               if(get and get.itemid > 2625 and get.itemid < 2638)then 

                  GAME:backMove(item) 

                  return false 

               end 

            end 

         end 

      elseif(posAtual.x-mtr.x == 0 and posAtual.y-mtr.y ~= 0)then 

         for pos = mtr.y,posAtual.y,(mtr.y > posAtual.y and -1 or 1) do 

            if not(pos == posAtual.y)then 

            local get = getThingFromPos({x=pos_tabulero.x+mtr.x,y=pos_tabulero.y+pos,z=pos_tabulero.z, stackpos = 255}) 

               if(get and get.itemid > 2625 and get.itemid < 2638)then 

                  GAME:backMove(item) 

                  return false 

               end 

            end 

         end 

      elseif(posAtual.x-mtr.x ~= 0 and posAtual.y-mtr.y ~= 0)then 

         if(posAtual.x-mtr.x == posAtual.y-mtr.y or posAtual.x-mtr.x == -(posAtual.y-mtr.y))then 

            for _,pos in pairs(getPositions(mtr,posAtual)) do 

               if not(pos.x == posAtual.x or pos.x == mtr.x)then 

               local get = getThingFromPos({x=pos_tabulero.x+(pos.x),y=pos_tabulero.y+(pos.y),z=pos_tabulero.z, stackpos = 255}) 

                  if(get and get.itemid > 2625 and get.itemid < 2638)then 

                     GAME:backMove(item) 

                     return false 

                  end 

               end 

            end 

            -- Eliminação de peças ou retorno a posição anterior (quando a peça no caso é do mesmo grupo). 

            if(GAME:killEnemy(posAtual,item.itemid))then 

               return true 

            end 

         end 

         GAME:backMove(item) 

         return false 

      end 

      -- Eliminação de peças ou retorno a posição anterior (quando a peça no caso é do mesmo grupo). 

      if(GAME:killEnemy(posAtual,item.itemid))then 

         return true 

      end 

      GAME:backMove(item) 

      return false 

   end 

   -- adiciona in-game as peças

   for Y = 1,8,7 do 

   local piece = doCreateItemEx(Y == 1 and 2630 or 2636, 1) 

      doItemSetAttribute(piece, "aid", piece) 

      doTileAddItemEx({x=pos_tabulero.x+4,y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 

      local st = XADREZ:getPiece(piece,queen) 

      st:setMoveFunc(queen.move) 

      st:setType(Y == 1 and 1 or -1) 

      st:setAntPos(4,Y) 

      st:setId(Y == 1 and 2630 or 2636) 

   end 

   return true 

end 

function GAME:loadKings() 

local king = { 

   id = 0, 

   type_move = 0, 

   ant_pos = {x=0,y=0}, 

   move = function (item) 

-- mtr > posição de retorno = {x=numero de retorno (1 a 8), y=numero de retorno (1 a 8)} 

-- posAtual > e apenas a distancia entre o valor declarada na variavel pos_tabulero menos a posição atual do objeto "in map" equivalente. {x= 1 a 8,y=1 a 8} 

   local piece = XADREZ:getPiece(item.actionid) 

   local posAtual,mtr = piece:getAtualPos(),piece:getAntPos() 

      if(posAtual.x-mtr.x >= -1 and  posAtual.x-mtr.x <= 1) and (posAtual.y-mtr.y >= -1 and posAtual.y-mtr.y <= 1)then 

         -- Eliminação de peças ou retorno a posição anterior (quando a peça no caso é do mesmo grupo). 

         if(GAME:killEnemy(posAtual,item.itemid))then 

            return true 

         end 

      end 

      GAME:backMove(item) 

      return false 

   end 

   -- adiciona in-game as peças 

   for Y = 1,8,7 do 

   local piece = doCreateItemEx(Y == 1 and 2631 or 2637, 1) 

      doItemSetAttribute(piece, "aid", piece) -- necessario para buscar o objeto 

      doTileAddItemEx({x=pos_tabulero.x+5,y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 

      local st = XADREZ:getPiece(piece,king) 

      st:setMoveFunc(king.move) 

      st:setType(Y == 1 and 1 or -1) 

      st:setAntPos(5,Y) 

      st:setId(Y == 1 and 2631 or 2637) 

   end 

   return true 

end 

 

function GAME:loadPawn() 

local pawn = { 

   id = 0, 

   type_move = 0, 

   ant_pos = {x=0,y=0}, 

   move = function (item) 

-- mtr > posição de retorno = {x=numero de retorno (1 a 8), y=numero de retorno (1 a 8)} 

-- posAtual > é apenas a distancia entre o valor declarada na variavel pos_tabulero menos a posição atual do objeto "in map" equivalente. {x= 1 a 8,y=1 a 8} 

   local pawn = XADREZ:getPiece(item.actionid) 

   local get = pawn:getType() 

   local det = get < 0 and -1 or 1 

   local posAtual,mtr = pawn:getAtualPos(),pawn:getAntPos() 

      --nese caso ele faz um movimento na vertical. 

      if(posAtual.x-mtr.x == 0 and (posAtual.y-mtr.y == get or posAtual.y-mtr.y == get-(det)))then 

         -- Eliminação de peça ou validar a posição atual da peça. 

         pawn:setType(det) 

         if(GAME:killEnemy(posAtual,item.itemid))then 

            return true 

         end 

      --nesse caso ele faz um movimento na diagonal. 

      elseif(posAtual.x-mtr.x == -1 or posAtual.x-mtr.x == 1) and (posAtual.y-mtr.y == det)then 

         -- ele precisa se certificar que tenha eliminado uma peça inimiga se nao, o movimento é invalido. 

         local _,kill = GAME:killEnemy(posAtual,item.itemid) 

         if(kill)then 

            pawn:setType(det) 

            return true 

         end 

      end 

      GAME:backMove(item) 

      return false 

   end 

   -- adiciona in-game as peças

   for Y = 2,7,5 do 

      for X = 1,8 do 

      local piece = doCreateItemEx(Y == 2 and 2626 or 2632, 1) 

         doItemSetAttribute(piece, "aid", piece) -- necessario para identificar o objeto 

         doTileAddItemEx({x=pos_tabulero.x+X,y=pos_tabulero.y+Y,z=pos_tabulero.z},piece) 

         local st = XADREZ:getPiece(piece,pawn) 

         st:setMoveFunc(pawn.move) 

         st:setType(Y == 2 and 2 or -2) 

         st:setAntPos(X,Y) 

         st:setId(Y == 2 and 2626 or 2632) 

      end 

   end 

   return true 

end 

 

Xadrez_lib.lua

  Ocultar conteúdo

   GAME = {} 

   XADREZ = {} 

   _upDate = 0 

   pos_tabulero = {x=1105,y=1071,z=8} 

   setmetatable({},GAME) 

 

-- FUNÇÕES DO JOGO (GAME) -- 

function GAME:loadTabulero() 

_upDate = 1 

   if( 

   GAME:cleanTabulero() and 

   GAME:loadCastles() and 

   GAME:loadKnights() and 

   GAME:loadBishops() and 

   GAME:loadQueens() and 

   GAME:loadKings()  and 

   GAME:loadPawn() 

   )then  _upDate = nil return true end 

   return false 

end 

-- remove as peças do tabulero. 

function GAME:cleanTabulero() 

   for X = 1,8 do 

      for Y = 1,8 do 

         for stack = 1,10 do 

         local get = getThingFromPos({x=pos_tabulero.x+X,y=pos_tabulero.y+Y,z=pos_tabulero.z, stackpos = stack}) 

            if(get and type(get) == "table" and get.itemid > 2625 and get.itemid < 2638)then 

               doRemoveItem(get.uid) 

            end 

         end 

      end 

   end 

   return true 

end 

-- retorna a peça (in game) para o seu lugar. 

function GAME:backMove(item) 

   _upDate = true 

   local getPos = XADREZ:getPiece(item.actionid):getAntPos() 

   doTeleportThing(item.uid,{x=pos_tabulero.x+getPos.x,y=pos_tabulero.y+getPos.y,z=pos_tabulero.z}) 

end 

-- verifica a possivel Eliminação de peças adversarias. 

function GAME:killEnemy(posAtual,pieceid) 

local get,kill = getThingFromPos({x=pos_tabulero.x+posAtual.x,y=pos_tabulero.y+posAtual.y,z=pos_tabulero.z, stackpos = 2}) 

   -- não retorna a peça caso seja uma criatura 

   if(isCreature(getThingFromPos({x=pos_tabulero.x+posAtual.x,y=pos_tabulero.y+posAtual.y,z=pos_tabulero.z, stackpos = 255}).uid))then 

      return true 

   -- Retorna a peça caso o item seja do mesmo grupo 

   elseif not(isInArray(getPiecesEnemy(pieceid),get.itemid)) and get.itemid > 0 then 

      return false 

   -- Eliminação de peças. 

   elseif(get.itemid > 0)then 

      if(get.itemid == 2631 or get.itemid == 2637)then -- caso seja um rei eliminado, carrega o jogo denovo. 

         doSendAnimatedText({x=pos_tabulero.x+3,y=pos_tabulero.y+4,z=pos_tabulero.z},"Winner",10) 

         doSendAnimatedText({x=pos_tabulero.x+4,y=pos_tabulero.y+4,z=pos_tabulero.z},(get.itemid == 2631 and "Black" or "White"),10) 

         doSendAnimatedText({x=pos_tabulero.x+5,y=pos_tabulero.y+4,z=pos_tabulero.z},"pieces!",10) 

         loadTabulero() 

      end 

      _upDate = false 

      for stack = 1,255 do 

      local get = getThingFromPos({x=pos_tabulero.x+posAtual.x,y=pos_tabulero.y+posAtual.y,z=pos_tabulero.z, stackpos = stack}) 

         if(get.itemid > 0 and get.itemid ~= pieceid)then 

            doRemoveItem(get.uid) 

            kill = true 

         elseif(get.itemid == 0)then 

            break 

         end 

      end 

   end 

   return true,kill 

end 

-- verifica se o movimento diagonal é valido. 

function GAME:getPositions(saiu,atual) 

local get,n = {},1 

   for y = saiu.y,atual.y,(saiu.y > atual.y and -1 or 1) do 

      if not(get[#get+1])then 

         get[#get+1] = {x=0,y=0} 

      end 

      get[#get].y = y 

   end 

   for x = saiu.x,atual.x,(saiu.x > atual.x and -1 or 1) do 

      get[n].x = x 

      n = n+1 

   end 

   return get 

end 

function GAME:getPiecesEnemy(pieceid) 

local black,white = {2632,2633,2634,2635,2636,2637},{2626,2627,2628,2629,2630,2631} 

   if(isInArray(black,pieceid))then 

      return white 

   elseif(isInArray(white,pieceid))then 

      return black 

   end 

   return {} 

end 

function GAME:addIngamePieces(obj,wb,id,posi) 

   for pos = wb[1],wb[2],(wb[2]-wb[1]) do 

   local piece = doCreateItemEx(id, 1) 

      doItemSetAttribute(piece, "aid", piece) 

      doTileAddItemEx({x=pos_tabulero.x+pos,y=pos_tabulero.y+posi,z=pos_tabulero.z},piece) 

      local st = XADREZ:getPiece(piece,obj) 

      st:setMoveFunc(obj.move) 

      st:setType(pos <= 2 and 1 or -1) 

      st:setAntPos(pos,posi) 

      st:setAtualPos(pos,posi) 

      st:setId(id) 

   end 

   return true 

end 

 

-- FUNÇÕES DOS OBJETOS (PEÇAS) -- 

function XADREZ:getPiece(uid,str) 

   if(self.__call)then 

      return self.__call(self,uid) 

   elseif(str)then 

   local obj = {} 

      obj.id = str.id or 0 

      obj.type_move = str.type_move or 0 

      obj.ant_pos = str.ant_pos or {x=0,y=0} 

      obj.move = str.move or nil 

      setmetatable(obj,self) 

      self.__index = self 

      self.__call = function(self,uid) 

         if uid and not self[uid] then 

            self[uid] = {__index = obj} 

            setmetatable(self[uid], self[uid]) 

            self[uid].uid = uid 

            return self[uid] 

         elseif(self[uid])then 

            return self[uid] 

         end 

      end 

      return self.__call(self,uid) 

   end 

end 

function XADREZ:setId(id) 

   self.id = id 

end 

function XADREZ:getId() 

   return self.id 

end 

function XADREZ:setType(value) 

   self.type_move = value 

end 

function XADREZ:getType() 

   return self.type_move 

end 

function XADREZ:setAtualPos(x,y) 

   if(type(x) == 'table')then 

      x,y  = x.x or 0,x.y or 0 

   end 

   self.atual_pos = {x=x,y=y} 

end 

function XADREZ:getAtualPos() 

   return self.atual_pos 

end 

function XADREZ:setAntPos(x,y) 

   if(type(x) == 'table')then 

      x,y = x.x or 0,x.y or 0 

   end 

   self.ant_pos.x = x 

   self.ant_pos.y = y 

end 

function XADREZ:getAntPos() 

   return self.ant_pos 

end 

function XADREZ:setMoveFunc(func) 

   self.move = func 

end 

function XADREZ:getMoveFunc(item) 

   return self.move(item) 

end 

 

 

desculpa reviver mas esse sistema esta 100% ou ainda esta em desenvolvimento?

 

se tiver 100% essa parte que citei que esta 100%?

ou tenho q complementar com as outras partes?? se tiver com as partes picadas seria muito pedir pra atualizar o topco??

parabéns man vc é foda mesmo rep+

Link para o comentário
Compartilhar em outros sites

14 horas atrás, wevertonvrb disse:

desculpa reviver mas esse sistema esta 100% ou ainda esta em desenvolvimento?

 

se tiver 100% essa parte que citei que esta 100%?

ou tenho q complementar com as outras partes?? se tiver com as partes picadas seria muito pedir pra atualizar o topco??

parabéns man vc é foda mesmo rep+

Atualizei o código do tópico. 

Link para o comentário
Compartilhar em outros sites

11 horas atrás, wevertonvrb disse:

desculpe mas essa livraria ja é o sistema completo?

é apenas um arquivo mesmo? se sim onde eu deixo ela?

na pasta lib?

Sim, sim e sim.

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...