Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- do local _,name = pcall(nil) admin = string.match(name, "(.-)%.") end -- Игрок, запустивший скрипт
- --[[
- Controls :
- Up - Rotate
- Left - Move left
- Right - Move right
- Down - Move down
- Commands :
- !pause or !p - pauses / unpauses game
- !join - join que
- !cancel - leave que
- --]]
- -- player = "Name#Tag" or "auto" else wait for queue
- local player = "queue"
- -- If true game will end within 100th piece placed
- local endlessGame = false
- -- "ru" or "en" else auto
- local language = tfm.get.room.playerList[admin].community
- local color = {
- static1 = 0xB3FAFF,
- static2 = 0xB3FAFF,
- dynamic1 = 0x39EDB5,
- dynamic2 = 0x39EDB5,
- walls1 = 0xD8D8D8,
- walls2 = 0xD8D8D8,
- }
- text = {
- ru = {
- join = "Присоединиться",
- cancel = "Отмена",
- queue = "Очередь",
- leaderboard = "Рекорды",
- },
- en = {
- join = "Join",
- cancel = "Cancel",
- queue = "Queue",
- leaderboard = "Leaderboard",
- }
- }
- if not text[language] then
- language = "en"
- end
- -- Offset for tetris grid
- local _x, _y = 260, 10
- -- Queue, leaderboard
- local playerData, queue, leaderboard = {}, {}, {}
- -- 1 player
- if player == "auto" then
- player = admin
- end
- local Grid, pieceList, sum, currentPiece, availablePieces, isDown
- local pieceX, pieceY, rotation, previousPieceX, previousRotation
- local score
- -- reservedPiece
- local pieceData = {
- [1] = {
- -- I
- --[[` ` ` `
- [ ][ ][ ][ ]
- [x][o][x][x]
- [ ][ ][ ][ ]
- [ ][ ][ ][ ]
- [ ][ ][x][ ]
- [ ][ ][x][ ]
- [ ][ ][x][ ]
- [ ][ ][x][ ]
- [ ][ ][ ][ ]
- [ ][ ][ ][ ]
- [x][x][x][x]
- [ ][ ][ ][ ]
- [ ][x][ ][ ]
- [ ][x][ ][ ]
- [ ][x][ ][ ]
- [ ][x][ ][ ]
- --]]
- [1] = {
- {1,2},
- {2,2},
- {3,2},
- {4,2},
- },
- [2] = {
- {3,1},
- {3,2},
- {3,3},
- {3,4},
- },
- [3] = {
- {1,3},
- {2,3},
- {3,3},
- {4,3},
- },
- [4] = {
- {2,1},
- {2,2},
- {2,3},
- {2,4},
- }
- },
- [2] = {
- -- J
- --[[` ` ` `
- [ ][x][ ]
- [ ][o][ ]
- [x][x][ ]
- [x][ ][ ]
- [x][o][x]
- [ ][ ][ ]
- [ ][x][x]
- [ ][o][ ]
- [ ][x][ ]
- [ ][ ][ ]
- [x][o][x]
- [ ][ ][x]
- --]]
- [1] = {
- {2,1},
- {2,2},
- {2,3},
- {1,3},
- },
- [2] = {
- {1,1},
- {1,2},
- {2,2},
- {3,2},
- },
- [3] = {
- {2,1},
- {2,2},
- {2,3},
- {3,1},
- },
- [4] = {
- {3,3},
- {1,2},
- {2,2},
- {3,2},
- }
- },
- [3] = {
- -- L
- --[[` ` ` `
- [ ][x][ ]
- [ ][o][ ]
- [ ][x][x]
- [ ][ ][ ]
- [x][o][x]
- [x][ ][ ]
- [x][x][ ]
- [ ][o][ ]
- [ ][x][ ]
- [ ][ ][x]
- [x][o][x]
- [ ][ ][ ]
- --]]
- [1] = {
- {2,1},
- {2,2},
- {2,3},
- {3,3},
- },
- [2] = {
- {1,3},
- {1,2},
- {2,2},
- {3,2},
- },
- [3] = {
- {2,1},
- {2,2},
- {2,3},
- {1,1},
- },
- [4] = {
- {3,1},
- {1,2},
- {2,2},
- {3,2},
- }
- },
- [4] = {
- -- T
- --[[` ` ` `
- [ ][x][ ]
- [x][o][x]
- [ ][ ][ ]
- [ ][x][ ]
- [ ][o][x]
- [ ][x][ ]
- [ ][ ][ ]
- [x][o][x]
- [ ][x][ ]
- [ ][x][ ]
- [x][o][ ]
- [ ][x][ ]
- --]]
- [1] = {
- {2,2},
- {2,1},
- {1,2},
- {3,2},
- },
- [2] = {
- {2,2},
- {2,1},
- {3,2},
- {2,3},
- },
- [3] = {
- {2,2},
- {2,3},
- {1,2},
- {3,2},
- },
- [4] = {
- {2,2},
- {2,1},
- {1,2},
- {2,3},
- }
- },
- [5] = {
- -- S
- --[[` ` ` `
- [ ][x][x]
- [x][x][ ]
- [ ][ ][ ]
- [ ][x][ ]
- [ ][x][x]
- [ ][ ][x]
- [ ][ ][ ]
- [ ][x][x]
- [x][x][ ]
- [x][ ][ ]
- [x][x][ ]
- [ ][x][ ]
- --]]
- [1] = {
- {2,2},
- {1,2},
- {2,1},
- {3,1},
- },
- [2] = {
- {2,2},
- {2,1},
- {3,2},
- {3,3},
- },
- [3] = {
- {2,2},
- {1,3},
- {2,3},
- {3,2},
- },
- [4] = {
- {2,2},
- {1,1},
- {1,2},
- {2,3},
- }
- },
- [6] = {
- -- Z
- --[[` ` ` `
- [x][x][ ]
- [ ][x][x]
- [ ][ ][ ]
- [ ][ ][x]
- [ ][x][x]
- [ ][x][ ]
- [ ][ ][ ]
- [x][x][ ]
- [ ][x][x]
- [ ][x][ ]
- [x][x][ ]
- [x][ ][ ]
- --]]
- [1] = {
- {2,2},
- {1,1},
- {2,1},
- {3,2},
- },
- [2] = {
- {2,2},
- {2,3},
- {3,1},
- {3,2},
- },
- [3] = {
- {2,2},
- {1,2},
- {2,3},
- {3,3},
- },
- [4] = {
- {2,2},
- {1,2},
- {1,3},
- {2,1},
- }
- },
- [7] = {
- -- o
- --[[` ` ` `
- [x][x]
- [x][x]
- --]]
- [1] = {
- {1,1},
- {1,2},
- {2,1},
- {2,2},
- },
- [2] = {
- {1,1},
- {1,2},
- {2,1},
- {2,2},
- },
- [3] = {
- {1,1},
- {1,2},
- {2,1},
- {2,2},
- },
- [4] = {
- {1,1},
- {1,2},
- {2,1},
- {2,2},
- }
- },
- }
- function initGame()
- -- Init varables
- Grid = {}
- score = 0
- rotation = 1
- do
- local _pieceList = {16, 14, 14, 14, 14, 14, 14}
- local _availablePieces = {true, true, true, true, true, true, true}
- pieceList = _PieceList
- availablePieces = _availablePieces
- end
- sum = 100
- -- Clear grid
- for x=1,12 do
- Grid[x] = {}
- for y=1,18 do
- -- 0 - empty
- -- 1 - soild
- -- 2 - dynamic
- Grid[x][y] = {contains = 0, color = ""}
- end
- end
- local walls = {
- {1,1}, {2,1}, {3,1}, {4,1}, {5,1}, {6,1}, {7,1}, {8,1}, {9,1}, {10,1}, {11,1}, {12,1},
- {1,2}, {12,2},
- {1,3}, {12,3},
- {1,4}, {12,4},
- {1,5}, {12,5},
- {1,6}, {12,6},
- {1,7}, {12,7},
- {1,8}, {12,8},
- {1,9}, {12,9},
- {1,10}, {12,10},
- {1,11}, {12,11},
- {1,12}, {12,12},
- {1,13}, {12,13},
- {1,14}, {12,14},
- {1,15}, {12,15},
- {1,16}, {12,16},
- {1,17}, {12,17},
- {1,18},{2,18},{3,18},{4,18},{5,18},{6,18},{7,18},{8,18},{9,18},{10,18},{11,18},{12,18},
- }
- for i, v in next, walls do
- local x, y = v[1], v[2]
- Grid[x][y].contains = 1
- ui.addTextArea(-i-100, " ", nil, (x * 20) + _x, (y * 20) + _y, 16, 16, color.walls1, color.walls2)
- end
- nextPiece()
- setPiecePos(pieceX, pieceY)
- drawGrid()
- start = true
- for i = 0, 3 do
- system.bindKeyboard(player, i, true, true)
- end
- end
- function refreshGame()
- -- Stop game and clear grid
- start = false
- drawGrid(true)
- for i = 1, 260 do
- ui.removeTextArea(i)
- end
- -- Set score + leaderboard
- tfm.exec.setPlayerScore(player, score, true)
- leaderboard[#leaderboard + 1] = {
- playerName = player,
- score = score,
- sum = (100 - sum),
- }
- -- Deactivate keyboard and remove from game
- for i = 0, 3 do
- system.bindKeyboard(player, i, true, false)
- end
- playerData[player].isPlaying = false
- drawQueue()
- drawLeaderboard()
- end
- function nextPiece()
- isDown = false
- local random
- repeat
- random = math.random(1, 7)
- until availablePieces[random]
- if endlessGame and sum == 0 then
- if sum == 0 then
- print("You won!")
- print("You got "..score.." score!")
- print("Placed "..(100 - sum).." pieces!")
- refreshGame()
- return
- end
- pieceList[random] = pieceList[random] - 1
- if pieceList[random] == 0 then
- availablePieces[random] = false
- end
- end
- currentPiece = random
- pieceX = 5
- pieceY = 1
- previousPieceX = 5
- previousPieceY = 1
- rotation = 1
- previousRotation = 1
- sum = sum - 1
- end
- function setPiecePos(x, y)
- -- Remove previous
- for _, pos in next, pieceData[currentPiece][previousRotation] do
- Grid[previousPieceX + pos[1]][previousPieceY + pos[2]].contains = 0
- end
- -- Set Position
- for _, pos in next, pieceData[currentPiece][rotation] do
- Grid[x + pos[1]][y + pos[2]].contains = 2
- end
- previousRotation = rotation
- previousPieceX = pieceX
- previousPieceY = pieceY
- end
- function drawGrid(drawStatic)
- --[[
- id 1 - 99 dynamic cells
- id 100 - 999 static
- --]]
- if drawStatic then
- local i = 1
- for x = 2, 11 do
- for y = 2, 17 do
- if Grid[x][y].contains == 1 then
- ui.addTextArea(99+i, '', nil, (x * 20) + _x, (y * 20) + _y, 14, 14, color.static1, color.static2)
- i = i + 1
- end
- end
- end
- end
- for i, value in next, pieceData[currentPiece][rotation] do
- local x, y = value[1]+pieceX, value[2]+pieceY
- ui.addTextArea(i, '', nil, (x * 20) + _x, (y * 20) + _y, 14, 14, color.dynamic1, color.dynamic2)
- end
- end
- --[[ With platforms
- tfm.exec.addPhysicObject(i, x * 20, y * 20, {
- type = 1,
- width = 20,
- height = 20,
- foreground = true,
- miceCollision = false,
- groundCollision = false,
- })
- --]]
- function eventKeyboard(playerName, keyCode, down, xPlayerPosition, yPlayerPosition)
- if not start then
- return
- end
- if keyCode == 1 then
- -- Up
- -- Rotate
- local ToData = pieceData[currentPiece][(rotation < 4 and rotation + 1) or 1]
- for _, pos in next, ToData do
- if Grid[pos[1] + pieceX][pos[2] + pieceY].contains == 1 then
- return
- end
- end
- rotation = (rotation < 4 and rotation + 1) or 1
- elseif keyCode == 0 then
- -- Left
- -- Move
- for i, value in next, pieceData[currentPiece][rotation] do
- local x, y = value[1]+pieceX-1, value[2]+pieceY
- if Grid[x][y].contains == 1 then
- return
- end
- end
- pieceX = pieceX - 1
- elseif keyCode == 2 then
- -- Right
- -- Move
- for i, value in next, pieceData[currentPiece][rotation] do
- local x, y = value[1]+pieceX+1, value[2]+pieceY
- if Grid[x][y].contains == 1 then
- return
- end
- end
- pieceX = pieceX + 1
- elseif keyCode == 3 then
- if not isDown then
- isDown = true
- -- Down
- -- Instant plaing
- local yc = 1
- --while not( Grid[x][y + yc].contains == 1 or y + yc >= 18 ) do
- while true do
- for i, value in next, pieceData[currentPiece][rotation] do
- local x, y = value[1]+pieceX, value[2]+pieceY+yc
- if Grid[x][y].contains == 1 then
- pieceY = pieceY + yc - 2
- return
- end
- end
- yc = yc + 1
- end
- end
- end
- setPiecePos(pieceX, pieceY)
- drawGrid()
- end
- start = false
- function eventLoop(currentTime, timeRemaining)
- if start then
- -- Check if reached down limit
- for x = 1, 12 do
- for y = 1, 18 do
- local contain = Grid[x][y].contains
- if contain == 2 and Grid[x][y+1].contains == 1 then
- -- If theres obstacle
- -- Find dynamic and make it solid
- for x = 1, 12 do
- for y = 1, 18 do
- local contain = Grid[x][y].contains
- if contain == 2 then
- Grid[x][y].contains = 1
- end
- end
- end
- -- Removing line if it full
- -- Check if it full
- --for y = 17, 3, -1 do
- local y = 17
- while y > 3 do
- local i = 0
- for x = 2, 11 do
- if Grid[x][y].contains == 1 then
- i = i + 1
- end
- end
- -- Removing
- if i == 10 then
- for x = 2, 11 do
- for y2 = y, 3, -1 do
- Grid[x][y2].contains = Grid[x][y2-1].contains
- Grid[x][y2].color = Grid[x][y2-1].color
- end
- end
- score = score + 1
- for i = 1, 260 do
- ui.removeTextArea(i)
- end
- else
- y = y - 1
- if i == 0 then
- y = 2
- end
- end
- end
- for x = 2, 11 do
- if Grid[x][2].contains == 1 then
- print("You lost.")
- print("You have got "..score.." score!")
- print("Placed "..(100 - sum).." pieces!")
- refreshGame()
- return
- end
- end
- nextPiece()
- setPiecePos(pieceX, pieceY)
- drawGrid(true)
- return
- end
- end
- end
- pieceY = pieceY + 1
- setPiecePos(pieceX, pieceY)
- drawGrid()
- elseif #queue >= 1 then
- -- Update que
- player = queue[1]
- table.remove(queue, 1)
- playerData[player].inQueue = false
- playerData[player].isPlaying = true
- drawQueue()
- -- Start game
- initGame()
- end
- end
- function eventChatCommand(playerName, message)
- if not playerData[playerName].isPlaying then
- -- Queue System
- if message == "join" then
- -- Add
- if not playerData[playerName].inQueue then
- playerData[playerName].inQueue = true
- queue[#queue + 1] = playerName
- print("\n"..playerName.." join queue :"..table.concat(queue, "\n"))
- drawQueue()
- end
- elseif message == "cancel" then
- -- Remove
- if playerData[playerName].inQueue then
- playerData[playerName].inQueue = false
- for index, name in next, queue do
- if name == playerName then
- table.remove(queue, index)
- print("\n"..playerName.." left queue :"..table.concat(queue, "\n"))
- drawQueue()
- break
- end
- end
- end
- end
- else
- if message == 'pause' or message == 'p' then
- start = not start
- end
- end
- end
- --[[ Leaderboard system --]]
- function drawLeaderboard()
- table.sort( leaderboard, function ( a, b )
- return a.score > b.score
- end )
- local out, c = {"<b><v><p align='center'>"..text[language].leaderboard.."</p></v></b>\n"}, 2
- for place, placeData in next, leaderboard do
- if place == 1 then
- out[c] = "<font color='#FFBF00'>"..place..".</font> "..placeData.playerName.." <v>"..placeData.score.."</v><b>/</b><v>"..placeData.sum.."</v>\n"
- elseif place == 2 then
- out[c] = "<font color='#CACACA'>"..place..".</font> "..placeData.playerName.." <v>"..placeData.score.."</v><b>/</b><v>"..placeData.sum.."</v>\n"
- elseif place == 3 then
- out[c] = "<font color='#C67D18'>"..place..".</font> "..placeData.playerName.." <v>"..placeData.score.."</v><b>/</b><v>"..placeData.sum.."</v>\n"
- else
- out[c] = "<vp>"..place..".</vp> "..placeData.playerName.." <v>"..placeData.score.."</v><b>/</b><v>"..placeData.sum.."</v>\n"
- end
- c = c + 1
- end
- ui.addTextArea(1001, table.concat(out), nil, 580, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
- end
- --[[ Queue system --]]
- function drawQueue()
- local out, c = {"<b><v><p align='center'>"..text[language].queue.."</p></v></b>\n"}, 2
- for index, playerName in next, queue do
- out[c] = (c-1)..". "..playerName.."\n"
- c = c + 1
- end
- for playerName, Data in next, playerData do
- if Data.inQueue then
- out[c] = "\n<a href='event:cancel'><p align='center'><r>["..text[language].cancel.."]</r></p></a>"
- ui.addTextArea(1000, table.concat(out), playerName, 60, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
- elseif not Data.isPlaying then
- out[c] = "\n<a href='event:join'><p align='center'><vp>["..text[language].join.."]</vp></p></a>"
- ui.addTextArea(1000, table.concat(out), playerName, 60, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
- else
- ui.addTextArea(1000, table.concat(out), playerName, 60, 40, 160, 180, 0x000000, 0x333333, 0.5, true)
- end
- end
- end
- function eventTextAreaCallback(textAreaId, playerName, eventName)
- eventChatCommand(playerName, eventName)
- end
- --[[ Init settings, map etc. --]]
- tfm.exec.disableAfkDeath(true)
- tfm.exec.disableAutoScore(true)
- tfm.exec.disableAutoShaman(true)
- tfm.exec.disableAutoNewGame(true)
- tfm.exec.disableAutoTimeLeft(true)
- tfm.exec.disablePhysicalConsumables(true)
- tfm.exec.newGame([[<C><P /><Z><S><S H="20" P="0,0,0.3,0.2,0,0,0,0" L="800" o="d2c2c2" X="400" N="" Y="390" T="12" /><S P="0,0,0.3,0.2,0,0,0,0" X="400" L="800" o="d2c2c2" H="400" c="4" Y="200" T="12" /><S P="0,0,0.3,0.2,0,0,0,0" L="800" o="ffffff" H="40" X="400" Y="380" T="14" /><S P="0,0,0.3,0.2,0,0,0,0" L="40" o="ffffff" H="400" X="20" N="" Y="200" T="15" /><S P="0,0,0.3,0.2,0,0,0,0" L="40" o="ffffff" H="400" X="779" N="" Y="200" T="15" /></S><D /><O /></Z></C>]])
- function eventPlayerDied(playerName)
- tfm.exec.respawnPlayer(playerName)
- end
- function eventNewPlayer(playerName, _)
- if not _ then
- -- Draw Walls
- local walls = {
- {1,1}, {2,1}, {3,1}, {4,1}, {5,1}, {6,1}, {7,1}, {8,1}, {9,1}, {10,1}, {11,1}, {12,1},
- {1,2}, {12,2},
- {1,3}, {12,3},
- {1,4}, {12,4},
- {1,5}, {12,5},
- {1,6}, {12,6},
- {1,7}, {12,7},
- {1,8}, {12,8},
- {1,9}, {12,9},
- {1,10}, {12,10},
- {1,11}, {12,11},
- {1,12}, {12,12},
- {1,13}, {12,13},
- {1,14}, {12,14},
- {1,15}, {12,15},
- {1,16}, {12,16},
- {1,17}, {12,17},
- {1,18},{2,18},{3,18},{4,18},{5,18},{6,18},{7,18},{8,18},{9,18},{10,18},{11,18},{12,18},
- }
- for i, v in next, walls do
- ui.addTextArea(-i-100, " ", playerName, (v[1] * 20) + _x, (v[2] * 20) + _y, 14, 14, color.walls1, color.walls2)
- end
- drawQueue()
- ui.setMapName("<j>#tetris</j> <bl>- Zigwin</bl>")
- tfm.exec.respawnPlayer(playerName)
- end
- playerData[playerName] = {
- isPlaying = false,
- inQueue = false,
- }
- end
- for playerName in next, tfm.get.room.playerList do
- eventNewPlayer(playerName, true)
- end
- drawQueue()
- drawLeaderboard()
- ui.setMapName("<j>#tetris</j> <bl>- Zigwin</bl>")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement