Initial commit
|
@ -0,0 +1,42 @@
|
|||
some media is licensed CC0:
|
||||
|
||||
AntumDeluge
|
||||
--------------
|
||||
balloon_inflate.ogg
|
||||
balloon_pop.ogg
|
||||
|
||||
|
||||
MisterE
|
||||
--------------
|
||||
balloon_bop_spike.png
|
||||
|
||||
the rest of the media is MIT, as well as the code by the authors below:
|
||||
|
||||
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 TBSHEB (from balloonblocks): Media: all [balloon_bop_<color>], balloon_bop_footstep.ogg, Code: blocks.lua
|
||||
|
||||
Copyright (c) 2022 ExeVirus (from balloonbash): Media: all [balloon.<number>], theme.ogg, punch.ogg, lose.ogg, balloon.ogg, Code: balloon entity and some gameplay code
|
||||
|
||||
Copyright (c) 2020 MisterE (arena_lib adaptation)
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,792 @@
|
|||
-- Detect creative mod --
|
||||
local creative_mod = minetest.get_modpath("creative")
|
||||
-- Cache creative mode setting as fallback if creative mod not present --
|
||||
local creative_mode_cache = minetest.settings:get_bool("creative_mode")
|
||||
|
||||
-- Returns a on_secondary_use function that places the balloon block in the air --
|
||||
local placeColour = function (colour)
|
||||
return function(itemstack, user, pointed_thing)
|
||||
-- Place node three blocks from the user in the air --
|
||||
local pos = user:getpos()
|
||||
local dir = user:get_look_dir()
|
||||
local balloonPlaceDistanceFromPlayer = 3
|
||||
local new_pos = {
|
||||
x = pos.x + (dir.x * balloonPlaceDistanceFromPlayer),
|
||||
y = pos.y + 1 + (dir.y * balloonPlaceDistanceFromPlayer),
|
||||
z = pos.z + (dir.z * balloonPlaceDistanceFromPlayer),
|
||||
}
|
||||
local getPos = minetest.get_node(new_pos)
|
||||
if getPos.name == "air" or
|
||||
getPos.name == "default:water_source" or
|
||||
getPos.name == "default:water_flowing" or
|
||||
getPos.name == "default:river_water_source" or
|
||||
getPos.name == "default:river_water_flowing" then
|
||||
local name = 'balloon_bop:'..colour
|
||||
minetest.set_node(new_pos, {name=name})
|
||||
local creative_enabled = (creative_mod and creative.is_enabled_for(user.get_player_name(user))) or creative_mode_cache
|
||||
if (not creative_enabled) then
|
||||
local stack = ItemStack(name)
|
||||
return ItemStack(name .. " " .. itemstack:get_count() - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local soundsConfig = function ()
|
||||
return {
|
||||
footstep = {name = "balloon_bop_footstep", gain = 0.2},
|
||||
dig = {name = "balloon_bop_footstep", gain = 0.3},
|
||||
dug = {name = "default_dug_hard.1", gain = 0.3},
|
||||
place = {name = "default_place_node_hard", gain = 1.0}
|
||||
}
|
||||
end
|
||||
|
||||
-- Holds balloonblock functions and config --
|
||||
local state = {
|
||||
placeRed = placeColour('red'),
|
||||
placeYellow = placeColour('yellow'),
|
||||
placeGreen = placeColour('green'),
|
||||
placeBlue = placeColour('blue'),
|
||||
placeBlack = placeColour('black'),
|
||||
placeWhite = placeColour('white'),
|
||||
placeOrange = placeColour('orange'),
|
||||
placePurple = placeColour('purple'),
|
||||
placeGrey = placeColour('grey'),
|
||||
placePink = placeColour('pink'),
|
||||
placeBrown = placeColour('brown'),
|
||||
placeGlowRed = placeColour('glowing_red'),
|
||||
placeGlowYellow = placeColour('glowing_yellow'),
|
||||
placeGlowGreen = placeColour('glowing_green'),
|
||||
placeGlowBlue = placeColour('glowing_blue'),
|
||||
placeGlowBlack = placeColour('glowing_black'),
|
||||
placeGlowWhite = placeColour('glowing_white'),
|
||||
placeGlowOrange = placeColour('glowing_orange'),
|
||||
placeGlowPurple = placeColour('glowing_purple'),
|
||||
placeGlowGrey = placeColour('glowing_grey'),
|
||||
placeGlowPink = placeColour('glowing_pink'),
|
||||
placeGlowBrown = placeColour('glowing_brown'),
|
||||
sounds = soundsConfig(),
|
||||
groups = {snappy=3, fall_damage_add_percent = -99, bouncy=70}
|
||||
}
|
||||
-- Normal balloon_bop --
|
||||
|
||||
minetest.register_node("balloon_bop:red", {
|
||||
description = "Red balloon",
|
||||
tiles = {"balloon_bop_red.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeRed,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:red',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:red', 'group:leaves'},
|
||||
-- {'dye:red', 'group:leaves', 'dye:red'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:yellow", {
|
||||
description = "Yellow balloon",
|
||||
tiles = {"balloon_bop_yellow.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeYellow,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:yellow',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:yellow', 'group:leaves'},
|
||||
-- {'dye:yellow', 'group:leaves', 'dye:yellow'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:green", {
|
||||
description = "Green balloon",
|
||||
tiles = {"balloon_bop_green.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGreen,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:green',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:green', 'group:leaves'},
|
||||
-- {'dye:green', 'group:leaves', 'dye:green'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:blue", {
|
||||
description = "Blue balloon",
|
||||
tiles = {"balloon_bop_blue.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeBlue,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:blue',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:blue', 'group:leaves'},
|
||||
-- {'dye:blue', 'group:leaves', 'dye:blue'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:black", {
|
||||
description = "Black balloon",
|
||||
tiles = {"balloon_bop_black.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeBlack,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:black',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:black', 'group:leaves'},
|
||||
-- {'dye:black', 'group:leaves', 'dye:black'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:white", {
|
||||
description = "White balloon",
|
||||
tiles = {"balloon_bop_white.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeWhite,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:white',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:white', 'group:leaves'},
|
||||
-- {'dye:white', 'group:leaves', 'dye:white'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:orange", {
|
||||
description = "Orange balloon",
|
||||
tiles = {"balloon_bop_orange.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeOrange,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:orange',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:orange', 'group:leaves'},
|
||||
-- {'dye:orange', 'group:leaves', 'dye:orange'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:purple", {
|
||||
description = "Purple balloon",
|
||||
tiles = {"balloon_bop_purple.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placePurple,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:purple',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:violet', 'group:leaves'},
|
||||
-- {'dye:violet', 'group:leaves', 'dye:violet'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:grey", {
|
||||
description = "Grey balloon",
|
||||
tiles = {"balloon_bop_grey.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGrey,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:grey',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:grey', 'group:leaves'},
|
||||
-- {'dye:grey', 'group:leaves', 'dye:grey'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
|
||||
minetest.register_node("balloon_bop:pink", {
|
||||
description = "Pink balloon",
|
||||
tiles = {"balloon_bop_pink.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placePink,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:pink',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:magenta', 'group:leaves'},
|
||||
-- {'dye:magenta', 'group:leaves', 'dye:magenta'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
|
||||
minetest.register_node("balloon_bop:brown", {
|
||||
description = "Brown balloon",
|
||||
tiles = {"balloon_bop_brown.png"},
|
||||
groups = state.groups,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeBrown,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:brown',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'dye:brown', 'group:leaves'},
|
||||
-- {'dye:brown', 'group:leaves', 'dye:brown'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
-- -- Extra crafting for the normal balloon_bop--
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:yellow', 'dye:blue' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:yellow', 'balloon_bop:blue' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:yellow', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:yellow', 'balloon_bop:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:red', 'dye:blue' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:red', 'balloon_bop:blue' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:white', 'dye:black' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:white', 'balloon_bop:black' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:white', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:white', 'balloon_bop:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:green', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:green', 'balloon_bop:red' }
|
||||
-- })
|
||||
|
||||
-- Glowing balloon_bop --
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_red", {
|
||||
description = "Glowing red balloon",
|
||||
tiles = {"balloon_bop_red.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowRed,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_red',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:red', 'group:leaves', 'dye:red'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_yellow", {
|
||||
description = "Glowing yellow balloon",
|
||||
tiles = {"balloon_bop_yellow.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowYellow,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_yellow',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:yellow', 'group:leaves', 'dye:yellow'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_green", {
|
||||
description = "Glowing green balloon",
|
||||
tiles = {"balloon_bop_green.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowGreen,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_green',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:green', 'group:leaves', 'dye:green'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_blue", {
|
||||
description = "Glowing blue balloon",
|
||||
tiles = {"balloon_bop_blue.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowBlue,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_blue',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:blue', 'group:leaves', 'dye:blue'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_black", {
|
||||
description = "Glowing black balloon",
|
||||
tiles = {"balloon_bop_black.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowBlack,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_black',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:black', 'group:leaves', 'dye:black'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_white", {
|
||||
description = "Glowing white balloon",
|
||||
tiles = {"balloon_bop_white.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowWhite,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_white',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:white', 'group:leaves', 'dye:white'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_orange", {
|
||||
description = "Glowing orange balloon",
|
||||
tiles = {"balloon_bop_orange.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowOrange,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_orange',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:orange', 'group:leaves', 'dye:orange'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_purple", {
|
||||
description = "Glowing purple balloon",
|
||||
tiles = {"balloon_bop_purple.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowPurple,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_purple',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:violet', 'group:leaves', 'dye:violet'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_grey", {
|
||||
description = "Glowing grey balloon",
|
||||
tiles = {"balloon_bop_grey.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowGrey,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_grey',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:grey', 'group:leaves', 'dye:grey'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_pink", {
|
||||
description = "Glowing pink balloon",
|
||||
tiles = {"balloon_bop_pink.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowPink,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_pink',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:magenta', 'group:leaves', 'dye:magenta'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
|
||||
minetest.register_node("balloon_bop:glowing_brown", {
|
||||
description = "Glowing brown balloon",
|
||||
tiles = {"balloon_bop_brown.png"},
|
||||
groups = state.groups,
|
||||
light_source = 30,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_secondary_use = state.placeGlowBrown,
|
||||
sounds = state.sounds
|
||||
})
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_brown',
|
||||
-- recipe = {
|
||||
-- {'group:leaves', 'group:leaves', 'group:leaves'},
|
||||
-- {'group:leaves', 'default:torch', 'group:leaves'},
|
||||
-- {'dye:brown', 'group:leaves', 'dye:brown'},
|
||||
-- }
|
||||
-- })
|
||||
|
||||
-- -- Extra crafting for the glowing balloons--
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_red',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:red', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_yellow',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:yellow', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:green', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_blue',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:blue', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_black',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:black', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_white',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:white', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:orange', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:purple', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:pink', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'default:torch', 'balloon_bop:grey' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:brown', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_yellow', 'dye:blue' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_blue', 'dye:yellow' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_red', 'dye:yellow' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_yellow', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_blue', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_red', 'dye:blue' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_white', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_red', 'dye:white' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_white', 'dye:black' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'dye:white', 'balloon_bop:glowing_black' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_red', 'dye:green' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:glowing_green', 'dye:red' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:yellow', 'dye:blue', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_green',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:blue', 'dye:yellow', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:red', 'dye:yellow', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_orange',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:yellow', 'dye:red', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:blue', 'dye:red', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_purple',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:red', 'dye:blue', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:white', 'dye:red', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_pink',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:red', 'dye:white', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:white', 'dye:black', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_grey',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:black', 'dye:white', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:red', 'dye:green', 'default:torch' }
|
||||
-- })
|
||||
|
||||
-- minetest.register_craft({
|
||||
-- output = 'balloon_bop:glowing_brown',
|
||||
-- type = 'shapeless',
|
||||
-- recipe = { 'balloon_bop:green', 'dye:red', 'default:torch' }
|
||||
-- })
|
|
@ -0,0 +1,167 @@
|
|||
|
||||
local modname = "balloon_bop"
|
||||
balloon_bop = {}
|
||||
|
||||
local round_time_default = 20
|
||||
|
||||
--====================================================
|
||||
--====================================================
|
||||
-- Minigame registration
|
||||
--====================================================
|
||||
--====================================================
|
||||
|
||||
|
||||
|
||||
|
||||
arena_lib.register_minigame( modname , {
|
||||
|
||||
properties = {
|
||||
starting_lives = 3,
|
||||
round_time = round_time_default,
|
||||
balloon_spawner = vector.new(0,7,0),
|
||||
spawner_range = 3.5,
|
||||
player_die_level = -1,
|
||||
arena_radius = 50,
|
||||
},
|
||||
|
||||
|
||||
temp_properties = {
|
||||
-- some minigames dont need temp properties
|
||||
num_balloons = 1,
|
||||
current_round_time = round_time_default,
|
||||
arena_lives = 1,
|
||||
score = 0,
|
||||
},
|
||||
|
||||
|
||||
-- The prefix (string) is what's going to appear in most of the lines printed by your mod. Default is [Arena_lib]
|
||||
|
||||
prefix = "["..modname.."] ",
|
||||
|
||||
|
||||
time_mode = 'incremental', -- for our sample minigame, we will use incrementing time. This will allow us to use on_time_tick if we want to.
|
||||
|
||||
|
||||
hotbar = {
|
||||
slots = 0,
|
||||
background_image = "blank.png", -- image not included!
|
||||
selected_image = "blank.png", -- image not included!
|
||||
},
|
||||
|
||||
|
||||
join_while_in_progress = true,
|
||||
|
||||
|
||||
in_game_physics = {
|
||||
speed = 1.5,
|
||||
jump = 1,
|
||||
gravity = 1,
|
||||
sneak = true,},
|
||||
|
||||
|
||||
disabled_damage_types = {"fall",},
|
||||
})
|
||||
|
||||
|
||||
|
||||
--====================================================
|
||||
--====================================================
|
||||
-- Calling the other files
|
||||
--====================================================
|
||||
--====================================================
|
||||
|
||||
|
||||
local path = minetest.get_modpath(modname)
|
||||
|
||||
|
||||
if not minetest.get_modpath("lib_chatcmdbuilder") then
|
||||
dofile(path .. "/libraries/chatcmdbuilder.lua")
|
||||
end
|
||||
|
||||
local manager_path = path .. "/minigame_manager/"
|
||||
|
||||
|
||||
|
||||
dofile(path .. "/nodes.lua")
|
||||
dofile(path .. "/items.lua")
|
||||
dofile(path .. "/blocks.lua")
|
||||
dofile(manager_path .. "on_load.lua")
|
||||
dofile(manager_path .. "on_start.lua")
|
||||
dofile(manager_path .. "on_time_tick.lua")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--====================================================
|
||||
--====================================================
|
||||
-- Chatcommands
|
||||
--====================================================
|
||||
--====================================================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_privilege( modname .."_admin", "Create and edit ".. modname .. " arenas")
|
||||
|
||||
|
||||
local required_privs = {}
|
||||
|
||||
required_privs[modname .."_admin" ] = true
|
||||
|
||||
|
||||
ChatCmdBuilder.new(modname, function(cmd)
|
||||
-- create arena
|
||||
cmd:sub("create :arena", function(name, arena_name)
|
||||
arena_lib.create_arena(name, modname, arena_name)
|
||||
end)
|
||||
|
||||
cmd:sub("create :arena :minplayers:int :maxplayers:int", function(name, arena_name, min_players, max_players)
|
||||
arena_lib.create_arena(name, modname, arena_name, min_players, max_players)
|
||||
end)
|
||||
|
||||
-- remove arena
|
||||
cmd:sub("remove :arena", function(name, arena_name)
|
||||
arena_lib.remove_arena(name, modname, arena_name)
|
||||
end)
|
||||
|
||||
-- list of the arenas
|
||||
cmd:sub("list", function(name)
|
||||
arena_lib.print_arenas(name, modname)
|
||||
end)
|
||||
|
||||
-- enter editor mode
|
||||
cmd:sub("edit :arena", function(sender, arena)
|
||||
arena_lib.enter_editor(sender, modname, arena)
|
||||
end)
|
||||
|
||||
-- enable and disable arenas
|
||||
cmd:sub("enable :arena", function(name, arena)
|
||||
arena_lib.enable_arena(name, modname, arena)
|
||||
end)
|
||||
|
||||
cmd:sub("disable :arena", function(name, arena)
|
||||
arena_lib.disable_arena(name, modname, arena)
|
||||
end)
|
||||
|
||||
end, {
|
||||
description = [[
|
||||
|
||||
(/help ]] .. modname .. [[)
|
||||
|
||||
Use this to configure your arena:
|
||||
- create <arena name> [min players] [max players]
|
||||
- edit <arena name>
|
||||
- enable <arena name>
|
||||
|
||||
Other commands:
|
||||
- remove <arena name>
|
||||
- disable <arena>
|
||||
- list (lists are created arenas)
|
||||
]],
|
||||
privs = required_privs,
|
||||
})
|
||||
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
-- licensed as follows:
|
||||
-- MIT License, ExeVirus (c) 2021
|
||||
--
|
||||
-- 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
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Balloon
|
||||
|
||||
|
||||
balloon_bop.spawn = function(arena)
|
||||
local obj = minetest.add_entity(vector.new(
|
||||
arena.balloon_spawner.x+rand:next(1,7)-arena.spawner_range,
|
||||
arena.balloon_spawner.y,
|
||||
arena.balloon_spawner.z+rand:next(1,7)-arena.spawner_range)
|
||||
, "balloon_bop:balloon", minetest.write_json({
|
||||
_arenaid = arena_lib.get_arena_by_name("balloon_bop", arena.name),
|
||||
}))
|
||||
minetest.sound_play("balloon", {
|
||||
gain = 1.0, -- default
|
||||
loop = false,
|
||||
pos = arena.balloon_spawner,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
local balloon = {
|
||||
initial_properties = {
|
||||
hp_max = 10,
|
||||
visual = "mesh",
|
||||
visual_size = {x=0.1,y=0.117,z=0.1},
|
||||
-- glow = 10,
|
||||
static_save = false,
|
||||
mesh = "balloon.obj",
|
||||
physical = true,
|
||||
collide_with_objects = true,
|
||||
collisionbox = {-0.6, -0.5, -0.6, 0.6, 0.5, 0.6},
|
||||
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", {
|
||||
gain = 1.0, -- default
|
||||
loop = false,
|
||||
pos = self.object:get_pos()
|
||||
})
|
||||
add_points(self,25)
|
||||
self.object:remove()
|
||||
--todo: add pop sound
|
||||
return
|
||||
end
|
||||
if moveresult.touching_ground then
|
||||
self._touching_ground = true
|
||||
else
|
||||
--slow our x,z velocities
|
||||
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})
|
||||
end
|
||||
end,
|
||||
|
||||
--Punch Physics
|
||||
on_punch = function(self, puncher, _, _, dir)
|
||||
self.object:set_velocity(dir*25)
|
||||
minetest.sound_play("punch", {
|
||||
gain = 1.0, -- default
|
||||
loop = false,
|
||||
pos = self.object:get_pos()
|
||||
})
|
||||
end,
|
||||
|
||||
--Setup fallspeed
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
self.object:set_acceleration({x=0,y=-4.0,z=0})
|
||||
local props = self.object:get_properties()
|
||||
props.textures = {"balloon." .. rand:next(1,4) .. ".png"}
|
||||
self.object:set_properties(props)
|
||||
minetest.sound_play("balloon_inflate", {
|
||||
gain = 1.0, -- default
|
||||
loop = false,
|
||||
pos = self.object:get_pos()
|
||||
})
|
||||
if staticdata ~= "" and staticdata ~= nil then
|
||||
local data = minetest.parse_json(staticdata) or {}
|
||||
if data._arenaid then
|
||||
self._arenaid = data._arenaid
|
||||
end
|
||||
end
|
||||
end,
|
||||
_touching_ground = false,
|
||||
}
|
||||
|
||||
minetest.register_entity("balloon_bop:balloon", balloon)
|
|
@ -0,0 +1,306 @@
|
|||
ChatCmdBuilder = {}
|
||||
|
||||
function ChatCmdBuilder.new(name, func, def)
|
||||
def = def or {}
|
||||
local cmd = ChatCmdBuilder.build(func)
|
||||
cmd.def = def
|
||||
def.func = cmd.run
|
||||
minetest.register_chatcommand(name, def)
|
||||
return cmd
|
||||
end
|
||||
|
||||
local STATE_READY = 1
|
||||
local STATE_PARAM = 2
|
||||
local STATE_PARAM_TYPE = 3
|
||||
local bad_chars = {}
|
||||
bad_chars["("] = true
|
||||
bad_chars[")"] = true
|
||||
bad_chars["."] = true
|
||||
bad_chars["%"] = true
|
||||
bad_chars["+"] = true
|
||||
bad_chars["-"] = true
|
||||
bad_chars["*"] = true
|
||||
bad_chars["?"] = true
|
||||
bad_chars["["] = true
|
||||
bad_chars["^"] = true
|
||||
bad_chars["$"] = true
|
||||
local function escape(char)
|
||||
if bad_chars[char] then
|
||||
return "%" .. char
|
||||
else
|
||||
return char
|
||||
end
|
||||
end
|
||||
|
||||
local dprint = function() end
|
||||
|
||||
ChatCmdBuilder.types = {
|
||||
pos = "%(? *(%-?[%d.]+) *, *(%-?[%d.]+) *, *(%-?[%d.]+) *%)?",
|
||||
text = "(.+)",
|
||||
number = "(%-?[%d.]+)",
|
||||
int = "(%-?[%d]+)",
|
||||
word = "([^ ]+)",
|
||||
alpha = "([A-Za-z]+)",
|
||||
modname = "([a-z0-9_]+)",
|
||||
alphascore = "([A-Za-z_]+)",
|
||||
alphanumeric = "([A-Za-z0-9]+)",
|
||||
username = "([A-Za-z0-9-_]+)",
|
||||
}
|
||||
|
||||
function ChatCmdBuilder.build(func)
|
||||
local cmd = {
|
||||
_subs = {}
|
||||
}
|
||||
function cmd:sub(route, func, def)
|
||||
dprint("Parsing " .. route)
|
||||
|
||||
def = def or {}
|
||||
if string.trim then
|
||||
route = string.trim(route)
|
||||
end
|
||||
|
||||
local sub = {
|
||||
pattern = "^",
|
||||
params = {},
|
||||
func = func
|
||||
}
|
||||
|
||||
-- End of param reached: add it to the pattern
|
||||
local param = ""
|
||||
local param_type = ""
|
||||
local should_be_eos = false
|
||||
local function finishParam()
|
||||
if param ~= "" and param_type ~= "" then
|
||||
dprint(" - Found param " .. param .. " type " .. param_type)
|
||||
|
||||
local pattern = ChatCmdBuilder.types[param_type]
|
||||
if not pattern then
|
||||
error("Unrecognised param_type=" .. param_type)
|
||||
end
|
||||
|
||||
sub.pattern = sub.pattern .. pattern
|
||||
|
||||
table.insert(sub.params, param_type)
|
||||
|
||||
param = ""
|
||||
param_type = ""
|
||||
end
|
||||
end
|
||||
|
||||
-- Iterate through the route to find params
|
||||
local state = STATE_READY
|
||||
local catching_space = false
|
||||
local match_space = " " -- change to "%s" to also catch tabs and newlines
|
||||
local catch_space = match_space.."+"
|
||||
for i = 1, #route do
|
||||
local c = route:sub(i, i)
|
||||
if should_be_eos then
|
||||
error("Should be end of string. Nothing is allowed after a param of type text.")
|
||||
end
|
||||
|
||||
if state == STATE_READY then
|
||||
if c == ":" then
|
||||
dprint(" - Found :, entering param")
|
||||
state = STATE_PARAM
|
||||
param_type = "word"
|
||||
catching_space = false
|
||||
elseif c:match(match_space) then
|
||||
print(" - Found space")
|
||||
if not catching_space then
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
end
|
||||
else
|
||||
catching_space = false
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
end
|
||||
elseif state == STATE_PARAM then
|
||||
if c == ":" then
|
||||
dprint(" - Found :, entering param type")
|
||||
state = STATE_PARAM_TYPE
|
||||
param_type = ""
|
||||
elseif c:match(match_space) then
|
||||
print(" - Found whitespace, leaving param")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
elseif c:match("%W") then
|
||||
dprint(" - Found nonalphanum, leaving param")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
else
|
||||
param = param .. c
|
||||
end
|
||||
elseif state == STATE_PARAM_TYPE then
|
||||
if c:match(match_space) then
|
||||
print(" - Found space, leaving param type")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
catching_space = true
|
||||
sub.pattern = sub.pattern .. catch_space
|
||||
elseif c:match("%W") then
|
||||
dprint(" - Found nonalphanum, leaving param type")
|
||||
state = STATE_READY
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. escape(c)
|
||||
else
|
||||
param_type = param_type .. c
|
||||
end
|
||||
end
|
||||
end
|
||||
dprint(" - End of route")
|
||||
finishParam()
|
||||
sub.pattern = sub.pattern .. "$"
|
||||
dprint("Pattern: " .. sub.pattern)
|
||||
|
||||
table.insert(self._subs, sub)
|
||||
end
|
||||
|
||||
if func then
|
||||
func(cmd)
|
||||
end
|
||||
|
||||
cmd.run = function(name, param)
|
||||
for i = 1, #cmd._subs do
|
||||
local sub = cmd._subs[i]
|
||||
local res = { string.match(param, sub.pattern) }
|
||||
if #res > 0 then
|
||||
local pointer = 1
|
||||
local params = { name }
|
||||
for j = 1, #sub.params do
|
||||
local param = sub.params[j]
|
||||
if param == "pos" then
|
||||
local pos = {
|
||||
x = tonumber(res[pointer]),
|
||||
y = tonumber(res[pointer + 1]),
|
||||
z = tonumber(res[pointer + 2])
|
||||
}
|
||||
table.insert(params, pos)
|
||||
pointer = pointer + 3
|
||||
elseif param == "number" or param == "int" then
|
||||
table.insert(params, tonumber(res[pointer]))
|
||||
pointer = pointer + 1
|
||||
else
|
||||
table.insert(params, res[pointer])
|
||||
pointer = pointer + 1
|
||||
end
|
||||
end
|
||||
if table.unpack then
|
||||
-- lua 5.2 or later
|
||||
return sub.func(table.unpack(params))
|
||||
else
|
||||
-- lua 5.1 or earlier
|
||||
return sub.func(unpack(params))
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, "Invalid command"
|
||||
end
|
||||
|
||||
return cmd
|
||||
end
|
||||
|
||||
local function run_tests()
|
||||
if not (ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("bar :one and :two:word", function(name, one, two)
|
||||
if name == "singleplayer" and one == "abc" and two == "def" then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end)).run("singleplayer", "bar abc and def") then
|
||||
error("Test 1 failed")
|
||||
end
|
||||
|
||||
local move = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("move :target to :pos:pos", function(name, target, pos)
|
||||
if name == "singleplayer" and target == "player1" and
|
||||
pos.x == 0 and pos.y == 1 and pos.z == 2 then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end).run
|
||||
if not move("singleplayer", "move player1 to 0,1,2") then
|
||||
error("Test 2 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to (0,1,2)") then
|
||||
error("Test 3 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0, 1,2") then
|
||||
error("Test 4 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0 ,1, 2") then
|
||||
error("Test 5 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0, 1, 2") then
|
||||
error("Test 6 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to 0 ,1 ,2") then
|
||||
error("Test 7 failed")
|
||||
end
|
||||
if not move("singleplayer", "move player1 to ( 0 ,1 ,2)") then
|
||||
error("Test 8 failed")
|
||||
end
|
||||
if move("singleplayer", "move player1 to abc,def,sdosd") then
|
||||
error("Test 9 failed")
|
||||
end
|
||||
if move("singleplayer", "move player1 to abc def sdosd") then
|
||||
error("Test 10 failed")
|
||||
end
|
||||
|
||||
if not (ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("does :one:int plus :two:int equal :three:int", function(name, one, two, three)
|
||||
if name == "singleplayer" and one + two == three then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end)).run("singleplayer", "does 1 plus 2 equal 3") then
|
||||
error("Test 11 failed")
|
||||
end
|
||||
|
||||
local checknegint = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checknegint :x:int", function(name, x)
|
||||
return x
|
||||
end)
|
||||
end).run
|
||||
if checknegint("checker","checknegint -2") ~= -2 then
|
||||
error("Test 12 failed")
|
||||
end
|
||||
|
||||
local checknegnumber = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checknegnumber :x:number", function(name, x)
|
||||
return x
|
||||
end)
|
||||
end).run
|
||||
if checknegnumber("checker","checknegnumber -3.3") ~= -3.3 then
|
||||
error("Test 13 failed")
|
||||
end
|
||||
|
||||
local checknegpos = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checknegpos :pos:pos", function(name, pos)
|
||||
return pos
|
||||
end)
|
||||
end).run
|
||||
local negpos = checknegpos("checker","checknegpos (-13.3,-4.6,-1234.5)")
|
||||
if negpos.x ~= -13.3 or negpos.y ~= -4.6 or negpos.z ~= -1234.5 then
|
||||
error("Test 14 failed")
|
||||
end
|
||||
|
||||
local checktypes = ChatCmdBuilder.build(function(cmd)
|
||||
cmd:sub("checktypes :int:int :number:number :pos:pos :word:word :text:text", function(name, int, number, pos, word, text)
|
||||
return int, number, pos.x, pos.y, pos.z, word, text
|
||||
end)
|
||||
end).run
|
||||
local int, number, posx, posy, posz, word, text
|
||||
int, number, posx, posy, posz, word, text = checktypes("checker","checktypes -1 -2.4 (-3,-5.3,6.12) some text to finish off with")
|
||||
--dprint(int, number, posx, posy, posz, word, text)
|
||||
if int ~= -1 or number ~= -2.4 or posx ~= -3 or posy ~= -5.3 or posz ~= 6.12 or word ~= "some" or text ~= "text to finish off with" then
|
||||
error("Test 15 failed")
|
||||
end
|
||||
dprint("All tests passed")
|
||||
|
||||
end
|
||||
if not minetest then
|
||||
run_tests()
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
arena_lib.on_load("balloon_bop", function(arena)
|
||||
|
||||
arena_lib.HUD_send_msg_all("title", arena, "Pop all the balloons, don't let them touch anything else!", 3, nil, "0xE6482E")
|
||||
|
||||
end)
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
-- This code is run when the game has finished the loading phase and starts the game timer.
|
||||
|
||||
-- For the sample minigame, we will use it to give each player a sword, and tell them to fight
|
||||
|
||||
|
||||
-- replace "sample_minigame" with the mod name here
|
||||
balloon_bop.infohuds = {}
|
||||
|
||||
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
|
||||
local player = minetest.get_player_by_name( pl_name )
|
||||
if player then
|
||||
balloon_bop.infohuds[pl_name] = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
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
|
||||
size = {x = 2 },
|
||||
})
|
||||
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)
|
||||
|
||||
|
||||
end)
|
|
@ -0,0 +1,79 @@
|
|||
local rand = PcgRandom(os.time())
|
||||
|
||||
|
||||
|
||||
arena_lib.on_time_tick("balloon_bop", function(arena)
|
||||
arena.score = arena.score+1
|
||||
arena.current_round_time = arena.current_round_time - 1
|
||||
if arena.current_round_time == 0 then
|
||||
arena.current_round_time = arena.round_time
|
||||
arena.num_balloons = arena.num_balloons + 1
|
||||
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()
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
--handle balloons falling out or touching smth
|
||||
local bal_c = 0
|
||||
for _,obj in pairs(minetest.get_objects_inside_radius(arena.balloon_spawner, arena.arena_radius)) do
|
||||
if obj and not( obj:is_player()) and obj:get_luaentity().name == "balloon_bop:balloon" then
|
||||
|
||||
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
|
||||
arena.arena_lives = arena.arena_lives - 1
|
||||
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
|
||||
player:hud_remove(balloon_bop.infohuds[pl_name])
|
||||
balloon_bop.infohuds[pl_name] = nil
|
||||
end
|
||||
end
|
||||
minetest.chat_send_player(pl_name,"Game Over! Your score is ".. arena.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')
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if bal_c < arena.num_balloons then
|
||||
balloon_bop.spawn(arena)
|
||||
end
|
||||
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])
|
||||
balloon_bop.infohuds[p_name] = nil
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
|
||||
-- you can register nodes here for your minigame.
|
||||
|
||||
-- given here is a solid airlike node that cant be dug, and a killer airlike node that kills players on contact
|
||||
|
||||
-- of course, if you want to keep these useful nodes for your minigame, change the mod name
|
||||
|
||||
local modname = "balloon_bop"
|
||||
|
||||
|
||||
-- minetest.register_node(modname .. ":killer",{
|
||||
-- description = "Minigame Killer",
|
||||
-- inventory_image = "no_texture_airlike.png",
|
||||
-- drawtype = "airlike",
|
||||
-- paramtype = "light",
|
||||
-- sunlight_propagates = true,
|
||||
-- walkable = false,
|
||||
-- pointable = true,
|
||||
-- diggable = false,
|
||||
-- buildable_to = false,
|
||||
-- drop = "",
|
||||
-- damage_per_second = 2000,
|
||||
-- groups = {},
|
||||
-- })
|
||||
|
||||
|
||||
minetest.register_node(modname .. ":wall",{
|
||||
description = "Minigame Blocker",
|
||||
inventory_image = "no_texture_airlike.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = true,
|
||||
pointable = true,
|
||||
diggable = false,
|
||||
buildable_to = false,
|
||||
drop = "",
|
||||
groups = {},
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("balloon_bop:spike", {
|
||||
description = "Balloonbop Spike",
|
||||
drawtype = "plantlike",
|
||||
tiles = {"balloon_bop_spike.png"},
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
})
|
After Width: | Height: | Size: 732 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 712 KiB |
After Width: | Height: | Size: 544 KiB |
After Width: | Height: | Size: 529 KiB |
After Width: | Height: | Size: 502 KiB |
After Width: | Height: | Size: 232 KiB |
After Width: | Height: | Size: 485 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 86 B |
After Width: | Height: | Size: 86 B |
After Width: | Height: | Size: 86 B |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 743 B |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 323 B |