diff --git a/common.lua b/common.lua index 8ce7327..452bb06 100644 --- a/common.lua +++ b/common.lua @@ -75,6 +75,8 @@ basic_machines = { use_keypad = function() end, -- mover add_mover_mode = function() end, + calculate_elevator_range = function() end, + calculate_elevator_requirement = function() end, check_mover_filter = function() end, check_mover_target = nil, -- function used with mover_no_large_stacks setting check_palette_index = function() end, diff --git a/locale/template b/locale/template index 3f3657f..ad79fec 100644 --- a/locale/template +++ b/locale/template @@ -170,7 +170,7 @@ MOVER: Source1 position for mover set. Punch again to set source2 position.= MOVER: Source2 position for mover set. Punch again to set target position.= ELEVATOR: Activate to use.= MOVER: Elevator setup completed, upgrade level @1.= -MOVER: Error while attempting to make an elevator. Need at least @1 of '@2' (@3) in upgrade (1 for every 100 distance).= +MOVER: Error while attempting to make an elevator. Need at least @1 of '@2' (@3) in upgrade (1 for every @4 distance).= MOVER: Punch closer to mover. Aborting.= MOVER: End position for mover set.= DISTRIBUTOR: Punch closer to distributor. Aborting.= @@ -185,7 +185,8 @@ DETECTOR: Now punch the target machine.= DETECTOR: Punch something else. Aborting.= DETECTOR: Setup complete.= MOVER: Position is protected. Aborting.= -MOVER: All coordinates must be between @1 and @2. For increased range set up positions by punching.= +MOVER: Target coordinates must be between @1 and @2. For increased range, upgrade with corresponding item.= +MOVER: All coordinates must be between @1 and @2. For increased range, set up positions by punching.= Mover block. Set up with source coordinates @1, @2, @3 -> @4, @5, @6 and target coordinates @7, @8, @9. Put charged battery next to it and start it with keypad.= MOVER: Battery found - displaying mark 1= MOVER: Please put battery nearby= @@ -226,7 +227,7 @@ Mesecon Adapter= This will move blocks as they are - without change@nUpgrade with movers to process additional blocks= This will transform blocks as if player dug them@nUpgrade with movers to process additional blocks= This will take block/item out of chest (you need to set filter) and will drop it= -Make TELEPORTER/ELEVATOR:@n This will move any object inside a sphere (with center source1 and radius defined by distance between source1/source2) to target position@n For ELEVATOR, teleport origin/destination need to be placed exactly in same coordinate line with mover, and you need to upgrade with 1 of '@1' (@2) for every 100 height difference= +Make TELEPORTER/ELEVATOR:@n This will move any object inside a sphere (with center source1 and radius defined by distance between source1/source2) to target position@n For ELEVATOR, teleport origin/destination need to be placed exactly in same coordinate line with the mover, and you need to upgrade with 1 of '@1' (@2) for every @3 height difference= This will move items from inventory of any block at source position to any inventory of block at target position= This will move all blocks at source area to new area starting at target position@nThis mode preserves all inventories and other metadata@nMake chest items transport: define the filter with the needed type of chest= normal= @@ -252,7 +253,8 @@ Mover introduction= This machine can move anything. General idea is the following:@n@nFirst you need to define rectangle box work area (larger area, where it takes from, defined by source1/source2 which appear as two number 1 boxes) and target position (where it puts, marked by one number 2 box) by punching mover then following chat instructions exactly.@n@nCheck why it doesn't work: 1. did you click OK in mover after changing setting 2. does it have battery, 3. does battery have enough fuel 4. did you set filter for taking out of chest ?@n@nImportant: Please read the help button inside machine before first use.= MOVER: Must reconfigure sources position.= Mover block. Protection fail.= -MOVER: Elevator error. Need at least @1 of '@2' (@3) in upgrade (1 for every 100 distance).= +MOVER: Elevator error. Target must be properly aligned and/or need at least @1 of '@2' (@3) in upgrade (1 for every @4 distance).= +MOVER: Elevator error. Need at least @1 of '@2' (@3) in upgrade (1 for every @4 distance).= Can not find nearby battery to connect to!= Mover block. Energy @1, needed energy @2. Put nonempty battery next to mover.= Mover block refueled. Fuel status @1.= diff --git a/machines_configuration.lua b/machines_configuration.lua index 7a1f270..b68c397 100644 --- a/machines_configuration.lua +++ b/machines_configuration.lua @@ -77,6 +77,10 @@ local function check_keypad(pos, name) -- called only when manually activated vi end end +local function calculate_mover_range(upgrade) -- returns the maximum range + return math.min(mover_upgrade_max + 1, upgrade) * max_range +end + local abs = math.abs minetest.register_on_punchnode(function(pos, node, puncher) @@ -144,7 +148,7 @@ minetest.register_on_punchnode(function(pos, node, puncher) if upgradetype == 1 or upgradetype == 3 or meta:get_inventory():get_stack("upgrade", 1):get_name() == "default:mese" -- for compatibility then - range = math.min(mover_upgrade_max + 1, meta:get_int("upgrade")) * max_range + range = calculate_mover_range(meta:get_int("upgrade")) else range = max_range end @@ -198,7 +202,7 @@ minetest.register_on_punchnode(function(pos, node, puncher) if ecost > 3 then -- trying to make an elevator ? -- count number of items to determine if an elevator can be set up with this height distance local upgrade = meta:get_int("upgrade") - local requirement = math.floor(ecost / 100) + 1 + local requirement = basic_machines.calculate_elevator_requirement(ecost) if (upgrade - 1) >= requirement and (meta:get_int("upgradetype") == 2 or meta:get_inventory():get_stack("upgrade", 1):get_name() == "default:diamondblock") or upgrade == -1 -- for compatibility then @@ -209,8 +213,8 @@ minetest.register_on_punchnode(function(pos, node, puncher) local upgrade_item = basic_machines.get_mover("revupgrades")[2] local description = basic_machines.get_item_description(upgrade_item) minetest.chat_send_player(name, - S("MOVER: Error while attempting to make an elevator. Need at least @1 of '@2' (@3) in upgrade (1 for every 100 distance).", - requirement, description, upgrade_item)) + S("MOVER: Error while attempting to make an elevator. Need at least @1 of '@2' (@3) in upgrade (1 for every @4 distance).", + requirement, description, upgrade_item, basic_machines.elevator_height)) machines.remove_markers(name, {"1", "11"}); punchset[name] = {state = 0, node = ""}; return end end @@ -418,23 +422,59 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.chat_send_player(name, S("MOVER: Position is protected. Aborting.")); return end - -- did the numbers change from last time ? - if meta:get_int("x0") ~= x0 or meta:get_int("y0") ~= y0 or meta:get_int("z0") ~= z0 or + local mode = meta:get_string("mode") + local target_range + + if mode == "object" and + (meta:get_int("x2") ~= x2 or meta:get_int("y2") ~= y2 or meta:get_int("z2") ~= z2) and + meta:get_int("x0") == x0 and meta:get_int("y0") == y0 and meta:get_int("z0") == z0 and + meta:get_int("x1") == x1 and meta:get_int("y1") == y1 and meta:get_int("z1") == z1 + then -- did the target change ? + local upgradetype = meta:get_int("upgradetype") + if meta:get_int("elevator") == 1 then + if upgradetype == 2 and ((x2 == 0 and z2 == 0) or + (y2 == 0 and z2 == 0) or (x2 == 0 and y2 == 0)) + then -- is the target in same coordinate line with the mover ? + local upgrade_max = basic_machines.get_mover("upgrades")[basic_machines.get_mover("revupgrades")[2]].max + target_range = basic_machines.calculate_elevator_range(upgrade_max, meta:get_int("upgrade") - 1) + else + local distance = abs(x2) + abs(y2) + abs(z2) + local requirement = basic_machines.calculate_elevator_requirement(distance) + local upgrade_item = basic_machines.get_mover("revupgrades")[2] + local description = basic_machines.get_item_description(upgrade_item) + minetest.chat_send_player(name, + S("MOVER: Elevator error. Target must be properly aligned and/or need at least @1 of '@2' (@3) in upgrade (1 for every @4 distance).", + requirement, description, upgrade_item, basic_machines.elevator_height)); return + end + elseif upgradetype == 1 then + target_range = calculate_mover_range(meta:get_int("upgrade")) + else + target_range = max_range + end + end + + if target_range then + if not minetest.check_player_privs(name, "privs") and + (abs(x2) > target_range or abs(y2) > target_range or abs(z2) > target_range) + then -- is the target inside bounds ? + minetest.chat_send_player(name, S("MOVER: Target coordinates must be between @1 and @2. For increased range, upgrade with corresponding item.", + -target_range, target_range)); return + end + elseif meta:get_int("x0") ~= x0 or meta:get_int("y0") ~= y0 or meta:get_int("z0") ~= z0 or meta:get_int("x1") ~= x1 or meta:get_int("y1") ~= y1 or meta:get_int("z1") ~= z1 or meta:get_int("x2") ~= x2 or meta:get_int("y2") ~= y2 or meta:get_int("z2") ~= z2 - then - -- are new numbers inside bounds ? + then -- did the numbers change from last time ? if not minetest.check_player_privs(name, "privs") and (abs(x0) > max_range or abs(y0) > max_range or abs(z0) > max_range or abs(x1) > max_range or abs(y1) > max_range or abs(z1) > max_range or abs(x2) > max_range or abs(y2) > max_range or abs(z2) > max_range) - then - minetest.chat_send_player(name, S("MOVER: All coordinates must be between @1 and @2. For increased range set up positions by punching.", + then -- are new numbers inside bounds ? + minetest.chat_send_player(name, S("MOVER: All coordinates must be between @1 and @2. For increased range, set up positions by punching.", -max_range, max_range)); return end end - if meta:get_string("mode") == "object" then + if mode == "object" then meta:set_int("dim", -1) else local x = x0; x0 = math.min(x, x1); x1 = math.max(x, x1) diff --git a/mover.lua b/mover.lua index 5fa7cff..05a961c 100644 --- a/mover.lua +++ b/mover.lua @@ -715,7 +715,7 @@ minetest.register_node("basic_machines:mover", { else -- calculate fuel cost if object then if meta:get_int("elevator") == 1 then -- check if elevator mode - local requirement = math.floor(get_distance(pos, pos2) / 100) + 1 + local requirement = basic_machines.calculate_elevator_requirement(get_distance(pos, pos2)) if (upgrade - 1) >= requirement and (meta:get_int("upgradetype") == 2 or meta:get_inventory():get_stack("upgrade", 1):get_name() == "default:diamondblock") -- for compatibility then @@ -724,8 +724,8 @@ minetest.register_node("basic_machines:mover", { local upgrade_item = mover_revupgrades[2] local description = basic_machines.get_item_description(upgrade_item) meta:set_string("infotext", - S("MOVER: Elevator error. Need at least @1 of '@2' (@3) in upgrade (1 for every 100 distance).", - requirement, description, upgrade_item)); return + S("MOVER: Elevator error. Need at least @1 of '@2' (@3) in upgrade (1 for every @4 distance).", + requirement, description, upgrade_item, basic_machines.elevator_height)); return end else local hardness = mover.hardness[node1_name] diff --git a/mover_object_mode.lua b/mover_object_mode.lua index e9a29f9..cf5f0d3 100644 --- a/mover_object_mode.lua +++ b/mover_object_mode.lua @@ -2,6 +2,19 @@ -- Copyright (C) 2022-2025 мтест -- See README.md for license details +local elevator_height = 100 +basic_machines.elevator_height = elevator_height + +-- returns the maximum range +basic_machines.calculate_elevator_range = function(max, upgrade) + return math.min(max, upgrade) * elevator_height +end + +-- returns the amount of upgrade required +basic_machines.calculate_elevator_requirement = function(distance) + return math.ceil(distance / elevator_height) +end + local F, S = basic_machines.F, basic_machines.S local mover_chests = basic_machines.get_mover("chests") local vector_add = vector.add @@ -141,7 +154,7 @@ local description = basic_machines.get_item_description(name) basic_machines.add_mover_mode("object", F(S("Make TELEPORTER/ELEVATOR:\n This will move any object inside a sphere (with center source1 and radius defined by distance between source1/source2) to target position\n" .. - " For ELEVATOR, teleport origin/destination need to be placed exactly in same coordinate line with mover, and you need to upgrade with 1 of '@1' (@2) for every 100 height difference", - description, name)), + " For ELEVATOR, teleport origin/destination need to be placed exactly in same coordinate line with the mover, and you need to upgrade with 1 of '@1' (@2) for every @3 height difference", + description, name, elevator_height)), F(S("object")), object ) \ No newline at end of file