From baf6d6ac44634555523c4539d3d28778b869212f Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Sun, 30 Oct 2022 11:08:33 -0700 Subject: [PATCH] handle interation w/ explosions --- api/register_machine.lua | 45 +++++++++++++++- modules/anvil/anvil.lua | 6 +++ modules/anvil/entity.lua | 19 +++++-- modules/water/api.lua | 92 --------------------------------- modules/water/entity.lua | 22 ++++++++ modules/water/init.lua | 1 - modules/water/well.lua | 108 ++++++++++++++++++++++++++++++++++++++- 7 files changed, 193 insertions(+), 100 deletions(-) delete mode 100644 modules/water/api.lua diff --git a/api/register_machine.lua b/api/register_machine.lua index 019756f..2240325 100644 --- a/api/register_machine.lua +++ b/api/register_machine.lua @@ -99,6 +99,26 @@ function api.register_machine(name, def) api.update(pos) end, + on_destruct = function(pos) + if def.inv_info then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + for inv_name, size in pairs(def.inv_info) do + for i = 1, size do + local item = inv:get_stack(inv_name, i) + if not item:is_empty() then + minetest.add_item(pos, item) + inv:set_stack(inv_name, i, "") + end + end + end + end + + if def.on_destruct then + def.on_destruct(pos) + end + end, + on_receive_fields = function(pos, formname, fields, sender) if fields.public and toggle_public(pos, sender) then api.update(pos) @@ -233,7 +253,30 @@ function api.register_machine(name, def) on_timer = def.on_timer, - on_blast = function() + on_blast = function(pos, intensity) + if minetest.is_protected(pos, "tnt:blast") then + return + end + + local drops = {name} + + if def.inv_info then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + for inv_name, size in pairs(def.inv_info) do + for i = 1, size do + local item = inv:get_stack(inv_name, i) + if not item:is_empty() then + table.insert(drops, item) + inv:set_stack(inv_name, i, "") + end + end + end + end + + minetest.remove_node(pos) + + return drops end, }) diff --git a/modules/anvil/anvil.lua b/modules/anvil/anvil.lua index 4fb9359..d98dbce 100644 --- a/modules/anvil/anvil.lua +++ b/modules/anvil/anvil.lua @@ -434,6 +434,10 @@ function anvil.preserve_metadata(pos, oldnode, oldmeta, drops) return drops end +function anvil.on_destruct(pos) + anvil.clear_entity(pos) +end + cottages.api.register_machine("cottages:anvil", { description = S("anvil"), drawtype = "nodebox", @@ -468,6 +472,8 @@ cottages.api.register_machine("cottages:anvil", { allow_metadata_inventory_move = anvil.allow_metadata_inventory_move, allow_metadata_inventory_put = anvil.allow_metadata_inventory_put, allow_metadata_inventory_take = anvil.allow_metadata_inventory_take, + + on_destruct = anvil.on_destruct, }) -- clear hud info diff --git a/modules/anvil/entity.lua b/modules/anvil/entity.lua index bb1e9bd..5726d50 100644 --- a/modules/anvil/entity.lua +++ b/modules/anvil/entity.lua @@ -4,11 +4,15 @@ local deserialize = minetest.deserialize local serialize = minetest.serialize minetest.register_entity("cottages:anvil_item", { - hp_max = 1, - visual = "wielditem", - visual_size = {x = .33, y = .33}, - collisionbox = {0, 0, 0, 0, 0, 0}, - physical = false, + initial_properties = { + hp_max = 1, + visual = "wielditem", + visual_size = {x = .33, y = .33}, + collisionbox = {0, 0, 0, 0, 0, 0}, + physical = false, + collide_with_objects = false, + pointable = false, + }, get_staticdata = function(self) return serialize({self.pos, self.item}) @@ -34,6 +38,11 @@ minetest.register_entity("cottages:anvil_item", { self.item = item obj:set_properties({wield_item = item}) + obj:set_armor_groups({immortal = 1}) + end, + + on_blast = function(self, damage) + return false, false, {} end, }) diff --git a/modules/water/api.lua b/modules/water/api.lua deleted file mode 100644 index c939e9c..0000000 --- a/modules/water/api.lua +++ /dev/null @@ -1,92 +0,0 @@ -local ci = cottages.craftitems -local s = cottages.sounds - -local settings = cottages.settings.water - -local api = cottages.water - -local sound_handles_by_pos = {} -local particlespawner_ids_by_pos = {} - -function api.add_filling_effects(pos) - local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) - - local spos = minetest.pos_to_string(pos) - - local previous_handle = sound_handles_by_pos[spos] - if previous_handle then - minetest.sound_stop(previous_handle) - end - sound_handles_by_pos[spos] = minetest.sound_play( - {name = s.water_fill}, - {pos = entity_pos, loop = true, gain = 0.5, pitch = 2.0} - ) - - local previous_id = particlespawner_ids_by_pos[spos] - if previous_id then - minetest.delete_particlespawner(previous_id) - end - local particle_pos = vector.add(pos, vector.new(0, 1/2 + 1/16, 0)) - particlespawner_ids_by_pos[spos] = minetest.add_particlespawner({ - amount = 10, - time = 0, - collisiondetection = false, - texture = "bubble.png", - minsize = 1, - maxsize = 1, - minexptime = 0.4, - maxexptime = 0.4, - minpos = particle_pos, - maxpos = particle_pos, - minvel = vector.new(-0.1, -0.2, -0.01), - maxvel = vector.new(0.1, -0.2, 0.1), - minacc = vector.new(0, -2, 0), - maxacc = vector.new(0, -2, 0), - }) -end - -function api.fill_bucket(pos) - local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) - - for _, obj in ipairs(minetest.get_objects_inside_radius(entity_pos, .1)) do - local ent = obj:get_luaentity() - if ent and ent.name == "cottages:bucket_entity" then - local props = obj:get_properties() - props.wield_item = ci.bucket_filled - obj:set_properties(props) - end - end - - local meta = minetest.get_meta(pos) - meta:set_string("bucket", ci.bucket_filled) - - local spos = minetest.pos_to_string(pos) - local handle = sound_handles_by_pos[spos] - if handle then - minetest.sound_stop(handle) - end - local id = particlespawner_ids_by_pos[spos] - if id then - minetest.delete_particlespawner(id) - end -end - -function api.initialize_entity(pos) - local meta = minetest.get_meta(pos) - local bucket = meta:get("bucket") - if bucket then - local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) - local obj = minetest.add_entity(entity_pos, "cottages:bucket_entity") - local props = obj:get_properties() - props.wield_item = bucket - obj:set_properties(props) - - if bucket == ci.bucket then - local timer = minetest.get_node_timer(pos) - if not timer:is_started() then - timer:start(settings.well_fill_time) - end - api.add_filling_effects(pos) - end - end -end diff --git a/modules/water/entity.lua b/modules/water/entity.lua index 3000010..e2960a5 100644 --- a/modules/water/entity.lua +++ b/modules/water/entity.lua @@ -11,4 +11,26 @@ minetest.register_entity("cottages:bucket_entity", { physical = false, static_save = false, }, + + get_staticdata = function(self) + -- note: static_save is false, so this won't get called, but i may revise that decision + return self.object:get_properties().wield_item + end, + + on_activate = function(self, staticdata, dtime_s) + if not staticdata or staticdata == "" then + minetest.chat_send_all("invalid cottages:bucket_entity initialization") + self.object:remove() + return + end + + local obj = self.object + + obj:set_properties({wield_item = staticdata}) + obj:set_armor_groups({immortal = 1}) + end, + + on_blast = function(self, damage) + return false, false, {} + end, }) diff --git a/modules/water/init.lua b/modules/water/init.lua index 55cd941..7bb7f98 100644 --- a/modules/water/init.lua +++ b/modules/water/init.lua @@ -4,7 +4,6 @@ end cottages.water = {} -cottages.dofile("modules", "water", "api") cottages.dofile("modules", "water", "entity") cottages.dofile("modules", "water", "well") cottages.dofile("modules", "water", "crafts") diff --git a/modules/water/well.lua b/modules/water/well.lua index cc45c9a..81b4ec6 100644 --- a/modules/water/well.lua +++ b/modules/water/well.lua @@ -7,6 +7,11 @@ local t = cottages.textures local water = cottages.water local ci = cottages.craftitems +local settings = cottages.settings.water + +local sound_handles_by_pos = {} +local particlespawner_ids_by_pos = {} + local well_fill_time = cottages.settings.water.well_fill_time function water.get_well_fs_parts(pos) @@ -45,7 +50,7 @@ function water.use_well(pos, puncher) if wielded_name == ci.bucket then meta:set_string("bucket", wielded_name) - minetest.add_entity(entity_pos, "cottages:bucket_entity") + water.initialize_entity(pos) pinv:remove_item("main", "bucket:bucket_empty") @@ -88,6 +93,83 @@ function water.use_well(pos, puncher) end end +function water.add_filling_effects(pos) + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + + local spos = minetest.hash_node_position(pos) + + local previous_handle = sound_handles_by_pos[spos] + if previous_handle then + minetest.sound_stop(previous_handle) + end + sound_handles_by_pos[spos] = minetest.sound_play( + {name = s.water_fill}, + {pos = entity_pos, loop = true, gain = 0.5, pitch = 2.0} + ) + + local previous_id = particlespawner_ids_by_pos[spos] + if previous_id then + minetest.delete_particlespawner(previous_id) + end + local particle_pos = vector.add(pos, vector.new(0, 1/2 + 1/16, 0)) + particlespawner_ids_by_pos[spos] = minetest.add_particlespawner({ + amount = 10, + time = 0, + collisiondetection = false, + texture = "bubble.png", + minsize = 1, + maxsize = 1, + minexptime = 0.4, + maxexptime = 0.4, + minpos = particle_pos, + maxpos = particle_pos, + minvel = vector.new(-0.1, -0.2, -0.01), + maxvel = vector.new(0.1, -0.2, 0.1), + minacc = vector.new(0, -2, 0), + maxacc = vector.new(0, -2, 0), + }) +end + +function water.fill_bucket(pos) + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + + for _, obj in ipairs(minetest.get_objects_inside_radius(entity_pos, .1)) do + local ent = obj:get_luaentity() + if ent and ent.name == "cottages:bucket_entity" then + obj:set_properties({wield_item = ci.bucket_filled}) + end + end + + local meta = minetest.get_meta(pos) + meta:set_string("bucket", ci.bucket_filled) + + local spos = minetest.hash_node_position(pos) + local handle = sound_handles_by_pos[spos] + if handle then + minetest.sound_stop(handle) + end + local id = particlespawner_ids_by_pos[spos] + if id then + minetest.delete_particlespawner(id) + end +end + +function water.initialize_entity(pos) + local meta = minetest.get_meta(pos) + local bucket = meta:get("bucket") + if bucket then + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + minetest.add_entity(entity_pos, "cottages:bucket_entity", bucket) + + if bucket == ci.bucket then + local timer = minetest.get_node_timer(pos) + if not timer:is_started() then + timer:start(settings.well_fill_time) + end + water.add_filling_effects(pos) + end + end +end cottages.api.register_machine("cottages:water_gen", { description = S("Tree Trunk Well"), @@ -161,6 +243,30 @@ cottages.api.register_machine("cottages:water_gen", { end, use = water.use_well, + + on_destruct = function(pos) + local entity_pos = vector.add(pos, vector.new(0, 1/4, 0)) + + for _, obj in ipairs(minetest.get_objects_inside_radius(entity_pos, .1)) do + local ent = obj:get_luaentity() + if ent and ent.name == "cottages:bucket_entity" then + minetest.add_item(pos, obj:get_properties().wield_item) + obj:remove() + end + end + + local spos = minetest.hash_node_position(pos) + + local handle = sound_handles_by_pos[spos] + if handle then + minetest.sound_stop(handle) + end + + local id = particlespawner_ids_by_pos[spos] + if id then + minetest.delete_particlespawner(id) + end + end, }) if cottages.has.node_entity_queue then