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.
Citarif(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.
Citarfunction 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]
endfunction 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.
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.









info
Grupo: Herói
Registrado: 07/03/16
Posts: 1.4k
Reputação: +385
Gênero: Masculino
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
--[=[
################################################################################################################
## 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.
or 0,x.y or 0
function XADREZ:setAtualPos(x,y)
if(type(x) == 'table')then
x,y =
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.
or 0,x.y or 0
function XADREZ:setAntPos(x,y)
if(type(x) == 'table')then
x,y =
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:
<!-- 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:
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 Maio 2 por Poccnn