Advertisement
dalvorsn

Untitled

Apr 27th, 2012
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.04 KB | None | 0 0
  1. --[[
  2. ###################################
  3. ##         Chess System          ##
  4. ##      Developed by Dalvo       ##
  5. ##       Date: 22/04/2012        ##
  6. ##   Tested on TFS 0.4_rev3884   ##
  7. ## Obs.: Need modified sources   ##
  8. ###################################
  9.  
  10. * criação das peças (.xml) [completo]
  11. * criação tabuleiro [completo]
  12. * função verifica posições que peça pode mover [parcialmente completa] ** faltam exceções
  13. * verificação de xeque [completo]
  14. * verificação de xeque-mate [não]
  15. * função que pega todas as peças do tabuleiro e separa por cor [completo]
  16. * movimentação de peças e captura [completo]
  17. * verificação de xeque ao mover rei [parcialmente completo]
  18. * envio de efeitos para facilitar a visualização das posições que se pode mover [completo]
  19. * talkaction para desafiar outro player [incompleto]
  20. * criação de peças o tabuleiro [completo]
  21. * modificação source em callback onPush [completo]
  22. * verificar xeque a cada movimentação de peça [não]
  23.  
  24. ]]
  25. --## config ##
  26. INITIAL_POS = {x=90, y = 139, z = 7}
  27. XADREZ_STORAGE = 759593 -- for look
  28. tile_white, tile_black = 965, 966
  29. stor_challenger = 752345
  30. --## end config ##
  31.  
  32.  
  33. Chess = {}
  34.  
  35. function Chess:new(cid)
  36.     --[[
  37.     Chess:new(cid)
  38.         * inicialmente usada apenas para usar as função como metodo
  39.         * necessita-se usar esta função antes de qualquer outra da lib
  40.     ]]
  41.     local attr = {cid = cid}
  42.     return setmetatable(attr, {__index = self})
  43. end
  44.  
  45. function Chess:hasTileSend(pos, namefind)
  46.     --[[
  47.     Chess:hasTileSend(pos, namefind)
  48.         * verifica se tile pertence ao tabuleiro
  49.         * se houver monstro no tile verifica se o monstro em questão tem 'namefind' no nome
  50.     ]]
  51.     local uid = getTopCreature(pos).uid
  52.     if((isInArray({tile_black, tile_white}, getTileInfo(pos).itemid) and not (isMonster(uid) and getCreatureName(uid):find(namefind)))then
  53.         return true
  54.     end
  55.     return false
  56. end
  57.  
  58. function Chess:getDirsToPos(fromPos, toPos)
  59.     --[[
  60.     Chess:getDirsToPos(fromPos, toPos)
  61.         * lista todas as direções para se mover da posição 'fromPos' até 'toPos'
  62.         * função a ser optimizada ainda
  63.     ]]
  64.     local dirs, fakeFromPos, fakeToPos = {}, {}, {}
  65.     fakeFromPos, fakeToPos = {x = fromPos.x, y=fromPos.y, z=fromPos.z}, {x = toPos.x, y = toPos.y, z= toPos.z}
  66.     while (not self:tableCompare(fakeFromPos, fakeToPos)) do
  67.         local dir = getDirectionTo(fakeFromPos, fakeToPos)
  68.         table.insert(dirs, dir)
  69.         local newPos = getPositionByDirection(fakeFromPos, dir, 1)
  70.         fakeFromPos.x, fakeFromPos.y, fakeFromPos.z = newPos.x, newPos.y, newPos.z
  71.     end
  72.     return dirs
  73. end
  74.  
  75. function Chess:moveDirs(uid, listDir, delayStep)
  76.     --[[
  77.     Chess:moveDirs(uid, listDir[, delayStep])
  78.         * move creature fornecida por 'uid' por todas as direções listadas em 'listDir' num intervalo de 'delayStep' em miliseconds
  79.         * se 'delayStep' não for fornecida, seu valor é '1000'
  80.     ]]
  81.     if not delayStep then
  82.         delayStep = 1000
  83.     end
  84.  
  85.     for i, dir in pairs(listDir) do
  86.         addEvent(function()
  87.                 if(isCreature(uid))then
  88.                     doMoveCreature(uid, dir)
  89.                 end
  90.             end, i*delayStep)
  91.     end
  92. end
  93.  
  94. function Chess:tableCompare(tab, tab2)
  95.     --[[
  96.     Chess:tableCompare(tab, tab2)
  97.         * compara se duas tabelas tem index iguais fornecendo valores iguais
  98.         * pouco usada, possivelmente será removida
  99.     ]]
  100.  
  101.     bool = true
  102.     for index,value in pairs(tab) do
  103.         if not(value == tab2[index])then
  104.             bool = false
  105.         end
  106.     end
  107.     return bool
  108. end
  109.  
  110. function Chess:isFirstPosPawn(pos, color)
  111.     --[[
  112.     Chess:isFirstPosPawn(pos, color)
  113.         * verifica se 'pos' é posição inicial de pawn para 'color' fornecida
  114.     ]]
  115.     local fakePos = {}
  116.     fakePos.x, fakePos.y, fakePos.z = pos.x,pos.y, pos.z
  117.     fakePos.y = (color == "black") and (fakePos.y + 2) or (fakePos.y - 2)
  118.     return ((getTileInfo(fakePos).itemid == tile_black or getTileInfo(fakePos).itemid == tile_white) == false)
  119. end
  120.  
  121. function Chess:isPiece(name)
  122.     --[[
  123.     Chess:isPiece(name)
  124.         * verifica se 'name' é nome de uma peça e se 'name' não é nome de um player
  125.     ]]
  126.     local pieceType = name:sub(7)
  127.     if(isPlayer(getCreatureByName(name)))then return false end
  128.     return isInArray({"king", "pawn", "horse", "tower", "queen", "bishop"}, pieceType)
  129. end
  130.  
  131. function Chess:getPathPos(uid_piece, xeque)
  132.     --[[
  133.     Chess:getPathPos(uid_piece[, xeque)
  134.         * função base do sistema
  135.         * a partir do uid fornecido pega pelo nome da peça todas as posições a que se pode mover a peças
  136.         * o parametro 'xeque' é um booleano e só deve ser usado para verificar posição de xeque para o rei
  137.     ]]
  138.     local piece_moves =
  139.     {
  140.         ["king"] = {distMove=1, dirs = {0,1,2,3,4,5,6,7}},
  141.         ["queen"] = {distMove=8, dirs = {0,1,2,3,4,5,6,7}},
  142.         ["bishop"] = {distMove=8, dirs = {4,5,6,7}},
  143.         ["horse"] = {posits = {{x = -1, y = -2}, {x = 1, y = -2}, {x = 2, y = 1}, {x = 2, y = -1},{x = -2, y = 1}, {x = -2, y = -1}, {x = -1, y = 2}, {x = 1, y = 2}}},
  144.         ["tower"] = {distMove=8, dirs = {0,1,2,3}},
  145.         ["pawn"] = 0 -- ignore this
  146.     }
  147.     if not(isCreature(uid_piece))then return error("[Chess System] Creature Not Found.") end
  148.     local positions, piecename = {}, getCreatureName(uid_piece)
  149.     local pieceType, pieceColor = piecename:sub(7):lower(), piecename:sub(1,5):lower()
  150.  
  151.     if(piece_moves[pieceType])then
  152.         if(isInArray({"king", "queen", "tower", "bishop"}, pieceType))then
  153.             for _, dir in pairs(piece_moves[pieceType].dirs)do
  154.                 for dist = 1, piece_moves[pieceType].distMove do
  155.                     local pos = getPositionByDirection(getThingPos(uid_piece), dir, dist)
  156.                     if(self:hasTileSend(pos, pieceColor))then
  157.                         table.insert(positions, pos)
  158.                     end
  159.                     local uid_pos = getTopCreature(pos).uid
  160.                     if(isCreature(uid_pos) or (not self:hasTileSend(pos, pieceColor)))then break end
  161.                 end
  162.             end
  163.         elseif(pieceType == "horse")then
  164.             for _, mod_ in pairs(piece_moves[pieceType].posits) do
  165.                 local pos = getThingPos(uid_piece)
  166.                 pos.x, pos.y = pos.x + mod_.x, pos.y + mod_.y
  167.                 if(self:hasTileSend(pos, pieceColor))then
  168.                     table.insert(positions, pos)
  169.                 end
  170.             end
  171.         elseif(pieceType == "pawn")then
  172.             local dir = (pieceColor == "black") and 0 or 2
  173.             local pos1 = getPositionByDirection(getThingPos(uid_piece), dir, 1)
  174.             if not(isCreature(getTopCreature(pos1).uid))then
  175.                 if not xeque then
  176.                     table.insert(positions, pos1)
  177.                     local pos_r, pos_l = {x= pos1.x -1,y=pos1.y,z=pos1.z}, {x= pos1.x +1 ,y=pos1.y,z=pos1.z}
  178.                     if(isMonster(getTopCreature(pos_l).uid))then
  179.                         table.insert(positions, pos_r)
  180.                     end
  181.                     if(isMonster(getTopCreature(pos_l).uid))then
  182.                         table.insert(positions, pos_l)
  183.                     end
  184.                     local pos2 = getPositionByDirection(getThingPos(uid_piece), dir, 2)
  185.                     if(self:isFirstPosPawn(getThingPos(uid_piece), pieceColor) and #positions > 0)then
  186.                         table.insert(positions, pos2)
  187.                     end
  188.                 else
  189.                     table.insert(positions, pos_r)
  190.                     table.insert(positions, pos_l)
  191.                 end
  192.             end
  193.         end
  194.         return positions
  195.     else
  196.         error("[Chess System] Invalid piece name")
  197.     end
  198. end
  199.  
  200. function Chess:isValidPos(uid, pos, xeque)
  201.     --[[
  202.     Chess:isValidPos(uid, pos[, xeque])
  203.         * verifica se a posição 'pos' está contida no pathpos da criatura
  204.         * o parametro 'xeque' é um booleano e só deve ser usado para verificar posição de xeque para o rei
  205.     ]]
  206.     local listPos = self:getPathPos(uid, xeque)
  207.     for _, posi in pairs(listPos) do
  208.         if(posi.x == pos.x and posi.y == pos.y and posi.z == pos.z)then
  209.             return true
  210.         end
  211.     end
  212.     return false
  213. end
  214.  
  215. function Chess:verifyXeque(uid, toPos)
  216.     --[[
  217.     Chess:verifyXeque(uid[, toPos])
  218.         * listar peças adversarias
  219.         * iterar sobre elas gerando o pathpos de cada uma e verificando se coincide com a pos do rei
  220.         * caso uma seja verdadeira retornar true finalizando o loop
  221.         * caso nenhuma seja verdadeira retornar false
  222.     ]]
  223.     if(isCreature(uid))then
  224.         local piecename = getCreatureName(uid)
  225.         local pieceType, pieceColor = piecename:sub(7):lower(), piecename:sub(1,5):lower()
  226.         if(self:isPiece(piecename) and pieceType == "king")then
  227.             local black, white = self:getPiecesOnTab()
  228.             for _, piece in pairs(pieceColor == "black" and white or black) do
  229.                 if(self:isValidPos(piece, type(toPos) == "table" and toPos or getThingPos(uid), true))then
  230.                     return true
  231.                 end
  232.             end
  233.         end
  234.     end
  235.     return false
  236. end
  237.  
  238. function Chess:sendEffects(uid)
  239.     --[[
  240.     Chess:sendEffects(uid)
  241.         * pega o path do uid para todas as posiçoes possiveis de se andar
  242.         * manda efeito em todas
  243.     ]]
  244.     local positions = self:getPathPos(uid)
  245.     doSendMagicEffect(getThingPos(uid), 55)
  246.     for _, pos in pairs(positions) do
  247.         doSendMagicEffect(pos, 56)
  248.     end
  249. end
  250.  
  251. function Chess:getPiecesOnTab()
  252.     --[[
  253.     Chess:getPiecesOnTab()
  254.         * pega o uid de todas as peças no tabuleiro partindo da posição configurada
  255.         por 'INITIAL_POS' e separar por time retornando duas tabelas
  256.     ]]
  257.     local black, white = {}, {}
  258.     for x = 0, 7 do
  259.         for y = 0, 7 do
  260.             local pos = {x = INITIAL_POS.x, y = INITIAL_POS.y, z = INITIAL_POS.z}
  261.             pos.x, pos.y = pos.x + x, pos.y + y
  262.             local creature = getTopCreature(pos)
  263.             if(isMonster(creature.uid))then
  264.                 local name = getCreatureName(creature.uid)
  265.                 if(self:isPiece(name))then
  266.                     table.insert(name:find("black") and black or white, creature.uid)
  267.                 end
  268.             end
  269.         end
  270.     end
  271.     return black, white
  272. end
  273.  
  274. function Chess:createPieces()
  275.     --[[
  276.     Chess:createPieces()
  277.         * remove todas peças do tabuleiro
  278.         * ao remover também cria as peças em sua posição inicial
  279.         * brancas em cima, pretas em baixo
  280.     ]]
  281.     local piecepos = {}
  282.     pieces = {"tower", "horse", "bishop", "queen", "king","bishop","horse","tower"}
  283.     for _, index in pairs({0,1,6,7}) do piecepos[index] = {} end
  284.     for index, piece in pairs(pieces) do
  285.         piecepos[0][index-1] = "white "..piece
  286.         piecepos[7][index-1] = "black "..piece
  287.     end
  288.     for i = 0, 7 do
  289.         piecepos[1][i] = "white pawn"
  290.         piecepos[6][i] = "black pawn"
  291.     end
  292.  
  293.     for x = 0, 7 do
  294.         for y = 0, 7 do
  295.             local pos = {x = INITIAL_POS.x, y = INITIAL_POS.y, z = INITIAL_POS.z}
  296.             pos.x, pos.y = (pos.x + x), (pos.y + y)
  297.             local creature = getTopCreature(pos)
  298.             if(isMonster(creature.uid))then
  299.                 doRemoveCreature(creature.uid)
  300.             end
  301.             if(piecepos[y] and piecepos[y][x]) then
  302.                 doCreateMonster(piecepos[y][x], pos)
  303.             end
  304.         end
  305.     end
  306. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement