ShadowNinja
2013-07-13 187015e0733e5e0bfa5efba215319c7d9d86f072
commit | author | age
305527 1 -- The enriched uranium rod driven EU generator.
K 2 -- A very large and advanced machine providing vast amounts of power.
3 -- Very efficient but also expensive to run as it needs uranium. (10000EU 86400 ticks (24h))
4 -- Provides HV EUs that can be down converted as needed.
5 --
6 -- The nuclear reactor core needs water and a protective shield to work.
7 -- This is checked now and then and if the machine is tampered with... BOOM!
187015 8
fa8469 9 local burn_ticks   = 24*60                      -- [minutes]. How many minutes does the power plant burn per serving?
305527 10 local power_supply = 10000                      -- [HV] EUs
187015 11 local fuel_type    = "technic:enriched_uranium" -- The reactor burns this stuff
S 12
305527 13
K 14 -- FIXME: recipe must make more sense like a rod recepticle, steam chamber, HV generator?
187015 15 minetest.register_craft({
S 16     output = 'technic:hv_nuclear_reactor_core',
17     recipe = {
18         {'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot', 'technic:stainless_steel_ingot'},
19         {'technic:stainless_steel_ingot',                              '', 'technic:stainless_steel_ingot'},
20         {'technic:stainless_steel_ingot',              'technic:hv_cable', 'technic:stainless_steel_ingot'},
21     }
22 })
305527 23
187015 24 minetest.register_craftitem("technic:hv_nuclear_reactor_core",{
S 25     description = "Uranium Rod Driven HV Reactor",
26     stack_max = 1,
27 }) 
305527 28
K 29 local generator_formspec =
187015 30     "invsize[8,9;]"..
S 31     --"image[0,0;5,5;technic_generator_menu.png]"..
32     "label[0,0;Nuclear Reactor Rod Compartment]"..
33     "list[current_name;src;2,1;3,2;]"..
34     "list[current_player;main;0,5;8,4;]"
305527 35
K 36 -- "Boxy sphere"
fa8469 37 local nodebox = {
187015 38     { -0.353, -0.353, -0.353, 0.353, 0.353, 0.353 }, -- Box
S 39     { -0.495, -0.064, -0.064, 0.495, 0.064, 0.064 }, -- Circle +-x
40     { -0.483, -0.128, -0.128, 0.483, 0.128, 0.128 },
41     { -0.462, -0.191, -0.191, 0.462, 0.191, 0.191 },
42     { -0.433, -0.249, -0.249, 0.433, 0.249, 0.249 },
43     { -0.397, -0.303, -0.303, 0.397, 0.303, 0.303 },
44     { -0.305, -0.396, -0.305, 0.305, 0.396, 0.305 }, -- Circle +-y
45     { -0.250, -0.432, -0.250, 0.250, 0.432, 0.250 },
46     { -0.191, -0.461, -0.191, 0.191, 0.461, 0.191 },
47     { -0.130, -0.482, -0.130, 0.130, 0.482, 0.130 },
48     { -0.066, -0.495, -0.066, 0.066, 0.495, 0.066 },
49     { -0.064, -0.064, -0.495, 0.064, 0.064, 0.495 }, -- Circle +-z
50     { -0.128, -0.128, -0.483, 0.128, 0.128, 0.483 },
51     { -0.191, -0.191, -0.462, 0.191, 0.191, 0.462 },
52     { -0.249, -0.249, -0.433, 0.249, 0.249, 0.433 },
53     { -0.303, -0.303, -0.397, 0.303, 0.303, 0.397 },
fa8469 54 }
305527 55
187015 56 minetest.register_node("technic:hv_nuclear_reactor_core", {
S 57     description = "Nuclear Reactor",
58     tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
59              "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
60              "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"},
61     groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
62     legacy_facedir_simple = true,
63     sounds = default.node_sound_wood_defaults(),
64     drawtype="nodebox",
65     paramtype = "light",
66     node_box = {
67         type = "fixed",
68         fixed = nodebox
69     },
70     on_construct = function(pos)
71         local meta = minetest.env:get_meta(pos)
72         meta:set_string("infotext", "Nuclear Reactor Core")
73         meta:set_float("technic_hv_power_machine", 1)
74         meta:set_int("HV_EU_supply", 0)
75         meta:set_int("HV_EU_from_fuel", 1) -- Signal to the switching station that this device burns some sort of fuel and needs special handling
76         meta:set_int("burn_time", 0)
77         meta:set_string("formspec", generator_formspec)
78         local inv = meta:get_inventory()
79         inv:set_size("src", 6)
80     end,    
81     can_dig = function(pos,player)
82         local meta = minetest.env:get_meta(pos);
83         local inv = meta:get_inventory()
84         if not inv:is_empty("src") then
85             minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
86             return false
87         else
88             return true
89         end
90     end,
91 })
305527 92
187015 93 minetest.register_node("technic:hv_nuclear_reactor_core_active", {
S 94     description = "Uranium Rod Driven HV Reactor",
95     tiles = {"technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
96              "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png",
97          "technic_hv_nuclear_reactor_core.png", "technic_hv_nuclear_reactor_core.png"},
98     groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, not_in_creative_inventory=1},
99     legacy_facedir_simple = true,
100     sounds = default.node_sound_wood_defaults(),
101     drop="technic:hv_nuclear_reactor_core",
102     drawtype="nodebox",
103     light_source = 15,
104     paramtype = "light",
105     node_box = {
106         type = "fixed",
107         fixed = nodebox
108     },
109     can_dig = function(pos,player)
110         local meta = minetest.env:get_meta(pos);
111         local inv = meta:get_inventory()
112         if not inv:is_empty("src") then
113             minetest.chat_send_player(player:get_player_name(), "Machine cannot be removed because it is not empty");
114             return false
115         else
116             return true
117         end
118     end,
119 })
305527 120
K 121 local check_reactor_structure = function(pos)
187015 122     -- The reactor consists of an 11x11x11 cube structure
S 123     -- A cross section through the middle:
124     --  CCCCC CCCCC
125     --  CCCCC CCCCC
126     --  CCSSS SSSCC
127     --  CCSCC CCSCC
128     --  CCSCWWWCSCC
129     --  CCSCW#WCSCC
130     --  CCSCW|WCSCC
131     --  CCSCC|CCSCC
132     --  CCSSS|SSSCC
133     --  CCCCC|CCCCC
134     --  C = Concrete, S = Stainless Steel, W = water node (not floating), #=reactor core, |=HV cable
135     --  The man-hole and the HV cable is only in the middle
136     --  The man-hole is optional
305527 137
187015 138     local source_water_nodes = minetest.find_nodes_in_area(
S 139         {x=pos.x-1, y=pos.y-1, z=pos.z-1},
140         {x=pos.x+1, y=pos.y+1, z=pos.z+1},
141         "default:water_source")
142     local flowing_water_nodes = minetest.find_nodes_in_area(
143         {x=pos.x-1, y=pos.y-1, z=pos.z-1},
144         {x=pos.x+1, y=pos.y+1, z=pos.z+1},
145         "default:water_flowing")
146     if not ((#source_water_nodes + #flowing_water_nodes) >= 25) then
147         return false
148     end
305527 149
187015 150     local inner_shield_nodes = minetest.find_nodes_in_area(
S 151         {x=pos.x-2, y=pos.y-2, z=pos.z-2},
152         {x=pos.x+2, y=pos.y+2, z=pos.z+2},
153         "technic:concrete")
154     if not (#inner_shield_nodes >= 96) then
155         return false
156     end
157
158     local steel_shield_nodes = minetest.find_nodes_in_area(
159         {x=pos.x-3, y=pos.y-3, z=pos.z-3},
160         {x=pos.x+3, y=pos.y+3, z=pos.z+3},
161         "default:steelblock")
162     if not (#steel_shield_nodes >= 216) then
163         return false
164     end
165
166     local outer_shield_nodes = minetest.find_nodes_in_area(
167         {x=pos.x-5, y=pos.y-5, z=pos.z-5},
168         {x=pos.x+5, y=pos.y+5, z=pos.z+5},
169         "technic:concrete")
170     if not (#outer_shield_nodes >= (984 + #inner_shield_nodes)) then
171         return false
172     end
173     return true
174 end
305527 175
K 176 local explode_reactor = function(pos)
187015 177     print("BOOM A reactor exploded!")
S 178 end
305527 179
187015 180 minetest.register_abm({
S 181     nodenames = {"technic:hv_nuclear_reactor_core", "technic:hv_nuclear_reactor_core_active"},
182     interval = 1,
183     chance   = 1,
184     action = function(pos, node, active_object_count, active_object_count_wider)
fa8469 185         local meta = minetest.env:get_meta(pos)
187015 186         local burn_time = meta:get_int("burn_time")
305527 187
fa8469 188         -- If more to burn and the energy produced was used: produce some more
187015 189         if burn_time > 0 then
S 190             if not check_reactor_structure(pos) then
191                 explode_reactor(pos)
192             end
193             if meta:get_int("HV_EU_supply") == 0 then
194                 -- We did not use the power
195                 meta:set_int("HV_EU_supply", power_supply)
196             else
197                 burn_time = burn_time - 1
198                 meta:set_int("burn_time", burn_time)
199                 local percent = math.floor(burn_time / (burn_ticks * 60) * 100)
200                 meta:set_string("infotext", "Nuclear Reactor Core ("..percent.."%)")
201             end
fa8469 202         end
305527 203
fa8469 204         -- Burn another piece of coal
187015 205         if burn_time <= 0 then
S 206             local inv = meta:get_inventory()
207             local correct_fuel_count = 0
208             if not inv:is_empty("src") then 
209                 local srclist = inv:get_list("src")
210                 for _, srcstack in pairs(srclist) do
211                     if srcstack then
212                         local src_item=srcstack:to_table()
213                         if src_item and src_item["name"] == fuel_type then
214                             correct_fuel_count = correct_fuel_count + 1
215                         end
216                     end
217                 end
218                 -- Check that the reactor is complete as well as the correct number of correct fuel
219                 if correct_fuel_count == 6 then
220                     if not check_reactor_structure(pos) then
221                         burn_time = burn_ticks * 60
222                         meta:set_int("burn_time", burn_time)
223                         hacky_swap_node (pos,"technic:hv_nuclear_reactor_core_active") 
224                         meta:set_int("HV_EU_supply", power_supply)
225                         for idx, srcstack in pairs(srclist) do
226                             srcstack:take_item()
227                             inv:set_stack("src", idx, srcstack)
228                         end
229                     end
230                 else
231                     meta:set_int("HV_EU_supply", 0)
232                 end
233             end
fa8469 234         end
305527 235
fa8469 236         -- Nothing left to burn
187015 237         if burn_time == 0 then
S 238             meta:set_string("infotext", "Nuclear Reactor Core (idle)")
239             hacky_swap_node(pos,"technic:hv_nuclear_reactor_core")
fa8469 240         end
187015 241     end
S 242 })
305527 243
K 244 technic.register_HV_machine ("technic:hv_nuclear_reactor_core","PR")
245 technic.register_HV_machine ("technic:hv_nuclear_reactor_core_active","PR")