Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions mods/hudbars/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local NS = function(s)
return s
end

-- Boilerplate for compatibiliity with pre-5.9.0
-- Boilerplate for compatibility with pre-5.9.0
-- versions of minetest
local hud_def_type_field
if minetest.features.hud_def_type_field then
Expand Down Expand Up @@ -237,13 +237,7 @@ function hb.register_hudbar(
local bar_image, bgicon, bar_size
if hb.settings.bar_type == 'progress_bar' then
bar_image = textures.bar
-- NOTE: Intentionally set to nil. For some reason, on some systems,
-- the progress bar is displaced when the bar_size is set explicitly here.
-- On the other hand, setting this to nil is deprecated in MT 5.0.0 due to
-- a debug log warning, but nothing is explained in lua_api.txt.
-- This section is a potential bug magnet, please watch with care!
-- The size of the bar image is expected to be exactly 2×16 pixels.
bar_size = nil
bar_size = { x = 2, y = 16 }
elseif hb.settings.bar_type == 'statbar_classic' or hb.settings.bar_type == 'statbar_modern' then
bar_image = textures.icon
bgicon = textures.bgicon
Expand Down
2 changes: 1 addition & 1 deletion mods/libox
Submodule libox updated 2 files
+11 −9 init.lua
+1 −0 main.lua
3 changes: 2 additions & 1 deletion mods/sbz_audio/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
-- sbz_api.sounds is gone. Replace with sbz_audio wherever used.
sbz_audio = sbz_audio or {}
-- Ensure global exists without triggering undeclared-global warning
sbz_audio = rawget(_G, "sbz_audio") or {}

-- Use as a template (include fade if needed on any)
function sbz_audio.blank()
Expand Down
167 changes: 122 additions & 45 deletions mods/sbz_base/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -573,60 +573,56 @@ function sbz_api.punch(target, hitter, time_from_last_punch, tool_caps, dir)
end
end

--- Async is todo, and it wont be true async, just the function would be delayed, useful for something like a detonator
---@param pos vector
---@param power number
---@param r number
---@param async boolean
sbz_api.explode = function(pos, r, power, async, owner, extra_damage, knockback_strength, sound)
if async then
sbz_api.delay_if_laggy(function()
sbz_api.explode(pos, r, power, false, owner, extra_damage, knockback_strength, sound)
end)
return
local fib_cache = {}
-- refer to: https://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere
local function fibonacci_sphere_points(samples)
if fib_cache[samples] then
return fib_cache[samples]
end
extra_damage = extra_damage or power
knockback_strength = knockback_strength or 2.5
owner = owner or ''

for _ = 1, 500 do
local raycast = core.raycast(pos, pos + vector.random_direction() * r, false, true)
local wear = 0
for pointed in raycast do
if pointed.type == 'node' then
local target_pos = pointed.under
local nodename = core.get_node(target_pos).name
local ndef = core.registered_nodes[nodename]
if not ndef then break end
wear = wear + (1 / core.get_item_group(nodename, 'explody'))
--the explody group hence signifies roughly how many such nodes in a straight line it can break before stopping
--although this is very random
if wear > power or core.is_protected(target_pos, owner) then break end
if ndef.on_blast then
ndef.on_blast(target_pos, power, pos, owner, r)
else
core.set_node(target_pos, { name = ndef._exploded or 'air' })
end
end
end
local points = {}
local phi = math.pi * (3 - math.sqrt(5))

for i = 0, samples - 1 do
local y = 1 - (i / (samples - 1)) * 2
local radius = math.sqrt(math.max(0, 1 - y * y))
local theta = phi * i
local x = math.cos(theta) * radius
local z = math.sin(theta) * radius
points[i + 1] = vector.new(x, y, z)
end
for _, obj in ipairs(core.get_objects_inside_radius(pos, r)) do
-- this is all messed up
-- TODO: improve
local dir = obj:get_pos() - pos

fib_cache[samples] = points
return points
end

sbz_api._start_explosion = function(ctx)
local MAX_ENTITIES = 9 -- finely tuned by means of divine revelation
local entity_count = 0

-- Damage & knockback to objects
for _, obj in ipairs(core.get_objects_inside_radius(ctx.pos, math.sqrt(ctx.r))) do
if entity_count >= MAX_ENTITIES then
break
end
entity_count = entity_count + 1

local dir = obj:get_pos() - ctx.pos
local len = vector.length(dir)

if len == 0 then dir = vector.new(0, 1, 0) len = 0.01 end

if sbz_api.can_move_object(obj:get_armor_groups()) then
obj:add_velocity(vector.normalize(dir) * (r - vector.length(dir)) * knockback_strength)
obj:add_velocity(vector.normalize(dir) * (ctx.r - len) * ctx.knockback_strength)
end
-- this is intentional. HP is only removed when there is line of sight, but velocity is added anyway
if sbz_api.line_of_sight(pos, obj:get_pos()) == true then
local dmg = math.abs(vector.length(vector.normalize(dir) * (r - vector.length(dir))) * extra_damage)
if sbz_api.line_of_sight(ctx.pos, obj:get_pos()) then
local dmg = math.abs((ctx.r - len) * ctx.extra_damage)
local groups = obj:get_armor_groups()
local tool_caps = {
full_punch_interval = 0,
damage_groups = {},
}

-- pick whichever damage group is more protected
if (groups.matter or 0) <= (groups.antimatter or 0) then
tool_caps.damage_groups.matter = dmg
Expand All @@ -637,15 +633,96 @@ sbz_api.explode = function(pos, r, power, async, owner, extra_damage, knockback_
sbz_api.punch(obj, nil, 100, tool_caps, dir)
end
end
if sound then

if ctx.sound then
core.sound_play('gen_explosion_with_reverb', {
gain = 2.5,
max_hear_distance = 128,
pos = pos,
max_hear_distance = ctx.r * ctx.r,
pos = ctx.pos,
}, true)
end
end

local function process_explosion_batch(ctx)
local batch_size = 50
local processed = 0

while ctx.i <= ctx.total and processed < batch_size do
local dir = ctx.ray_dirs[ctx.i]
local raycast = core.raycast(
ctx.pos,
ctx.pos + dir * ctx.r,
false,
true
)

local wear = 0
for pointed in raycast do
if pointed.type == 'node' then
local target_pos = pointed.under
local nodename = core.get_node(target_pos).name
local ndef = core.registered_nodes[nodename]
if not ndef then break end

wear = wear + (1 / core.get_item_group(nodename, 'explody'))
--the explody group hence signifies roughly how many such nodes in a straight line it can break before stopping
--although this is very random
if wear > ctx.power or core.is_protected(target_pos, ctx.owner) then
break
end

if ndef.on_blast then
ndef.on_blast(target_pos, ctx.power, ctx.pos, ctx.owner, ctx.r)
else
core.set_node(target_pos, { name = ndef._exploded or 'air' })
end
end
end

ctx.i = ctx.i + 1
processed = processed + 1
end

if ctx.i <= ctx.total then
sbz_api.delay_if_laggy(function()
process_explosion_batch(ctx)
end)
end
end

--- Async is todo, and it wont be true async, just the function would be delayed, useful for something like a detonator
---@param pos vector
---@param power number
---@param r number
---@param async boolean
sbz_api.explode = function(pos, r, power, async, owner, extra_damage, knockback_strength, sound)
local total_rays = math.min(math.pi * r * r, 3000)

local ctx = {
pos = pos,
r = r,
power = power,
owner = owner or '',
extra_damage = extra_damage or power,
knockback_strength = knockback_strength or 2.5,
sound = sound,
i = 1,
total = total_rays,
ray_dirs = fibonacci_sphere_points(total_rays),
}

if async then
sbz_api.delay_if_laggy(function()
sbz_api.explode(pos, r, power, false, owner, extra_damage, knockback_strength, sound)
end)
else
-- 1. Trigger the start effects (Damage, Sound, Knockback)
sbz_api._start_explosion(ctx)
-- 2. Batched raycasting for nodes
process_explosion_batch(ctx)
end
end

sbz_api.on_place_recharge = function(charge_per_1_wear, after)
return function(stack, user, pointed)
if pointed.type ~= 'node' then return end
Expand Down
2 changes: 1 addition & 1 deletion mods/sbz_progression/quests/Decorator.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ More fancy traditional bricks to build with.

### Meta

Requires: Clay
Requires: Dirt

## Mystery Terrarium

Expand Down
96 changes: 96 additions & 0 deletions mods/sbz_resources/bomb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,99 @@ core.register_node("sbz_resources:bomb", {
core.add_entity(pos, "sbz_resources:bomb_entity", owner)
end
})

local function fission_bomb_detonate(obj, owner)
sbz_api.explode(obj:get_pos(), 256, 0.9, true, owner or "", 2.5, nil, true)
obj:remove()
end

local fission_time = 5

core.register_entity("sbz_resources:fission_bomb_entity", {
initial_properties = {
physical = true,
collide_with_objects = false,
visual = "cube",
textures = {
"fission_bomb_top.png^[brighten",
"fission_bomb_top.png^[brighten",
"fission_bomb.png^[brighten",
"fission_bomb.png^[brighten",
"fission_bomb.png^[brighten",
"fission_bomb.png^[brighten",
},
static_save = false,
pointable = true
},

on_activate = function(self, staticdata)
self.object:set_armor_groups({ immortal = 1, can_move = 1 })
self.time = fission_time
self.owner = staticdata
self.object:add_velocity(vector.new(0, 1, 0))
self.object:set_acceleration(vector.new(0, -sbz_api.gravity, 0))
end,

on_step = function(self, dtime, moveresult)
self.time = self.time - dtime
self.object:set_acceleration(vector.new(0, -sbz_api.gravity, 0))

if moveresult.touching_ground or moveresult.standing_on_object then
self.object:set_velocity(self.object:get_velocity() * 0.9)
end

if self.time <= 0 then
fission_bomb_detonate(self.object, self.owner)
end
end,
})

core.register_node("sbz_resources:fission_bomb", {
description = "Fission Bomb",
tiles = {
"fission_bomb_top.png",
"fission_bomb_top.png",
"fission_bomb.png"
},
groups = { matter = 1, explody = 100 },
sounds = {
footstep = { name = 'gen_full_container_thunk', gain = 0.2, pitch = 0.5 },
dig = { name = 'gen_pew_waveform', gain = 0.2, pitch = 0.1 },
dug = { name = 'gen_pew_flange', gain = 1.0, pitch = 1.0 },
place = { name = 'gen_full_container_thunk', gain = 0.7, pitch = 1.0 },
},

on_rightclick = function(pos, node, player)
local name = player:get_player_name()

if core.is_protected(pos, name) then
return core.record_protection_violation(pos, name)
end

core.remove_node(pos)
core.add_entity(pos, "sbz_resources:fission_bomb_entity", name)

core.sound_play("gen_noise_fuse", {
pos = pos,
gain = 1.2,
fade = 10.0,
pitch = 0.8, -- deeper sound?
})
end,

on_blast = function(pos, power, original_pos, owner)
if core.is_protected(pos, owner) then return end

core.remove_node(pos)
core.add_entity(pos, "sbz_resources:fission_bomb_entity", owner)
end
})

core.register_craft({
output = "sbz_resources:fission_bomb",
recipe = {
{ "sbz_resources:bomb", "sbz_chem:lead_block", "sbz_resources:bomb" },
{ "sbz_resources:heating_element", "sbz_chem:plutonium_fuel_rod", "sbz_resources:heating_element" },
{ "sbz_resources:bomb", "sbz_chem:lead_block", "sbz_resources:bomb" }
}
})
Binary file added mods/sbz_resources/textures/fission_bomb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/sbz_resources/textures/fission_bomb_top.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions mods/sbz_resources/wormhole.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ sbz_api.recipe.register_craft {
items = {
"sbz_resources:unrefined_firmament",
"sbz_resources:gravitational_lens",
"",
},
}

Expand Down
Loading