summaryrefslogtreecommitdiff
path: root/pacmine
diff options
context:
space:
mode:
Diffstat (limited to 'pacmine')
-rw-r--r--pacmine/blocks.lua76
-rw-r--r--pacmine/craftitems.lua97
-rwxr-xr-xpacmine/gamestate.lua296
-rw-r--r--pacmine/ghost.lua147
-rwxr-xr-xpacmine/hud.lua43
-rw-r--r--pacmine/init.lua102
-rw-r--r--pacmine/portals.lua73
-rw-r--r--pacmine/schems/pacmine_3.mtsbin0 -> 1156 bytes
-rw-r--r--pacmine/sounds/pacmine_beginning.oggbin0 -> 17153 bytes
-rw-r--r--pacmine/sounds/pacmine_chomp.oggbin0 -> 7014 bytes
-rw-r--r--pacmine/sounds/pacmine_death.oggbin0 -> 7619 bytes
-rw-r--r--pacmine/sounds/pacmine_eatfruit.oggbin0 -> 4343 bytes
-rw-r--r--pacmine/sounds/pacmine_eatghost.oggbin0 -> 4687 bytes
-rw-r--r--pacmine/sounds/pacmine_extrapac.oggbin0 -> 7594 bytes
-rw-r--r--pacmine/sounds/pacmine_powerup.oggbin0 -> 20591 bytes
-rw-r--r--pacmine/textures/pacmine_1.pngbin0 -> 473 bytes
-rw-r--r--pacmine/textures/pacmine_apple.pngbin0 -> 313 bytes
-rw-r--r--pacmine/textures/pacmine_blinkyf.pngbin0 -> 155 bytes
-rw-r--r--pacmine/textures/pacmine_blinkys.pngbin0 -> 126 bytes
-rw-r--r--pacmine/textures/pacmine_cherrys.pngbin0 -> 296 bytes
-rw-r--r--pacmine/textures/pacmine_clydef.pngbin0 -> 157 bytes
-rw-r--r--pacmine/textures/pacmine_clydes.pngbin0 -> 126 bytes
-rw-r--r--pacmine/textures/pacmine_door.pngbin0 -> 126 bytes
-rw-r--r--pacmine/textures/pacmine_egg.pngbin0 -> 198 bytes
-rw-r--r--pacmine/textures/pacmine_floor.pngbin0 -> 556 bytes
-rw-r--r--pacmine/textures/pacmine_glass.pngbin0 -> 431 bytes
-rw-r--r--pacmine/textures/pacmine_inkyf.pngbin0 -> 158 bytes
-rw-r--r--pacmine/textures/pacmine_inkys.pngbin0 -> 126 bytes
-rw-r--r--pacmine/textures/pacmine_inv.pngbin0 -> 274 bytes
-rw-r--r--pacmine/textures/pacmine_orange.pngbin0 -> 377 bytes
-rw-r--r--pacmine/textures/pacmine_pinkyf.pngbin0 -> 158 bytes
-rw-r--r--pacmine/textures/pacmine_pinkys.pngbin0 -> 127 bytes
-rw-r--r--pacmine/textures/pacmine_portal.pngbin0 -> 450 bytes
-rw-r--r--pacmine/textures/pacmine_strawberry.pngbin0 -> 386 bytes
-rw-r--r--pacmine/textures/pacmine_wall.pngbin0 -> 498 bytes
-rw-r--r--pacmine/textures/pacmine_wallc.pngbin0 -> 500 bytes
-rw-r--r--pacmine/textures/pacmine_walle.pngbin0 -> 465 bytes
-rw-r--r--pacmine/textures/pacmine_walls.pngbin0 -> 467 bytes
38 files changed, 834 insertions, 0 deletions
diff --git a/pacmine/blocks.lua b/pacmine/blocks.lua
new file mode 100644
index 0000000..79ca2dc
--- /dev/null
+++ b/pacmine/blocks.lua
@@ -0,0 +1,76 @@
+local sbox = {
+ type = "fixed",
+ fixed = {
+ {-0.5, -0.5, -0.0625, 0.5, 0.5, 0.0625}
+ }
+ }
+local cbox = {
+ type = "fixed",
+ fixed = {
+ {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
+ }
+ }
+local blocks = {
+{"Floor", "floor", "floor","floor",0,true},
+{"Wall", "wall", "wall","floor",11,true},
+{"Wallc", "wallc", "wallc","floor",11,true},
+{"Walle", "walle", "walle","floor",11,true},
+{"Wall Walkthrough","walk_wall","wall","floor",11,false},
+}
+for i in ipairs(blocks) do
+local des = blocks[i][1]
+local itm = blocks[i][2]
+local i1 = blocks[i][3]
+local i2 = blocks[i][4]
+local lit = blocks[i][5]
+local tf = blocks[i][6]
+
+minetest.register_alias("mypacman:"..itm, "pacmine:"..itm)
+
+minetest.register_node("pacmine:"..itm, {
+ description = des,
+ tiles = {
+ "pacmine_"..i1..".png",
+ "pacmine_"..i2..".png",
+ "pacmine_walls.png",
+ "pacmine_walls.png",
+ "pacmine_walls.png",
+ "pacmine_walls.png",
+ },
+ drawtype = "normal",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ light_source = lit,
+ walkable = tf,
+ groups = {disable_jump = 1, immortal=1, not_in_creative_inventory = 1},
+ selection_box = sbox,
+ collision_box = cbox,
+
+})
+end
+--Glass
+minetest.register_alias("mypacman:glass", "pacmine:glass")
+minetest.register_node("pacmine:glass", {
+ description = "glass",
+ tiles = {"pacmine_glass.png"},
+ drawtype = "glasslike",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ groups = {immortal=1,not_in_creative_inventory = 1},
+ selection_box = cbox,
+ collision_box = cbox,
+
+})
+minetest.register_alias("mypacman:glassw", "pacmine:glassw")
+minetest.register_node("pacmine:glassw", {
+ description = "glassw",
+ tiles = {"pacmine_glass.png"},
+ drawtype = "glasslike",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ walkable = false,
+ groups = {immortal=1,not_in_creative_inventory = 1},
+ selection_box = cbox,
+ colision_box = cbox,
+
+})
diff --git a/pacmine/craftitems.lua b/pacmine/craftitems.lua
new file mode 100644
index 0000000..cab05f0
--- /dev/null
+++ b/pacmine/craftitems.lua
@@ -0,0 +1,97 @@
+local cherry_box = {
+ type = "fixed",
+ fixed = {
+ {0, -0.375, -0.0625, 0.25, 0, 0.0625},
+ {-0.0625, -0.3125, -0.0625, 0.3125, -0.0625, 0.0625},
+ {-0.3125, -0.25, -0.0625, -0.125, 0.125, 0.0625},
+ {-0.375, -0.1875, -0.0625, -0.125, 0.0625, 0.0625},
+ {-0.125, -0.0625, -0.0625, -0.0625, 0.125, 0.0625},
+ {-0.0625, 0, -0.0625, 0, 0.0625, 0.0625},
+ {-0.0625, 0.125, -0.0625, 0, 0.1875, 0.0625},
+ {0, 0.1875, -0.0625, 0.125, 0.25, 0.0625},
+ {0.125, 0.25, -0.0625, 0.375, 0.3125, 0.0625},
+ {0.25, 0.3125, -0.0625, 0.375, 0.375, 0.0625},
+ {0.1875, 0.125, -0.0625, 0.25, 0.25, 0.0625},
+ {0.125, 0.0625, -0.0625, 0.1875, 0.125, 0.0625},
+ {0.0625, 0, -0.0625, 0.125, 0.0625, 0.0625},
+ }
+ }
+local strawberry_box = {
+ type = "fixed",
+ fixed = {
+ {-0.0625, 0.3125, -0.0625, 0, 0.375, 0.0625},
+ {-0.25, 0.25, -0.0625, 0.1875, 0.3125, 0.0625},
+ {-0.3125, 0.1875, -0.0625, 0.25, 0.25, 0.0625},
+ {-0.375, -0.0625, -0.0625, 0.3125, 0.1875, 0.0625},
+ {-0.3125, -0.1875, -0.0625, 0.25, -0.0625, 0.0625},
+ {-0.25, -0.25, -0.0625, 0.1875, -0.1875, 0.0625},
+ {-0.1875, -0.3125, -0.0625, 0.125, -0.25, 0.0625},
+ {-0.0625, -0.375, -0.0625, 0, -0.3125, 0.0625},
+ }
+ }
+local apple_box = {
+ type = "fixed",
+ fixed = {
+ {-0.3125, -0.125, -0.0625, 0.375, 0.25, 0.0625},
+ {-0.375, -0.125, -0.0625, -0.3125, 0.1875, 0.0625},
+ {-0.3125, -0.25, -0.0625, 0.3125, -0.125, 0.0625},
+ {-0.25, -0.3125, -0.0625, 0.25, -0.25, 0.0625},
+ {0.0625, -0.375, -0.0625, 0.1875, -0.3125, 0.0625},
+ {-0.1875, -0.375, -0.0625, 0, -0.3125, 0.0625},
+ {0.125, 0.25, -0.0625, 0.3125, 0.3125, 0.0625},
+ {0, 0.25, -0.0625, 0.0625, 0.3125, 0.0625},
+ {-0.25, 0.25, -0.0625, -0.0625, 0.3125, 0.0625},
+ {-0.0625, 0.3125, -0.0625, 0, 0.375, 0.0625},
+ }
+ }
+local orange_box = {
+ type = "fixed",
+ fixed = {
+ {-0.375, -0.125, -0.0625, 0.375, 0.125, 0.0625},
+ {-0.3125, -0.25, -0.0625, 0.3125, 0.1875, 0.0625},
+ {-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.0625},
+ {0.0625, -0.375, -0.0625, 0.1875, -0.3125, 0.0625},
+ {-0.1875, -0.375, -0.0625, 0, -0.3125, 0.0625},
+ {0, 0.25, -0.0625, 0.0625, 0.375, 0.0625},
+ {-0.25, 0.3125, -0.0625, 0.0625, 0.375, 0.0625},
+ {-0.1875, 0.25, -0.0625, -0.0625, 0.4375, 0.0625},
+ {-0.25, 0.25, -0.0625, -0.1875, 0.3125, 0.0625},
+ }
+ }
+
+local pelletitems = {
+ {"cherrys", "Cherrys","2",cherry_box},
+ {"apple", "Apple","3",apple_box},
+ {"orange", "Orange","4",orange_box},
+ {"strawberry", "Strawberry","2",strawberry_box},
+ }
+for i in ipairs (pelletitems) do
+ local itm = pelletitems[i][1]
+ local desc = pelletitems[i][2]
+ local hlth = pelletitems[i][3]
+ local cbox = pelletitems[i][4]
+
+minetest.register_node("pacmine:"..itm,{
+ description = desc,
+ inventory_image = "pacmine_"..itm..".png",
+ tiles = {
+ "pacmine_"..itm..".png",
+ "pacmine_"..itm..".png",
+ "pacmine_"..itm..".png",
+ "pacmine_"..itm..".png",
+ "pacmine_"..itm..".png",
+ "pacmine_"..itm..".png^[transformFX",
+ },
+ drawtype = "nodebox",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ walkable = false,
+ light_source = 14,
+ groups = {cracky=3,not_in_creative_inventory = 0},
+ node_box = cbox,
+ collision_box = cbox,
+ after_destruct = function(pos, oldnode)
+ pacmine.on_player_got_fruit()
+ end,
+})
+end
diff --git a/pacmine/gamestate.lua b/pacmine/gamestate.lua
new file mode 100755
index 0000000..76c8994
--- /dev/null
+++ b/pacmine/gamestate.lua
@@ -0,0 +1,296 @@
+
+-- Array to hold all the running game states
+pacmine.games = {}
+
+-- Store all the currently playing players
+pacmine.players = {}
+
+-- Duration of the power pellet effect (in seconds)
+local power_pellet_duration = 10
+
+---------------------------------------------------------
+-- Public functions (these can be called from any other place)
+
+-- Start the game from the spawn block at position "pos" activated by "player"
+function pacmine.game_start(pos, player)
+ -- create an id unique for the given position
+ local id = minetest.pos_to_string(pos)
+
+ -- make sure any previous game with the same id has ended
+ if pacmine.games[id] then
+ pacmine.game_end(id)
+ end
+
+ -- Create a new game state with that id and add it to the game list
+ local gamestate = {
+ id = id,
+ player_name = player:get_player_name(),
+ pos = pos,
+ start = {x=pos.x+14,y=pos.y+0.5,z=pos.z+16},
+ pellet_count = 0,
+ level = 1,
+ speed = 2,
+ lives = 3,
+ score = 0,
+ }
+ pacmine.games[id] = gamestate
+ pacmine.players[id] = player
+
+ minetest.log("action","New pacman game started at " .. id .. " by " .. gamestate.player_name)
+
+ -- place schematic
+ local schem = minetest.get_modpath("pacmine").."/schems/pacmine_3.mts"
+ minetest.place_schematic({x=pos.x,y=pos.y-1,z=pos.z-2},schem,0, "air", true)
+
+ -- Set start positions
+ pacmine.game_reset(id, player)
+ pacmine.update_hud(id, player)
+ minetest.sound_play("pacmine_beginning", {pos = pos,max_hear_distance = 40,gain = 10.0,})
+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)
+ -- Clear the data
+ pacmine.games[id] = nil
+ pacmine.players[id] = nil
+end
+
+-- Resets the game to the start positions
+function pacmine.game_reset(id, player)
+ local gamestate = pacmine.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.power_pellet = false
+ gamestate.last_reset = last_reset
+
+ -- Position the player
+ local player = player or minetest.get_player_by_name(gamestate.player_name)
+ player:setpos(gamestate.start)
+
+ -- Spawn the ghosts and assign the game id to each ghost
+ minetest.after(2, function()
+ if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then
+ local pos = vector.add(gamestate.pos, {x=13,y=0.5,z=19})
+ local ghost = minetest.add_entity(pos, "pacmine:inky")
+ ghost:get_luaentity().gameid = id
+ end
+ end)
+ minetest.after(12, function()
+ if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then
+ local pos = vector.add(gamestate.pos, {x=15,y=0.5,z=19})
+ local ghost = minetest.add_entity(pos, "pacmine:pinky")
+ ghost:get_luaentity().gameid = id
+ end
+ end)
+ minetest.after(22, function()
+ if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then
+ local pos = vector.add(gamestate.pos, {x=13,y=0.5,z=18})
+ local ghost = minetest.add_entity(pos, "pacmine:blinky")
+ ghost:get_luaentity().gameid = id
+ end
+ end)
+ minetest.after(32, function()
+ if pacmine.games[id] and last_reset == pacmine.games[id].last_reset then
+ local pos = vector.add(gamestate.pos, {x=15,y=0.5,z=18})
+ local ghost = minetest.add_entity(pos, "pacmine:clyde")
+ ghost:get_luaentity().gameid = id
+ end
+ end)
+end
+
+-- Remove all the ghosts from the board with the given id
+function pacmine.remove_ghosts(id)
+ local gamestate = pacmine.games[id]
+ if not gamestate then return end
+
+ -- Remove all non-players (ghosts!)
+ 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
+
+-- A player got a pellet, update the state
+function pacmine.on_player_got_pellet(player)
+ local name = player:get_player_name()
+ local gamestate = pacmine.get_game_by_player(name)
+ if not gamestate then return end
+
+ gamestate.pellet_count = gamestate.pellet_count + 1
+ gamestate.score = gamestate.score + 10
+ pacmine.update_hud(gamestate.id, player)
+
+ if gamestate.pellet_count >= 252 then -- 252
+ minetest.chat_send_player(name, "You cleared the board!")
+
+ pacmine.remove_ghosts(gamestate.id)
+ gamestate.pellet_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("pacmine").."/schems/pacmine_3.mts"
+ minetest.place_schematic(vector.add(gamestate.pos, {x=0,y=-1,z=-2}),schem,0, "air", true)
+
+ -- Set start positions
+ pacmine.game_reset(gamestate.id, player)
+ minetest.sound_play("pacmine_beginning", {pos = pos,max_hear_distance = 40,gain = 10.0,})
+ end)
+ end
+end
+
+-- A player got a power pellet, update the state
+function pacmine.on_player_got_power_pellet(player)
+ local name = player:get_player_name()
+ local gamestate = pacmine.get_game_by_player(name)
+ if not gamestate then return end
+
+ minetest.chat_send_player(name, "You got a POWER PELLET")
+ gamestate.power_pellet = os.time() + power_pellet_duration
+ gamestate.score = gamestate.score + 50
+ pacmine.update_hud(gamestate.id, player)
+
+ local boardcenter = vector.add(gamestate.pos, {x=13,y=0.5,z=15})
+ local powersound = minetest.sound_play("pacmine_powerup", {pos = boardcenter,max_hear_distance = 20, object=player, loop=true})
+
+ minetest.after(power_pellet_duration, function()
+ minetest.sound_stop(powersound)
+ if os.time() >= (gamestate.power_pellet or 0) then
+ gamestate.power_pellet = false
+ minetest.chat_send_player(name, "POWER PELLET wore off")
+ end
+ end)
+end
+
+-- Get the game that the given player is playing
+function pacmine.get_game_by_player(player_name)
+ for _,gamestate in pairs(pacmine.games) do
+ if gamestate.player_name == player_name then
+ return gamestate
+ end
+ end
+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 pacman
+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 == "pacmine:pellet_1" then
+ minetest.remove_node(pos)
+ pacmine.on_player_got_pellet(player)
+ elseif node.name == "pacmine:pellet_2" then
+ minetest.remove_node(pos)
+ pacmine.on_player_got_power_pellet(player)
+
+ minetest.sound_play("pacmine_eatfruit", {
+ pos = pos,
+ max_hear_distance = 100,
+ gain = 10.0,
+ })
+ end
+ end
+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)
+ end
+ end
+end)
+
+-- Chatcommand to end the game for the current player
+minetest.register_chatcommand("pacmine_exit", {
+ params = "",
+ description = "Loads and saves all rooms",
+ func = function(name, param)
+ 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 pacman")
+ else
+ minetest.chat_send_player(name, "You are not currently in a pacman game")
+ end
+ end
+})
+
+minetest.register_on_shutdown(function()
+ minetest.log("action", "Server shuts down. Saving pacman data")
+ gamestate_save()
+end)
diff --git a/pacmine/ghost.lua b/pacmine/ghost.lua
new file mode 100644
index 0000000..7c7c374
--- /dev/null
+++ b/pacmine/ghost.lua
@@ -0,0 +1,147 @@
+
+local ghosts_death_delay = 5
+
+
+local ghosts = {
+ {"pinky","Pinky"},
+ {"inky","Inky"},
+ {"blinky","Blinky"},
+ {"clyde","Clyde"},
+ }
+for i in ipairs(ghosts) do
+ local itm = ghosts[i][1]
+ local desc = ghosts[i][2]
+
+ minetest.register_entity("pacmine:"..itm, {
+ hp_max = 1,
+ physical = true,
+ collide_with_objects = true,
+ visual = "cube",
+ visual_size = {x = 0.6, y = 1},
+ textures = {
+ "pacmine_"..itm.."s.png",
+ "pacmine_"..itm.."s.png",
+ "pacmine_"..itm.."s.png",
+ "pacmine_"..itm.."s.png",
+ "pacmine_"..itm.."f.png",
+ "pacmine_"..itm.."s.png",
+ },
+ 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},
+ is_visible = true,
+ automatic_rotate = true,
+ automatic_face_movement_dir = -90, -- set yaw direction in degrees, false to disable
+ makes_footstep_sound = false,
+
+ set_velocity = function(self, v)
+ if not v then v = 0 end
+ local yaw = self.object:getyaw()
+ self.object:setvelocity({x=math.sin(yaw) * -v, y=self.object:getvelocity().y, z=math.cos(yaw) * v})
+ end,
+
+ on_step = function(self, dtime)
+ -- every 1 second
+ 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]
+ if not gamestate then
+ minetest.log("action", "Removing pacman ghost without game assigned")
+ self.object:remove()
+ return
+ end
+ -- Make sure we are in the right state by keeping track of the reset time
+ -- if the reset time changed it's likely the game got resetted while the entity wasn't loaded
+ if self.last_reset then
+ if self.last_reset ~= gamestate.last_reset then
+ minetest.log("action", "Removing pacman ghost remaining after reset ")
+ self.object:remove()
+ end
+ else
+ self.last_reset = gamestate.last_reset
+ end
+
+ -- Make sure we have a targetted player
+ if not self.target then
+ self.target = minetest.get_player_by_name(gamestate.player_name)
+ end
+ local player = self.target
+
+ -- If there's no player just stop
+ if not player then
+ self.set_velocity(self, 0)
+ return
+ end
+
+ local s = self.object:getpos() -- ghost
+ local p = player:getpos() -- player
+
+ -- find distance from ghost to player
+ local distance = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
+ if distance < 1.5 then
+ -- player touches ghost!!
+
+ if gamestate.power_pellet then
+ -- Player eats ghost! move it to spawn
+ local ghost_spawn = vector.add(gamestate.pos, {x=13,y=0.5,z=19})
+ self.object:setpos(ghost_spawn)
+ -- 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')
+ else
+ -- Ghost catches the player!
+ 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})
+
+ elseif gamestate.lives == 1 then
+ minetest.chat_send_player(gamestate.player_name,"This is your last life")
+ pacmine.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)
+ end
+ end
+ pacmine.update_hud(self.gameid, player)
+
+ else
+ local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z}
+ local yaw = (math.atan(vec.z/vec.x)+math.pi/2)
+ if p.x > s.x then
+ yaw = yaw + math.pi
+ end
+ -- face player and move backwards/forwards
+ self.object:setyaw(yaw)
+ if gamestate.power_pellet then
+ self.set_velocity(self, -gamestate.speed) --negative velocity
+ else
+ self.set_velocity(self, gamestate.speed)
+ end
+ end
+ end,
+
+ -- This function should return the saved state of the entity in a string
+ get_staticdata = function(self)
+ return (self.gameid or "") .. ";" .. (self.last_reset or "")
+ end,
+
+ -- This function should load the saved state of the entity from a string
+ on_activate = function(self, staticdata)
+ self.object:set_armor_groups({immortal=1})
+ if staticdata and staticdata ~= "" then
+ local data = string.split(staticdata, ";")
+ if #data == 2 then
+ self.gameid = data[1]
+ self.last_reset = tonumber(data[2])
+ end
+ end
+ end
+ })
+end
diff --git a/pacmine/hud.lua b/pacmine/hud.lua
new file mode 100755
index 0000000..162917d
--- /dev/null
+++ b/pacmine/hud.lua
@@ -0,0 +1,43 @@
+
+
+local hud_table = {}
+
+function pacmine.update_hud(id, player)
+ local game = pacmine.games[id]
+ player = player or minetest.get_player_by_name(game.player_name)
+ if not player then
+ return
+ elseif not game then
+ pacmine.remove_hud(player)
+ return
+ end
+
+ local hudtext = "Score: " .. game.score
+ .. "\nLevel: " .. game.level
+ .. "\nLives: " .. game.lives
+
+ local hud = hud_table[game.player_name]
+ if not hud then
+ hud = player:hud_add({
+ hud_elem_type = "text",
+ position = {x = 0, y = 1},
+ offset = {x=100, y = -100},
+ scale = {x = 100, y = 100},
+ number = 0x8888FF, --color
+ text = hudtext
+ })
+ hud_table[game.player_name] = hud
+ else
+ player:hud_change(hud, "text", hudtext)
+ end
+end
+
+
+function pacmine.remove_hud(player, playername)
+ local name = playername or player:get_player_name()
+ local hud = hud_table[name]
+ if hud then
+ player:hud_remove(hud)
+ hud_table[name] = nil
+ end
+end
diff --git a/pacmine/init.lua b/pacmine/init.lua
new file mode 100644
index 0000000..c8232b2
--- /dev/null
+++ b/pacmine/init.lua
@@ -0,0 +1,102 @@
+
+-- This variable will be exported to other mods when they "depend" on this mod
+pacmine = {}
+
+
+dofile(minetest.get_modpath("pacmine").."/craftitems.lua")
+dofile(minetest.get_modpath("pacmine").."/ghost.lua")
+dofile(minetest.get_modpath("pacmine").."/blocks.lua")
+dofile(minetest.get_modpath("pacmine").."/portals.lua")
+dofile(minetest.get_modpath("pacmine").."/gamestate.lua")
+dofile(minetest.get_modpath("pacmine").."/hud.lua")
+
+
+--Yellow Pellets
+minetest.register_alias("mypacman:pellet_1", "pacmine:pellet_1")
+minetest.register_alias("mypacman:pellet_2", "pacmine:pellet_2")
+minetest.register_alias("mypacman:block2", "pacmine:block2")
+minetest.register_node("pacmine:pellet_1", {
+ description = "Pellet 1",
+ tiles = {"wool_yellow.png"},
+ drawtype = "nodebox",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ walkable = false,
+ light_source = 11,
+ drop = "",
+ groups = {dig_immediate = 3, not_in_creative_inventory = 0},
+ 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
+minetest.register_node("pacmine:pellet_2", {
+ description = "Pellet 2",
+ tiles = {"wool_yellow.png^[colorize:white:140"},
+ drawtype = "nodebox",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ walkable = false,
+ light_source = 11,
+ drop = {max_items = 1,items = {
+ {items = {"pacmine:cherrys"},rarity = 4,},
+ {items = {"pacmine:apple"},rarity = 4,},
+ {items = {"pacmine:peach"},rarity = 4,},
+ {items = {"pacmine:strawberry"},rarity = 4,},},
+ },
+ groups = {dig_immediate = 3, not_in_creative_inventory = 0},
+ node_box = {
+ type = "fixed",
+ fixed = {
+ {-0.625, -0.125, -0.25, -0.375, 0.125, 0.25},
+ {-0.75, -0.125, -0.125, -0.25, 0.125, 0.125},
+ {-0.625, -0.25, -0.125, -0.375, 0.25, 0.125},
+ {-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
+minetest.register_node("pacmine:block2",{
+ description = "Pacman",
+ inventory_image = "pacmine_1.png",
+ tiles = {
+ "pacmine_wallc.png",
+ "pacmine_1.png",
+ "pacmine_1.png",
+ "pacmine_1.png",
+ "pacmine_1.png",
+ "pacmine_1.png",
+ },
+ drawtype = "normal",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ light_source = 8,
+ groups = {cracky = 1},
+ on_rightclick = function(pos, node, player, itemstack, pointed_thing)
+ pacmine.game_start(pos, player)
+ end,
+})
diff --git a/pacmine/portals.lua b/pacmine/portals.lua
new file mode 100644
index 0000000..f40763f
--- /dev/null
+++ b/pacmine/portals.lua
@@ -0,0 +1,73 @@
+local sbox = {
+ type = "fixed",
+ fixed = {
+ {0, 0, 0, 0, 0, 0}
+ }
+ }
+local cbox = {
+ type = "fixed",
+ fixed = {
+ {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
+ }
+ }
+
+--Portals
+minetest.register_alias("mypacman:portalr", "pacmine:portalr")
+minetest.register_node("pacmine:portalr", {
+ description = "Portalr ",
+ drawtype = "allfaces",
+ tiles = {"pacmine_portal.png"},
+ paramtype = "light",
+ sunlight_propagates = true,
+ light_source = 14,
+ paramtype2 = "facedir",
+ walkable = false,
+ is_ground_content = false,
+ groups = {snappy = 2, cracky = 2, dig_immediate = 3,not_in_creative_inventory=1},
+ selection_box = sbox,
+
+})
+minetest.register_alias("mypacman:portall", "pacmine:portall")
+minetest.register_node("pacmine:portall", {
+ description = "Portall ",
+ drawtype = "allfaces",
+ tiles = {"pacmine_portal.png"},
+ paramtype = "light",
+ sunlight_propagates = true,
+ light_source = 14,
+ paramtype2 = "facedir",
+ walkable = false,
+ is_ground_content = false,
+ groups = {snappy = 2, cracky = 2, dig_immediate = 3,not_in_creative_inventory=1},
+ selection_box = sbox,
+
+})
+
+minetest.register_abm({
+ nodenames = {"pacmine:portall"},
+ interval = 0.5,
+ chance = 1,
+ action = function(pos, node, active_object_count, active_object_count_wider)
+ local objs = minetest.env:get_objects_inside_radius(pos, 1)
+ for k, player in pairs(objs) do
+ if player:get_player_name() then
+
+ player:setpos({x=pos.x-23,y=pos.y+0.5,z=pos.z})
+ end
+ end
+ end
+})
+minetest.register_abm({
+ nodenames = {"pacmine:portalr"},
+ interval = 0.5,
+ chance = 1,
+ action = function(pos, node, active_object_count, active_object_count_wider)
+ local objs = minetest.env:get_objects_inside_radius(pos, 1)
+ for k, player in pairs(objs) do
+ if player:get_player_name() then
+
+ player:setpos({x=pos.x+23,y=pos.y+0.5,z=pos.z})
+ end
+ end
+ end
+})
diff --git a/pacmine/schems/pacmine_3.mts b/pacmine/schems/pacmine_3.mts
new file mode 100644
index 0000000..a3124f9
--- /dev/null
+++ b/pacmine/schems/pacmine_3.mts
Binary files differ
diff --git a/pacmine/sounds/pacmine_beginning.ogg b/pacmine/sounds/pacmine_beginning.ogg
new file mode 100644
index 0000000..2188e55
--- /dev/null
+++ b/pacmine/sounds/pacmine_beginning.ogg
Binary files differ
diff --git a/pacmine/sounds/pacmine_chomp.ogg b/pacmine/sounds/pacmine_chomp.ogg
new file mode 100644
index 0000000..1d14e93
--- /dev/null
+++ b/pacmine/sounds/pacmine_chomp.ogg
Binary files differ
diff --git a/pacmine/sounds/pacmine_death.ogg b/pacmine/sounds/pacmine_death.ogg
new file mode 100644
index 0000000..277acb2
--- /dev/null
+++ b/pacmine/sounds/pacmine_death.ogg
Binary files differ
diff --git a/pacmine/sounds/pacmine_eatfruit.ogg b/pacmine/sounds/pacmine_eatfruit.ogg
new file mode 100644
index 0000000..212782f
--- /dev/null
+++ b/pacmine/sounds/pacmine_eatfruit.ogg
Binary files differ
diff --git a/pacmine/sounds/pacmine_eatghost.ogg b/pacmine/sounds/pacmine_eatghost.ogg
new file mode 100644
index 0000000..f628395
--- /dev/null
+++ b/pacmine/sounds/pacmine_eatghost.ogg
Binary files differ
diff --git a/pacmine/sounds/pacmine_extrapac.ogg b/pacmine/sounds/pacmine_extrapac.ogg
new file mode 100644
index 0000000..3be1dff
--- /dev/null
+++ b/pacmine/sounds/pacmine_extrapac.ogg
Binary files differ
diff --git a/pacmine/sounds/pacmine_powerup.ogg b/pacmine/sounds/pacmine_powerup.ogg
new file mode 100644
index 0000000..23b2854
--- /dev/null
+++ b/pacmine/sounds/pacmine_powerup.ogg
Binary files differ
diff --git a/pacmine/textures/pacmine_1.png b/pacmine/textures/pacmine_1.png
new file mode 100644
index 0000000..fac4af2
--- /dev/null
+++ b/pacmine/textures/pacmine_1.png
Binary files differ
diff --git a/pacmine/textures/pacmine_apple.png b/pacmine/textures/pacmine_apple.png
new file mode 100644
index 0000000..22e060f
--- /dev/null
+++ b/pacmine/textures/pacmine_apple.png
Binary files differ
diff --git a/pacmine/textures/pacmine_blinkyf.png b/pacmine/textures/pacmine_blinkyf.png
new file mode 100644
index 0000000..fb1a17d
--- /dev/null
+++ b/pacmine/textures/pacmine_blinkyf.png
Binary files differ
diff --git a/pacmine/textures/pacmine_blinkys.png b/pacmine/textures/pacmine_blinkys.png
new file mode 100644
index 0000000..79bb09d
--- /dev/null
+++ b/pacmine/textures/pacmine_blinkys.png
Binary files differ
diff --git a/pacmine/textures/pacmine_cherrys.png b/pacmine/textures/pacmine_cherrys.png
new file mode 100644
index 0000000..0009e27
--- /dev/null
+++ b/pacmine/textures/pacmine_cherrys.png
Binary files differ
diff --git a/pacmine/textures/pacmine_clydef.png b/pacmine/textures/pacmine_clydef.png
new file mode 100644
index 0000000..e041375
--- /dev/null
+++ b/pacmine/textures/pacmine_clydef.png
Binary files differ
diff --git a/pacmine/textures/pacmine_clydes.png b/pacmine/textures/pacmine_clydes.png
new file mode 100644
index 0000000..14803e7
--- /dev/null
+++ b/pacmine/textures/pacmine_clydes.png
Binary files differ
diff --git a/pacmine/textures/pacmine_door.png b/pacmine/textures/pacmine_door.png
new file mode 100644
index 0000000..ec92f9e
--- /dev/null
+++ b/pacmine/textures/pacmine_door.png
Binary files differ
diff --git a/pacmine/textures/pacmine_egg.png b/pacmine/textures/pacmine_egg.png
new file mode 100644
index 0000000..fbee286
--- /dev/null
+++ b/pacmine/textures/pacmine_egg.png
Binary files differ
diff --git a/pacmine/textures/pacmine_floor.png b/pacmine/textures/pacmine_floor.png
new file mode 100644
index 0000000..8e4adc8
--- /dev/null
+++ b/pacmine/textures/pacmine_floor.png
Binary files differ
diff --git a/pacmine/textures/pacmine_glass.png b/pacmine/textures/pacmine_glass.png
new file mode 100644
index 0000000..2c6dee9
--- /dev/null
+++ b/pacmine/textures/pacmine_glass.png
Binary files differ
diff --git a/pacmine/textures/pacmine_inkyf.png b/pacmine/textures/pacmine_inkyf.png
new file mode 100644
index 0000000..aba85e3
--- /dev/null
+++ b/pacmine/textures/pacmine_inkyf.png
Binary files differ
diff --git a/pacmine/textures/pacmine_inkys.png b/pacmine/textures/pacmine_inkys.png
new file mode 100644
index 0000000..c94a44c
--- /dev/null
+++ b/pacmine/textures/pacmine_inkys.png
Binary files differ
diff --git a/pacmine/textures/pacmine_inv.png b/pacmine/textures/pacmine_inv.png
new file mode 100644
index 0000000..244894a
--- /dev/null
+++ b/pacmine/textures/pacmine_inv.png
Binary files differ
diff --git a/pacmine/textures/pacmine_orange.png b/pacmine/textures/pacmine_orange.png
new file mode 100644
index 0000000..68793e6
--- /dev/null
+++ b/pacmine/textures/pacmine_orange.png
Binary files differ
diff --git a/pacmine/textures/pacmine_pinkyf.png b/pacmine/textures/pacmine_pinkyf.png
new file mode 100644
index 0000000..e31a81b
--- /dev/null
+++ b/pacmine/textures/pacmine_pinkyf.png
Binary files differ
diff --git a/pacmine/textures/pacmine_pinkys.png b/pacmine/textures/pacmine_pinkys.png
new file mode 100644
index 0000000..1731cf8
--- /dev/null
+++ b/pacmine/textures/pacmine_pinkys.png
Binary files differ
diff --git a/pacmine/textures/pacmine_portal.png b/pacmine/textures/pacmine_portal.png
new file mode 100644
index 0000000..f351ff5
--- /dev/null
+++ b/pacmine/textures/pacmine_portal.png
Binary files differ
diff --git a/pacmine/textures/pacmine_strawberry.png b/pacmine/textures/pacmine_strawberry.png
new file mode 100644
index 0000000..dcedbe6
--- /dev/null
+++ b/pacmine/textures/pacmine_strawberry.png
Binary files differ
diff --git a/pacmine/textures/pacmine_wall.png b/pacmine/textures/pacmine_wall.png
new file mode 100644
index 0000000..4f6d2c0
--- /dev/null
+++ b/pacmine/textures/pacmine_wall.png
Binary files differ
diff --git a/pacmine/textures/pacmine_wallc.png b/pacmine/textures/pacmine_wallc.png
new file mode 100644
index 0000000..548b32f
--- /dev/null
+++ b/pacmine/textures/pacmine_wallc.png
Binary files differ
diff --git a/pacmine/textures/pacmine_walle.png b/pacmine/textures/pacmine_walle.png
new file mode 100644
index 0000000..7f65702
--- /dev/null
+++ b/pacmine/textures/pacmine_walle.png
Binary files differ
diff --git a/pacmine/textures/pacmine_walls.png b/pacmine/textures/pacmine_walls.png
new file mode 100644
index 0000000..a7c4012
--- /dev/null
+++ b/pacmine/textures/pacmine_walls.png
Binary files differ