2021-11-29 15:53:42 -06:00

262 lines
8.7 KiB
Lua

-- yes, the power meter is technically a bed
local recipe = {}
if minetest.get_modpath("currency") then
recipe = {
{"", "technic:control_logic_unit", ""},
{"technic:lv_cable", "currency:shop", "technic:lv_cable"},
}
else
recipe = {
{"", "technic:control_logic_unit", ""},
{"technic:lv_cable", "default:chest", "technic:lv_cable"},
}
end
beds.register_bed("technic_powermeter:meter", {
description = "Power Meter",
inventory_image = "technic_powermeter_meter.png",
wield_image = "technic_powermeter_meter.png",
tiles = {
bottom = {
"beds_bed_top_bottom.png^[transformR90",
"default_wood.png",
"beds_bed_side_bottom_r.png",
"beds_bed_side_bottom_r.png^[transformfx",
"beds_transparent.png",
"beds_bed_side_bottom.png"
},
top = {
"beds_bed_top_top.png^[transformR90",
"default_wood.png",
"beds_bed_side_top_r.png",
"beds_bed_side_top_r.png^[transformfx",
"beds_bed_side_top.png",
"beds_transparent.png",
}
},
nodebox = {
bottom = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
top = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 1.5},
recipe = recipe
})
local function form_meter(pos, owner)
local meta = minetest.get_meta(pos)
local spos = pos.x .. "," .. pos.y .. "," .. pos.z
local price = meta:get_string("price")
if price == "" then price = "0" end
local form = "size[8,7]" ..
"list[current_player;main;0,3;8,4;0]" ..
"list[nodemeta:"..spos..";input;6,0.9;1,1.1;0]" ..
"label[5.7,0.4;Bought: "..technic.EU_string(meta:get_int("bought")).."]" ..
"button_exit[6,1.8;1,1;buy;Buy]"..
"label[5.7,-.2;Price: "..price.." minegeld/kEU]"
if owner then
form = form..
"label[0.5,0;Customers gave:]" ..
"list[nodemeta:" .. spos .. ";output;0.5,0.5;2.5,2;0]"..
"field[3,0.6;2.5,1;price;Price (minegeld/kEU);"..price.."]"
else
end
return form
end
local form_table = {}
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "technic_powermeter:form" then return end
if not player then return end
local name = player:get_player_name()
local pos = form_table[name]
if not pos then return end
local meta = minetest.get_meta(pos)
if fields.buy then
local inv = meta:get_inventory()
local price = (tonumber(meta:get_string("price")) or 0)/1000
local input = inv:get_stack("input", 1)
local moneys = {minegeld = 1, minegeld_5 = 5, minegeld_10 = 10}
local amount = (moneys[string.gsub(input:get_name(), "currency:", "")] or 0) * input:get_count()
if amount > 0 and price > 0 and (amount >= price or meta:get_int("bought") > 0) then
local bought = math.floor(amount/price)
local change = math.floor(amount-bought*price)
local output = ItemStack({name = "currency:minegeld", count = amount-change})
local changestack = ItemStack({name = "currency:minegeld", count = change})
if inv:room_for_item("output", output) then
if change > 0 then
inv:set_stack("input", 1, changestack)
else
inv:set_stack("input", 1, ItemStack())
end
inv:add_item("output", output)
bought = bought+meta:get_int("bought")
meta:set_int("bought", bought)
else
minetest.chat_send_player(name, "Meter is full and cannot fit payment, contact pump owner.")
end
end
end
if fields.key_enter_field == "price" then
if default.can_interact_with_node(player, pos) then
if tonumber(fields.price) then
meta:set_string("price", fields.price)
end
end
end
if fields.quit then
form_table[name] = nil
return true
end
end)
local S = technic.getter
local run = function(pos1, node)
-- Machine information
local machine_name = S("Power Meter")
local meta1 = minetest.get_meta(pos1)
local enabled = meta1:get_string("enabled")
local bought = meta1:get_int("bought")
--enabled = enabled == "1"
--if not enabled or (meta1:get_int("mesecon_mode") == 1 and meta1:get_int("mesecon_effect") == 0) then return end
local dir = minetest.facedir_to_dir(node.param2)
local pos2 = vector.add(pos1, dir)
local node2 = minetest.get_node_or_nil(pos2)
if not node2 or not minetest.get_item_group(node2.name, "bed") == 2 or
not node.param2 == node2.param2 then
return
end
--pos1 is bottom/recieving pos2 is top/producing
local meta2 = minetest.get_meta(pos2)
local name_bottom = minetest.get_node(vector.subtract(pos1, dir)).name
local name_top = minetest.get_node(vector.add(pos2, dir)).name
local from = technic.get_cable_tier(name_bottom)
local to = technic.get_cable_tier(name_top)
meta1:set_int("LV_EU_timeout", 2)
meta1:set_int("MV_EU_timeout", 2)
meta1:set_int("HV_EU_timeout", 2)
meta2:set_int("LV_EU_timeout", 2)
meta2:set_int("MV_EU_timeout", 2)
meta2:set_int("HV_EU_timeout", 2)
if bought == 0 then
meta1:set_string("infotext", S("@1 (@2)", machine_name, technic.EU_string(bought)))
if from then
meta1:set_int(from.."_EU_demand", 0)
meta1:set_int(from.."_EU_supply", 0)
end
if to then
meta2:set_int(to.."_EU_demand", 0)
meta2:set_int(to.."_EU_supply", 0)
end
return
end
local network_hash = technic.cables[minetest.hash_node_position(pos2)]
local network = network_hash and minetest.get_position_from_hash(network_hash)
local sw_pos = network and {x=network.x,y=network.y+1,z=network.z}
if not sw_pos or not minetest.get_node(sw_pos).name == "technic:switching_station" then return end
local sw_meta = minetest.get_meta(sw_pos)
local demand = sw_meta:get_int("demand")
local supply = sw_meta:get_int("supply")
network_hash = technic.cables[minetest.hash_node_position(pos1)]
network = network_hash and minetest.get_position_from_hash(network_hash)
local sw_pos2 = network and {x=network.x,y=network.y+1,z=network.z}
if not sw_pos2 or not minetest.get_node(sw_pos2).name == "technic:switching_station" then return end
if from and to and from==to and not vector.equals(sw_pos, sw_pos2) then
local input = meta1:get_int(from.."_EU_input")
if supply > 0 then
demand = math.max(demand - (supply-meta2:get_int(to.."_EU_supply")), 0)
end
if input > bought then
demand = bought
else
bought = bought - input
end
meta1:set_int(from.."_EU_demand", demand)
meta1:set_int(from.."_EU_supply", 0)
meta2:set_int(to.."_EU_demand", 0)
meta2:set_int(to.."_EU_supply", input)
meta1:set_int("bought", bought)
meta1:set_string("infotext", S("@1 (@2)", machine_name, technic.EU_string(bought)))
else
meta1:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name))
if to then
meta1:set_int(to.."_EU_supply", 0)
end
if from then
meta1:set_int(from.."_EU_demand", 0)
end
return
end
end
local old_func = minetest.registered_nodes["technic_powermeter:meter_bottom"].on_place
--bottom is the one with the selectionbox
minetest.override_item("technic_powermeter:meter_bottom",{
groups = {bed = 1, snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_all_tiers=1},
connect_sides = {"front"},
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("input") and
inv:is_empty("output") and
default.can_interact_with_node(player, pos)
end,
on_rightclick = function(pos, node, clicker)
if not clicker then return end
local name = clicker:get_player_name()
if not name then return end
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
minetest.show_formspec(name,"technic_powermeter:form", form_meter(pos, default.can_interact_with_node(clicker, pos)))
form_table[name] = pos
end,
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local node = minetest.get_node(under)
local udef = minetest.registered_nodes[node.name]
local pos
if udef and udef.buildable_to then
pos = under
else
pos = pointed_thing.above
end
itemstack = old_func(itemstack, placer, pointed_thing)
if minetest.get_node(pos).name == "technic_powermeter:meter_bottom" then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("input", 1)
inv:set_size("output", 4)
meta:set_string("owner", placer:get_player_name() or "")
meta:set_string("infotext", "Power Meter (owned by "..meta:get_string("owner")..")")
--meta:set_int("LV_EU_timeout", 2)
--meta:set_int("MV_EU_timeout", 2)
--meta:set_int("HV_EU_timeout", 2)
technic.clear_networks(pos)
end
return itemstack
end,
technic_run = run,
--technic_on_disable = run,
})
minetest.override_item("technic_powermeter:meter_top",{
groups = {bed = 2, snappy=2, choppy=2, oddly_breakable_by_hand=2,
technic_machine=1, technic_all_tiers=1, not_on_creative_inventory = 1},
connect_sides = {"back"}
})
for tier, machines in pairs(technic.machines) do
technic.register_machine(tier, "technic_powermeter:meter_bottom", technic.receiver)
technic.register_machine(tier, "technic_powermeter:meter_top", technic.producer)
end