diff options
author | DonBatman <serfdon@gmail.com> | 2015-10-26 16:33:48 -0700 |
---|---|---|
committer | DonBatman <serfdon@gmail.com> | 2015-10-26 16:33:48 -0700 |
commit | ff0c1eef4b5e4e06b02b164509590c18e7b450b9 (patch) | |
tree | ef0852788832607dab0540a62ae2255b7e4dcf33 /mario/gamestate.lua | |
parent | 551b77b9dc7da84299c39f333314eaa36e699981 (diff) |
added sound files to mario
fixed portal issue
updated schematic
started on turtles and gamestate
Diffstat (limited to 'mario/gamestate.lua')
-rwxr-xr-x | mario/gamestate.lua | 295 |
1 files changed, 295 insertions, 0 deletions
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 +}) |