ShadowNinja
2013-10-06 363f0332788e04e2e4bb63af5cd21fac5ae56ae5
commit | author | age
ee0765 1
S 2 technic.battery_box_formspec =
3     "invsize[8,9;]"..
4     "image[1,1;1,2;technic_power_meter_bg.png]"..
5     "list[current_name;src;3,1;1,1;]"..
6     "image[4,1;1,1;technic_battery_reload.png]"..
7     "list[current_name;dst;5,1;1,1;]"..
8     "label[0,0;Battery Box]"..
9     "label[3,0;Charge]"..
10     "label[5,0;Discharge]"..
11     "label[1,3;Power level]"..
12     "list[current_player;main;0,5;8,4;]"
13
14 function technic.register_battery_box(data)
15     local tier = data.tier
16     local ltier = string.lower(tier)
17
18     for i = 0, 8 do
19         local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}
20         if i ~= 0 then
21             groups.not_in_creative_inventory = 1
22         end
23         minetest.register_node("technic:"..ltier.."_battery_box"..i, {
24             description = tier.." Battery Box",
25             tiles = {"technic_"..ltier.."_battery_box_top.png",
26                      "technic_"..ltier.."_battery_box_bottom.png",
27                  "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
28                  "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
29                  "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png",
30                  "technic_"..ltier.."_battery_box_side.png^technic_power_meter"..i..".png"},
31             groups = groups,
32             sounds = default.node_sound_wood_defaults(),
33             drop = "technic:"..ltier.."_battery_box0",
34             technic = data,
35             on_construct = function(pos)
36                 local meta = minetest.get_meta(pos)
37                 local inv = meta:get_inventory()
38                 local node = minetest.get_node(pos)
39                 local data = minetest.registered_nodes[node.name].technic
40
41                 meta:set_string("infotext", data.tier.." Battery Box")
42                 meta:set_string("formspec", battery_box_formspec)
43                 meta:set_int(data.tier.."_EU_demand", 0)
44                 meta:set_int(data.tier.."_EU_supply", 0)
45                 meta:set_int(data.tier.."_EU_input",  0)
46                 meta:set_float("internal_EU_charge", 0)
47                 inv:set_size("src", 1)
48                 inv:set_size("dst", 1)
49             end,
50             can_dig = function(pos,player)
51                 local meta = minetest.get_meta(pos);
52                 local inv = meta:get_inventory()
53                 if not inv:is_empty("src") or not inv:is_empty("dst") then
54                     minetest.chat_send_player(player:get_player_name(),
55                         "Machine cannot be removed because it is not empty");
56                     return false
57                 else
58                     return true
59                 end
60             end,
61         })
62     end
63
64
65     minetest.register_abm({
66         nodenames = {"technic:"..ltier.."_battery_box0", "technic:"..ltier.."_battery_box1",
67                      "technic:"..ltier.."_battery_box2", "technic:"..ltier.."_battery_box3",
68                      "technic:"..ltier.."_battery_box4", "technic:"..ltier.."_battery_box5",
69                      "technic:"..ltier.."_battery_box6", "technic:"..ltier.."_battery_box7",
70                      "technic:"..ltier.."_battery_box8"},
71         interval = 1,
72         chance   = 1,
73         action = function(pos, node, active_object_count, active_object_count_wider)
74             local data           = minetest.registered_nodes[node.name].technic
75             local meta           = minetest.get_meta(pos)
76             local eu_input       = meta:get_int(data.tier.."_EU_input")
77             local current_charge = meta:get_int("internal_EU_charge")
78             local max_charge     = data.max_charge
79             local charge_rate    = data.charge_rate
80             local discharge_rate = data.discharge_rate
81
82             -- Power off automatically if no longer connected to a switching station
83             technic.switching_station_timeout_count(pos, data.tier)
84
85             -- Charge/discharge the battery with the input EUs
86             if eu_input >= 0 then
87                 current_charge = math.min(current_charge + eu_input, max_charge)
88             else
89                 current_charge = math.max(current_charge + eu_input, 0)
90             end
91
92             -- Charging/discharging tools here
93             current_charge = technic.charge_tools(meta,
94                     current_charge, data.charge_step)
95             current_charge = technic.discharge_tools(meta,
96                     current_charge, data.discharge_step, max_charge)
97
98             -- We allow batteries to charge on less than the demand
99             meta:set_int(data.tier.."_EU_demand",
100                     math.min(charge_rate, max_charge - current_charge))
101             meta:set_int(data.tier.."_EU_supply",
102                     math.min(discharge_rate, current_charge))
103
104             meta:set_int("internal_EU_charge", current_charge)
105
106             -- Select node textures
107             local charge_count = math.ceil((current_charge / max_charge) * 8)
108             charge_count = math.min(charge_count, 8)
109             charge_count = math.max(charge_count, 0)
110             local last_count = meta:get_float("last_side_shown")
111             if charge_count ~= last_count then
112                 hacky_swap_node(pos,"technic:"..string.lower(data.tier).."_battery_box"..charge_count)
113                 meta:set_float("last_side_shown", charge_count)
114             end
115
116             local charge_percent = math.floor(current_charge / max_charge * 100)
117             meta:set_string("formspec",
118                 technic.battery_box_formspec..
119                 "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:"
120                 ..charge_percent..":technic_power_meter_fg.png]")
121
122             local infotext = data.tier.." battery box: "
123                     ..current_charge.."/"..max_charge
124             if eu_input == 0 then
125                 infotext = infotext.." (idle)"
126             end
127             meta:set_string("infotext", infotext)
128         end
129     })
130
131     -- Register as a battery type
132     -- Battery type machines function as power reservoirs and can both receive and give back power
133     for i = 0, 8 do
134         technic.register_machine(tier, "technic:"..ltier.."_battery_box"..i, technic.battery)
135     end
136
137 end -- End registration
138
139
140 function technic.charge_tools(meta, charge, charge_step)
141     --charge registered power tools
142     local inv = meta:get_inventory()
143     if not inv:is_empty("src") then
144         local srcstack = inv:get_stack("src", 1)
145         local src_item = srcstack:to_table()
146         local src_meta = get_item_meta(src_item["metadata"])
147
148         local toolname = src_item["name"]
149         if technic.power_tools[toolname] ~= nil then
150             -- Set meta data for the tool if it didn't do it itself :-(
151             src_meta = get_item_meta(src_item["metadata"])
152             src_meta = src_meta or {}
153             if src_meta["charge"] == nil then
154                 src_meta["charge"] = 0
155             end
156             -- Do the charging
157             local item_max_charge = technic.power_tools[toolname]
158             local tool_charge     = src_meta["charge"]
159             if tool_charge < item_max_charge and charge > 0 then
160                 if charge - charge_step < 0 then
161                     charge_step = charge
162                 end
163                 if tool_charge + charge_step > item_max_charge then
164                     charge_step = item_max_charge - tool_charge
165                 end
166                 tool_charge = tool_charge + charge_step
167                 charge = charge - charge_step
168                 technic.set_RE_wear(src_item, tool_charge, item_max_charge)
169                 src_meta["charge"]   = tool_charge
170                 src_item["metadata"] = set_item_meta(src_meta)
171                 inv:set_stack("src", 1, src_item)
172             end
173         end
174     end
175     return charge -- return the remaining charge in the battery
176 end
177
178
179 function technic.discharge_tools(meta, charge, charge_step, max_charge)
180     -- discharging registered power tools
181     local inv = meta:get_inventory()
182     if not inv:is_empty("dst") then
183         srcstack = inv:get_stack("dst", 1)
184         src_item = srcstack:to_table()
185         local src_meta = get_item_meta(src_item["metadata"])
186         local toolname = src_item["name"]
187         if technic.power_tools[toolname] ~= nil then
188             -- Set meta data for the tool if it didn't do it itself :-(
189             src_meta = get_item_meta(src_item["metadata"])
190             src_meta = src_meta or {}
191             if src_meta["charge"] == nil then
192                 src_meta["charge"] = 0
193             end
194
195             -- Do the discharging
196             local item_max_charge = technic.power_tools[toolname]
197             local tool_charge     = src_meta["charge"]
198             if tool_charge > 0 and charge < max_charge then
199                 if charge + charge_step > max_charge then
200                     charge_step = max_charge - charge
201                 end
202                 if tool_charge - charge_step < 0 then
203                     charge_step = charge
204                 end
205                 tool_charge = tool_charge - charge_step
206                 charge = charge + charge_step
207                 technic.set_RE_wear(src_item, tool_charge, item_max_charge)
208                 src_meta["charge"] = tool_charge
209                 src_item["metadata"] = set_item_meta(src_meta)
210                 inv:set_stack("dst", 1, src_item)
211             end
212         end
213     end
214     return charge -- return the remaining charge in the battery
215 end
216