This is a simple game of tetris, nothing exceptional...
EXCEPT. Its the first luanti game to be written in a language different than lua (without counting transpilers) since its written in my own programming language made for luanti (lush)
It looks like bash with lua keywords. So if you ever thought "oh man, i wish i could be writing in bash right now instead of lua!", then here you have it, you psycho
Since really the only interesting thing is the language i've written it in, here is the source code, you can take a peek
Code: Select all
$path=$(modpath "lushtetris_core")
run !absolute $path .. "/nodes.lush"
time night !permament
// pieces:
// 0: bar
// 1: counter L
// 2: L
// 3: square
// 4: S
// 5: T
// 6: reverse S
$pieces={
$(echo (-1, 0, 0) (0, 0, 0) (1, 0, 0) (2, 0, 0)),
$(echo (-1, 1, 0) (-1, 0, 0) (0, 0, 0) (1, 0, 0)),
$(echo (-1, 0, 0) (0, 0, 0) (1, 0, 0) (1, 1, 0)),
$(echo (1, 1, 0) (1, 0, 0) (0, 1, 0) (0, 0, 0)),
$(echo (-1, 0, 0) (0, 0, 0) (0, 1, 0) (1, 1, 0)),
$(echo (-1, 0, 0) (0, 0, 0) (0, 1, 0) (1, 0, 0)),
$(echo (-1, 1, 0) (0, 1, 0) (0, 0, 0) (1, 0, 0))
}
$board_origin=(-5,0,10)
$board_height=20
$board_width=10
$DAS_delay=20
register_hook on_load function()
sleep 1
for i in <0:$board_width + 2) do
for j in <0:$board_height + 2) do
nset $board_origin + ($i, $j, 0) "lushtetris_core:background_tile";
end
end
// borders
for i in {0, $board_width + 1} do
for j in (-1:$board_height+2) do
nset $board_origin + ($i, $j, -1) "lushtetris_core:background_tile";
end
end
for j in {0, $board_height + 1} do
for i in (0:$board_width + 2) do
nset $board_origin + ($i, $j, -1) "lushtetris_core:background_tile";
end
end
end
sleep 1
freeze singleplayer
nset (0, 9, -10) "lushtetris_core:background_tile"
$start_pos=(0, 18, 9)
$board_width_boundries=($board_origin.x:$board_origin.x + $board_width + 1)
register_control_hook !repeat_rate 3 singleplayer left function(player player, string key, number duration)
if $game_active and ($duration == 0 or $duration >= $DAS_delay) then
$piece_pos.x=$piece_pos.x - 1
if $(check_if_valid_position) then
update_map_state
else
$piece_pos.x=$piece_pos.x + 1
end
end
end
register_control_hook !repeat_rate 2 singleplayer down function(player player, string key, number duration)
if $game_active then
$piece_pos.y=$piece_pos.y - 1
if $(check_if_valid_position) then
update_map_state
else
$piece_pos.y=$piece_pos.y + 1
commit_piece
pick_new_piece
update_map_state
end
end
end
register_control_hook !repeat_rate 3 singleplayer right function(player player, string key, number duration)
if $game_active and ($duration == 0 or $duration >= $DAS_delay) then
$piece_pos.x=$piece_pos.x + 1
if $(check_if_valid_position) then
update_map_state
else
$piece_pos.x=$piece_pos.x - 1
end
end
end
register_control_hook !tap singleplayer aux1 function(player player, string key, number duration)
if $game_active then
$piece=$(transform $piece $transformations.rotate_z_counterclockwise)
if $(check_if_valid_position) then
update_map_state
$old_piece=$piece
else
$piece=$old_piece
end
end
end
function get_random_piece()
$num=$(random (0:7))
$color=$(get_color $num)
echo $pieces[$num]
end
function get_color(number piece)
echo $palette * 8 + $piece
end
function clear_board()
for i in (0:$board_width + 1) do
for j in (0:$board_height + 1) do
nset $board_origin + ($i, $j, -1) "air";
end
end
end
// recolors the pieces so their param2 corresponds to the next color in the palette
function bump_color_values()
for i in (0:$board_width + 1) do
for j in (0:$board_height + 1) do
$pos=$board_origin + ($i, $j, -1)
nsetinfo param2 $pos $(ninfo param2 $pos) + 8
end
end
end
function pick_new_piece()
$piece=$(get_random_piece)
$piece_pos=$(veccopy $start_pos)
$old_piece=$piece
$old_piece_pos=$piece_pos
$highlighted_piece=$piece
$highlighted_piece_pos=$piece
$old_highlighted_piece=$piece
$old_highlighted_piece_pos=$piece
end
function commit_piece()
nset $(get_piece_positions $piece $piece_pos) "lushtetris_core:tile"
nsetinfo param2 $(get_piece_positions $piece $piece_pos) $color
$cleared=$(scan_lines)
$lines_cleared=$lines_cleared + $cleared
$line_clears_this_level=$line_clears_this_level + $cleared
if $line_clears_this_level >= 10 then
$game_speed=$game_speed * 0.8
$palette=$palette + 1
$line_clears_this_level=$line_clears_this_level - 10
bump_color_values
end
end
function instant_drop()
nset $(get_piece_positions $old_piece $old_piece_pos) "air"
while $(check_if_valid_position) do
$piece_pos.y=$piece_pos.y - 1
end
// go up one, since the last position is invalid
$piece_pos.y=$piece_pos.y + 1
commit_piece
pick_new_piece
end
register_control_hook !tap singleplayer jump $instant_drop
register_control_hook !tap singleplayer sneak $clear_board
function get_piece_positions(vector[] _piece, vector offset)
echo $_piece >/ echo $stdin + $offset
end
// moves the pieces so it corresponds with the new $piece_pos value
function update_map_state()
$highlighted_piece=$piece
$highlighted_piece_pos=$(veccopy $piece_pos)
while $(check_if_valid_position $highlighted_piece $highlighted_piece_pos) do
$highlighted_piece_pos.y=$highlighted_piece_pos.y - 1
end
// go up one, since the last position is invalid
$highlighted_piece_pos.y=$highlighted_piece_pos.y + 1
nset $(get_piece_positions $old_highlighted_piece $old_highlighted_piece_pos) "air"
nset $(get_piece_positions $highlighted_piece $highlighted_piece_pos) "lushtetris_core:highlighted_tile"
nsetinfo param2 $(get_piece_positions $highlighted_piece $highlighted_piece_pos) $color
$old_highlighted_piece=$highlighted_piece
$old_highlighted_piece_pos=$highlighted_piece_pos
nset $(get_piece_positions $old_piece $old_piece_pos) "air"
nset $(get_piece_positions $piece $piece_pos) "lushtetris_core:tile_active"
nsetinfo param2 $(get_piece_positions $piece $piece_pos) $color
$old_piece_pos=$(veccopy $piece_pos)
end
// scan for completed lines and clear them
// returns the amount of cleared lines
function scan_lines()
$clear_amount=0
for y in $(seq $board_height - 1 $board_origin.y + 1 (-1)) do
$is_filled=true
$row_positions=$(seq $board_origin.x + 1 $board_origin.x + $board_width 1)
for x in $row_positions do
if not $(ngroup ($x, $y, $board_origin.z - 1) "solid") then
$is_filled=false
end
end
if $is_filled then
$clear_amount=$clear_amount + 1
for y2 in <$y:$board_height - 2) do
for x2 in <$board_origin.x + 1:$board_origin.x + $board_width> do
nset ($x2, $y2, $board_origin.z - 1) ($x2, $y2 + 1, $board_origin.z - 1)
nsetinfo param2 ($x2, $y2, $board_origin.z - 1) $(ninfo param2 ($x2, $y2 + 1, $board_origin.z - 1))
end
end
end
end
echo $clear_amount
end
function check_if_valid_position(vector[] _piece?, vector offset?)
$_piece=$_piece or $piece
$offset=$offset or $piece_pos
$positions=$(get_piece_positions $_piece $offset)
$valid=true
for pos in $positions do
if $(ngroup $pos "solid") then
$valid=false
end
end
echo $valid
end
// a little animation to slowly turn the pieces grey row by row
function finish_game_animation()
for j in (0:$board_height + 1) do
for i in (0:$board_width + 1) do
$pos=$board_origin + ($i, $j, -1)
if $(ninfo name $pos) != "air" then
nset $pos "lushtetris_core:greyed_out_tile"
sleep 0.01
end
end
end
end
clear_board
$game_speed=0.7
$palette=0
$color=0
$game_active=true
$piece=$(get_random_piece)
$piece_pos=$(veccopy $start_pos)
$old_piece_pos=$(veccopy $piece_pos)
$old_piece=$piece
$highlighted_piece_pos=$(veccopy $piece_pos)
$highlighted_piece=$piece
$old_highlighted_piece_pos=$highlighted_piece_pos
$old_highlighted_piece=$highlighted_piece
$lines_cleared=0
$line_clears_this_level=0
$non=0
while true do
$non=$non + 1
sleep $game_speed
$piece_pos.y=$piece_pos.y - 1
if $(check_if_valid_position) then
update_map_state
else
$piece_pos.y=$piece_pos.y + 1
commit_piece
pick_new_piece
if not $(check_if_valid_position) then
finish_game_animation
$game_active=false
sleep 2
$lines_cleared=0
$line_clears_this_level=0
$palette=0
$game_speed=1
clear_board
end
$game_active=true
update_map_state
end
teleport singleplayer to (0, 10, -10)
end