diff --git a/change.log b/change.log index c1e5821..ab3a85f 100644 --- a/change.log +++ b/change.log @@ -15,3 +15,10 @@ v0.1.2 * Added support for hopper as optional dependency for droppers, dispensers and collectors. * Added digilines message to punchers when something is punched. + + +v0.1.3 +* Added hp and height info from detector. +* Added dispensers spawn if spawner with optional dependency on mobs mod. + If mobs:egg is dispensed 10% change a chicken is dispensed instead. +* Added player_button. diff --git a/crafting.lua b/crafting.lua index 8dd221d..d2873b6 100644 --- a/crafting.lua +++ b/crafting.lua @@ -121,6 +121,21 @@ end -- utils.digilines_supported +if utils.digilines_supported and utils.digistuff_supported then + + +minetest.register_craft({ + output = "lwcomponents:player_button", + recipe = { + { "mesecons_button:button_off", "digilines:wire_std_00000000" } + }, +}) + + +end -- utils.digilines_supported and utils.digistuff_supported + + + if utils.mesecon_supported and mesecon.mvps_push then minetest.register_craft ({ diff --git a/depends.txt b/depends.txt index be9235a..aac988c 100644 --- a/depends.txt +++ b/depends.txt @@ -5,3 +5,5 @@ digilines? unifieddyes? intllib? hopper? +mobs? +digistuff? diff --git a/detector.lua b/detector.lua index d009964..00fd91e 100644 --- a/detector.lua +++ b/detector.lua @@ -60,7 +60,7 @@ end -local function send_detect_message (pos, item_type, name, label, item_pos, count) +local function send_detect_message (pos, item_type, name, label, item_pos, count, hp, height) if utils.digilines_supported then local meta = minetest.get_meta (pos) @@ -76,7 +76,9 @@ local function send_detect_message (pos, item_type, name, label, item_pos, count name = name, label = label, pos = to_relative_coords (pos, item_pos), - count = count }) + count = count, + hp = hp, + height = height }) end end end @@ -132,6 +134,33 @@ end +local function get_entity_height (objref) + if objref.get_luaentity then + entity = objref:get_luaentity () + + if entity and entity.name then + def = minetest.registered_entities[entity.name] + + if def and type (def.collisionbox) == "table" and + type (def.collisionbox[5]) == "number" then + + return def.collisionbox[5] + end + end + end + + local props = objref:get_properties () + if props and props.collisionbox and type (props.collisionbox) == "table" and + type (props.collisionbox[5]) == "number" then + + return props.collisionbox[5] + end + + return 0 +end + + + local function detect (pos) local meta = minetest.get_meta (pos) local detected = false @@ -153,7 +182,9 @@ local function detect (pos) object[i]:get_player_name (), object[i]:get_player_name (), object[i]:get_pos (), - 1) + 1, + object[i]:get_hp (), + get_entity_height (object[i])) detected = true end @@ -174,7 +205,9 @@ local function detect (pos) stack:get_name (), stack:get_name (), object[i]:get_pos (), - stack:get_count ()) + stack:get_count (), + 0, + 0) detected = true end @@ -203,7 +236,9 @@ local function detect (pos) name, label, object[i]:get_pos (), - 1) + 1, + object[i]:get_hp (), + get_entity_height (object[i])) detected = true @@ -228,7 +263,9 @@ local function detect (pos) node.name, node.name, testpos, - 1) + 1, + 0, + 0) detected = true end diff --git a/dispenser.lua b/dispenser.lua index 7d13a59..415d870 100644 --- a/dispenser.lua +++ b/dispenser.lua @@ -64,6 +64,90 @@ end +local function try_spawn (pos, node, item) + if utils.mobs_supported then + local mob = item:get_name () + local item_def = minetest.registered_craftitems[mob] + local spawn_pos = dispense_pos (pos, node) + + if item_def and item_def.groups and item_def.groups.spawn_egg then + if mob:sub (mob:len () - 4) == "_set" then + mob = mob:sub (1, mob:len () - 5) + + if minetest.registered_entities[mob] then + local data = item:get_metadata () + local smob = minetest.add_entity (spawn_pos, mob, data) + local ent = smob and smob:get_luaentity () + + if ent then + local meta = minetest.get_meta (pos) + + if meta then + local owner = meta:get_string ("owner") + + -- set owner if not a monster + if owner:len () > 0 and ent.type ~= "monster" then + ent.owner = owner + ent.tamed = true + end + end + end + + return smob + end + + else + if minetest.registered_entities[mob] then + local smob = minetest.add_entity (spawn_pos, mob) + local ent = smob and smob:get_luaentity () + + if ent then + local meta = minetest.get_meta (pos) + + if meta then + local owner = meta:get_string ("owner") + + -- set owner if not a monster + if owner:len () > 0 and ent.type ~= "monster" then + ent.owner = owner + ent.tamed = true + end + end + end + + return smob + end + + end + + elseif mob == "mobs:egg" then + if math.random (1, 10) == 1 then + local smob = minetest.add_entity (spawn_pos, "mobs_animal:chicken") + local ent = smob and smob:get_luaentity () + + if ent then + local meta = minetest.get_meta (pos) + + if meta then + local owner = meta:get_string ("owner") + + -- set owner if not a monster + if owner:len () > 0 and ent.type ~= "monster" then + ent.owner = owner + ent.tamed = true + end + end + end + + return smob + end + end + end + + return nil +end + + -- slot: -- nil - next item, no dispense if empty -- number - 1 item from slot, no dispense if empty @@ -119,7 +203,11 @@ local function dispense_item (pos, node, slot) if item then item:set_count (1) - local obj = minetest.add_item (dispense_pos (pos, node), item) + local obj = try_spawn (pos, node, item) + + if not obj then + obj = minetest.add_item (dispense_pos (pos, node), item) + end if obj then obj:set_velocity (dispense_velocity (node)) diff --git a/init.lua b/init.lua index 20dbfa2..ad60e55 100644 --- a/init.lua +++ b/init.lua @@ -1,4 +1,4 @@ -local version = "0.1.2" +local version = "0.1.3" local mod_storage = minetest.get_mod_storage () @@ -22,6 +22,7 @@ loadfile (modpath.."/dispenser.lua") (utils) loadfile (modpath.."/detector.lua") (utils) loadfile (modpath.."/siren.lua") (utils) loadfile (modpath.."/puncher.lua") (utils) +loadfile (modpath.."/player_button.lua") (utils) loadfile (modpath.."/extras.lua") (utils) loadfile (modpath.."/digiswitch.lua") (utils) loadfile (modpath.."/movefloor.lua") (utils) diff --git a/license.txt b/license.txt index 635ce81..051713c 100644 --- a/license.txt +++ b/license.txt @@ -64,6 +64,8 @@ Media license siren images derived from images from https://openclipart.org, which is public domain. +player button images derived from mesecons button image. + All other media, or media not covered by a licence, is licensed Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) diff --git a/mod.conf b/mod.conf index a9c7ebb..e5748c6 100644 --- a/mod.conf +++ b/mod.conf @@ -3,4 +3,4 @@ description = Various components for mesecons and digilines. title = LWComponents name = lwcomponents depends = default -optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper +optional_depends = lwdrops, mesecons, digilines, unifieddyes, intllib, hopper, mobs, digistuff diff --git a/player_button.lua b/player_button.lua new file mode 100644 index 0000000..33ea484 --- /dev/null +++ b/player_button.lua @@ -0,0 +1,232 @@ +local utils = ... +local S = utils.S + + + +if utils.digilines_supported and utils.digistuff_supported then + + + +local function on_contruct (pos) + local meta = minetest.get_meta(pos) + local spec = + "size[7.5,3]".. + "field[1,1;6,2;channel;Channel;${channel}]".. + "button_exit[2.5,2;3,1;submit;Set]" + + meta:set_string("formspec", spec) +end + + + +local function on_receive_fields (pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + + if fields.submit then + if fields.channel ~= "" then + meta:set_string ("channel", fields.channel) + meta:set_string ("formspec", "") + minetest.swap_node (pos, { name = "lwcomponents:player_button_off", + param2 = minetest.get_node(pos).param2 }) + else + minetest.chat_send_player (sender:get_player_name(), "Please set a channel!") + end + end +end + + + +local function player_button_push (pos, node, player) + local meta = minetest.get_meta (pos) + + if player and player:is_player () then + local channel = meta:get_string ("channel") + local formspec = meta:get_string ("formspec") + + if channel:len () > 0 and formspec:len () == 0 then + utils.digilines_receptor_send (pos, + digistuff.button_get_rules (node), + channel, + { action = "player", + name = player:get_player_name () }) + end + end + + if node.name == "lwcomponents:player_button_off" then + node.name = "lwcomponents:player_button_on" + + minetest.swap_node(pos, node) + + if digistuff.mesecons_installed then + minetest.sound_play ("mesecons_button_push", { pos = pos }) + end + + minetest.get_node_timer (pos):start (0.25) + end +end + + + +local function player_button_turnoff (pos) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + + if node.name == "lwcomponents:player_button_on" then + node.name = "lwcomponents:player_button_off" + + minetest.swap_node (pos, node) + + if digistuff.mesecons_installed then + minetest.sound_play ("mesecons_button_pop", { pos = pos }) + end + end +end + + + +minetest.register_node ("lwcomponents:player_button", { + description = "Player Button", + drawtype = "nodebox", + tiles = { + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button.png" + }, + paramtype = "light", + paramtype2 = "facedir", + legacy_wallmounted = true, + walkable = false, + sunlight_propagates = true, + drop = "lwcomponents:player_button", + selection_box = { + type = "fixed", + fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } + }, + node_box = { + type = "fixed", + fixed = { + { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button + { -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself + } + }, + groups = { dig_immediate = 2, digiline_receiver = 1 }, + _digistuff_channelcopier_fieldname = "channel", + sounds = default and default.node_sound_stone_defaults(), + + digiline = + { + receptor = {}, + wire = { + rules = digistuff.button_get_rules, + }, + }, + + on_construct = on_contruct, + after_place_node = digistuff.place_receiver, + after_destruct = digistuff.remove_receiver, + on_receive_fields = on_receive_fields, +}) + + + +minetest.register_node ("lwcomponents:player_button_off", { + description = "Player Button", + drawtype = "nodebox", + tiles = { + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button.png" + }, + paramtype = "light", + paramtype2 = "facedir", + legacy_wallmounted = true, + walkable = false, + sunlight_propagates = true, + drop = "lwcomponents:player_button", + selection_box = { + type = "fixed", + fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } + }, + node_box = { + type = "fixed", + fixed = { + { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the thin plate behind the button + { -4/16, -2/16, 4/16, 4/16, 2/16, 6/16 } -- the button itself + } + }, + groups = { dig_immediate = 2, digiline_receiver = 1, not_in_creative_inventory = 1 }, + _digistuff_channelcopier_fieldname = "channel", + sounds = default and default.node_sound_stone_defaults(), + + digiline = + { + receptor = {}, + wire = { + rules = digistuff.button_get_rules, + }, + effector = { + action = digistuff.button_handle_digilines, + }, + }, + + after_destruct = digistuff.remove_receiver, + on_rightclick = player_button_push, +}) + + + +minetest.register_node ("lwcomponents:player_button_on", { + description = "Player Button", + drawtype = "nodebox", + tiles = { + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_side.png", + "lwplayer_button_on.png" + }, + paramtype = "light", + paramtype2 = "facedir", + legacy_wallmounted = true, + walkable = false, + sunlight_propagates = true, + light_source = 7, + drop = "lwcomponents:player_button", + selection_box = { + type = "fixed", + fixed = { -6/16, -6/16, 5/16, 6/16, 6/16, 8/16 } + }, + node_box = { + type = "fixed", + fixed = { + { -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, + { -4/16, -2/16, 11/32, 4/16, 2/16, 6/16 } + } + }, + groups = { dig_immediate = 2, digiline_receiver = 1, not_in_creative_inventory = 1 }, + _digistuff_channelcopier_fieldname = "channel", + sounds = default and default.node_sound_stone_defaults(), + + digiline = + { + receptor = {}, + wire = { + rules = digistuff.button_get_rules, + }, + }, + + after_destruct = digistuff.remove_receiver, +-- on_rightclick = player_button_push, + on_timer = player_button_turnoff, +}) + + + +end -- utils.digilines_supported and utils.digistuff_supported diff --git a/readme.txt b/readme.txt index a7850fd..4b570b5 100644 --- a/readme.txt +++ b/readme.txt @@ -101,6 +101,10 @@ Contains an inventory and dispenses (with velocity) an item on command. Also acts as a digilines conductor. If the hopper mod is loaded, will take items from the top and sides, and release them from the bottom. +Dispensers support mobs mod if loaded. Will spawn the entity from an 'egg' +if possible, or the 'egg' is dispensed. If a chicken egg is dispensed a +10% chance a chicken is dispensed instead. + UI Channel - digilines channel of dispenser. @@ -234,7 +238,9 @@ message is a table with the following keys: name = "", label = "