Advertisement
dalvorsn

Untitled

Apr 26th, 2012
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.67 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. Falta ainda:
  10. - verificações de cheque e cheque-mate
  11. - verificações de passant
  12. - iniciar partida
  13.  -- invite por talk
  14.  -- criação das peças no tabuleiro caso aceite e teleport dos players para area de xadrez
  15.  -- limitar a um player por vez
  16.  -- limitar a uma jogada por vez de cada player
  17.  -- impedir que mova o rei para posição de cheque
  18.  -- função para "resetar" a partida
  19.  -- colocar opção de tempo por jogada, caso o tempo esgote, eliminar jogador e terminar a partida
  20.  -- impedir que players subam no tabuleiro, apenas peças podem estar em cima do mesmo
  21.  -- fazer hook da torre com o rei
  22.  
  23. Posiveis alterações posteriores a criação do sistema completo:
  24.  - criação de cachê afim de reduzir o gasto e memoria e tempo de execução
  25.  
  26.  
  27. ]]
  28. -- const
  29. INITIAL_POS = {x=90, y = 139, z = 7}
  30. XADREZ_STORAGE = 759593
  31. tile_white, tile_black = 965, 966
  32.  
  33. Chess = {}
  34.  
  35. function Chess:new(cid)
  36.     local attr = {cid = cid}
  37.     return setmetatable(attr, {__index = self})
  38. end
  39.  
  40. function Chess:hasTileSend(pos, namefind)
  41.     if((getTileInfo(pos).itemid == tile_black or getTileInfo(pos).itemid == tile_white) and not (isCreature(getTopCreature(pos).uid) and getCreatureName(getTopCreature(pos).uid):find(namefind)))then
  42.         return true
  43.     end
  44.     return false
  45. end
  46.  
  47. function Chess:getDirsToPos(fromPos, toPos)
  48.     local dirs, fakeFromPos, fakeToPos = {}, {}, {}
  49.     fakeFromPos, fakeToPos = {x = fromPos.x, y=fromPos.y, z=fromPos.z}, {x = toPos.x, y = toPos.y, z= toPos.z}
  50.     while (not self:tableCompare(fakeFromPos, fakeToPos)) do
  51.         local dir = getDirectionTo(fakeFromPos, fakeToPos)
  52.         table.insert(dirs, dir)
  53.         local newPos = getPositionByDirection(fakeFromPos, dir, 1)
  54.         fakeFromPos.x, fakeFromPos.y, fakeFromPos.z = newPos.x, newPos.y, newPos.z
  55.     end
  56.     return dirs
  57. end
  58.  
  59. function Chess:moveDirs(uid, listDir, delayStep)
  60.     for i, dir in pairs(listDir) do
  61.         addEvent(function()
  62.                 if(isCreature(uid))then
  63.                     doMoveCreature(uid, dir)
  64.                 end
  65.             end, i*delayStep)
  66.     end
  67. end
  68.  
  69. function Chess:tableCompare(tab, tab2)
  70.     bool = true
  71.     for index,value in pairs(tab) do
  72.         if not(value == tab2[index])then
  73.             bool = false
  74.         end
  75.     end
  76.     return bool
  77. end
  78.  
  79. function Chess:isFirstPosPawn(pos, color)
  80.     local fakePos = {}
  81.     fakePos.x, fakePos.y, fakePos.z = pos.x,pos.y, pos.z
  82.     fakePos.y = (color == "black") and (fakePos.y + 2) or (fakePos.y - 2)
  83.     return ((getTileInfo(fakePos).itemid == tile_black or getTileInfo(fakePos).itemid == tile_white) == false)
  84. end
  85.  
  86. function Chess:isPiece(name)
  87.     local pieceType = name:sub(7)
  88.     if(isPlayer(getCreatureByName(name)))then return false end
  89.     return isInArray({"king", "pawn", "horse", "tower", "queen", "bishop"}, pieceType)
  90. end
  91. function Chess:getPathPos(uid_piece)
  92.     local piece_moves =
  93.     {
  94.         ["king"] = {distMove=1, dirs = {0,1,2,3,4,5,6,7}},
  95.         ["queen"] = {distMove=8, dirs = {0,1,2,3,4,5,6,7}},
  96.         ["bishop"] = {distMove=8, dirs = {4,5,6,7}},
  97.         ["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}}},
  98.         ["tower"] = {distMove=8, dirs = {0,1,2,3}},
  99.         ["pawn"] = 0 -- ignore this
  100.     }
  101.     if not(isCreature(uid_piece))then return error("[Chess System] Creature Not Found.") end
  102.     local positions, piecename = {}, getCreatureName(uid_piece)
  103.     local pieceType, pieceColor = piecename:sub(7):lower(), piecename:sub(1,5):lower()
  104.  
  105.     if(piece_moves[pieceType])then
  106.         if(isInArray({"king", "queen", "tower", "bishop"}, pieceType))then
  107.             for _, dir in pairs(piece_moves[pieceType].dirs)do
  108.                 for dist = 1, piece_moves[pieceType].distMove do
  109.                     local pos = getPositionByDirection(getThingPos(uid_piece), dir, dist)
  110.                     if(self:hasTileSend(pos, pieceColor))then
  111.                         table.insert(positions, pos)
  112.                     end
  113.                     local uid_pos = getTopCreature(pos).uid
  114.                     if(isCreature(uid_pos) or (not self:hasTileSend(pos, pieceColor)))then break end
  115.                 end
  116.             end
  117.         elseif(pieceType == "horse")then
  118.             for _, mod_ in pairs(piece_moves[pieceType].posits) do
  119.                 local pos = getThingPos(uid_piece)
  120.                 pos.x, pos.y = pos.x + mod_.x, pos.y + mod_.y
  121.                 if(self:hasTileSend(pos, pieceColor))then
  122.                     table.insert(positions, pos)
  123.                 end
  124.             end
  125.         elseif(pieceType == "pawn")then
  126.             local dir = (pieceColor == "black") and 0 or 2
  127.             local pos1 = getPositionByDirection(getThingPos(uid_piece), dir, 1)
  128.             if not(isCreature(getTopCreature(pos1).uid))then
  129.                 table.insert(positions, pos1)
  130.                 local pos2 = getPositionByDirection(getThingPos(uid_piece), dir, 2)
  131.                 --local pos_r, pos_l = {}, {}
  132.                 if(self:isFirstPosPawn(getThingPos(uid_piece), pieceColor) and #positions > 0)then
  133.                     table.insert(positions, pos2)
  134.                 end
  135.             end
  136.         end
  137.         return positions
  138.     else
  139.         error("[Chess System] Invalid piece name")
  140.     end
  141. end
  142.  
  143. function Chess:isValidPos(uid, pos)
  144.     local listPos = self:getPathPos(uid)
  145.     for _, posi in pairs(listPos) do
  146.         if(posi.x == pos.x and posi.y == pos.y and posi.z == pos.z)then
  147.             return true
  148.         end
  149.     end
  150.     return false
  151. end
  152.  
  153. function Chess:verifyXeque(uid, toPos)
  154.     -- Chess:verifyXeque(uid[, toPos])
  155.     --[[
  156.     * listar peças adversarias
  157.     * iterar sobre elas gerando o pathpos de cada uma e verificando se coincide com a pos do rei
  158.     * caso uma seja verdadeiro retornar true finalizando o loop
  159.     * caso nenhum seja verdadeira retornar false
  160.     ]]
  161.     if(isCreature(uid))then
  162.         local piecename = getCreatureName(uid)
  163.         local pieceType, pieceColor = piecename:sub(7):lower(), piecename:sub(1,5):lower()
  164.         if(self:isPiece(piecename) and pieceType == "king")then
  165.             local black, white = self:getPiecesOnTab()
  166.             for _, piece in pairs(pieceColor == "black" and white or black) do
  167.                 if(self:isValidPos(piece, type(toPos) == "table" and toPos or getThingPos(uid)))then
  168.                     return true
  169.                 end
  170.             end
  171.         end
  172.     end
  173.     return false
  174. end
  175.  
  176. function Chess:sendEffects(uid)
  177.     local positions = self:getPathPos(uid)
  178.     doSendMagicEffect(getThingPos(uid), 55)
  179.     for _, pos in pairs(positions) do
  180.         doSendMagicEffect(pos, 56)
  181.     end
  182. end
  183.  
  184. function Chess:getPiecesOnTab()
  185.     local black, white = {}, {}
  186.     for x = 0, 7 do
  187.         for y = 0, 7 do
  188.             local pos = {x = INITIAL_POS.x, y = INITIAL_POS.y, z = INITIAL_POS.z}
  189.             pos.x, pos.y = pos.x + x, pos.y + y
  190.             local creature = getTopCreature(pos)
  191.             if(isCreature(creature.uid) and (not isPlayer(creature.uid)))then
  192.                 local name = getCreatureName(creature.uid)
  193.                 if(self:isPiece(name))then
  194.                     table.insert(name:find("black") and black or white, creature.uid)
  195.                 end
  196.             end
  197.         end
  198.     end
  199.     return black, white
  200. end
  201.  
  202. function Chess:createPieces()
  203.     local piecepos = {}
  204.     pieces = {"tower", "horse", "bishop", "queen", "king","bishop","horse","tower"}
  205.     for _, index in pairs({0,1,6,7}) do piecepos[index] = {} end
  206.     for index, piece in pairs(pieces) do
  207.         piecepos[0][index-1] = "white "..piece
  208.         piecepos[7][index-1] = "black "..piece
  209.     end
  210.     for i = 0, 7 do
  211.         piecepos[1][i] = "white pawn"
  212.         piecepos[6][i] = "black pawn"
  213.     end
  214.  
  215.     for x = 0, 7 do
  216.         for y = 0, 7 do
  217.             local pos = {x = INITIAL_POS.x, y = INITIAL_POS.y, z = INITIAL_POS.z}
  218.             pos.x, pos.y = (pos.x + x), (pos.y + y)
  219.             local creature = getTopCreature(pos)
  220.             if(isCreature(creature.uid) and not isPlayer(creature.uid))then
  221.                 doRemoveCreature(creature.uid)
  222.             end
  223.             if(piecepos[y] and piecepos[y][x]) then
  224.                 doCreateMonster(piecepos[y][x], pos)
  225.             end
  226.         end
  227.     end
  228. end
  229.  
  230. function onPush(cid, target, toTile)
  231.     local chess = Chess:new(cid)
  232.     local piecetarget = getTopCreature(getThingPos(toTile.uid)).uid
  233.     local namefind = getCreatureName(target):sub(1,5) == "black" and "white" or "black"
  234.     --chess:createPieces()
  235.     if(chess:isValidPos(target,getThingPos(toTile.uid)))then
  236.         if(chess:verifyXeque(target, getThingPos(toTile.uid)))then
  237.             doPlayerSendCancel(cid, "You can not leave his king in check.")
  238.             return false
  239.         end
  240.  
  241.         local dirs = chess:getDirsToPos(getThingPos(target), getThingPos(toTile.uid))
  242.         chess:moveDirs(target, dirs,1000)
  243.  
  244.         if(isCreature(piecetarget) and getCreatureName(piecetarget):find(namefind))then
  245.             doRemoveCreature(piecetarget)
  246.         end
  247.     else
  248.         doPlayerSendCancel(cid, "You can not move this piece for this position.")
  249.     end
  250.     return false
  251. end
  252.  
  253. function onLook(cid, thing, position, lookDistance)
  254.  
  255.     if(isPlayer(thing.uid) or (not isCreature(thing.uid)))then return true end
  256.     if not(exhaustion.check(cid, XADREZ_STORAGE))then
  257.         exhaustion.set(cid, XADREZ_STORAGE, 8)
  258.         local chess = Chess:new(cid)
  259.         chess:sendEffects(thing.uid)
  260.         return false
  261.     end
  262. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement