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