Merge branch 'master' of https://github.com/DonBatman/myarcade
commit
4a9d35295a
|
@ -0,0 +1,75 @@
|
|||
|
||||
-- Store any information we might need for the games that will use highscore
|
||||
-- (icons, description, or whatever)
|
||||
myhighscore.registered_games = {}
|
||||
|
||||
-- This table will contain a table for each registered game which
|
||||
-- will be an array of player scores
|
||||
myhighscore.scores = {}
|
||||
|
||||
-- How many scores to keep saved per game
|
||||
local stored_scores = 50
|
||||
|
||||
-- Name of the folder to save the scores to
|
||||
-- each game highscore list will be saved in a file inside this directory
|
||||
local score_directory = minetest.get_worldpath().."/myhighscores/"
|
||||
|
||||
-- You can register a new arcade game using this function
|
||||
-- The definition will get added to the table of registered games.
|
||||
function myhighscore.register_game(name, definition)
|
||||
definition.description = definition.description or name
|
||||
myhighscore.registered_games[name] = definition
|
||||
myhighscore.load_scores(name)
|
||||
end
|
||||
|
||||
-- Returns true if score from A is smaller than score from B
|
||||
-- Used for sorting the score arra
|
||||
function myhighscore.is_score_higher(scoreA, scoreB)
|
||||
return scoreA.score > scoreB.score
|
||||
end
|
||||
|
||||
-- Saves a given score for the given game. "score" will be a table containing at least:
|
||||
-- player (player name) and score (points)
|
||||
function myhighscore.save_score(name, score)
|
||||
local scores = myhighscore.scores[name]
|
||||
|
||||
-- Check first if the last score is higher
|
||||
if scores[stored_scores] and
|
||||
myhighscore.is_score_higher(scores[stored_scores], score) then
|
||||
return false
|
||||
end
|
||||
|
||||
table.insert(scores, score)
|
||||
-- sort the array
|
||||
table.sort(scores, myhighscore.is_score_higher)
|
||||
-- check position and remove any extra ones
|
||||
local pos = 0
|
||||
for i,sc in pairs(scores) do
|
||||
if sc == score then
|
||||
pos = i
|
||||
elseif i > stored_scores then
|
||||
scores[i] = nil
|
||||
end
|
||||
end
|
||||
-- save it to disk
|
||||
local f, err = io.open(score_directory .. name, "w")
|
||||
f:write(minetest.serialize(scores))
|
||||
f:close()
|
||||
-- return the position we hold on the list
|
||||
return pos
|
||||
end
|
||||
|
||||
|
||||
-- Read scores from disk for the given game, or initialize the scores table if not present
|
||||
function myhighscore.load_scores(name)
|
||||
local f, err = io.open(score_directory .. name, "r")
|
||||
local data = {}
|
||||
if f then
|
||||
data = minetest.deserialize(f:read("*a")) or {}
|
||||
f:close()
|
||||
end
|
||||
myhighscore.scores[name] = data
|
||||
end
|
||||
|
||||
-- Create the scores directory if it doesn't exist!
|
||||
minetest.mkdir(score_directory)
|
|
@ -1,64 +1,5 @@
|
|||
|
||||
myhighscore = {}
|
||||
|
||||
local button_form = "size[6,8;]"..
|
||||
"background[0,0;6,8;myhighscore_form_bg.png]"..
|
||||
"label[1,0.5;HIGH SCORES]"..
|
||||
"button[1,1;4,1;game;label]"..
|
||||
"button_exit[4,7;1,2;exit;Exit]"
|
||||
|
||||
--place holders
|
||||
local game_name = "the game"
|
||||
local game_player_name = "the player"
|
||||
local game_player_score = "648138"
|
||||
|
||||
local game_form = "size[6,8;]"..
|
||||
"background[0,0;6,8;myhighscore_form_bg.png]"..
|
||||
"label[1,0.5;HIGH SCORES FOR "..game_name.."]"..
|
||||
"label[1,1.5;PLAYER]"..
|
||||
"label[3.5,1.5;SCORE]"..
|
||||
"label[0.5,2;"..game_player_name.."]"..
|
||||
"label[3,2;"..game_player_score.."]"..
|
||||
"button[2,7;1,2;back;Back]"..
|
||||
"button_exit[4,7;1,2;exit;Exit]"
|
||||
|
||||
minetest.register_node("myhighscore:score_board", {
|
||||
description = "Score Board",
|
||||
tiles = {
|
||||
"myhighscore_top.png",
|
||||
"myhighscore_back.png",
|
||||
"myhighscore_side.png^[transformFX",
|
||||
"myhighscore_side.png",
|
||||
"myhighscore_back.png",
|
||||
"myhighscore_front.png",
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky = 1},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.375, -0.5, -0.5, 0.375, -0.1875, 0.5},
|
||||
{-0.375, -0.5, 0.1875, 0.375, 0.5, 0.5},
|
||||
{-0.1875, -0.5, -0.3125, -0.125, 0, -0.25},
|
||||
{-0.375, -0.5, 0, -0.3125, 0.5, 0.5},
|
||||
{0.3125, -0.5, 0, 0.375, 0.5, 0.5},
|
||||
{-0.375, 0.4375, 0, 0.375, 0.5, 0.5},
|
||||
}
|
||||
},
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", button_form)
|
||||
meta:set_string("infotext", "High Scores")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
if fields['game'] then
|
||||
meta:set_string('formspec', game_form)
|
||||
elseif fields["back"] then
|
||||
meta:set_string('formspec', button_form)
|
||||
end
|
||||
end,
|
||||
|
||||
})
|
||||
dofile(minetest.get_modpath("myhighscore").."/api.lua")
|
||||
dofile(minetest.get_modpath("myhighscore").."/scoreboard.lua")
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
|
||||
|
||||
|
||||
local button_form = "size[6,8;]"..
|
||||
"background[0,0;6,8;myhighscore_form_bg.png]"..
|
||||
"label[1,0.5;HIGH SCORES]"..
|
||||
"button[1,1;4,1;game;label]"..
|
||||
"button_exit[4,7;1,2;exit;Exit]"
|
||||
|
||||
--place holders
|
||||
local game_name = "the game"
|
||||
local game_player_name = "the player"
|
||||
local game_player_score = "648138"
|
||||
|
||||
local function get_formspec_for_game(name)
|
||||
local def = myhighscore.registered_games[name]
|
||||
local scores = myhighscore.scores[name] or {}
|
||||
-- Obtain a comma separated list of scores to display
|
||||
local scorelist = ""
|
||||
for _,score in pairs(scores) do
|
||||
scorelist = scorelist .. minetest.formspec_escape(score.player) ..
|
||||
"\t\t\t\t " .. score.score ..","
|
||||
end
|
||||
|
||||
return "size[6,8;]"..
|
||||
"background[0,0;6,8;myhighscore_form_bg.png]"..
|
||||
"label[1,0.5;HIGH SCORES FOR "..def.description.."]"..
|
||||
"label[1,1.5;PLAYER]"..
|
||||
"label[3.5,1.5;SCORE]"..
|
||||
"textlist[0.5,2;5,5;;"..scorelist.."]"..
|
||||
"button[2,7;1,2;back;Back]"..
|
||||
"button_exit[4,7;1,2;exit;Exit]"
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("myhighscore:score_board", {
|
||||
description = "Score Board",
|
||||
tiles = {
|
||||
"myhighscore_top.png",
|
||||
"myhighscore_back.png",
|
||||
"myhighscore_side.png^[transformFX",
|
||||
"myhighscore_side.png",
|
||||
"myhighscore_back.png",
|
||||
"myhighscore_front.png",
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky = 1},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.375, -0.5, -0.5, 0.375, -0.1875, 0.5},
|
||||
{-0.375, -0.5, 0.1875, 0.375, 0.5, 0.5},
|
||||
{-0.1875, -0.5, -0.3125, -0.125, 0, -0.25},
|
||||
{-0.375, -0.5, 0, -0.3125, 0.5, 0.5},
|
||||
{0.3125, -0.5, 0, 0.375, 0.5, 0.5},
|
||||
{-0.375, 0.4375, 0, 0.375, 0.5, 0.5},
|
||||
}
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
meta:set_string("formspec", button_form)
|
||||
meta:set_string("infotext", "High Scores")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local meta = minetest.env:get_meta(pos)
|
||||
if fields['game'] then
|
||||
meta:set_string('formspec', get_formspec_for_game("pacmine"))
|
||||
elseif fields["back"] then
|
||||
meta:set_string('formspec', button_form)
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
myhighscore
|
|
@ -18,17 +18,19 @@ local score_for_life_award = 5000
|
|||
function pacmine.game_start(pos, player)
|
||||
-- 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 = pacmine.games[id]
|
||||
if gamestate then
|
||||
pacmine.game_end(id)
|
||||
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
|
||||
gamestate = {
|
||||
id = id,
|
||||
player_name = player:get_player_name(),
|
||||
player_name = player_name,
|
||||
pos = pos,
|
||||
start = {x=pos.x+14,y=pos.y+0.5,z=pos.z+16},
|
||||
pellet_count = 0,
|
||||
|
@ -56,7 +58,20 @@ end
|
|||
-- Finish the game with the given id
|
||||
function pacmine.game_end(id)
|
||||
pacmine.remove_ghosts(id)
|
||||
pacmine.remove_hud(pacmine.players[id], pacmine.games[id].player_name)
|
||||
local gamestate = pacmine.games[id]
|
||||
local player = pacmine.players[id] or minetest.get_player_by_name(gamestate.player_name)
|
||||
if player then
|
||||
pacmine.remove_hud(player, gamestate.player_name)
|
||||
player:moveto(vector.add(gamestate.pos,{x=0.5,y=0.5,z=-1.5}))
|
||||
end
|
||||
-- Save score
|
||||
local ranking = myhighscore.save_score("pacmine", {
|
||||
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
|
||||
-- Clear the data
|
||||
pacmine.games[id] = nil
|
||||
pacmine.players[id] = nil
|
||||
|
@ -122,10 +137,12 @@ function pacmine.remove_ghosts(id)
|
|||
end
|
||||
end
|
||||
|
||||
-- Add a fruit to the game board
|
||||
function pacmine.add_fruit(id)
|
||||
local gamestate = pacmine.games[id]
|
||||
if not gamestate then return end
|
||||
local node = {}
|
||||
-- Different fruit will be used depending on the level
|
||||
if gamestate.level == 1 then
|
||||
node.name = "pacmine:cherrys"
|
||||
elseif gamestate.level == 2 then
|
||||
|
@ -137,6 +154,7 @@ function pacmine.add_fruit(id)
|
|||
end
|
||||
local pos = vector.add(gamestate.start,{x=0,y=-1,z=0})
|
||||
minetest.set_node(pos, node)
|
||||
-- Set the timer for the fruit to disappear
|
||||
minetest.get_node_timer(pos):start(math.random(20, 30))
|
||||
end
|
||||
|
||||
|
@ -149,6 +167,7 @@ function pacmine.on_player_got_pellet(player)
|
|||
gamestate.pellet_count = gamestate.pellet_count + 1
|
||||
gamestate.score = gamestate.score + 10
|
||||
pacmine.update_hud(gamestate.id, player)
|
||||
minetest.sound_play("pacmine_chomp", {object = player, max_hear_distance = 6})
|
||||
|
||||
if gamestate.pellet_count == 70 or gamestate.pellet_count == 180 then
|
||||
pacmine.add_fruit(gamestate.id)
|
||||
|
@ -200,7 +219,6 @@ function pacmine.on_player_got_power_pellet(player)
|
|||
minetest.chat_send_player(name, "POWER PELLET wore off")
|
||||
end
|
||||
end)
|
||||
minetest.sound_play("pacmine_eatfruit", {pos = pos, max_hear_distance = 6})
|
||||
end
|
||||
|
||||
-- A player got a fruit, update the state
|
||||
|
@ -225,26 +243,6 @@ end
|
|||
---------------------------------------------------------
|
||||
--- Private functions (only can be used inside this file)
|
||||
|
||||
-- Save Table
|
||||
local function gamestate_save()
|
||||
local data = pacmine.games
|
||||
local f, err = io.open(minetest.get_worldpath().."/pacmine_data", "w")
|
||||
if err then return err end
|
||||
f:write(minetest.serialize(data))
|
||||
f:close()
|
||||
end
|
||||
|
||||
--Read Table
|
||||
local function gamestate_load()
|
||||
local f, err = io.open(minetest.get_worldpath().."/pacmine_data", "r")
|
||||
if f then
|
||||
local data = minetest.deserialize(f:read("*a"))
|
||||
f:close()
|
||||
return data
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Called every 0.5 seconds for each player that is currently playing
|
||||
local function on_player_gamestep(player, gameid)
|
||||
|
@ -281,47 +279,35 @@ end
|
|||
-------------------
|
||||
--- Execution code
|
||||
|
||||
-- load the gamestate from disk
|
||||
pacmine.games = gamestate_load() or {}
|
||||
|
||||
-- Time counters
|
||||
local tmr_gamestep = 0
|
||||
local tmr_savestep = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
tmr_gamestep = tmr_gamestep + dtime;
|
||||
if tmr_gamestep > 0.2 then
|
||||
for id,player in pairs(pacmine.players) do
|
||||
on_player_gamestep(player, id)
|
||||
end
|
||||
tmr_savestep = tmr_savestep + tmr_gamestep
|
||||
if tmr_savestep > 10 then
|
||||
gamestate_save()
|
||||
tmr_savestep = 0
|
||||
end
|
||||
tmr_gamestep = 0
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
for id,game in pairs(pacmine.games) do
|
||||
if game.player_name == name then
|
||||
pacmine.players[id] = player
|
||||
pacmine.update_hud(id, player)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
for id,game in pairs(pacmine.games) do
|
||||
if game.player_name == name then
|
||||
pacmine.players[id] = nil
|
||||
pacmine.remove_hud(player, name)
|
||||
pacmine.game_end(id)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
minetest.log("action", "Server shuts down. Ending all pacmine games")
|
||||
for id,game in pairs(pacmine.games) do
|
||||
pacmine.game_end(id)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Chatcommand to end the game for the current player
|
||||
minetest.register_chatcommand("pacmine_exit", {
|
||||
params = "",
|
||||
|
@ -330,7 +316,6 @@ minetest.register_chatcommand("pacmine_exit", {
|
|||
local gamestate = pacmine.get_game_by_player(name)
|
||||
if gamestate then
|
||||
pacmine.game_end(gamestate.id)
|
||||
minetest.get_player_by_name(name):moveto(vector.add(gamestate.pos,{x=0.5,y=0.5,z=-1.5}))
|
||||
minetest.chat_send_player(name, "You are no longer playing pacmine")
|
||||
else
|
||||
minetest.chat_send_player(name, "You are not currently in a pacmine game")
|
||||
|
@ -338,7 +323,8 @@ minetest.register_chatcommand("pacmine_exit", {
|
|||
end
|
||||
})
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
minetest.log("action", "Server shuts down. Saving pacmine data")
|
||||
gamestate_save()
|
||||
end)
|
||||
-- Register with the myhighscore mod
|
||||
myhighscore.register_game("pacmine", {
|
||||
description = "Pacmine",
|
||||
icon = "pacmine_1.png",
|
||||
})
|
||||
|
|
|
@ -97,7 +97,6 @@ for i in ipairs(ghosts) do
|
|||
gamestate.lives = gamestate.lives - 1
|
||||
if gamestate.lives < 1 then
|
||||
minetest.chat_send_player(gamestate.player_name,"Game Over")
|
||||
player:moveto(vector.add(gamestate.pos,{x=0.5,y=0.5,z=-1.5}))
|
||||
pacmine.game_end(self.gameid)
|
||||
minetest.sound_play("pacmine_death", {pos = boardcenter,max_hear_distance = 20, object=player, loop=false})
|
||||
|
||||
|
|
|
@ -22,23 +22,13 @@ minetest.register_node("pacmine:pellet_1", {
|
|||
walkable = false,
|
||||
light_source = 11,
|
||||
drop = "",
|
||||
groups = {dig_immediate = 3, not_in_creative_inventory = 0},
|
||||
groups = {immortal = 1, not_in_creative_inventory = 1},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.625, 0.25, -0.125, -0.375, 0.5, 0.125},
|
||||
}
|
||||
},
|
||||
on_destruct = function(pos)
|
||||
minetest.sound_play("pacmine_chomp", {
|
||||
pos = pos,
|
||||
max_hear_distance = 100,
|
||||
gain = 10.0,
|
||||
})
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
pacmine.on_player_got_pellet(digger)
|
||||
end,
|
||||
})
|
||||
|
||||
--Power Pellets. Need to make these do something
|
||||
|
@ -56,7 +46,7 @@ minetest.register_node("pacmine:pellet_2", {
|
|||
{items = {"pacmine:peach"},rarity = 4,},
|
||||
{items = {"pacmine:strawberry"},rarity = 4,},},
|
||||
},
|
||||
groups = {dig_immediate = 3, not_in_creative_inventory = 0},
|
||||
groups = {immortal = 1, not_in_creative_inventory = 1},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
|
@ -66,15 +56,6 @@ minetest.register_node("pacmine:pellet_2", {
|
|||
{-0.6875, -0.1875, -0.1875, -0.3125, 0.1875, 0.1875},
|
||||
}
|
||||
},
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
pacmine.on_player_got_power_pellet(digger)
|
||||
|
||||
minetest.sound_play("pacmine_eatfruit", {
|
||||
pos = pos,
|
||||
max_hear_distance = 100,
|
||||
gain = 10.0,
|
||||
})
|
||||
end,
|
||||
})
|
||||
|
||||
--The placer block
|
||||
|
|
Loading…
Reference in New Issue