Initial commit (version 0.1-test)

This commit is contained in:
2022-11-21 16:12:22 -05:00
commit e4e2a9116d
2062 changed files with 52261 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
explosion sounds (CC0) from https://freesound.org/people/tommccann/sounds/235968/
touch sounds (CC0) from http://freesound.org/people/talesjc/sounds/152572/
extinguish sounds (CC0) from http://freesound.org/people/Planet-Leader/sounds/155516/
textures (CC0) made with the GNU image manipulation program
code (CC0) partially copied from my version of the nuke mod

View File

@@ -0,0 +1,6 @@
For a description of this Minetest mod, see
https://forum.minetest.net/viewtopic.php?f=9&t=10263.
TODO:
* Add a fire extinguisher node which automatically shoots at fire nodes
* Add an alternative recipe if poisonify is not available

347
mods/extinguisher/init.lua Normal file
View File

@@ -0,0 +1,347 @@
local range = 100
local v = 1
local a = 100
local speed = 0.1 --0 or less for default maximum speed
local function spray_foam(pos)
if minetest.get_node(pos).name == "extinguisher:foam" then
-- Do not spray foam onto foam
return
end
for z = -1,1 do
for y = -1,1 do
for x = -1,1 do
local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
local nn = minetest.get_node(p).name
if nn == "fire:basic_flame" or nn == "fire:permanent_flame" then
minetest.set_node(p, {name="air"})
minetest.sound_play("fire_extinguish_flame",
{pos = p, max_hear_distance = 16, gain = 0.15})
minetest.check_for_falling(p)
elseif math.random(0,3) >= 1 then
if nn == "air" then
minetest.set_node(p, {name="air"})
minetest.check_for_falling(p)
end
end
end
end
end
end
local function extinguish(player)
--local t1 = os.clock()
local playerpos = player:get_pos()
local dir = player:get_look_dir()
local startpos = vector.new(playerpos)
startpos.y = startpos.y+1.625
local bl, pos = minetest.line_of_sight(startpos,
vector.add(vector.multiply(dir, range), startpos), 1)
local snd = minetest.sound_play("extinguisher",
{pos = playerpos, gain = 0.5, max_hear_distance = range})
local flight_time = 1
if pos then
local s = math.max(vector.distance(startpos, pos)-0.5, 0)
flight_time = (math.sqrt(v * v + 2 * a * s) - v) / a
end
if not bl then
minetest.after(flight_time, function()
-- Extinguish the node
minetest.sound_stop(snd)
spray_foam(vector.round(pos))
end)
end
minetest.add_particle({
pos = startpos,
velocity = vector.multiply(dir, v),
acceleration = vector.multiply(dir, a),
expirationtime = flight_time,
size = 1,
texture = "extinguisher_shot.png^[transform" .. math.random(0,7),
})
--print("[extinguisher] my shot was calculated after "..tostring(os.clock()-t1).."s")
end
--[[
local function table_empty(t)
for _,_ in pairs(t) do
return false
end
return true
end
local function get_tab(pos)
local tab_tmp = {pos}
local tab_avoid = {[pos.x.." "..pos.y.." "..pos.z] = true}
local tab_done,num = {pos},2
while not table_empty(tab_tmp) do
for n,p in pairs(tab_tmp) do
tab_tmp[n] = nil
for z = -2,2 do
for y = -2,2 do
for x = -2,2 do
local p2 = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
local pstr = p2.x.." "..p2.y.." "..p2.z
if not tab_avoid[pstr]
and minetest.get_node(p2).name == "fire:basic_flame" then
tab_avoid[pstr] = true
tab_done[num] = p2
num = num+1
table.insert(tab_tmp, p2)
end
end
end
end
end
end
return tab_done
end]]
local function stop_all_fire_sounds()
local players = minetest.get_connected_players()
for i = 1, #players do
fire.update_player_sound(players[i])
end
end
local c_fire, c_foam, c_lava, c_lavaf, c_obsidian, c_cobble
local function extinguish_fire(pos)
local t1 = os.clock()
c_fire = c_fire or minetest.get_content_id("fire:basic_flame")
c_fire1 = c_fire1 or minetest.get_content_id("fire:permanent_flame")
c_foam = c_foam or minetest.get_content_id("extinguisher:foam")
local tab = vector.explosion_table(40)
local manip = minetest.get_voxel_manip()
local emerged_pos1, emerged_pos2 = manip:read_from_map(vector.add(pos, -40),
vector.add(pos, 40))
local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
local nodes = manip:get_data()
for _,i in pairs(tab) do
local ran = i[2]
if not ran
or math.random(2) == 1 then
local p = area:indexp(vector.add(pos, i[1]))
local d_p = nodes[p]
if d_p == c_fire then
nodes[p] = air;
elseif d_p == c_fire1 then
nodes[p] = air;
end
end
end
manip:set_data(nodes)
manip:write_to_map()
stop_all_fire_sounds()
print(string.format("[extinguisher] exploded at %s after ca. %.2fs",
minetest.pos_to_string(pos), os.clock() - t1))
--[[t1 = os.clock()
manip:update_map()
print(string.format("[extinguisher] map updated after ca. %.2fs", os.clock() - t1))]]
end
local function eexpl(pos)
if minetest.get_node(pos).name ~= "extinguisher:automatic" then
return
end
minetest.sound_play("extinguisher_explosion", {pos=pos})
minetest.set_node(pos, {name="extinguisher:destroyed"})
local startpos = minetest.find_node_near(pos, 2, {"fire:basic_flame"})
if not startpos then
return
end
extinguish_fire(startpos)
end
minetest.register_node("extinguisher:foam", {
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
}
},
use_texture_alpha = "blend",
tiles = {"extinguisher_foam.png"},
drop = "",
groups = {dig_immediate=3, puts_out_fire=1, not_in_creative_inventory=1, falling_node=1},
})
local adtime = 0
local time = minetest.get_us_time()
local count = 0
minetest.register_abm({
nodenames = {"extinguisher:foam"},
interval = 5,
chance = 5,
catch_up = false,
action = function(pos)
count = count+1
local ct = minetest.get_us_time()
if count > 10
and ct-time < 1000000 then
return
end
time = ct
count = 0
minetest.remove_node(pos)
if adtime < 0.1 then
minetest.check_for_falling(pos)
end
end,
})
minetest.register_node("extinguisher:automatic", {
description = "Extinguisher",
tiles = {"extinguisher_top.png", "extinguisher_bottom.png",
"extinguisher.png", "extinguisher.png^[transformFX",
"extinguisher_front.png", "extinguisher_back.png"},
use_texture_alpha = "opaque",
inventory_image = "extinguisher.png",
wield_image = "extinguisher_pipe.png",
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
-- Main bottle
{-2/16, -0.5, -5/16, 3/16, 0, 0},
{-1/16, 0, -5/16, 2/16, 3/16, 0},
{-2/16, 0, -4/16, 3/16, 3/16, -1/16},
{-1/16, 3/16, -4/16, 2/16, 5/16, -1/16},
{0, 5/16, -3/16, 1/16, 6/16, -2/16},
-- Outlet
{0, 3/16, -1/16, 1/16, 4/16, 2/16},
{-1/16, 3/16, 2/16, 0, 4/16, 4/16},
{1/16, 3/16, 2/16, 2/16, 4/16, 4/16},
{0, 4/16, 2/16, 1/16, 5/16, 6/16},
{0, 2/16, 2/16, 1/16, 3/16, 6/16},
-- Handle
{0, 6/16, -6/16, 1/16, 7/16, -1/16},
{-1/16, 6/16, -3/16, 2/16, 7/16, -2/16},
{0, 5/16, -7/16, 1/16, 6/16, -5/16},
{0, 4/16, -7/16, 1/16, 5/16, -6/16},
},
},
groups = {dig_immediate=2},
sounds = {dig=""},
on_punch = function(pos, _, player)
minetest.sound_play("extinguisher_touch", {pos=pos, gain=0.25, max_hear_distance=8})
if player:get_wielded_item():get_name() == "main:torch" then
minetest.after(math.random()*5, eexpl, pos)
end
end,
on_use = function() -- do not dig or punch nodes
end,
})
minetest.register_node("extinguisher:destroyed", {
description = "Destroyed Extinguisher",
tiles = {"extinguisher_top.png", "extinguisher_bottom.png",
"extinguisher.png", "extinguisher.png^[transformFX",
"extinguisher_front.png", "extinguisher_destroyed.png"},
use_texture_alpha = "opaque",
inventory_image = "extinguisher.png",
wield_image = "extinguisher_pipe.png",
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
-- Main bottle
{-2/16, -0.5, -3/16, 3/16, 0, 0},
{-1/16, 0, -5/16, 1/16, 3/16, 0},
{-1/16, 0, -4/16, 3/16, 3/16, -1/16},
{-1/16, -3/16, -4/16, 2/16, 4/16, -1/16},
},
},
groups = {dig_immediate=2},
sounds = {dig=""},
on_punch = function(pos, _, player)
minetest.sound_play("extinguisher_touch", {pos=pos, gain=0.25, max_hear_distance=8})
if player:get_wielded_item():get_name() == "main:torch" then
minetest.after(math.random()*5, eexpl, pos)
end
end,
on_use = function() -- do not dig or punch nodes
end,
})
local timer = 0
minetest.register_globalstep(function(dtime)
adtime = dtime
timer = timer+dtime
if timer < speed then
return
end
timer = 0
for _,player in pairs(minetest.get_connected_players()) do
if player:get_wielded_item():get_name() == "extinguisher:automatic"
and player:get_player_control().LMB then
extinguish(player)
end
end
end)
minetest.register_craftitem("extinguisher:foam_ingredient_1", {
description = "Foam Ingredient",
inventory_image = "extinguisher_essence_1.png",
})
minetest.register_craftitem("extinguisher:foam_ingredient_2", {
description = "Foam Ingredient",
inventory_image = "extinguisher_essence_2.png",
})
minetest.register_craftitem("extinguisher:foam_bucket", {
description = "Foam",
inventory_image = "extinguisher_foam_bucket.png",
})
if minetest.registered_items["poisonivy:climbing"] then
minetest.register_craft({
output = "extinguisher:foam_ingredient_1 2",
recipe = {
{"default:stone"},
{"poisonivy:climbing"},
{"default:stone"},
},
replacements = {{"default:stone", "default:stone"}, {"default:stone", "default:stone"}},
})
minetest.register_craft({
output = "extinguisher:foam_ingredient_2",
recipe = {
{"default:stone"},
{"poisonivy:seedling"},
{"default:stone"},
},
replacements = {{"default:stone", "default:stone"}, {"default:stone", "default:stone"}},
})
minetest.register_craft({
output = "extinguisher:foam_ingredient_2 3",
recipe = {
{"default:stone"},
{"poisonivy:sproutling"},
{"default:stone"},
},
replacements = {{"default:stone", "default:stone"}, {"default:stone", "default:stone"}},
})
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B