summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmyhighscore/api.lua75
-rw-r--r--myhighscore/init.lua65
-rwxr-xr-xmyhighscore/scoreboard.lua75
-rwxr-xr-xpacmine/depends.txt1
-rwxr-xr-xpacmine/gamestate.lua78
-rw-r--r--pacmine/ghost.lua1
-rw-r--r--pacmine/init.lua23
7 files changed, 188 insertions, 130 deletions
diff --git a/myhighscore/api.lua b/myhighscore/api.lua
new file mode 100755
index 0000000..f1e84f8
--- /dev/null
+++ b/myhighscore/api.lua
@@ -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)
diff --git a/myhighscore/init.lua b/myhighscore/init.lua
index 0eab03c..854be70 100644
--- a/myhighscore/init.lua
+++ b/myhighscore/init.lua
@@ -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")
diff --git a/myhighscore/scoreboard.lua b/myhighscore/scoreboard.lua
new file mode 100755
index 0000000..38e659e
--- /dev/null
+++ b/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,
+})
diff --git a/pacmine/depends.txt b/pacmine/depends.txt
new file mode 100755
index 0000000..01e0fb0
--- /dev/null
+++ b/pacmine/depends.txt
@@ -0,0 +1 @@
+myhighscore
diff --git a/pacmine/gamestate.lua b/pacmine/gamestate.lua
index 53e2985..7bbc0af 100755
--- a/pacmine/gamestate.lua
+++ b/pacmine/gamestate.lua
@@ -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,44 +279,32 @@ 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)
+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] = player
- pacmine.update_hud(id, player)
+ pacmine.game_end(id)
end
end
end)
-minetest.register_on_leaveplayer(function(player)
- local name = player:get_player_name()
+minetest.register_on_shutdown(function()
+ minetest.log("action", "Server shuts down. Ending all pacmine games")
for id,game in pairs(pacmine.games) do
- if game.player_name == name then
- pacmine.players[id] = nil
- pacmine.remove_hud(player, name)
- end
+ pacmine.game_end(id)
end
end)
@@ -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",
+})
diff --git a/pacmine/ghost.lua b/pacmine/ghost.lua
index 7c7c374..adc106d 100644
--- a/pacmine/ghost.lua
+++ b/pacmine/ghost.lua
@@ -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})
diff --git a/pacmine/init.lua b/pacmine/init.lua
index 4d4db2a..e9e37dc 100644
--- a/pacmine/init.lua
+++ b/pacmine/init.lua
@@ -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