RealBadAngel
2013-03-20 c6da0a6713e1dc77838d180987256bda62dbb19b
commit | author | age
c6da0a 1 --Forcefield mod by ShadowNinja
R 2
3 local forcefield_emitter_buffer_size = 10000
4 local forcefield_emitter_power_consumption = 1
5 local forcefield_update_interval = 1
6
7 minetest.register_craft({
8     output = 'technic:forcefield_emitter_off',
9     recipe = {
10             {'default:mese',         'technic:deployer_off', 'default:mese'        },
11             {'technic:deployer_off', 'technic:motor',        'technic:deployer_off'},
12             {'default:mese',         'technic:deployer_off', 'default:mese'        },
13     }
14 })
15
16 local function get_forcefield_count(range)
17     local count = 0
18     for x=-range,range do
19     for y=0,range do
20     for z=-range,range do
21         if ((x*x+y*y+z*z) <= (range * range + range)) then
22             if (y == 0) or ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then
23                 count = count + 1
24             end
25         end
26     end
27     end
28     end
29     return count
30 end
31
32 local function add_forcefield(pos, range)
33     for x=-range,range do
34     for y=-range,range do
35     for z=-range,range do
36         if ((x*x+y*y+z*z) <= (range * range + range)) then
37             if ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then
38                 local np={x=pos.x+x,y=pos.y+y,z=pos.z+z}
39                 local n = minetest.env:get_node(np).name
40                 if (n == "air") then
41                     minetest.env:add_node(np, {name = "technic:forcefield"})
42                 end
43             end
44         end
45     end
46     end
47     end
48     return true
49 end
50
51 local function remove_forcefield(p, range)
52     for x=-range,range do
53     for y=-range,range do
54     for z=-range,range do
55         if ((x*x+y*y+z*z) <= (range * range + range)) then
56             if ((range-1) * (range-1) + (range-1) <= x*x+y*y+z*z) then
57                 local np={x=p.x+x,y=p.y+y,z=p.z+z}
58                 local n = minetest.env:get_node(np).name
59                 if (n == "technic:forcefield") then
60                     minetest.env:remove_node(np)
61                 end
62             end
63         end
64     end
65     end
66     end
67 end
68
69 forcefield_receive_fields = function(pos, formname, fields, sender)
70     local meta = minetest.env:get_meta(pos)
71     local range = meta:get_int("range")
72     if fields.add then range = range + 1 end
73     if fields.subtract then range = range - 1 end
74     if range <= 20 and range >= 0 and meta:get_int("range") ~= range then
75         remove_forcefield(pos, meta:get_int("range"))
76         meta:set_int("range", range)
77         local buffer = meta:get_float("internal_EU_buffer")
78         local buffer_size = meta:get_float("internal_EU_buffer_size")
79         local load = math.floor(buffer / buffer_size * 100)
80         meta:set_string("formspec", get_forcefield_formspec(range, 0))
81     end
82 end
83
84 function get_forcefield_formspec(range, load)
85     if not load then load = 0 end
86     return "invsize[8,9;]"..
87     "label[0,0;Forcefield emitter]"..
88     "label[1,3;Power level]"..
89     "image[1,1;1,2;technic_power_meter_bg.png^[lowpart:"..
90     load..":technic_power_meter_fg.png]"..
91     "label[4,1;Range]"..
92     "label[4,2;"..range.."]"..
93     "button[3,2;1,1;add;+]"..
94     "button[5,2;1,1;subtract;-]"..
95     "list[current_player;main;0,5;8,4;]"
96 end
97
98 local function forcefield_check(pos)
99     local meta = minetest.env:get_meta(pos)
100     local node = minetest.env:get_node(pos)
101     local internal_EU_buffer=meta:get_float("internal_EU_buffer")
102     local internal_EU_buffer_size=meta:get_float("internal_EU_buffer_size")
103
104     local load = math.floor(internal_EU_buffer/internal_EU_buffer_size * 100)
105     meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"), load))
106
107     local power_requirement = get_forcefield_count(meta:get_int("range")) * forcefield_emitter_power_consumption
108     if meta:get_int("mesecons_powered") == 0 and internal_EU_buffer >= power_requirement then
109         if node.name == "technic:forcefield_emitter_off" then
110             hacky_swap_node(pos, "technic:forcefield_emitter_on")
111             minetest.env:get_node_timer(pos):start(forcefield_update_interval)
112         end
113         internal_EU_buffer=internal_EU_buffer-power_requirement;
114         meta:set_float("internal_EU_buffer", internal_EU_buffer)
115         add_forcefield(pos, meta:get_int("range"))
116     else
117         remove_forcefield(pos, meta:get_int("range"))
118         if node.name == "technic:forcefield_emitter_on" then
119             hacky_swap_node(pos, "technic:forcefield_emitter_off")
120             minetest.env:get_node_timer(pos):start(forcefield_update_interval)
121         end
122     end
123     return true
124
125 end
126
127 minetest.register_node("technic:forcefield_emitter_off", {
128     description = "Forcefield emitter",
129     inventory_image = minetest.inventorycube("technic_forcefield_emitter_off.png"),
130     tiles = {"technic_forcefield_emitter_off.png"},
131     is_ground_content = true,
132     groups = {cracky = 1},
133     technic_power_machine=1,
134     on_timer = forcefield_check,
135     on_receive_fields = forcefield_receive_fields,
136     on_construct = function(pos)
137         minetest.env:get_node_timer(pos):start(forcefield_update_interval)
138         local meta = minetest.env:get_meta(pos)
139         meta:set_float("technic_power_machine", 1)
140         meta:set_float("internal_EU_buffer", 0)
141         meta:set_float("internal_EU_buffer_size", forcefield_emitter_buffer_size)
142         meta:set_int("range", 10)
143         meta:set_int("mesecons_powered", 0)
144         meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range", 0)))
145         meta:set_string("infotext", "Forcefield emitter");
146     end,
147     mesecons = {effector = {
148         action_on = function (pos, node)
149             minetest.env:get_meta(pos):set_int("mesecons_powered", 1)
150         end,
151         action_off = function(pos, node)
152             minetest.env:get_meta(pos):set_int("mesecons_powered", 0)
153         end
154     }}
155 })
156
157 minetest.register_node("technic:forcefield_emitter_on", {
158     description = "Forcefield emitter on (you hacker you)",
159     tiles = {"technic_forcefield_emitter_on.png"},
160     is_ground_content = true,
161     groups = {cracky = 1, not_in_creative_inventory=1},
162     drop='"technic:forcefield_emitter_off" 1',
163     on_timer = forcefield_check,
164     on_receive_fields = forcefield_receive_fields,
165     on_construct = function(pos) 
166         minetest.env:get_node_timer(pos):start(forcefield_update_interval)
167         local meta = minetest.env:get_meta(pos)
168         meta:set_float("technic_power_machine", 1)
169         meta:set_float("internal_EU_buffer", 0)
170         meta:set_float("internal_EU_buffer_size", forcefield_emitter_buffer_size)
171         meta:set_int("range", 10)
172         meta:set_int("mesecons_powered", 0)
173         meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"), 0))
174         meta:set_string("infotext", "Forcefield emitter");
175     end,
176     on_dig = function(pos, node, digger)    
177         remove_forcefield(pos, minetest.env:get_meta(pos):get_int("range"))
178         return minetest.node_dig(pos, node, digger)
179     end,
180     technic_power_machine=1,
181     mesecons = {effector = {
182         action_on = function(pos, node)
183             minetest.env:get_meta(pos):set_int("mesecons_powered", 1)
184         end,
185         action_off = function(pos, node)
186             minetest.env:get_meta(pos):set_int("mesecons_powered", 0)
187         end
188     }}
189 })
190
191 minetest.register_node("technic:forcefield", {
192     description = "Forcefield (you hacker you)",
193     sunlight_propagates = true,
194     drop = '',
195     tiles = {{name="technic_forcefield_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}},
196     is_ground_content = true,
197     groups = {not_in_creative_inventory=1, unbreakable=1},
198     paramtype = "light",
199     drawtype = "nodebox",
200     node_box = {  --hacky way to get the field blue and not see through the ground
201         type = "fixed",
202         fixed={
203             {-.5,-.5,-.5,.5,.5,.5},
204         },
205     },
206 })
207
208 register_MV_machine ("technic:forcefield_emitter_on","RE")
209 register_MV_machine ("technic:forcefield_emitter_off","RE")
210
211
212
213