Advertisement
dalvorsn

Untitled

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