diff --git a/locale/template b/locale/template index 1bf9cd6..3f55ddf 100644 --- a/locale/template +++ b/locale/template @@ -256,8 +256,8 @@ Mover block refueled. Fuel status @1.= Cow= Cows= Mover block. Temperature: @1, Fuel: @2.= -MOVER: Filter defined with unknown node (@1) at @2,@3,@4.= -MOVER: Wrong filter (@1) at @2,@3,@4.= +MOVER: Filter defined with unknown node (@1) at @2, @3, @4.= +MOVER: Wrong filter (@1) at @2, @3, @4.= Mover= object= inventory= diff --git a/mover.lua b/mover.lua index 108d24b..78f3344 100644 --- a/mover.lua +++ b/mover.lua @@ -673,6 +673,7 @@ minetest.register_node("basic_machines:mover", { if upgrade == -1 then if not object then node1 = minetest.get_node(pos1); node1_name = node1.name + if node1_name == "air" or node1_name == "ignore" then return end -- nothing to move if not inventory then source_chest = mover.chests[node1_name] or false end @@ -693,6 +694,7 @@ minetest.register_node("basic_machines:mover", { end else node1 = minetest.get_node(pos1); node1_name = node1.name + if node1_name == "air" or node1_name == "ignore" then return end -- nothing to move if inventory then -- taking items from chests/inventory move fuel_cost = mover.hardness[prefer] or 1 else @@ -882,14 +884,10 @@ minetest.register_node("basic_machines:mover", { elseif msg then meta:set_string("infotext", msg) end - return - end - - if node1_name == "air" then if msg then meta:set_string("infotext", msg) end; return end -- nothing to move -- INVENTORY MODE - if inventory then + elseif inventory then local invName1, invName2 if mreverse == 1 then -- reverse inventory names too @@ -953,276 +951,276 @@ minetest.register_node("basic_machines:mover", { fuel = fuel - fuel_cost; meta:set_float("fuel", fuel) meta:set_string("infotext", S("Mover block. Temperature: @1, Fuel: @2.", T, twodigits_float(fuel))) - return - end -- NORMAL, DIG, DROP, TRANSPORT MODES - local bonemeal + else + local bonemeal - if prefer ~= "" then -- filter check - if source_chest then - bonemeal = mover.bonemeal_table[prefer] - else - if prefer ~= node1_name then -- only take preferred node - if msg then meta:set_string("infotext", msg) end; return + if prefer ~= "" then -- filter check + if source_chest then + bonemeal = mover.bonemeal_table[prefer] else - local inv_stack = meta:get_inventory():get_stack("filter", 1) - if inv_stack:get_count() > 0 then - local inv_palette_index = tonumber(inv_stack:get_meta():get("palette_index")) - if inv_palette_index then - local def = inv_stack:get_definition() - local palette_index = minetest.strip_param2_color(node1.param2, def and def.paramtype2) - if inv_palette_index ~= palette_index then - if msg then meta:set_string("infotext", msg) end; return + if prefer ~= node1_name then -- only take preferred node + if msg then meta:set_string("infotext", msg) end; return + else + local inv_stack = meta:get_inventory():get_stack("filter", 1) + if inv_stack:get_count() > 0 then + local inv_palette_index = tonumber(inv_stack:get_meta():get("palette_index")) + if inv_palette_index then + local def = inv_stack:get_definition() + local palette_index = minetest.strip_param2_color(node1.param2, def and def.paramtype2) + if inv_palette_index ~= palette_index then + if msg then meta:set_string("infotext", msg) end; return + end end end end end + elseif source_chest then -- prefer == "", doesn't know what to take out of chest/inventory + if msg then meta:set_string("infotext", msg) end; return end - elseif source_chest then -- prefer == "", doesn't know what to take out of chest/inventory - if msg then meta:set_string("infotext", msg) end; return - end - local node2_name = minetest.get_node(pos2).name - local target_chest = mover.chests[node2_name] or false + local node2_name = minetest.get_node(pos2).name + local target_chest = mover.chests[node2_name] or false - -- do nothing if target non-empty and not chest and not bonemeal or transport mode and target chest - if not target_chest and node2_name ~= "air" and not bonemeal or transport and target_chest then - if msg then meta:set_string("infotext", msg) end; return - end + -- do nothing if target non-empty and not chest and not bonemeal or transport mode and target chest + if not target_chest and node2_name ~= "air" and not bonemeal or transport and target_chest then + if msg then meta:set_string("infotext", msg) end; return + end - local drop, dig = mode == "drop", mode == "dig" + local drop, dig = mode == "drop", mode == "dig" - -- filtering - if prefer ~= "" then -- preferred node set - local plant, normal = mover.plants_table[prefer], mode == "normal"; local def + -- filtering + if prefer ~= "" then -- preferred node set + local plant, normal = mover.plants_table[prefer], mode == "normal"; local def - if drop or mreverse == 1 and plant or - normal and target_chest - then - node1.name, node1_name = prefer, prefer - elseif normal or dig or transport then - def = minetest.registered_nodes[prefer] - if def then + if drop or mreverse == 1 and plant or + normal and target_chest + then node1.name, node1_name = prefer, prefer + elseif normal or dig or transport then + def = minetest.registered_nodes[prefer] + if def then + node1.name, node1_name = prefer, prefer + else + minetest.chat_send_player(owner, S("MOVER: Filter defined with unknown node (@1) at @2, @3, @4.", + prefer, pos.x, pos.y, pos.z)); return + end else - minetest.chat_send_player(owner, S("MOVER: Filter defined with unknown node (@1) at @2,@3,@4.", + minetest.chat_send_player(owner, S("MOVER: Wrong filter (@1) at @2, @3, @4.", prefer, pos.x, pos.y, pos.z)); return end - else - minetest.chat_send_player(owner, S("MOVER: Wrong filter (@1) at @2,@3,@4.", - prefer, pos.x, pos.y, pos.z)); return - end - if source_chest and not transport then -- take stuff from chest - local inv_stack = meta:get_inventory():get_stack("filter", 1) - local stack, match_meta = ItemStack(prefer), false - local inv = minetest.get_meta(pos1):get_inventory() + if source_chest and not transport then -- take stuff from chest + local inv_stack = meta:get_inventory():get_stack("filter", 1) + local stack, match_meta = ItemStack(prefer), false + local inv = minetest.get_meta(pos1):get_inventory() - if inv_stack:get_count() > 0 then - local palette_index = tonumber(inv_stack:get_meta():get("palette_index")) - if palette_index then - stack:get_meta():set_int("palette_index", palette_index) - match_meta = true; node1.param1, node1.param2 = nil, palette_index + if inv_stack:get_count() > 0 then + local palette_index = tonumber(inv_stack:get_meta():get("palette_index")) + if palette_index then + stack:get_meta():set_int("palette_index", palette_index) + match_meta = true; node1.param1, node1.param2 = nil, palette_index + end end - end - if inv:contains_item("main", stack, match_meta) then - if mreverse == 1 and not match_meta then - if normal or dig then - if plant then -- planting mode: check if transform seed -> plant is needed - def = minetest.registered_nodes[plant] - if def then - node1 = {name = plant, param1 = nil, - param2 = def.place_param2} - node1_name = plant + if inv:contains_item("main", stack, match_meta) then + if mreverse == 1 and not match_meta then + if normal or dig then + if plant then -- planting mode: check if transform seed -> plant is needed + def = minetest.registered_nodes[plant] + if def then + node1 = {name = plant, param1 = nil, + param2 = def.place_param2} + node1_name = plant + else + if msg then meta:set_string("infotext", msg) end; return + end + elseif def and def.paramtype2 ~= "facedir" then + node1.param2 = nil + end + elseif drop and bonemeal then -- bonemeal check + local on_use = (minetest.registered_items[prefer] or {}).on_use + if on_use then + vplayer[owner] = vplayer[owner] or create_virtual_player(owner) + local itemstack = on_use(ItemStack(prefer .. " 2"), + vplayer[owner], {type = "node", under = pos2, + above = {x = pos2.x, y = pos2.y + 1, z = pos2.z}}) + bonemeal = itemstack and itemstack:get_count() == 1 or + basic_machines.creative(owner) else if msg then meta:set_string("infotext", msg) end; return end - elseif def and def.paramtype2 ~= "facedir" then - node1.param2 = nil - end - elseif drop and bonemeal then -- bonemeal check - local on_use = (minetest.registered_items[prefer] or {}).on_use - if on_use then - vplayer[owner] = vplayer[owner] or create_virtual_player(owner) - local itemstack = on_use(ItemStack(prefer .. " 2"), - vplayer[owner], {type = "node", under = pos2, - above = {x = pos2.x, y = pos2.y + 1, z = pos2.z}}) - bonemeal = itemstack and itemstack:get_count() == 1 or - basic_machines.creative(owner) - else - if msg then meta:set_string("infotext", msg) end; return end + elseif not match_meta then + node1.param1, node1.param2 = nil, nil end - elseif not match_meta then - node1.param1, node1.param2 = nil, nil + inv:remove_item("main", stack) + else + if msg then meta:set_string("infotext", msg) end; return end - inv:remove_item("main", stack) - else - if msg then meta:set_string("infotext", msg) end; return end end - end - local not_special = true -- mode for special items: trees, liquids using bucket, mese crystals ore + local not_special = true -- mode for special items: trees, liquids using bucket, mese crystals ore - if target_chest and not transport then -- if target chest put in chest - local inv = minetest.get_meta(pos2):get_inventory() - if dig then - if not source_chest then - local dig_up = mover.dig_up_table[node1_name] -- digs up node as a tree - if dig_up then - local h, r, d = 16, 1, 0 -- height, radius, depth + if target_chest and not transport then -- if target chest put in chest + local inv = minetest.get_meta(pos2):get_inventory() + if dig then + if not source_chest then + local dig_up = mover.dig_up_table[node1_name] -- digs up node as a tree + if dig_up then + local h, r, d = 16, 1, 0 -- height, radius, depth - if type(dig_up) == "table" then - h, r, d = dig_up.h or h, dig_up.r or r, dig_up.d or d - end - - local positions = minetest.find_nodes_in_area( - {x = pos1.x - r, y = pos1.y - d, z = pos1.z - r}, - {x = pos1.x + r, y = pos1.y + h, z = pos1.z + r}, - node1_name) - - for _, pos3 in ipairs(positions) do - minetest.set_node(pos3, {name = "air"}) - end - check_for_falling(pos1) - - local count, stack_max, stacks = #positions, ItemStack(node1_name):get_stack_max(), {} - - if count > stack_max then - local stacks_n = count / stack_max - for i = 1, stacks_n do stacks[i] = stack_max end - stacks[#stacks + 1] = stacks_n % 1 * stack_max - else - stacks[1] = count - end - - not_special = false - - local i = 1 - repeat - local item = node1_name .. " " .. stacks[i] - if inv:room_for_item("main", item) then - inv:add_item("main", item) -- if tree or cactus was dug up - else - minetest.add_item(pos1, item) + if type(dig_up) == "table" then + h, r, d = dig_up.h or h, dig_up.r or r, dig_up.d or d end - i = i + 1 - until(i > #stacks) - else - local liquiddef = have_bucket_liquids and bucket.liquids[node1_name] - local harvest_node1 = mover.harvest_table[node1_name] - if liquiddef and node1_name == liquiddef.source and liquiddef.itemname then - local itemname = liquiddef.itemname - if inv:contains_item("main", "bucket:bucket_empty") then - not_special = false; inv:remove_item("main", "bucket:bucket_empty") - if inv:room_for_item("main", itemname) then - inv:add_item("main", itemname) - -- force_renew requires a source neighbour (borrowed from bucket mod) - local source_neighbor = false - if liquiddef.force_renew then - source_neighbor = minetest.find_node_near(pos1, 1, liquiddef.source) + local positions = minetest.find_nodes_in_area( + {x = pos1.x - r, y = pos1.y - d, z = pos1.z - r}, + {x = pos1.x + r, y = pos1.y + h, z = pos1.z + r}, + node1_name) + + for _, pos3 in ipairs(positions) do + minetest.set_node(pos3, {name = "air"}) + end + check_for_falling(pos1) + + local count, stack_max, stacks = #positions, ItemStack(node1_name):get_stack_max(), {} + + if count > stack_max then + local stacks_n = count / stack_max + for i = 1, stacks_n do stacks[i] = stack_max end + stacks[#stacks + 1] = stacks_n % 1 * stack_max + else + stacks[1] = count + end + + not_special = false + + local i = 1 + repeat + local item = node1_name .. " " .. stacks[i] + if inv:room_for_item("main", item) then + inv:add_item("main", item) -- if tree or cactus was dug up + else + minetest.add_item(pos1, item) + end + i = i + 1 + until(i > #stacks) + else + local liquiddef = have_bucket_liquids and bucket.liquids[node1_name] + local harvest_node1 = mover.harvest_table[node1_name] + + if liquiddef and node1_name == liquiddef.source and liquiddef.itemname then + local itemname = liquiddef.itemname + if inv:contains_item("main", "bucket:bucket_empty") then + not_special = false; inv:remove_item("main", "bucket:bucket_empty") + if inv:room_for_item("main", itemname) then + inv:add_item("main", itemname) + -- force_renew requires a source neighbour (borrowed from bucket mod) + local source_neighbor = false + if liquiddef.force_renew then + source_neighbor = minetest.find_node_near(pos1, 1, liquiddef.source) + end + if not (source_neighbor and liquiddef.force_renew) then + minetest.set_node(pos1, {name = "air"}) + end + else + minetest.add_item(pos1, itemname) end - if not (source_neighbor and liquiddef.force_renew) then - minetest.set_node(pos1, {name = "air"}) + end + elseif harvest_node1 then -- do we harvest the node ? + local item = harvest_node1[2] + if item and inv:room_for_item("main", item) then + not_special = false + inv:add_item("main", item) + minetest.set_node(pos1, {name = harvest_node1[1]}) + else + if msg then meta:set_string("infotext", msg) end; return + end + end + end + end + + if not_special then -- minetest drop code emulation, alternative: minetest.get_node_drops + local def = minetest.registered_items[node1_name] + if def then -- put in chest + local drops = def.drop + if drops then -- drop handling + if drops.items then -- handle drops better, emulation of drop code + local max_items = drops.max_items or 0 -- item lists to drop + if max_items == 0 then -- just drop all the items (taking the rarity into consideration) + max_items = #drops.items or 0 + end + local itemlists_dropped = 0 + for _, item in ipairs(drops.items) do + if itemlists_dropped >= max_items then break end + if math.random(1, item.rarity or 1) == 1 then + local inherit_color, palette_index = item.inherit_color, nil + if inherit_color then + palette_index = minetest.strip_param2_color(node1.param2, def.paramtype2) + end + for _, add_item in ipairs(item.items) do -- pick all items from list + if inherit_color and palette_index then + add_item = itemstring_to_stack(add_item, palette_index) + end + inv:add_item("main", add_item) + end + itemlists_dropped = itemlists_dropped + 1 + end end else - minetest.add_item(pos1, itemname) + inv:add_item("main", drops) end - end - elseif harvest_node1 then -- do we harvest the node ? - local item = harvest_node1[2] - if item and inv:room_for_item("main", item) then - not_special = false - inv:add_item("main", item) - minetest.set_node(pos1, {name = harvest_node1[1]}) else - if msg then meta:set_string("infotext", msg) end; return + inv:add_item("main", item_to_stack(node1, def.paramtype2)) end end end + else -- if not dig just put it in + inv:add_item("main", item_to_stack(node1)) end + end - if not_special then -- minetest drop code emulation, alternative: minetest.get_node_drops - local def = minetest.registered_items[node1_name] - if def then -- put in chest - local drops = def.drop - if drops then -- drop handling - if drops.items then -- handle drops better, emulation of drop code - local max_items = drops.max_items or 0 -- item lists to drop - if max_items == 0 then -- just drop all the items (taking the rarity into consideration) - max_items = #drops.items or 0 - end - local itemlists_dropped = 0 - for _, item in ipairs(drops.items) do - if itemlists_dropped >= max_items then break end - if math.random(1, item.rarity or 1) == 1 then - local inherit_color, palette_index = item.inherit_color, nil - if inherit_color then - palette_index = minetest.strip_param2_color(node1.param2, def.paramtype2) - end - for _, add_item in ipairs(item.items) do -- pick all items from list - if inherit_color and palette_index then - add_item = itemstring_to_stack(add_item, palette_index) - end - inv:add_item("main", add_item) - end - itemlists_dropped = itemlists_dropped + 1 - end - end - else - inv:add_item("main", drops) - end - else - inv:add_item("main", item_to_stack(node1, def.paramtype2)) - end + local count = meta:get_int("activation_count") + if count < 16 then + minetest.sound_play("basic_machines_transporter", {pos = pos2, gain = 1, max_hear_distance = 8}, true) + end + + if t0 > tn then + meta:set_int("activation_count", count + 1) + elseif count > 0 then + meta:set_int("activation_count", 0) + end + + if target_chest and source_chest then -- chest to chest transport has lower cost, * 0.1 + fuel_cost = fuel_cost * 0.1 + end + + fuel = fuel - fuel_cost; meta:set_float("fuel", fuel) + meta:set_string("infotext", S("Mover block. Temperature: @1, Fuel: @2.", T, twodigits_float(fuel))) + + if transport then -- transport nodes parallel as defined by source1 and target, clone with complete metadata + local meta1 = minetest.get_meta(pos1):to_table() + minetest.set_node(pos2, node1); minetest.get_meta(pos2):from_table(meta1) + minetest.set_node(pos1, {name = "air"}); minetest.get_meta(pos1):from_table(nil) + else + -- REMOVE NODE DUG + if not target_chest and not bonemeal then + if drop then -- drops node instead of placing it + minetest.add_item(pos2, item_to_stack(node1)) -- drops it + else + minetest.set_node(pos2, node1) end end - else -- if not dig just put it in - inv:add_item("main", item_to_stack(node1)) - end - end - local count = meta:get_int("activation_count") - if count < 16 then - minetest.sound_play("basic_machines_transporter", {pos = pos2, gain = 1, max_hear_distance = 8}, true) - end - - if t0 > tn then - meta:set_int("activation_count", count + 1) - elseif count > 0 then - meta:set_int("activation_count", 0) - end - - if target_chest and source_chest then -- chest to chest transport has lower cost, * 0.1 - fuel_cost = fuel_cost * 0.1 - end - - fuel = fuel - fuel_cost; meta:set_float("fuel", fuel) - meta:set_string("infotext", S("Mover block. Temperature: @1, Fuel: @2.", T, twodigits_float(fuel))) - - if transport then -- transport nodes parallel as defined by source1 and target, clone with complete metadata - local meta1 = minetest.get_meta(pos1):to_table() - minetest.set_node(pos2, node1); minetest.get_meta(pos2):from_table(meta1) - minetest.set_node(pos1, {name = "air"}); minetest.get_meta(pos1):from_table(nil) - else - -- REMOVE NODE DUG - if not target_chest and not bonemeal then - if drop then -- drops node instead of placing it - minetest.add_item(pos2, item_to_stack(node1)) -- drops it - else - minetest.set_node(pos2, node1) + if not source_chest and not_special then + minetest.set_node(pos1, {name = "air"}) + if dig then check_for_falling(pos1) end -- pre 5.0.0 nodeupdate(pos1) end end - - if not source_chest and not_special then - minetest.set_node(pos1, {name = "air"}) - if dig then check_for_falling(pos1) end -- pre 5.0.0 nodeupdate(pos1) - end end end, diff --git a/technic_power.lua b/technic_power.lua index 0f089bb..a48471d 100644 --- a/technic_power.lua +++ b/technic_power.lua @@ -30,17 +30,18 @@ local energy_crystals = { ["basic_machines:power_rod"] = 100 * energy_multiplier } -local function battery_recharge(pos, origin) +local function battery_recharge(pos, energy, origin) local meta = minetest.get_meta(pos) - local energy = meta:get_float("energy") - local capacity = meta:get_float("capacity") local inv = meta:get_inventory() local stack = inv:get_stack("fuel", 1) + local capacity + energy = energy or meta:get_float("energy") local add_energy = energy_crystals[stack:get_name()] if add_energy and add_energy > 0 then if pos.y > space_start_eff then add_energy = 2 * add_energy end -- in space recharge is more efficient + capacity = meta:get_float("capacity") if add_energy <= capacity then stack:take_item(1); inv:set_stack("fuel", 1, stack) else @@ -53,6 +54,7 @@ local function battery_recharge(pos, origin) if fueladd.time > 0 then add_energy = fueladd.time / 40 local energy_new = energy + add_energy + capacity = meta:get_float("capacity") if energy_new <= capacity then inv:set_stack("fuel", 1, afterfuel.items[1]) else @@ -67,9 +69,11 @@ local function battery_recharge(pos, origin) if energy_new < 0 then energy_new = 0 end if energy_new > capacity then energy_new = capacity end -- excess energy is wasted - meta:set_float("energy", energy_new) - if origin ~= "check_power" then + if origin ~= "recharge_furnace" then + meta:set_float("energy", energy_new) + end + if capacity > 0 then local full_coef_new = math.floor(energy_new / capacity * 3) -- 0, 1, 2 local full_coef = math.floor(energy / capacity * 3) @@ -105,6 +109,7 @@ local function battery_recharge(pos, origin) minetest.swap_node(pos, {name = "basic_machines:battery_0"}) meta:set_string("infotext", S("Furnace needs at least 1 energy")) else + capacity = capacity or meta:get_float("capacity") meta:set_string("infotext", S("Energy: @1 / @2", math.ceil(energy * 10) / 10, capacity)) end @@ -126,19 +131,23 @@ basic_machines.check_power = function(pos, power_draw) end local energy = meta:get_float("energy") + local energy_recharge, energy_new if power_draw > energy then - energy = battery_recharge(pos, "check_power") -- try recharge battery and continue operation immediately + energy_recharge = battery_recharge(pos, energy, "check_power") -- try recharge battery and continue operation immediately + energy_new = energy_recharge - power_draw + else + energy_new = energy - power_draw end - local energy_new = energy - power_draw - if energy_new < 0 then + if energy_recharge and energy_recharge ~= energy then + meta:set_float("energy", energy_recharge) + end meta:set_string("infotext", S("Used fuel provides too little power for current power draw @1", power_draw)); return 0 - end -- recharge wasnt enough, needs to be repeated manually, return 0 power available + end -- recharge wasn't enough, needs to be repeated manually, return 0 power available meta:set_float("energy", energy_new) - local capacity = meta:get_float("capacity") if capacity > 0 then local full_coef_new = math.floor(energy_new / capacity * 3) -- 0, 1, 2 @@ -149,7 +158,6 @@ basic_machines.check_power = function(pos, power_draw) minetest.swap_node(pos, {name = "basic_machines:battery_" .. full_coef_new}) end end - -- update energy display meta:set_string("infotext", S("Energy: @1 / @2", math.ceil(energy_new * 10) / 10, capacity)) @@ -173,7 +181,7 @@ local function battery_upgrade(meta, pos) if pos.y > space_start_eff then count1, count2 = 2 * count1, 2 * count2 end -- space increases efficiency local energy = 0 - local capacity = 3 + 3 * count1 -- mese for capacity + local capacity = 3 + count1 * 3 -- mese for capacity capacity = math.ceil(capacity * 10) / 10 -- adjust capacity local maxpower = 1 + count2 * 2 -- old 99 upgrade -> 200 power @@ -312,9 +320,8 @@ minetest.register_node("basic_machines:battery_0", { fmeta:set_float("src_time", fmeta:get_float("src_time") + machines_timer * upgrade) end - meta:set_float("energy", energy_new) - if energy_new > 0 then -- no need to recharge yet, will still work next time + meta:set_float("energy", energy_new) local capacity = meta:get_float("capacity") if capacity > 0 then local full_coef_new = math.floor(energy_new / capacity * 3) -- 0, 1, 2 @@ -328,7 +335,10 @@ minetest.register_node("basic_machines:battery_0", { -- update energy display meta:set_string("infotext", S("Energy: @1 / @2", math.ceil(energy_new * 10) / 10, capacity)) else - battery_recharge(pos, "recharge_furnace") + local energy_recharge = battery_recharge(pos, energy_new, "recharge_furnace") + if energy_recharge ~= energy_new then + meta:set_float("energy", energy_recharge) + end end return @@ -337,7 +347,7 @@ minetest.register_node("basic_machines:battery_0", { -- try to recharge by converting inserted fuel/power crystals into energy if energy < meta:get_float("capacity") then -- not full, try to recharge - battery_recharge(pos) + battery_recharge(pos, energy) end end }