kpoppel
2013-06-12 390ea043527203bb2d0cb6f873fedbffa68ae83f
commit | author | age
cfb5bd 1 -- register MV machines here
K 2 technic.HV_machines = {}
3 local HV_machines = technic.HV_machines
4 function register_HV_machine(string1,string2)
5    technic.HV_machines[string1] = string2
64207b 6 end
R 7
8 minetest.register_craft({
cfb5bd 9                output = 'technic:hv_battery_box 1',
K 10                recipe = {
11                   {'technic:mv_battery_box', 'technic:mv_battery_box', 'mv_technic:battery_box'},
12                   {'technic:mv_battery_box', 'technic:hv_transformer', 'mv_technic:battery_box'},
13                   {'', 'technic:hv_cable', ''},
14                }
15             })
64207b 16
R 17 hv_battery_box_formspec =
cfb5bd 18    "invsize[8,9;]"..
K 19    "image[1,1;1,2;technic_power_meter_bg.png]"..
20    "list[current_name;src;3,1;1,1;]"..
21    "image[4,1;1,1;technic_battery_reload.png]"..
22    "list[current_name;dst;5,1;1,1;]"..
23    "label[0,0;HV Battery Box]"..
24    "label[3,0;Charge]"..
25    "label[5,0;Discharge]"..
26    "label[1,3;Power level]"..
27    "list[current_player;main;0,5;8,4;]"
64207b 28
cfb5bd 29 minetest.register_node(
K 30    "technic:hv_battery_box", {
31       description = "HV Battery Box",
32       tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png",
33            "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png", "technic_hv_battery_box_side0.png"},
34       groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
35       sounds = default.node_sound_wood_defaults(),
36       drop="technic:hv_battery_box",
37       on_construct = function(pos)
38             if pos==nil then return end
39             local meta = minetest.env:get_meta(pos)
40             local inv = meta:get_inventory()
41             meta:set_string("infotext", "HV Battery Box")
42             meta:set_float("technic_hv_power_machine", 1)
43             meta:set_string("formspec", battery_box_formspec)
44             inv:set_size("src", 1)
45             inv:set_size("dst", 1)
46              end,
47       can_dig = function(pos,player)
48            if pos==nil then return end
49            local meta = minetest.env:get_meta(pos);
50            local inv = meta:get_inventory()
51            if not inv:is_empty("dst") then
52               return false
53            elseif not inv:is_empty("src") then
54               return false
55            end
56            return true
57         end,
58    })
64207b 59
R 60 for i=1,8,1 do
cfb5bd 61    minetest.register_node(
K 62       "technic:hv_battery_box"..i, {
63      description = "HV Battery Box",
64      tiles = {"technic_hv_battery_box_top.png", "technic_hv_battery_box_bottom.png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png",
65           "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png", "technic_hv_battery_box_side0.png^technic_power_meter"..i..".png"},
66      groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,not_in_creative_inventory=1},
67      sounds = default.node_sound_wood_defaults(),
68      paramtype="light",
69      light_source=9,
70      drop="technic:hv_battery_box",
71      on_construct = function(pos)
72                local meta = minetest.env:get_meta(pos)
73                local inv = meta:get_inventory()
74                meta:set_string("infotext", "HV Battery box")
75                meta:set_float("technic_hv_power_machine", 1)
76                meta:set_string("formspec", battery_box_formspec)
77                inv:set_size("src", 1)
78                inv:set_size("dst", 1)
79             end,
80      can_dig = function(pos,player)
81               local meta = minetest.env:get_meta(pos);
82               local inv = meta:get_inventory()
83               if not inv:is_empty("dst") then
84              return false
85               elseif not inv:is_empty("src") then
86              return false
87               end
88               return true
89            end,
90       })
64207b 91 end
R 92
cfb5bd 93 minetest.register_abm(
K 94    {nodenames = {"technic:hv_battery_box","technic:hv_battery_box1","technic:hv_battery_box2","technic:hv_battery_box3","technic:hv_battery_box4",
95          "technic:hv_battery_box5","technic:hv_battery_box6","technic:hv_battery_box7","technic:hv_battery_box8"
96           },
97     interval = 1,
98     chance = 1,
99     action = function(pos, node, active_object_count, active_object_count_wider)
100         local meta       = minetest.env:get_meta(pos)
101         local max_charge = 1500000
102         local charge     = meta:get_int("internal_EU_buffer")
64207b 103
cfb5bd 104         -- Select node textures
K 105         local i = math.ceil((charge/max_charge)*8)
106         if i > 8 then i = 8 end
107         local j = meta:get_float("last_side_shown")
108         if i~=j then
109            if i>0 then hacky_swap_node(pos,"technic:hv_battery_box"..i)
110            elseif i==0 then hacky_swap_node(pos,"technic:hv_battery_box") end
111            meta:set_float("last_side_shown",i)
64207b 112         end
R 113
cfb5bd 114         --charge registered power tools
K 115         local inv = meta:get_inventory()
116         if inv:is_empty("src")==false  then
117            local srcstack = inv:get_stack("src", 1)
118            local src_item=srcstack:to_table()
119            local src_meta=get_item_meta(src_item["metadata"])
64207b 120
cfb5bd 121            for i=1,registered_power_tools_count,1 do
K 122               if power_tools[i].tool_name==src_item["name"] then
123              src_meta=get_item_meta(src_item["metadata"])
124              if src_meta==nil then
125                 src_meta={}
126                 src_meta["technic_power_tool"]=true
127                 src_meta["charge"]=0
128              else
129                 if src_meta["technic_power_tool"]==nil then
130                    src_meta["technic_power_tool"]=true
131                    src_meta["charge"]=0
132                 end
133              end
134              -- Do the charging
135              local item_max_charge = power_tools[i].max_charge
136              local load1           = src_meta["charge"]
137              local load_step       = 16000 -- how much to charge per tick
138              if load1<item_max_charge and charge>0 then
139                 if charge-load_step<0 then load_step=charge end
140                 if load1+load_step>item_max_charge then load_step=item_max_charge-load1 end
141                 load1=load1+load_step
142                 charge=charge-load_step
143                 set_RE_wear(src_item,load1,item_max_charge)
144                 src_meta["charge"]=load1
145                 src_item["metadata"]=set_item_meta(src_meta)
146                 inv:set_stack("src", 1, src_item)
147              end
148              meta:set_int("internal_EU_buffer",charge)
149              break
150               end
151            end
152         end
153
154         -- discharging registered power tools
155         if inv:is_empty("dst") == false then
156            srcstack = inv:get_stack("dst", 1)
157            src_item=srcstack:to_table()
158            local src_meta=get_item_meta(src_item["metadata"])
159            local item_max_charge=nil
160            for i=1,registered_power_tools_count,1 do
161               if power_tools[i].tool_name==src_item["name"] then
162              src_meta=get_item_meta(src_item["metadata"])
163              if src_meta==nil then
164                 src_meta={}
165                 src_meta["technic_power_tool"]=true
166                 src_meta["charge"]=0
167              else
168                 if src_meta["technic_power_tool"]==nil then
169                    src_meta["technic_power_tool"]=true
170                    src_meta["charge"]=0
171                 end
172              end
173              local item_max_charge = power_tools[i].max_charge
174              local load1           = src_meta["charge"]
175              local load_step       = 16000 -- how much to discharge per tick
176              if load1>0 and charge<max_charge then
177                 if charge+load_step>max_charge then load_step=max_charge-charge end
178                 if load1-load_step<0 then load_step=load1 end
179                 load1=load1-load_step
180                 charge=charge+load_step
181                 set_RE_wear(src_item,load1,item_max_charge)
182                 src_meta["charge"]=load1
183                 src_item["metadata"]=set_item_meta(src_meta)
184                 inv:set_stack("dst", 1, src_item)
185              end
186              meta:set_int("internal_EU_buffer",charge)
187              break
188               end
189            end
190         end
191
192
193         local load = math.floor((charge/1500000) * 100)
194         meta:set_string("formspec",
64207b 195                 hv_battery_box_formspec..
cfb5bd 196                    "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:"..
K 197                    (load)..":technic_power_meter_fg.png]"
198                  )
64207b 199
cfb5bd 200         -- Next index the surrounding network the get the producers and receivers on the 
K 201         local pos1={}
202         pos1.y=pos.y-1
203         pos1.x=pos.x
204         pos1.z=pos.z
64207b 205
cfb5bd 206         meta1 = minetest.env:get_meta(pos1)
K 207         if meta1:get_float("hv_cablelike")~=1 then return end
64207b 208
R 209         local HV_nodes = {}
210         local PR_nodes = {}
211         local RE_nodes = {}
cfb5bd 212         local BA_nodes = {}
64207b 213
R 214         HV_nodes[1]={}
215         HV_nodes[1].x=pos1.x
216         HV_nodes[1].y=pos1.y
217         HV_nodes[1].z=pos1.z
218         HV_nodes[1].visited=false
219
cfb5bd 220         local table_index=1
K 221         repeat
222            check_HV_node (PR_nodes,RE_nodes,BA_nodes,HV_nodes,table_index)
223            table_index=table_index+1
224            if HV_nodes[table_index]==nil then break end
225         until false
64207b 226
cfb5bd 227         -- Get power from all connected producers
K 228         local pr_pos
229                 for _,pr_pos in ipairs(PR_nodes) do
230            local meta1              = minetest.env:get_meta(pr_pos)
231            local internal_EU_buffer = meta1:get_float("internal_EU_buffer")
232            local charge_to_take     = 4000
233            if charge<max_charge then
234               if internal_EU_buffer-charge_to_take<=0 then
235              charge_to_take=internal_EU_buffer
236               end
237               if charge_to_take>0 then
238              charge=charge+charge_to_take
239              internal_EU_buffer=internal_EU_buffer-charge_to_take
240              meta1:set_float("internal_EU_buffer",internal_EU_buffer)
241               end
242            end
243         end
64207b 244
cfb5bd 245         if charge>max_charge then charge=max_charge end
64207b 246
cfb5bd 247         -- Provide power to all connected receivers
K 248         local re_pos
249                 for _,re_pos in ipairs(RE_nodes) do
250            local meta1                   = minetest.env:get_meta(re_pos)
251            local internal_EU_buffer      = meta1:get_float("internal_EU_buffer")
252            local internal_EU_buffer_size = meta1:get_float("internal_EU_buffer_size")
253            local charge_to_give          = math.min(4000, charge/table.getn(RE_nodes))
254            if internal_EU_buffer+charge_to_give>internal_EU_buffer_size then
255               charge_to_give=internal_EU_buffer_size-internal_EU_buffer
256            end
257            if charge-charge_to_give<0 then charge_to_give=charge end
64207b 258
cfb5bd 259            internal_EU_buffer=internal_EU_buffer+charge_to_give
K 260            meta1:set_float("internal_EU_buffer",internal_EU_buffer)
261            charge=charge-charge_to_give;
262         end
263         charge=math.floor(charge)
264         meta:set_string("infotext", "MV Battery box: "..charge.."/"..max_charge);
265         meta:set_int("internal_EU_buffer",charge)
266          end
267  })
64207b 268
cfb5bd 269 -- Register as a battery type
K 270 -- Battery type machines function as power reservoirs and can both receive and give back power
271 register_HV_machine("technic:hv_battery_box","BA")
272 for i=1,8,1 do
273    register_HV_machine("technic:hv_battery_box"..i,"BA")
64207b 274 end
R 275
276 function add_new_HVcable_node (HV_nodes,pos1)
cfb5bd 277    if HV_nodes == nil then return true end
K 278    local i=1
279    repeat
280       if HV_nodes[i]==nil then break end
281       if pos1.x==HV_nodes[i].x and pos1.y==HV_nodes[i].y and pos1.z==HV_nodes[i].z then return false end
282       i=i+1
283    until false
284    HV_nodes[i]={}
285    HV_nodes[i].x=pos1.x
286    HV_nodes[i].y=pos1.y
287    HV_nodes[i].z=pos1.z
288    return true
64207b 289 end
R 290
cfb5bd 291 function check_HV_node(PR_nodes,RE_nodes,BA_nodes,HV_nodes,i)
K 292    local pos1={}
293    pos1.x=HV_nodes[i].x
294    pos1.y=HV_nodes[i].y
295    pos1.z=HV_nodes[i].z
64207b 296
cfb5bd 297    pos1.x=pos1.x+1
K 298    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
299    pos1.x=pos1.x-2
300    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
301    pos1.x=pos1.x+1
302
303    pos1.y=pos1.y+1
304    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
305    pos1.y=pos1.y-2
306    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
307    pos1.y=pos1.y+1
308
309    pos1.z=pos1.z+1
310    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
311    pos1.z=pos1.z-2
312    check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
313    pos1.z=pos1.z+1
64207b 314 end
R 315
cfb5bd 316 function check_HV_node_subp (PR_nodes,RE_nodes,BA_nodes,HV_nodes,pos1)
K 317    local meta = minetest.env:get_meta(pos1)
318    local name = minetest.env:get_node(pos1).name
319    if meta:get_float("hv_cablelike")==1 then
320       add_new_HVcable_node(HV_nodes,pos1)
321    elseif HV_machines[name] then
322       --print(name.." is a "..HV_machines[name])
323       if     HV_machines[name] == "PR" then
324      add_new_HVcable_node(PR_nodes,pos1)
325       elseif HV_machines[name] == "RE" then
326      add_new_HVcable_node(RE_nodes,pos1)
327       elseif HV_machines[name] == "BA" then
328      add_new_HVcable_node(BA_nodes,pos1)
329       end
330    end
64207b 331 end