Jordan Snelling
2013-06-27 c687e8cb7b9e624474353b0cc10acc5db14192f8
commit | author | age
c6da0a 1 --Forcefield mod by ShadowNinja
R 2
3 local forcefield_emitter_buffer_size = 10000
e5d48e 4 local forcefield_emitter_power_consumption = 0.8
c6da0a 5 local forcefield_update_interval = 1
R 6
7 minetest.register_craft({
8     output = 'technic:forcefield_emitter_off',
9     recipe = {
10             {'default:mese',         'technic:deployer_off', 'default:mese'        },
11             {'technic:deployer_off', 'technic:motor',        'technic:deployer_off'},
12             {'default:mese',         'technic:deployer_off', 'default:mese'        },
13     }
14 })
15
16 local function get_forcefield_count(range)
17     local count = 0
18     for x=-range,range do
e5d48e 19     for y=-range,range do
c6da0a 20     for z=-range,range do
R 21         if ((x*x+y*y+z*z) <= (range * range + range)) then
22             if (y == 0) or ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then
23                 count = count + 1
24             end
25         end
26     end
27     end
28     end
29     return count
30 end
31
32 local function add_forcefield(pos, range)
33     for x=-range,range do
34     for y=-range,range do
35     for z=-range,range do
36         if ((x*x+y*y+z*z) <= (range * range + range)) then
37             if ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then
38                 local np={x=pos.x+x,y=pos.y+y,z=pos.z+z}
39                 local n = minetest.env:get_node(np).name
40                 if (n == "air") then
41                     minetest.env:add_node(np, {name = "technic:forcefield"})
42                 end
43             end
44         end
45     end
46     end
47     end
48     return true
49 end
50
51 local function remove_forcefield(p, range)
52     for x=-range,range do
53     for y=-range,range do
54     for z=-range,range do
55         if ((x*x+y*y+z*z) <= (range * range + range)) then
56             if ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then
57                 local np={x=p.x+x,y=p.y+y,z=p.z+z}
58                 local n = minetest.env:get_node(np).name
59                 if (n == "technic:forcefield") then
60                     minetest.env:remove_node(np)
61                 end
62             end
63         end
64     end
65     end
66     end
67 end
68
69 forcefield_receive_fields = function(pos, formname, fields, sender)
70     local meta = minetest.env:get_meta(pos)
71     local range = meta:get_int("range")
72     if fields.add then range = range + 1 end
73     if fields.subtract then range = range - 1 end
e5d48e 74     if fields.toggle then
S 75         if meta:get_int("enabled") == 1 then
76             meta:set_int("enabled", 0)
77         else
78             meta:set_int("enabled", 1)
79         end
80     end
c6da0a 81     if range <= 20 and range >= 0 and meta:get_int("range") ~= range then
R 82         remove_forcefield(pos, meta:get_int("range"))
83         meta:set_int("range", range)
84         local buffer = meta:get_float("internal_EU_buffer")
85         local buffer_size = meta:get_float("internal_EU_buffer_size")
86         local load = math.floor(buffer / buffer_size * 100)
87         meta:set_string("formspec", get_forcefield_formspec(range, 0))
88     end
89 end
90
91 function get_forcefield_formspec(range, load)
92     if not load then load = 0 end
93     return "invsize[8,9;]"..
94     "label[0,0;Forcefield emitter]"..
95     "label[1,3;Power level]"..
96     "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:"..
97     load..":technic_power_meter_fg.png]"..
98     "label[4,1;Range]"..
99     "label[4,2;"..range.."]"..
100     "button[3,2;1,1;add;+]"..
101     "button[5,2;1,1;subtract;-]"..
e5d48e 102     "button[3,3;3,1;toggle;Enable/Disable]"..
c6da0a 103     "list[current_player;main;0,5;8,4;]"
R 104 end
105
106 local function forcefield_check(pos)
107     local meta = minetest.env:get_meta(pos)
108     local node = minetest.env:get_node(pos)
109     local internal_EU_buffer=meta:get_float("internal_EU_buffer")
110     local internal_EU_buffer_size=meta:get_float("internal_EU_buffer_size")
111
112     local load = math.floor(internal_EU_buffer/internal_EU_buffer_size * 100)
113     meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"), load))
114
115     local power_requirement = get_forcefield_count(meta:get_int("range")) * forcefield_emitter_power_consumption
e5d48e 116     if meta:get_int("enabled") == 1 and internal_EU_buffer >= power_requirement then
c6da0a 117         if node.name == "technic:forcefield_emitter_off" then
R 118             hacky_swap_node(pos, "technic:forcefield_emitter_on")
119         end
120         internal_EU_buffer=internal_EU_buffer-power_requirement;
121         meta:set_float("internal_EU_buffer", internal_EU_buffer)
122         add_forcefield(pos, meta:get_int("range"))
123     else
124         if node.name == "technic:forcefield_emitter_on" then
e5d48e 125             remove_forcefield(pos, meta:get_int("range"))
c6da0a 126             hacky_swap_node(pos, "technic:forcefield_emitter_off")
R 127         end
128     end
129     return true
130
131 end
e5d48e 132
S 133 local mesecons = {effector = {
134     action_on = function(pos, node)
135         minetest.env:get_meta(pos):set_int("enabled", 0)
136     end,
137     action_off = function(pos, node)
138         minetest.env:get_meta(pos):set_int("enabled", 1)
139     end
140 }}
c6da0a 141
R 142 minetest.register_node("technic:forcefield_emitter_off", {
143     description = "Forcefield emitter",
144     inventory_image = minetest.inventorycube("technic_forcefield_emitter_off.png"),
145     tiles = {"technic_forcefield_emitter_off.png"},
146     is_ground_content = true,
147     groups = {cracky = 1},
148     technic_power_machine=1,
149     on_timer = forcefield_check,
150     on_receive_fields = forcefield_receive_fields,
151     on_construct = function(pos)
152         minetest.env:get_node_timer(pos):start(forcefield_update_interval)
153         local meta = minetest.env:get_meta(pos)
154         meta:set_float("technic_power_machine", 1)
155         meta:set_float("internal_EU_buffer", 0)
156         meta:set_float("internal_EU_buffer_size", forcefield_emitter_buffer_size)
157         meta:set_int("range", 10)
e5d48e 158         meta:set_int("enabled", 1)
c6da0a 159         meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range", 0)))
R 160         meta:set_string("infotext", "Forcefield emitter");
161     end,
e5d48e 162     mesecons = mesecons
c6da0a 163 })
R 164
165 minetest.register_node("technic:forcefield_emitter_on", {
166     description = "Forcefield emitter on (you hacker you)",
167     tiles = {"technic_forcefield_emitter_on.png"},
168     is_ground_content = true,
169     groups = {cracky = 1, not_in_creative_inventory=1},
170     drop='"technic:forcefield_emitter_off" 1',
171     on_timer = forcefield_check,
172     on_receive_fields = forcefield_receive_fields,
173     on_construct = function(pos) 
174         minetest.env:get_node_timer(pos):start(forcefield_update_interval)
175         local meta = minetest.env:get_meta(pos)
176         meta:set_float("technic_power_machine", 1)
177         meta:set_float("internal_EU_buffer", 0)
178         meta:set_float("internal_EU_buffer_size", forcefield_emitter_buffer_size)
179         meta:set_int("range", 10)
e5d48e 180         meta:set_int("enabled", 1)
c6da0a 181         meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"), 0))
R 182         meta:set_string("infotext", "Forcefield emitter");
183     end,
184     on_dig = function(pos, node, digger)    
185         remove_forcefield(pos, minetest.env:get_meta(pos):get_int("range"))
186         return minetest.node_dig(pos, node, digger)
187     end,
188     technic_power_machine=1,
e5d48e 189     mesecons = mesecons
c6da0a 190 })
R 191
192 minetest.register_node("technic:forcefield", {
193     description = "Forcefield (you hacker you)",
194     sunlight_propagates = true,
195     drop = '',
196     tiles = {{name="technic_forcefield_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}},
197     is_ground_content = true,
198     groups = {not_in_creative_inventory=1, unbreakable=1},
199     paramtype = "light",
200     drawtype = "nodebox",
201     node_box = {  --hacky way to get the field blue and not see through the ground
202         type = "fixed",
203         fixed={
204             {-.5,-.5,-.5,.5,.5,.5},
205         },
206     },
207 })
208
209 register_MV_machine ("technic:forcefield_emitter_on","RE")
210 register_MV_machine ("technic:forcefield_emitter_off","RE")
211
212
213
214