ShadowNinja
2013-10-19 eac48441754260fe42c7a605e72141a79ed79bc1
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
eac484 140 function technic.charge_tools(meta, batt_charge, charge_step)
ee0765 141     local inv = meta:get_inventory()
eac484 142     if inv:is_empty("src") then
S 143         return batt_charge
ee0765 144     end
eac484 145     local srcstack = inv:get_stack("src", 1)
S 146     local src_meta = get_item_meta(srcstack:get_metadata())
147
148     local toolname = srcstack:get_name()
149     if not technic.power_tools[toolname] then
150         return batt_charge
151     end
152     -- Set meta data for the tool if it didn't do it itself
153     src_meta = get_item_meta(srcstack:get_metadata())
154     src_meta = src_meta or {}
155     if not src_meta.charge then
156         src_meta.charge = 0
157     end
158     -- Do the charging
159     local item_max_charge = technic.power_tools[toolname]
160     local tool_charge     = src_meta.charge
161     if tool_charge >= item_max_charge or batt_charge <= 0 then
162         return batt_charge
163     end
164     charge_step = math.min(charge_step, batt_charge)
165     charge_step = math.min(charge_step, item_max_charge - tool_charge)
166     tool_charge = tool_charge + charge_step
167     batt_charge = batt_charge - charge_step
168     technic.set_RE_wear(srcstack, tool_charge, item_max_charge)
169     src_meta.charge = tool_charge
170     srcstack:set_metadata(set_item_meta(src_meta))
171     inv:set_stack("src", 1, srcstack)
172     return batt_charge
ee0765 173 end
S 174
175
eac484 176 function technic.discharge_tools(meta, batt_charge, charge_step, max_charge)
ee0765 177     local inv = meta:get_inventory()
eac484 178     if inv:is_empty("dst") then
S 179         return batt_charge
ee0765 180     end
eac484 181     srcstack = inv:get_stack("dst", 1)
S 182     local toolname = srcstack:get_name()
183     if technic.power_tools[toolname] == nil then
184         return batt_charge
185     end
186     -- Set meta data for the tool if it didn't do it itself :-(
187     local src_meta = get_item_meta(srcstack:get_metadata())
188     src_meta = src_meta or {}
189     if not src_meta.charge then
190         src_meta.charge = 0
191     end
192
193     -- Do the discharging
194     local item_max_charge = technic.power_tools[toolname]
195     local tool_charge     = src_meta.charge
196     if tool_charge <= 0 or batt_charge >= max_charge then
197         return batt_charge
198     end
199     charge_step = math.min(charge_step, max_charge - batt_charge)
200     charge_step = math.min(charge_step, tool_charge)
201     tool_charge = tool_charge - charge_step
202     batt_charge = batt_charge + charge_step
203     technic.set_RE_wear(srcstack, tool_charge, item_max_charge)
204     src_meta.charge = tool_charge
205     srcstack:set_metadata(set_item_meta(src_meta))
206     inv:set_stack("dst", 1, srcstack)
207     return batt_charge
ee0765 208 end
S 209