mirror of
				https://github.com/LDDestroier/CC/
				synced 2025-10-30 23:12:59 +00:00 
			
		
		
		
	Added TGM locking, T-spin detection, other
Every time you place a mino down, it will now darken slightly before spawning the next one.
This commit is contained in:
		
							
								
								
									
										108
									
								
								ldris.lua
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								ldris.lua
									
									
									
									
									
								
							| @@ -17,6 +17,8 @@ | ||||
| --  + Add random color pulsation (for effect!) | ||||
| --  + Add a proper title screen. The current one is pathetic. | ||||
|  | ||||
| local sentInfos = 0 | ||||
|  | ||||
| local scr_x, scr_y = term.getSize() | ||||
| local keysDown = {} | ||||
| local game = { | ||||
| @@ -32,8 +34,10 @@ local game = { | ||||
| 	canPause = true,		-- if false, cannot pause game (such as in online multiplayer) | ||||
| 	inputDelay = 0.05,		-- amount of time between each input | ||||
| 	gameDelay = 0.05,		-- amount of time between game ticks | ||||
| 	minimumLockTimer = 0.4,	-- shortest amount of time before a piece locks upon touching the ground | ||||
| 	appearanceDelay = 0.15,	-- amount of time to wait after placing a piece | ||||
| 	config = { | ||||
| 		TGMlock = true,		-- replicate the piece locking from Tetris: The Grand Master | ||||
| 		TGMlock = false,		-- replicate the piece locking from Tetris: The Grand Master | ||||
| 		scrubMode = false,	-- gives you nothing but I-pieces | ||||
| 	}, | ||||
| 	control = {					-- client's control scheme | ||||
| @@ -149,6 +153,7 @@ local minos = { | ||||
| 	[1] = {	-- I-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = false, | ||||
| 		mainColor = "3", | ||||
| 		shape = { | ||||
| 			"    ", | ||||
| 			"3333", | ||||
| @@ -159,6 +164,7 @@ local minos = { | ||||
| 	[2] = {	-- L-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = false, | ||||
| 		mainColor = "1", | ||||
| 		shape = { | ||||
| 			"  1", | ||||
| 			"111", | ||||
| @@ -168,6 +174,7 @@ local minos = { | ||||
| 	[3] = {	-- J-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = false, | ||||
| 		mainColor = "b", | ||||
| 		shape = { | ||||
| 			"b  ", | ||||
| 			"bbb", | ||||
| @@ -177,6 +184,7 @@ local minos = { | ||||
| 	[4] = {	-- O-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = false, | ||||
| 		mainColor = "4", | ||||
| 		shape = { | ||||
| 			"44", | ||||
| 			"44", | ||||
| @@ -185,6 +193,7 @@ local minos = { | ||||
| 	[5] = { -- T-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = true, | ||||
| 		mainColor = "a", | ||||
| 		shape = { | ||||
| 			" a ", | ||||
| 			"aaa", | ||||
| @@ -194,6 +203,7 @@ local minos = { | ||||
| 	[6] = { -- Z-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = false, | ||||
| 		mainColor = "e", | ||||
| 		shape = { | ||||
| 			"ee ", | ||||
| 			" ee", | ||||
| @@ -203,6 +213,7 @@ local minos = { | ||||
| 	[7] = {	-- S-piece | ||||
| 		canRotate = true, | ||||
| 		canTspin = false, | ||||
| 		mainColor = "5", | ||||
| 		shape = { | ||||
| 			" 55", | ||||
| 			"55 ", | ||||
| @@ -340,6 +351,7 @@ local transmit = function(msg) | ||||
| end | ||||
|  | ||||
| local sendInfo = function(command, doSendTime, playerNumber) | ||||
| 	sentInfos = sentInfos + 1 | ||||
| 	if game.net.isHost then | ||||
| 		transmit({ | ||||
| 			command = command, | ||||
| @@ -375,6 +387,7 @@ local makeNewMino = function(minoType, board, x, y, replaceColor) | ||||
|  | ||||
| 	mino.x = x | ||||
| 	mino.y = y | ||||
| 	mino.color = minos[minoType].mainColor or "c" | ||||
| 	mino.didTspin = false	-- if the player has done a T-spin with this piece | ||||
| 	mino.lockBreaks = 16	-- anti-infinite measure | ||||
| 	mino.waitingForLock = false | ||||
| @@ -415,19 +428,29 @@ local makeNewMino = function(minoType, board, x, y, replaceColor) | ||||
| 			output[y] = table.concat(output[y]) | ||||
| 		end | ||||
| 		mino.shape = output | ||||
| 		-- check T-spin | ||||
| 		local checkTspin = function(mino) | ||||
| 			if (mino.checkCollision(-1, 0) and mino.checkCollision(1, 0) and mino.checkCollision(0, -1)) then | ||||
| 				mino.didTspin = true | ||||
| 				return true | ||||
| 			else | ||||
| 				return false | ||||
| 			end | ||||
| 		end | ||||
| 		-- try to kick off wall/floor | ||||
| 		if mino.checkCollision(0, 0) then | ||||
| 			-- try T-spin triple rotation | ||||
| 			if not mino.checkCollision(-direction, 2) then | ||||
| 				mino.y = mino.y + 2 | ||||
| 				mino.x = mino.x - direction | ||||
| 				mino.didTspin = true | ||||
| 				checkTspin(mino) | ||||
| 				return true | ||||
| 			end | ||||
| 			-- kick off floor | ||||
| 			for y = 1, math.floor(#mino.shape) do | ||||
| 			for y = 1, math.floor(#mino.shape / 2) do | ||||
| 				if not mino.checkCollision(0, -y) then | ||||
| 					mino.y = mino.y - y | ||||
| 					checkTspin(mino) | ||||
| 					return true | ||||
| 				end | ||||
| 			end | ||||
| @@ -435,13 +458,15 @@ local makeNewMino = function(minoType, board, x, y, replaceColor) | ||||
| 			for x = 0, -math.floor(#mino.shape[1] / 2), -1 do | ||||
| 				if not mino.checkCollision(x, 0) then | ||||
| 					mino.x = mino.x + x | ||||
| 					checkTspin(mino) | ||||
| 					return true | ||||
| 				end | ||||
| 				-- try diagonal-down | ||||
| 				if not mino.checkCollision(x, 1) then | ||||
| 					mino.x = mino.x + x | ||||
| 					mino.y = mino.y + 1 | ||||
| 					mino.didTspin = true | ||||
| 					sendInfo("send_info", false) | ||||
| 					checkTspin(mino) | ||||
| 					return true | ||||
| 				end | ||||
| 			end | ||||
| @@ -449,13 +474,15 @@ local makeNewMino = function(minoType, board, x, y, replaceColor) | ||||
| 			for x = 0, math.floor(#mino.shape[1] / 2) do | ||||
| 				if not mino.checkCollision(x, 0) then | ||||
| 					mino.x = mino.x + x | ||||
| 					checkTspin(mino) | ||||
| 					return true | ||||
| 				end | ||||
| 				-- try diagonal-down | ||||
| 				if not mino.checkCollision(x, 1) then | ||||
| 					mino.x = mino.x + x | ||||
| 					mino.y = mino.y + 1 | ||||
| 					mino.didTspin = true | ||||
| 					sendInfo("send_info", false) | ||||
| 					checkTspin(mino) | ||||
| 					return true | ||||
| 				end | ||||
| 			end | ||||
| @@ -466,14 +493,14 @@ local makeNewMino = function(minoType, board, x, y, replaceColor) | ||||
| 		end | ||||
| 	end | ||||
| 	-- draws a mino onto a board; you'll still need to render the board, though | ||||
| 	mino.draw = function(isSolid) | ||||
| 	mino.draw = function(isSolid, colorReplace) | ||||
| 		for y = 1, #mino.shape do | ||||
| 			for x = 1, #mino.shape[y] do | ||||
| 				if mino.shape[y]:sub(x,x) ~= " " then | ||||
| 					if doesSpaceExist(mino.board, x + math.floor(mino.x), y + math.floor(mino.y)) then | ||||
| 						mino.board[y + math.floor(mino.y)][x + math.floor(mino.x)] = { | ||||
| 							isSolid or false, | ||||
| 							mino.shape[y]:sub(x,x), | ||||
| 							colorReplace or mino.shape[y]:sub(x,x), | ||||
| 							isSolid and 0 or 0, | ||||
| 							isSolid and 0 or 1 | ||||
| 						} | ||||
| @@ -495,15 +522,19 @@ local makeNewMino = function(minoType, board, x, y, replaceColor) | ||||
| 					mino.x = mino.x + sx - math.abs(x) / x | ||||
| 					break | ||||
| 				end | ||||
| 				if sx ~= 0 then | ||||
| 					mino.didTspin = false | ||||
| 				end | ||||
| 			end | ||||
| 			for sy = 0, math.ceil(y), math.abs(y) / y do | ||||
| 				if mino.checkCollision(0, sy) then | ||||
| 					mino.y = mino.y + sy - math.abs(y) / y | ||||
| 					break | ||||
| 				end | ||||
| 				if sy ~= 0 then | ||||
| 					mino.didTspin = false | ||||
| 				end | ||||
| 			end | ||||
| 		else | ||||
| 			return false | ||||
| 		end | ||||
| @@ -717,6 +748,18 @@ local gameOver = function(player, cPlayer) | ||||
| 	return | ||||
| end | ||||
|  | ||||
| -- used when darkening just-placed pieces | ||||
| local normalPalettes = {} | ||||
| local darkerPalettes = {} | ||||
| for i = 1, 16 do | ||||
| 	normalPalettes[("0123456789abcdef"):sub(i,i)] = {term.getPaletteColor(2 ^ (i - 1))} | ||||
| 	darkerPalettes[("0123456789abcdef"):sub(i,i)] = { | ||||
| 		normalPalettes[("0123456789abcdef"):sub(i,i)][1] * 0.6, | ||||
| 		normalPalettes[("0123456789abcdef"):sub(i,i)][2] * 0.6, | ||||
| 		normalPalettes[("0123456789abcdef"):sub(i,i)][3] * 0.6, | ||||
| 	} | ||||
| end | ||||
|  | ||||
| -- calculates the amount of garbage to send | ||||
| local calculateGarbage = function(lines, combo, backToBack, didTspin) | ||||
| 	local output = 0 | ||||
| @@ -783,7 +826,7 @@ local startGame = function(playerNumber) | ||||
| 		board = player.board | ||||
| 		control = player.control | ||||
|  | ||||
| 		local draw = function(isSolid) | ||||
| 		local draw = function(isSolid, doSendInfo) | ||||
| 			local canChangeSpecial = true | ||||
| 			for k,v in pairs(game.p) do | ||||
| 				if v.flashingSpecial then | ||||
| @@ -799,8 +842,12 @@ local startGame = function(playerNumber) | ||||
| 			ghostMino.move(0, board.ySize, true) | ||||
| 			ghostMino.draw(false) | ||||
| 			mino.draw(isSolid, ageSpaces) | ||||
| 			if doSendInfo then | ||||
| 				sendInfo("send_info", false, playerNumber) | ||||
| 			end | ||||
| 			renderBoard(board, 0, 0, true) | ||||
| 			term.setCursorPos(1, 1) | ||||
| 			term.write(mino.didTspin) | ||||
| 		end | ||||
|  | ||||
| 		local currentMinoType | ||||
| @@ -831,38 +878,44 @@ local startGame = function(playerNumber) | ||||
| 						if mino.move(-1, 0) then | ||||
| 							game.cancelTimer(lockTimer or 0) | ||||
| 							mino.waitingForLock = false | ||||
| 							draw() | ||||
| 							draw(nil, true) | ||||
| 						end | ||||
| 					end | ||||
| 					if control.moveRight == 1 or (control.moveRight or 0) >= 1 + game.moveHoldDelay then | ||||
| 						if mino.move(1, 0) then | ||||
| 							game.cancelTimer(lockTimer or 0) | ||||
| 							mino.waitingForLock = false | ||||
| 							draw() | ||||
| 							draw(nil, true) | ||||
| 						end | ||||
| 					end | ||||
| 					if control.moveDown then | ||||
| 						game.cancelTimer(lockTimer or 0) | ||||
| 						mino.waitingForLock = false | ||||
| 						if mino.move(0, 1) then | ||||
| 							draw() | ||||
| 							draw(nil, true) | ||||
| 						else | ||||
| 							if game.config.TGMlock then | ||||
| 								draw(true, true) | ||||
| 								cPlayer.canHold = true | ||||
| 								finished = true | ||||
| 							else | ||||
| 								if mino.waitingForLock then | ||||
| 									game.alterTimer(lockTimer, -0.1) | ||||
| 								else | ||||
| 									mino.lockBreaks = mino.lockBreaks - 1 | ||||
| 								lockTimer = game.startTimer(math.max(0.2 / cPlayer.fallSteps, 0.5)) | ||||
| 									lockTimer = game.startTimer(math.max(0.2 / cPlayer.fallSteps, game.minimumLockTimer)) | ||||
| 									mino.waitingForLock = true | ||||
| 								end | ||||
| 							end | ||||
| 						end | ||||
| 					end | ||||
| 					if control.rotateLeft == 1 then | ||||
| 						if mino.rotate(-1) then | ||||
| 							ghostMino.y = mino.y | ||||
| 							ghostMino.rotate(-1) | ||||
| 							game.cancelTimer(lockTimer or 0) | ||||
| 							mino.waitingForLock = false | ||||
| 							draw() | ||||
| 							draw(nil, true) | ||||
| 						end | ||||
| 					end | ||||
| 					if control.rotateRight == 1 then | ||||
| @@ -871,7 +924,7 @@ local startGame = function(playerNumber) | ||||
| 							ghostMino.rotate(1) | ||||
| 							game.cancelTimer(lockTimer or 0) | ||||
| 							mino.waitingForLock = false | ||||
| 							draw() | ||||
| 							draw(nil, true) | ||||
| 						end | ||||
| 					end | ||||
| 					if control.hold == 1 then | ||||
| @@ -889,20 +942,25 @@ local startGame = function(playerNumber) | ||||
| 								player.holdBoard, | ||||
| 								#minos[cPlayer.hold].shape[1] == 2 and 1 or 0, | ||||
| 								0 | ||||
| 							).draw() | ||||
| 							).draw(false) | ||||
| 							sendInfo("send_info", false, playerNumber) | ||||
| 							renderBoard(player.holdBoard, 0, 0, false) | ||||
| 							finished = true | ||||
| 							cPlayer.didHold = true | ||||
| 						end | ||||
| 					end | ||||
| 					if control.fastDrop == 1 then | ||||
| 						mino.move(0, board.ySize, true) | ||||
| 						draw(true) | ||||
| 						if game.config.TGMlock then | ||||
| 							draw(false) | ||||
| 						else | ||||
| 							draw(true, true) | ||||
| 							cPlayer.canHold = true | ||||
| 							finished = true | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 			end | ||||
| 			for k,v in pairs(player.control) do | ||||
| 				player.control[k] = v + game.inputDelay | ||||
| 			end | ||||
| @@ -914,6 +972,7 @@ local startGame = function(playerNumber) | ||||
|  | ||||
| 			cPlayer.level = math.ceil((1 + cPlayer.lines) / 10) | ||||
| 			cPlayer.fallSteps = 0.075 * (1.33 ^ cPlayer.level) | ||||
| 			cPlayer.didHold = false | ||||
|  | ||||
| 			if takeFromQueue then | ||||
| 				currentMinoType = cPlayer.queue[1] | ||||
| @@ -1048,6 +1107,7 @@ local startGame = function(playerNumber) | ||||
| 							dropTimer = game.startTimer(0) | ||||
| 							if not game.paused then | ||||
| 								if not cPlayer.frozen then | ||||
| 									mino.oldY = mino.y | ||||
| 									if mino.checkCollision(0, 1) then | ||||
| 										if mino.lockBreaks == 0 then | ||||
| 											draw(true) | ||||
| @@ -1055,11 +1115,14 @@ local startGame = function(playerNumber) | ||||
| 											break | ||||
| 										elseif not mino.waitingForLock then | ||||
| 											mino.lockBreaks = mino.lockBreaks - 1 | ||||
| 											lockTimer = game.startTimer(math.max(0.2 / cPlayer.fallSteps, 0.25)) | ||||
| 											lockTimer = game.startTimer(math.max(0.2 / cPlayer.fallSteps, game.minimumLockTimer)) | ||||
| 											mino.waitingForLock = true | ||||
| 										end | ||||
| 									else | ||||
| 										mino.move(0, cPlayer.fallSteps, true) | ||||
| 										if math.floor(mino.oldY) ~= math.floor(mino.y) then | ||||
| 											sendInfo("send_info", false) | ||||
| 										end | ||||
| 										draw() | ||||
| 									end | ||||
| 								end | ||||
| @@ -1097,7 +1160,7 @@ local startGame = function(playerNumber) | ||||
| 					player.backToBack = 0 | ||||
| 				end | ||||
|  | ||||
| 				drawComboMessage(player, cPlayer, #clearedLines) | ||||
| 				drawComboMessage(player, cPlayer, #clearedLines, mino.didTspin) | ||||
|  | ||||
| 				cPlayer.lastLinesCleared = #clearedLines | ||||
|  | ||||
| @@ -1140,6 +1203,15 @@ local startGame = function(playerNumber) | ||||
| 			if cPlayer.garbage > 0 then | ||||
| 				doleOutGarbage(player, cPlayer, cPlayer.garbage) | ||||
| 			end | ||||
|  | ||||
| 			if #clearedLines == 0 and game.running and not cPlayer.didHold then | ||||
| 				mino.draw(false, "c") | ||||
| 				term.setPaletteColor(colors.brown, table.unpack(darkerPalettes[mino.color])) | ||||
| 				renderBoard(board, 0, 0, true) | ||||
| 				sleep(game.appearanceDelay) | ||||
| 				mino.draw(true) | ||||
| 				renderBoard(board, 0, 0, true) | ||||
| 			end | ||||
| 		end | ||||
| 	else | ||||
| 		-- if you're a client, take in all that board info and just fukkin draw it | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 LDDestroier
					LDDestroier