add individual scores and graphics improvements
5
init.lua
|
@ -24,13 +24,14 @@ arena_lib.register_minigame( modname , {
|
|||
arena_radius = 50,
|
||||
},
|
||||
|
||||
|
||||
player_properties = {
|
||||
score = 0,
|
||||
},
|
||||
temp_properties = {
|
||||
-- some minigames dont need temp properties
|
||||
num_balloons = 1,
|
||||
current_round_time = round_time_default,
|
||||
arena_lives = 1,
|
||||
score = 0,
|
||||
},
|
||||
|
||||
|
||||
|
|
170
items.lua
|
@ -1,112 +1,48 @@
|
|||
-- licensed as follows:
|
||||
-- MIT License, ExeVirus (c) 2021
|
||||
-- MIT License, ExeVirus (c) 2021, MisterE (c) 2022
|
||||
--
|
||||
-- Please see the LICENSE file for more details
|
||||
|
||||
local spawn_time = 10
|
||||
local time = 0
|
||||
|
||||
-- --Common node between styles, used for hidden floor to fall onto
|
||||
-- minetest.register_node("game:ground",
|
||||
-- {
|
||||
-- description = "Ground Block",
|
||||
-- tiles = {"ground.png"},
|
||||
-- light_source = 11,
|
||||
-- })
|
||||
|
||||
-- --Override the default hand
|
||||
-- minetest.register_item(":", {
|
||||
-- type = "none",
|
||||
-- wield_image = "wieldhand.png",
|
||||
-- wield_scale = {x = 1, y = 1, z = 2.5},
|
||||
-- range = 12,
|
||||
-- groups = {not_in_creative_inventory=1},
|
||||
-- })
|
||||
|
||||
-- local num_balloons = 1
|
||||
local rand = PcgRandom(os.time())
|
||||
|
||||
-- local function spawn_balloon(arena)
|
||||
-- num_balloons = num_balloons + 1
|
||||
-- minetest.chat_send_all(num_balloons .. " balloons!")
|
||||
-- local players = minetest.get_connected_players()
|
||||
-- local player = players[rand:next(1,#players)] --random player
|
||||
-- local pos = player:get_pos()
|
||||
-- minetest.add_entity({
|
||||
-- x=pos.x+rand:next(1,7)-3.5,
|
||||
-- y=22,
|
||||
-- z=pos.z+rand:next(1,7)-3.5,
|
||||
-- }, "game:balloon", nil)
|
||||
-- minetest.sound_play("balloon", {
|
||||
-- gain = 1.0, -- default
|
||||
-- loop = false,
|
||||
-- })
|
||||
-- spawn_time = spawn_time + 3
|
||||
-- end
|
||||
|
||||
-- local first = true -- first player?
|
||||
-- local started = false -- delay
|
||||
-- minetest.register_on_joinplayer(
|
||||
-- function(player)
|
||||
-- player:hud_set_flags(
|
||||
-- {
|
||||
-- hotbar = false,
|
||||
-- healthbar = false,
|
||||
-- crosshair = true,
|
||||
-- wielditem = false,
|
||||
-- breathbar = false,
|
||||
-- minimap = false,
|
||||
-- minimap_radar = false,
|
||||
-- }
|
||||
-- )
|
||||
-- music = minetest.sound_play("balloon", {
|
||||
-- gain = 1.0, -- default
|
||||
-- loop = false,
|
||||
-- to_player = player:get_player_name(),
|
||||
-- })
|
||||
|
||||
-- player:set_physics_override({
|
||||
-- speed = 4.0,
|
||||
-- jump = 1.0,
|
||||
-- gravity = 4.0,
|
||||
-- sneak = false,
|
||||
-- })
|
||||
|
||||
-- player:set_pos({x=0,y=1.1,z=0})
|
||||
-- player:set_look_horizontal(0)
|
||||
-- player:set_look_vertical(-0.5)
|
||||
-- minetest.sound_play("theme", {
|
||||
-- gain = 0.8, -- default
|
||||
-- loop = true,
|
||||
-- to_player = player:get_player_name()
|
||||
-- })
|
||||
-- if first then
|
||||
-- minetest.add_entity({x=0,y=12,z=10}, "game:balloon", nil)
|
||||
-- first = false
|
||||
-- minetest.after(1, function() started = true end)
|
||||
-- end
|
||||
-- end
|
||||
-- )
|
||||
|
||||
-- minetest.register_globalstep(
|
||||
-- function(dtime)
|
||||
-- if started then
|
||||
-- time = time + dtime
|
||||
-- if time > spawn_time then
|
||||
-- time = 0
|
||||
-- spawn_balloon()
|
||||
-- end
|
||||
-- end
|
||||
-- end)
|
||||
local function add_points(self,pts)
|
||||
-- minetest.chat_send_all(self._arenaid)
|
||||
if self._arenaid then
|
||||
if arena_lib.mods["balloon_bop"].arenas[self._arenaid].in_game == true then
|
||||
local arena = arena_lib.mods["balloon_bop"].arenas[self._arenaid]
|
||||
arena.score = arena.score + pts
|
||||
if self._player then
|
||||
local score = arena.players[self._player].score
|
||||
arena.players[self._player].score = score + tonumber(self._points)
|
||||
-- show points particle
|
||||
local pos = self.object:get_pos()
|
||||
local o_texture = self._original_texture
|
||||
minetest.add_particlespawner({
|
||||
amount = 1,
|
||||
time = .5,
|
||||
minpos=vector.new(pos.x,pos.y+4,pos.z),
|
||||
maxpos=vector.new(pos.x,pos.y+3.5,pos.z),
|
||||
minvel=vector.new(0,1,0),
|
||||
maxvel=vector.new(0,1,0),
|
||||
minacc = vector.new(0,0,0),
|
||||
maxacc = vector.new(0,0,0),
|
||||
minexptime = 2,
|
||||
maxexptime = 2,
|
||||
minsize = 10,
|
||||
maxsize = 13,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture="balloon_bop_point_screen_"..self._points..".png^[mask:"..o_texture .. "^[opacity:170",
|
||||
playername = self._player,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Balloon
|
||||
|
||||
|
||||
|
@ -137,11 +73,12 @@ local balloon = {
|
|||
physical = true,
|
||||
collide_with_objects = true,
|
||||
collisionbox = {-0.6, -0.5, -0.6, 0.6, 0.5, 0.6},
|
||||
textures = {"balloon.1.png"},
|
||||
textures = {"balloon_1.png"},
|
||||
},
|
||||
|
||||
--Physics, and collisions
|
||||
on_step = function(self, dtime, moveresult)
|
||||
|
||||
if minetest.find_node_near(self.object:get_pos(), 1.5, {"balloon_bop:spike"}) then
|
||||
-- pop balloon harmlessly
|
||||
minetest.sound_play("balloon_pop", {
|
||||
|
@ -149,9 +86,31 @@ local balloon = {
|
|||
loop = false,
|
||||
pos = self.object:get_pos()
|
||||
})
|
||||
-- balloon particles
|
||||
local pos = self.object:get_pos()
|
||||
local o_texture = self._original_texture
|
||||
local vel = 10
|
||||
minetest.add_particlespawner({
|
||||
amount = 35,
|
||||
time = .1,
|
||||
minpos=vector.new(pos.x-1.1,pos.y-1.1,pos.z-1.1),
|
||||
maxpos=vector.new(pos.x+1.1,pos.y+1.1,pos.z+1.1),
|
||||
minvel=vector.new(-vel,-vel,-vel),
|
||||
maxvel=vector.new(vel,vel,vel),
|
||||
minacc = vector.new(0,0,0),
|
||||
maxacc = vector.new(0,0,0),
|
||||
minexptime = .05,
|
||||
maxexptime = .05,
|
||||
minsize = 10,
|
||||
maxsize = 13,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture="balloon_bop_scrap.png".."^[mask:"..o_texture .. "^[opacity:170",
|
||||
})
|
||||
-- add points
|
||||
add_points(self,25)
|
||||
--remove balloon
|
||||
self.object:remove()
|
||||
--todo: add pop sound
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -162,6 +121,8 @@ local balloon = {
|
|||
local vel = self.object:get_velocity()
|
||||
if vel == nil then vel = {x=0,y=0,z=0} end
|
||||
self.object:set_velocity({x=vel.x*0.97, y=vel.y*0.97, z=vel.z*0.97})
|
||||
local rot = self.object:get_rotation()
|
||||
self.object:set_rotation(vector.new(rot.x,rot.y+.04,rot.z))
|
||||
end
|
||||
end,
|
||||
|
||||
|
@ -173,13 +134,31 @@ local balloon = {
|
|||
loop = false,
|
||||
pos = self.object:get_pos()
|
||||
})
|
||||
if not (puncher:is_player()) then return end
|
||||
self._player = puncher:get_player_name()
|
||||
end,
|
||||
|
||||
--Setup fallspeed
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
math.randomseed(os.time())
|
||||
local point_chance = math.random(1,3)
|
||||
if point_chance == 1 then
|
||||
self._points = "10"
|
||||
elseif point_chance == 2 then
|
||||
self._points = "15"
|
||||
else
|
||||
self._points = "20"
|
||||
end
|
||||
|
||||
|
||||
self.object:set_acceleration({x=0,y=-3.0,z=0})
|
||||
local props = self.object:get_properties()
|
||||
props.textures = {"balloon." .. rand:next(1,4) .. ".png"}
|
||||
local text = "balloon_" .. rand:next(1,4) .. ".png"
|
||||
self._original_texture = text
|
||||
props.textures = {
|
||||
text.."^(balloon_bop_point_screen_"..self._points..".png^[colorize:#302C2E:255)",
|
||||
}
|
||||
props.automatic_rotate = 40,
|
||||
self.object:set_properties(props)
|
||||
minetest.sound_play("balloon_inflate", {
|
||||
gain = 1.0, -- default
|
||||
|
@ -194,6 +173,9 @@ local balloon = {
|
|||
end
|
||||
end,
|
||||
_touching_ground = false,
|
||||
_player = nil,
|
||||
_points = nil,
|
||||
|
||||
}
|
||||
|
||||
minetest.register_entity("balloon_bop:balloon", balloon)
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
|
||||
-- replace "sample_minigame" with the mod name here
|
||||
balloon_bop.infohuds = {}
|
||||
balloon_bop.numhuds = {}
|
||||
|
||||
arena_lib.on_start("balloon_bop", function(arena)
|
||||
|
||||
for pl_name,stats in pairs(arena.players) do -- it is a good convention to use "pl_name" in for loops and "p_name" elsewhere
|
||||
|
||||
arena.num_balloons = #arena.players
|
||||
if arena.num_balloons == 0 then arena.num_balloons = 1 end
|
||||
arena.arena_lives = arena.starting_lives
|
||||
arena.current_round_time = arena.round_time
|
||||
for pl_name,stats in pairs(arena.players) do
|
||||
local player = minetest.get_player_by_name( pl_name )
|
||||
if player then
|
||||
balloon_bop.infohuds[pl_name] = player:hud_add({
|
||||
|
@ -17,19 +23,29 @@ arena_lib.on_start("balloon_bop", function(arena)
|
|||
number = 0xE6482E,
|
||||
position = { x = .97, y = .03},
|
||||
offset = {x = 0, y = 0},
|
||||
text = arena.score,
|
||||
alignment = {x = -1, y = 1}, -- change y later!
|
||||
scale = {x = 100, y = 100}, -- covered later
|
||||
text = arena.players[pl_name].score,
|
||||
alignment = {x = -1, y = 1},
|
||||
scale = {x = 100, y = 100},
|
||||
size = {x = 2 },
|
||||
})
|
||||
local hud_list = {}
|
||||
for i=1,arena.arena_lives do
|
||||
|
||||
balloon_bop.numhuds[pl_name] = {}
|
||||
table.insert(hud_list, player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
number = 0xE6482E,
|
||||
position = { x = .97, y = .1},
|
||||
offset = {x = -3*18*(i-1), y = 0},
|
||||
text = "balloon_bop_hudballoon.png",
|
||||
alignment = {x = -1, y = 1},
|
||||
scale = {x = 3, y = 3},
|
||||
}))
|
||||
|
||||
end
|
||||
balloon_bop.numhuds[pl_name] = hud_list
|
||||
end
|
||||
end
|
||||
-- arena.current_round_time = arena.round_time
|
||||
|
||||
arena.num_balloons = #arena.players
|
||||
if arena.num_balloons == 0 then arena.num_balloons = 1 end
|
||||
arena.arena_lives = arena.starting_lives
|
||||
arena.current_round_time = arena.round_time
|
||||
arena_lib.HUD_send_msg_all("broadcast", arena, "1 balloon!", 1, nil, "0xB6D53C")
|
||||
|
||||
balloon_bop.spawn(arena)
|
||||
|
@ -47,11 +63,27 @@ arena_lib.on_join("balloon_bop", function(p_name, arena, as_spectator)
|
|||
number = 0xE6482E,
|
||||
position = { x = .97, y = .03},
|
||||
offset = {x = 0, y = 0},
|
||||
text = arena.score,
|
||||
alignment = {x = -1, y = 1}, -- change y later!
|
||||
scale = {x = 100, y = 100}, -- covered later
|
||||
text = arena.players[pl_name].score,
|
||||
alignment = {x = -1, y = 1},
|
||||
scale = {x = 100, y = 100},
|
||||
size = {x = 2 },
|
||||
})
|
||||
local hud_list = {}
|
||||
for i=1,arena.arena_lives do
|
||||
|
||||
balloon_bop.numhuds[p_name] = {}
|
||||
table.insert(hud_list, player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
number = 0xE6482E,
|
||||
position = { x = .97, y = .1},
|
||||
offset = {x = -3*18*(i-1), y = 0},
|
||||
text = "balloon_bop_hudballoon.png",
|
||||
alignment = {x = -1, y = 1},
|
||||
scale = {x = 3, y = 3},
|
||||
}))
|
||||
|
||||
end
|
||||
balloon_bop.numhuds[p_name] = hud_list
|
||||
end
|
||||
end
|
||||
end)
|
|
@ -3,7 +3,10 @@ local rand = PcgRandom(os.time())
|
|||
|
||||
|
||||
arena_lib.on_time_tick("balloon_bop", function(arena)
|
||||
arena.score = arena.score+1
|
||||
if arena.in_game == false then return end
|
||||
for pl_name,stats in pairs(arena.players) do
|
||||
arena.players[pl_name].score = arena.players[pl_name].score+1
|
||||
end
|
||||
arena.current_round_time = arena.current_round_time - 1
|
||||
if arena.current_round_time == 0 then
|
||||
arena.current_round_time = arena.round_time
|
||||
|
@ -11,15 +14,19 @@ arena_lib.on_time_tick("balloon_bop", function(arena)
|
|||
arena_lib.HUD_send_msg_all("broadcast", arena, arena.num_balloons .. " balloons!", 1, nil, "0xB6D53C")
|
||||
end
|
||||
|
||||
-- handle player "fall death"
|
||||
|
||||
for pl_name,stats in pairs(arena.players) do -- it is a good convention to use "pl_name" in for loops and "p_name" elsewhere
|
||||
local player = minetest.get_player_by_name( pl_name )
|
||||
if player then
|
||||
local pos = player:get_pos()
|
||||
-- handle player "fall death"
|
||||
local pos = player:get_pos()
|
||||
if pos.y < arena.player_die_level then
|
||||
player:set_pos(arena_lib.get_random_spawner(arena))
|
||||
end
|
||||
player:hud_change(balloon_bop.infohuds[pl_name],"text",arena.score)
|
||||
-- update score hud
|
||||
if balloon_bop.infohuds[pl_name] then
|
||||
player:hud_change(balloon_bop.infohuds[pl_name],"text",arena.players[pl_name].score)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,41 +38,78 @@ arena_lib.on_time_tick("balloon_bop", function(arena)
|
|||
bal_c = bal_c + 1
|
||||
|
||||
if obj:get_luaentity()._touching_ground == true or obj:get_pos().y <= arena.player_die_level then
|
||||
-- minetest.chat_send_all(arena.arena_lives)
|
||||
minetest.sound_play("lose", {
|
||||
gain = 1.0, -- default
|
||||
loop = false,
|
||||
pos = obj:get_pos()
|
||||
})
|
||||
obj:remove()
|
||||
arena.score = arena.score - 20
|
||||
if arena.score < 0 then arena.score = 0 end
|
||||
-- deduct 20 points from everyone for letting a balloon touch!
|
||||
for pl_name,stats in pairs(arena.players) do
|
||||
arena.players[pl_name].score = arena.players[pl_name].score+1
|
||||
if arena.players[pl_name].score < 0 then arena.players[pl_name].score = 0 end
|
||||
end
|
||||
arena.arena_lives = arena.arena_lives - 1
|
||||
-- update the lives HUD
|
||||
for pl_name,stats in pairs(arena.players) do
|
||||
local player = minetest.get_player_by_name( pl_name )
|
||||
if player then
|
||||
for idx,hud_id in ipairs(balloon_bop.numhuds[pl_name]) do
|
||||
if idx > arena.arena_lives then
|
||||
player:hud_change(hud_id, "text", "blank.png")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--handle end of game
|
||||
if arena.arena_lives == 0 then
|
||||
-- arena_lib.load_celebration(mod, arena, winner_name)
|
||||
for pl_name,stats in pairs(arena.players) do -- it is a good convention to use "pl_name" in for loops and "p_name" elsewhere
|
||||
if balloon_bop.infohuds[pl_name] then
|
||||
player = minetest.get_player_by_name(pl_name)
|
||||
if player then
|
||||
-- clear HUDs
|
||||
player:hud_remove(balloon_bop.infohuds[pl_name])
|
||||
for idx,hud_id in ipairs(balloon_bop.numhuds[pl_name]) do
|
||||
player:hud_remove(hud_id)
|
||||
end
|
||||
balloon_bop.infohuds[pl_name] = nil
|
||||
balloon_bop.numhuds[pl_name] = nil
|
||||
end
|
||||
end
|
||||
minetest.chat_send_player(pl_name,"Game Over! Your score is ".. arena.score .."!")
|
||||
minetest.chat_send_player(pl_name,"Game Over! Your score is ".. arena.players[pl_name].score .."!")
|
||||
end
|
||||
for _,obj in pairs(minetest.get_objects_inside_radius(arena.balloon_spawner, arena.arena_radius)) do
|
||||
if not( obj:is_player()) and obj:get_luaentity().name == "balloon_bop:balloon" then
|
||||
obj:remove()
|
||||
end
|
||||
end
|
||||
arena_lib.force_arena_ending('balloon_bop', arena,'Game')
|
||||
-- determine if there is a clear winner
|
||||
local highscore = {[1]="",[2]=0}
|
||||
for pl_name,stats in pairs(arena.players) do
|
||||
if stats.score > highscore[2] then
|
||||
highscore = {pl_name,stats.score}
|
||||
end
|
||||
end
|
||||
local high = highscore[2]
|
||||
local count = 0
|
||||
for pl_name,stats in pairs(arena.players) do
|
||||
if stats.score == high then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
if count > 1 then -- we cannot have more than one winner
|
||||
arena_lib.force_arena_ending('balloon_bop', arena,'Game')
|
||||
else
|
||||
arena_lib.load_celebration('balloon_bop', arena, highscore[1])
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if bal_c < arena.num_balloons then
|
||||
balloon_bop.spawn(arena)
|
||||
balloon_bop.spawn(arena)
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -73,7 +117,11 @@ end)
|
|||
arena_lib.on_quit("balloon_bop", function(arena, p_name, is_spectator)
|
||||
player = minetest.get_player_by_name(p_name)
|
||||
if player then
|
||||
player:hud_remove(balloon_bop.infohuds[pl_name])
|
||||
player:hud_remove(balloon_bop.infohuds[p_name])
|
||||
for idx,hud_id in ipairs(balloon_bop.numhuds[p_name]) do
|
||||
player:hud_remove(hud_id)
|
||||
end
|
||||
balloon_bop.infohuds[p_name] = nil
|
||||
balloon_bop.numhuds[p_name] = nil
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,12 @@
|
|||
# Blender MTL File: 'balloon.blend'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl green
|
||||
Ns 225.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.800000 0.800000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
d 1.000000
|
||||
illum 2
|
9916
models/balloon.obj
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 86 B |
Before Width: | Height: | Size: 86 B |
Before Width: | Height: | Size: 86 B |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 647 B |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 655 B |
After Width: | Height: | Size: 799 B |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 640 B |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 655 B |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 655 B |
After Width: | Height: | Size: 692 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 114 B |