diff options
Diffstat (limited to 'mario')
| -rw-r--r-- | mario/blocks.lua | 9 | ||||
| -rwxr-xr-x | mario/gamestate.lua | 295 | ||||
| -rw-r--r-- | mario/init.lua | 8 | ||||
| -rw-r--r-- | mario/portal.lua | 4 | ||||
| -rw-r--r-- | mario/sounds/mario-1-up.ogg | bin | 0 -> 28681 bytes | |||
| -rw-r--r-- | mario/sounds/mario-bonus.ogg | bin | 0 -> 153519 bytes | |||
| -rw-r--r-- | mario/sounds/mario-continue.ogg | bin | 0 -> 19741 bytes | |||
| -rw-r--r-- | mario/sounds/mario-game-over.ogg | bin | 0 -> 56498 bytes | |||
| -rw-r--r-- | mario/sounds/mario-game-start.ogg | bin | 0 -> 59419 bytes | |||
| -rw-r--r-- | mario/sounds/mario-next-level-start.ogg | bin | 0 -> 23164 bytes | |||
| -rw-r--r-- | mario/sounds/mario_coin.ogg | bin | 0 -> 4814 bytes | |||
| -rw-r--r-- | mario/turtle.lua | 28 | 
12 files changed, 326 insertions, 18 deletions
diff --git a/mario/blocks.lua b/mario/blocks.lua index f2afdac..7005de3 100644 --- a/mario/blocks.lua +++ b/mario/blocks.lua @@ -49,6 +49,9 @@ minetest.register_node("mario:coin", {  	paramtype = "light",  	walkable = false,  	groups = {cracky = 2}, +	on_destruct = function(pos) +		minetest.sound_play("mario-coin", {pos = pos,max_hear_distance = 40,gain = 10.0,}) +	end,  })  local nbox = { @@ -79,6 +82,9 @@ minetest.register_node("mario:mushroom",{  	paramtype = "light",  	groups = {cracky = 3},  	node_box = nbox, +	on_destruct = function(pos) +		minetest.sound_play("mario-bonus", {pos = pos,max_hear_distance = 40,gain = 10.0,}) +	end,  })  minetest.register_node("mario:mushroom_green",{ @@ -95,4 +101,7 @@ minetest.register_node("mario:mushroom_green",{  	paramtype = "light",  	groups = {cracky = 3},  	node_box = nbox, +	on_destruct = function(pos) +		minetest.sound_play("mario-1-up", {pos = pos,max_hear_distance = 40,gain = 10.0,}) +	end,  }) diff --git a/mario/gamestate.lua b/mario/gamestate.lua new file mode 100755 index 0000000..c58b5e4 --- /dev/null +++ b/mario/gamestate.lua @@ -0,0 +1,295 @@ + +-- Array to hold all the running game states +mario.games = {} + +-- Store all the currently playing players +mario.players = {} + +-- Amount of points that will award a life +local score_for_life_award = 5000 + +--------------------------------------------------------- +-- Public functions (these can be called from any other place) + +-- Start the game from the spawn block at position "pos" activated by "player" +function mario.game_start(pos, player, gamedef) +	-- create an id unique for the given position +	local id = minetest.pos_to_string(pos) +	local player_name = player:get_player_name() + +	-- make sure any previous game with the same id has ended +	local gamestate = mario.games[id] +	if gamestate then +		minetest.chat_send_player(name, "A game is already in progress for player " .. gamestate.player_name) +		return +	end + +	-- Create a new game state with that id and add it to the game list +	gamedef = gamedef or {} +	gamestate = { +		id = id, +		player_name = player_name, +		pos = pos, +		player_start = vector.add(pos, (gamedef.player_start or {x=16,y=0,z=1})), +		turtle1_start = vector.add(pos, (gamedef.turtle_start or {x=3,y=0.5,z=12})), +		turtle2_start = vector.add(pos, (gamedef.turtle_start or {x=30,y=0.5,z=12})), +		coin_total =  gamedef.coin_total or 84, +		speed = gamedef.speed or 2, +		lives = gamedef.lives or 3, +		scorename = gamedef.scorename, +		level = 1, +		score = 0, +		awarded_lives = 0, +		coin_count = 0, +	} + 	mario.games[id] = gamestate +	mario.players[id] = player + +	minetest.log("action","New mario game started at " .. id .. " by " .. gamestate.player_name) + +	-- place schematic +	local schem = gamedef +	minetest.place_schematic({x=pos.x-1,y=pos.y-2,z=pos.z-2},gamedef.schematic,0, "air", true) + +	-- Set start positions +	mario.game_reset(id, player) +	mario.update_hud(id, player) +	minetest.sound_play("mario-game-start", {pos = pos,max_hear_distance = 40,gain = 10.0,}) +end + +-- Finish the game with the given id +function mario.game_end(id) +	mario.remove_turtles(id) +	local gamestate = mario.games[id] +	local player = mario.players[id] or minetest.get_player_by_name(gamestate.player_name) +	if player then +		mario.remove_hud(player, gamestate.player_name) +		player:moveto(vector.add(gamestate.pos,{x=0.5,y=0.5,z=-1.5})) +	end +	-- Save score +	if gamestate.scorename then +		local ranking = myhighscore.save_score(gamestate.scorename, { +			player = gamestate.player_name, +			score = gamestate.score +		}) +		if ranking then +			minetest.chat_send_player(gamestate.player_name, "You made it to the highscores! Your Ranking: " .. ranking) +		end +	end +	-- Clear the data +	mario.games[id] = nil +	mario.players[id] = nil +end + +-- Resets the game to the start positions +function mario.game_reset(id, player) +	local gamestate = mario.games[id] +	minetest.log("action", "resetting game " .. id) + +	-- Save the time when the game was last resetted (to solve timing issues) +	local last_reset = os.time() + +	gamestate.last_reset = last_reset + +	-- Position the player +	local player = player or minetest.get_player_by_name(gamestate.player_name) +	player:setpos(gamestate.player_start) + +	-- Spawn the turtles and assign the game id to each turtle +	minetest.after(2, function() +		if mario.games[id] and last_reset == mario.games[id].last_reset then +			local turtle = minetest.add_entity(gamestate.turtle_start, "mario:turtle") +			turtle:get_luaentity().gameid = id +		end +	end) +	minetest.after(2, function() +		if mario.games[id] and last_reset == mario.games[id].last_reset then +			local turtle = minetest.add_entity(gamestate.turtle_start, "mario:turtle2") +			turtle:get_luaentity().gameid = id +		end +	end) +	minetest.after(45, function() +		if mario.games[id] and last_reset == mario.games[id].last_reset then +			local turtle = minetest.add_entity(gamestate.turtle_start, "mario:turtle3") +			turtle:get_luaentity().gameid = id +		end +	end) +	minetest.after(45, function() +		if mario.games[id] and last_reset == mario.games[id].last_reset then +			local turtle = minetest.add_entity(gamestate.turtle_start, "mario:turtle4") +			turtle:get_luaentity().gameid = id +		end +	end) +end + +-- Remove all the turtles from the board with the given id +function mario.remove_turtles(id) +	local gamestate = mario.games[id] +	if not gamestate then return end + +	-- Remove all non-players (turtles!) +	local boardcenter = vector.add(gamestate.pos, {x=13,y=0.5,z=15}) +	for index, object in ipairs(minetest.get_objects_inside_radius(boardcenter,20)) do +		if object:is_player() ~= true then +		object:remove() +		end +	end +end + +-- Add a mushroom to the game board +function mario.add_mushroom(id) +	local gamestate = mario.games[id] +	if not gamestate then return end +	local node = {} +	-- Different mushroom will be used depending on the level +	if gamestate.level == 1 then +		node.name = "mario:mushroom" +	end +	local pos = vector.add(gamestate.player_start,{x=0,y=12,z=0}) +	minetest.set_node(pos, node) +	print(node.param2) +	-- Set the timer for the mushroom to disappear +	minetest.get_node_timer(pos):start(60) +end + +-- A player got a coin, update the state +function mario.on_player_got_coin(player) +	local name = player:get_player_name() +	local gamestate = mario.get_game_by_player(name) +	if not gamestate then return end + +	gamestate.coin_count = gamestate.coin_count + 1 +	gamestate.score = gamestate.score + 10 +	mario.update_hud(gamestate.id, player) +	minetest.sound_play("mario-coin", {object = player, max_hear_distance = 6}) + +	if gamestate.coin_count == 70 or gamestate.coin_count == 180 then +		mario.add_mushroom(gamestate.id) +	elseif gamestate.coin_count >= gamestate.coin_total then +		minetest.chat_send_player(name, "You cleared the board!") + +		mario.remove_turtles(gamestate.id) +		gamestate.coin_count = 0 +		gamestate.level = gamestate.level + 1 +		gamestate.speed = gamestate.level + 1 + +		minetest.after(3.0, function() +			minetest.chat_send_player(name, "Starting Level "..gamestate.level) +			-- place schematic +			local schem = minetest.get_modpath("mario").."/schems/mario.mts" +			minetest.place_schematic(vector.add(gamestate.pos, {x=-1,y=-2,z=-2}),schem,0, "air", true) + +			-- Set start positions +			mario.game_reset(gamestate.id, player) +			minetest.sound_play("mario-game-start", {pos = pos,max_hear_distance = 40,gain = 10.0,}) +		end) +	end + +	if gamestate.score / score_for_life_award >= 1 + gamestate.awarded_lives then +		minetest.chat_send_player(name, "You reached " .. gamestate.score .. " points and earned an extra life!") +		gamestate.lives = gamestate.lives + 1 +		gamestate.awarded_lives = gamestate.awarded_lives + 1 +	end +end + +-- A player got a mushroom, update the state +function mario.on_player_got_mushroom(player, points) +	local name = player:get_player_name() +	local gamestate = mario.get_game_by_player(name) +	if not gamestate then return end +	gamestate.score = gamestate.score + points +	minetest.chat_send_player(name, points .. " bonus points!") +	minetest.sound_play("mario-bonus", {pos = pos, max_hear_distance = 6}) +end + +-- Get the game that the given player is playing +function mario.get_game_by_player(player_name) +	for _,gamestate in pairs(mario.games) do +		if gamestate.player_name == player_name then +			return gamestate +		end +	end +end + +--------------------------------------------------------- +--- Private functions (only can be used inside this file) + + +-- Called every 0.5 seconds for each player that is currently playing +local function on_player_gamestep(player, gameid) +	local player_pos = player:getpos() +	local positions = { +		{x=0.5,y=0.5,z=0.5}, +		{x=-0.5,y=0.5,z=-0.5}, +	} +	for _,pos in pairs(positions) do +		pos = vector.add(player_pos, pos) +		local node = minetest.get_node(pos) +		if node.name == "mario:coin_1" then +			minetest.remove_node(pos) +			mario.on_player_got_coin(player) +		elseif node.name == "mario:coin_2" then +			minetest.remove_node(pos) +			mario.on_player_got_power_coin(player) +		elseif node.name == "mario:cherrys" then +			minetest.remove_node(pos) +			mario.on_player_got_mushroom(player, 100) +		elseif node.name == "mario:strawberry" then +			minetest.remove_node(pos) +			mario.on_player_got_mushroom(player, 300) +		elseif node.name == "mario:orange" then +			minetest.remove_node(pos) +			mario.on_player_got_mushroom(player, 500) +		elseif node.name == "mario:apple" then +			minetest.remove_node(pos) +			mario.on_player_got_mushroom(player, 700) +		end +	end +end + +------------------- +--- Execution code + + +-- Time counters +local tmr_gamestep = 0 +minetest.register_globalstep(function(dtime) +	tmr_gamestep = tmr_gamestep + dtime; +	if tmr_gamestep > 0.2 then +		for id,player in pairs(mario.players) do +			on_player_gamestep(player, id) +		end +		tmr_gamestep = 0 +	end +end) + +minetest.register_on_leaveplayer(function(player) +	local name = player:get_player_name() +	for id,game in pairs(mario.games) do +		if game.player_name == name then +			mario.game_end(id) +		end +	end +end) + +minetest.register_on_shutdown(function() +	minetest.log("action", "Server shuts down. Ending all mario games") +	for id,game in pairs(mario.games) do +		mario.game_end(id) +	end +end) + +-- Chatcommand to end the game for the current player +minetest.register_chatcommand("mario_exit", { +	params = "", +	description = "Loads and saves all rooms", +	func = function(name, param) +		local gamestate = mario.get_game_by_player(name) +		if gamestate then +			mario.game_end(gamestate.id) +			minetest.chat_send_player(name, "You are no longer playing mario") +		else +			minetest.chat_send_player(name, "You are not currently in a mario game") +		end +	end +}) diff --git a/mario/init.lua b/mario/init.lua index 51b1b64..2538dc1 100644 --- a/mario/init.lua +++ b/mario/init.lua @@ -1,8 +1,11 @@ +mario = {}  dofile(minetest.get_modpath("mario").."/pipes.lua")  dofile(minetest.get_modpath("mario").."/blocks.lua")  dofile(minetest.get_modpath("mario").."/portal.lua")  dofile(minetest.get_modpath("mario").."/turtle.lua") +dofile(minetest.get_modpath("mario").."/gamestate.lua") +  minetest.register_node("mario:placer",{  	description = "Reset", @@ -23,8 +26,9 @@ minetest.register_node("mario:placer",{  		player:setpos({x=pos.x+16,y=pos.y+0.1,z=pos.z+1})  		print(name)  		player:set_physics_override(1,1,0.3,true,false) -		minetest.add_entity({x=pos.x+3,y=pos.y+12,z=pos.z+1}, "mario:1") -		minetest.add_entity({x=pos.x+30,y=pos.y+12,z=pos.z+1}, "mario:1") +		minetest.add_entity({x=pos.x+3,y=pos.y+12,z=pos.z+1}, "mario:turtle1") +		minetest.add_entity({x=pos.x+30,y=pos.y+12,z=pos.z+1}, "mario:turtle1") +		minetest.sound_play("mario-game-start", {pos = pos,max_hear_distance = 40,gain = 10.0,})  	end,  })  minetest.register_node("mario:placer2",{ diff --git a/mario/portal.lua b/mario/portal.lua index 1c61d8d..7b9945d 100644 --- a/mario/portal.lua +++ b/mario/portal.lua @@ -55,7 +55,7 @@ minetest.register_abm({  		for k, player in pairs(objs) do  			if player:get_player_name() then -				player:setpos({x=pos.x+31,y=pos.y+0.1,z=pos.z}) +				player:setpos({x=pos.x+31,y=pos.y+0.5,z=pos.z})  			end  		end  	end @@ -69,7 +69,7 @@ minetest.register_abm({  		for k, player in pairs(objs) do  			if player:get_player_name() then -				player:setpos({x=pos.x-31,y=pos.y+0.1,z=pos.z}) +				player:setpos({x=pos.x-31,y=pos.y+0.5,z=pos.z})  			end  		end  	end diff --git a/mario/sounds/mario-1-up.ogg b/mario/sounds/mario-1-up.ogg Binary files differnew file mode 100644 index 0000000..f0a08ab --- /dev/null +++ b/mario/sounds/mario-1-up.ogg diff --git a/mario/sounds/mario-bonus.ogg b/mario/sounds/mario-bonus.ogg Binary files differnew file mode 100644 index 0000000..2fb7688 --- /dev/null +++ b/mario/sounds/mario-bonus.ogg diff --git a/mario/sounds/mario-continue.ogg b/mario/sounds/mario-continue.ogg Binary files differnew file mode 100644 index 0000000..270f2f7 --- /dev/null +++ b/mario/sounds/mario-continue.ogg diff --git a/mario/sounds/mario-game-over.ogg b/mario/sounds/mario-game-over.ogg Binary files differnew file mode 100644 index 0000000..9c66411 --- /dev/null +++ b/mario/sounds/mario-game-over.ogg diff --git a/mario/sounds/mario-game-start.ogg b/mario/sounds/mario-game-start.ogg Binary files differnew file mode 100644 index 0000000..0d90de2 --- /dev/null +++ b/mario/sounds/mario-game-start.ogg diff --git a/mario/sounds/mario-next-level-start.ogg b/mario/sounds/mario-next-level-start.ogg Binary files differnew file mode 100644 index 0000000..7e7644f --- /dev/null +++ b/mario/sounds/mario-next-level-start.ogg diff --git a/mario/sounds/mario_coin.ogg b/mario/sounds/mario_coin.ogg Binary files differnew file mode 100644 index 0000000..aa789b0 --- /dev/null +++ b/mario/sounds/mario_coin.ogg diff --git a/mario/turtle.lua b/mario/turtle.lua index d7d0967..7010803 100644 --- a/mario/turtle.lua +++ b/mario/turtle.lua @@ -3,10 +3,10 @@ local ghosts_death_delay = 5  local turtles = { -	{"1","Ferk"}, -	{"2","Don"}, -	{"3","Max"}, -	{"4","Nathan"}, +	{"turtle1","Ferk"}, +	{"turtle2","Don"}, +	{"turtle3","Max"}, +	{"turtle4","Nathan"},  	}  for i in ipairs(turtles) do  	local itm = turtles[i][1] @@ -28,7 +28,7 @@ for i in ipairs(turtles) do  		},  		velocity = {x=math.random(-1,1), y=0, z=math.random(-1,1)}, -		collisionbox = {-0.25, -1.0, -0.25, 0.25, 0.48, 0.25}, +		collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25},  		is_visible = true,  		automatic_rotate = true,  		automatic_face_movement_dir = -90, -- set yaw direction in degrees, false to disable @@ -44,9 +44,9 @@ for i in ipairs(turtles) do  			self.timer = (self.timer or 0) + dtime  			if self.timer < 1 then return end  			self.timer = 0 ---[[ +---[[  			-- Do we have game state? if not just die -			local gamestate = pacmine.games[self.gameid] +			local gamestate = mario.games[self.gameid]  			if not gamestate then  				minetest.log("action", "Removing pacman ghost without game assigned")  				self.object:remove() @@ -90,25 +90,25 @@ for i in ipairs(turtles) do  					-- set the timer negative so it'll have to wait extra time  					self.timer = -ghosts_death_delay  					-- play sound and reward player -					minetest.sound_play("pacmine_eatghost", {pos = boardcenter,max_hear_distance = 6, object=player, loop=false}) -					player:get_inventory():add_item('main', 'pacmine:cherrys') +					minetest.sound_play("mario_eatghost", {pos = boardcenter,max_hear_distance = 6, object=player, loop=false}) +					player:get_inventory():add_item('main', 'mario:cherrys')  				else  					-- Ghost catches the player!  					gamestate.lives = gamestate.lives - 1  					if gamestate.lives < 1 then  						minetest.chat_send_player(gamestate.player_name,"Game Over") -						pacmine.game_end(self.gameid) -						minetest.sound_play("pacmine_death", {pos = boardcenter,max_hear_distance = 20, object=player, loop=false}) +						mario.game_end(self.gameid) +						minetest.sound_play("mario_death", {pos = boardcenter,max_hear_distance = 20, object=player, loop=false})  					elseif gamestate.lives == 1 then  						minetest.chat_send_player(gamestate.player_name,"This is your last life") -						pacmine.game_reset(self.gameid, player) +						mario.game_reset(self.gameid, player)  					else  						minetest.chat_send_player(gamestate.player_name,"You have ".. gamestate.lives .." lives left") -						pacmine.game_reset(self.gameid, player) +						mario.game_reset(self.gameid, player)  					end  				end -				pacmine.update_hud(self.gameid, player) +				mario.update_hud(self.gameid, player)  			else  				local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}  | 
