Option for forcefield to be cubical
authorZefram <zefram@fysh.org>
Thu, 14 Aug 2014 19:50:40 +0000 (20:50 +0100)
committerZefram <zefram@fysh.org>
Fri, 15 Aug 2014 11:25:46 +0000 (12:25 +0100)
technic/machines/HV/forcefield.lua

index 0e530e0d8f47f57cf55c260a185257891be480f7..5a1cced4d727a1ad58973b688f806ec65a77528a 100644 (file)
@@ -28,7 +28,9 @@ minetest.register_craft({
 --  |          |
 --   \___/\___/
 
-local function update_forcefield(pos, range, active)
+local function update_forcefield(pos, meta, active)
+       local shape = meta:get_int("shape")
+       local range = meta:get_int("range")
        local vm = VoxelManip()
        local p1 = {x = pos.x-range, y = pos.y-range, z = pos.z-range}
        local p2 = {x = pos.x+range, y = pos.y+range, z = pos.z+range}
@@ -43,8 +45,18 @@ local function update_forcefield(pos, range, active)
        for y=-range, range do
        local vi = area:index(pos.x+(-range), pos.y+y, pos.z+z)
        for x=-range, range do
-               if x*x+y*y+z*z <= range     *  range    +  range    and
-                  x*x+y*y+z*z >= (range-1) * (range-1) + (range-1) then
+               local relevant
+               if shape == 0 then
+                       relevant =
+                          x*x+y*y+z*z <= range     *  range    +  range    and
+                          x*x+y*y+z*z >= (range-1) * (range-1) + (range-1)
+               else
+                       relevant =
+                               x == -range or x == range or
+                               y == -range or y == range or
+                               z == -range or z == range
+               end
+               if relevant then
                        if active and data[vi] == c_air then
                                data[vi] = c_field
                        elseif not active and data[vi] == c_field then
@@ -64,11 +76,16 @@ end
 
 local function set_forcefield_formspec(meta)
        local formspec = "size[5,2.25]"..
-               "field[2,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
+               "field[0.3,0.5;2,1;range;"..S("Range")..";"..meta:get_int("range").."]"
        -- The names for these toggle buttons are explicit about which
        -- state they'll switch to, so that multiple presses (arising
        -- from the ambiguity between lag and a missed press) only make
        -- the single change that the user expects.
+       if meta:get_int("shape") == 0 then
+               formspec = formspec.."button[3,0.2;2,1;shape1;"..S("Sphere").."]"
+       else
+               formspec = formspec.."button[3,0.2;2,1;shape0;"..S("Cube").."]"
+       end
        if meta:get_int("mesecon_mode") == 0 then
                formspec = formspec.."button[0,1;5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
        else
@@ -84,18 +101,22 @@ end
 
 local forcefield_receive_fields = function(pos, formname, fields, sender)
        local meta = minetest.get_meta(pos)
+       local range = nil
        if fields.range then
-               local range = tonumber(fields.range) or 0
+               range = tonumber(fields.range) or 0
                -- Smallest field is 5. Anything less is asking for trouble.
                -- Largest is 20. It is a matter of pratical node handling.
                -- At the maximim range updating the forcefield takes about 0.2s
                range = math.max(range, 5)
                range = math.min(range, 20)
-               if meta:get_int("range") ~= range then
-                       update_forcefield(pos, meta:get_int("range"), false)
-                       meta:set_int("range", range)
-               end
+               if range == meta:get_int("range") then range = nil end
        end
+       if fields.shape0 or fields.shape1 or range then
+               update_forcefield(pos, meta, false)
+       end
+       if range then meta:set_int("range", range) end
+       if fields.shape0 then meta:set_int("shape", 0) end
+       if fields.shape1 then meta:set_int("shape", 1) end
        if fields.enable then meta:set_int("enabled", 1) end
        if fields.disable then meta:set_int("enabled", 0) end
        if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
@@ -121,14 +142,19 @@ local run = function(pos, node, active_object_count, active_object_count_wider)
        local enabled = meta:get_int("enabled") ~= 0 and (meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
        local machine_name = S("%s Forcefield Emitter"):format("HV")
 
-       local power_requirement = math.floor(
-                       4 * math.pi * math.pow(meta:get_int("range"), 2)
-               ) * forcefield_power_drain
+       local range = meta:get_int("range")
+       local power_requirement
+       if meta:get_int("shape") == 0 then
+               power_requirement = math.floor(4 * math.pi * range * range)
+       else
+               power_requirement = 24 * range * range
+       end
+       power_requirement = power_requirement * forcefield_power_drain
 
        if not enabled then
                if node.name == "technic:forcefield_emitter_on" then
                        meta:set_int("HV_EU_demand", 0)
-                       update_forcefield(pos, meta:get_int("range"), false)
+                       update_forcefield(pos, meta, false)
                        technic.swap_node(pos, "technic:forcefield_emitter_off")
                        meta:set_string("infotext", S("%s Disabled"):format(machine_name))
                        return
@@ -136,7 +162,7 @@ local run = function(pos, node, active_object_count, active_object_count_wider)
        elseif eu_input < power_requirement then
                meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
                if node.name == "technic:forcefield_emitter_on" then
-                       update_forcefield(pos, meta:get_int("range"), false)
+                       update_forcefield(pos, meta, false)
                        technic.swap_node(pos, "technic:forcefield_emitter_off")
                end
        elseif eu_input >= power_requirement then
@@ -144,7 +170,7 @@ local run = function(pos, node, active_object_count, active_object_count_wider)
                        technic.swap_node(pos, "technic:forcefield_emitter_on")
                        meta:set_string("infotext", S("%s Active"):format(machine_name))
                end
-               update_forcefield(pos, meta:get_int("range"), true)
+               update_forcefield(pos, meta, true)
        end
        meta:set_int("HV_EU_demand", power_requirement)
 end
@@ -177,13 +203,13 @@ minetest.register_node("technic:forcefield_emitter_on", {
        on_receive_fields = forcefield_receive_fields,
        on_destruct = function(pos)
                local meta = minetest.get_meta(pos)
-               update_forcefield(pos, meta:get_int("range"), false)
+               update_forcefield(pos, meta, false)
        end,
        mesecons = mesecons,
        technic_run = run,
        technic_on_disable = function (pos, node)
                local meta = minetest.get_meta(pos)
-               update_forcefield(pos, meta:get_int("range"), false)
+               update_forcefield(pos, meta, false)
                technic.swap_node(pos, "technic:forcefield_emitter_off")
        end,
 })