commit | author | age
|
9a0d3f
|
1 |
-- Forcefield mod by ShadowNinja |
K |
2 |
-- Modified by kpoppel |
|
3 |
-- |
|
4 |
-- Forcefields are powerful barriers but they consume huge amounts of power. |
|
5 |
-- Forcefield Generator is a HV machine. |
c6da0a
|
6 |
|
73209c
|
7 |
-- How expensive is the generator? Leaves room for upgrades lowering the power drain? |
30361a
|
8 |
local forcefield_power_drain = 10 |
4f35f4
|
9 |
local forcefield_step_interval = 1 |
c6da0a
|
10 |
|
R |
11 |
minetest.register_craft({ |
|
12 |
output = 'technic:forcefield_emitter_off', |
|
13 |
recipe = { |
|
14 |
{'default:mese', 'technic:deployer_off', 'default:mese' }, |
|
15 |
{'technic:deployer_off', 'technic:motor', 'technic:deployer_off'}, |
|
16 |
{'default:mese', 'technic:deployer_off', 'default:mese' }, |
|
17 |
} |
|
18 |
}) |
|
19 |
|
30361a
|
20 |
|
9a0d3f
|
21 |
-- Idea: Let forcefields have different colors by upgrade slot. |
K |
22 |
-- Idea: Let forcefields add up by detecting if one hits another. |
|
23 |
-- ___ __ |
|
24 |
-- / \/ \ |
|
25 |
-- | | |
|
26 |
-- \___/\___/ |
30361a
|
27 |
|
4f35f4
|
28 |
local function update_forcefield(pos, range, active) |
S |
29 |
local vm = VoxelManip() |
|
30 |
local p1 = {x = pos.x-range, y = pos.y-range, z = pos.z-range} |
|
31 |
local p2 = {x = pos.x+range, y = pos.y+range, z = pos.z+range} |
|
32 |
local MinEdge, MaxEdge = vm:read_from_map(p1, p2) |
|
33 |
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge}) |
|
34 |
local data = vm:get_data() |
30361a
|
35 |
|
4f35f4
|
36 |
local c_air = minetest.get_content_id("air") |
S |
37 |
local c_field = minetest.get_content_id("technic:forcefield") |
|
38 |
|
|
39 |
for z=-range, range do |
|
40 |
for y=-range, range do |
|
41 |
local vi = area:index(pos.x+(-range), pos.y+y, pos.z+z) |
|
42 |
for x=-range, range do |
|
43 |
if x*x+y*y+z*z <= range * range + range and |
|
44 |
x*x+y*y+z*z >= (range-1) * (range-1) + (range-1) and |
|
45 |
((active and data[vi] == c_air) or ((not active) and data[vi] == c_field)) then |
|
46 |
if active then |
|
47 |
data[vi] = c_field |
|
48 |
else |
|
49 |
data[vi] = c_air |
c6da0a
|
50 |
end |
R |
51 |
end |
4f35f4
|
52 |
vi = vi + 1 |
c6da0a
|
53 |
end |
R |
54 |
end |
|
55 |
end |
|
56 |
|
4f35f4
|
57 |
vm:set_data(data) |
S |
58 |
vm:update_liquids() |
|
59 |
vm:write_to_map() |
|
60 |
vm:update_map() |
c6da0a
|
61 |
end |
R |
62 |
|
9a0d3f
|
63 |
local get_forcefield_formspec = function(range) |
K |
64 |
return "invsize[3,4;]".. |
30361a
|
65 |
"label[0,0;Forcefield emitter]".. |
S |
66 |
"label[1,1;Range]".. |
|
67 |
"label[1,2;"..range.."]".. |
|
68 |
"button[0,2;1,1;subtract;-]".. |
|
69 |
"button[2,2;1,1;add;+]".. |
|
70 |
"button[0,3;3,1;toggle;Enable/Disable]" |
c6da0a
|
71 |
end |
R |
72 |
|
9a0d3f
|
73 |
local forcefield_receive_fields = function(pos, formname, fields, sender) |
30361a
|
74 |
local meta = minetest.env:get_meta(pos) |
S |
75 |
local range = meta:get_int("range") |
9a0d3f
|
76 |
|
30361a
|
77 |
if fields.add then range = range + 1 end |
S |
78 |
if fields.subtract then range = range - 1 end |
|
79 |
if fields.toggle then |
|
80 |
if meta:get_int("enabled") == 1 then |
|
81 |
meta:set_int("enabled", 0) |
|
82 |
else |
|
83 |
meta:set_int("enabled", 1) |
|
84 |
end |
|
85 |
end |
|
86 |
|
|
87 |
-- Smallest field is 5. Anything less is asking for trouble. |
|
88 |
-- Largest is 20. It is a matter of pratical node handling. |
|
89 |
if range < 5 then range = 5 end |
|
90 |
if range > 20 then range = 20 end |
|
91 |
|
|
92 |
if range <= 20 and range >= 5 and meta:get_int("range") ~= range then |
4f35f4
|
93 |
update_forcefield(pos, meta:get_int("range"), false) |
30361a
|
94 |
meta:set_int("range", range) |
S |
95 |
meta:set_string("formspec", get_forcefield_formspec(range)) |
|
96 |
end |
|
97 |
end |
c6da0a
|
98 |
|
4f35f4
|
99 |
local function forcefield_step(pos) |
30361a
|
100 |
local meta = minetest.env:get_meta(pos) |
S |
101 |
local node = minetest.env:get_node(pos) |
|
102 |
local eu_input = meta:get_int("HV_EU_input") |
|
103 |
local eu_demand = meta:get_int("HV_EU_demand") |
|
104 |
local enabled = meta:get_int("enabled") |
c6da0a
|
105 |
|
30361a
|
106 |
-- Power off automatically if no longer connected to a switching station |
S |
107 |
technic.switching_station_timeout_count(pos, "HV") |
c6da0a
|
108 |
|
30361a
|
109 |
local power_requirement = 0 |
S |
110 |
if enabled == 1 then |
|
111 |
power_requirement = math.floor( |
|
112 |
4 * math.pi * math.pow(meta:get_int("range"), 2) |
|
113 |
) * forcefield_power_drain |
|
114 |
else |
|
115 |
power_requirement = eu_demand |
e5d48e
|
116 |
end |
30361a
|
117 |
|
S |
118 |
if meta:get_int("enabled") == 0 then |
|
119 |
if node.name == "technic:forcefield_emitter_on" then |
4f35f4
|
120 |
update_forcefield(pos, meta:get_int("range"), false) |
30361a
|
121 |
hacky_swap_node(pos, "technic:forcefield_emitter_off") |
S |
122 |
meta:set_int("HV_EU_demand", 100) |
|
123 |
meta:set_string("infotext", "Forcefield Generator Disabled") |
|
124 |
end |
|
125 |
elseif eu_input < power_requirement then |
|
126 |
meta:set_string("infotext", "Forcefield Generator Unpowered") |
|
127 |
if node.name == "technic:forcefield_emitter_on" then |
4f35f4
|
128 |
update_forcefield(pos, meta:get_int("range"), false) |
30361a
|
129 |
hacky_swap_node(pos, "technic:forcefield_emitter_off") |
S |
130 |
end |
|
131 |
elseif eu_input >= power_requirement then |
|
132 |
if node.name == "technic:forcefield_emitter_off" then |
|
133 |
hacky_swap_node(pos, "technic:forcefield_emitter_on") |
|
134 |
meta:set_string("infotext", "Forcefield Generator Active") |
|
135 |
end |
4f35f4
|
136 |
update_forcefield(pos, meta:get_int("range"), true) |
30361a
|
137 |
end |
S |
138 |
meta:set_int("HV_EU_demand", power_requirement) |
|
139 |
return true |
|
140 |
end |
|
141 |
|
|
142 |
local mesecons = { |
|
143 |
effector = { |
|
144 |
action_on = function(pos, node) |
|
145 |
minetest.env:get_meta(pos):set_int("enabled", 0) |
|
146 |
end, |
|
147 |
action_off = function(pos, node) |
|
148 |
minetest.env:get_meta(pos):set_int("enabled", 1) |
|
149 |
end |
|
150 |
} |
|
151 |
} |
c6da0a
|
152 |
|
R |
153 |
minetest.register_node("technic:forcefield_emitter_off", { |
|
154 |
description = "Forcefield emitter", |
|
155 |
inventory_image = minetest.inventorycube("technic_forcefield_emitter_off.png"), |
|
156 |
tiles = {"technic_forcefield_emitter_off.png"}, |
|
157 |
is_ground_content = true, |
|
158 |
groups = {cracky = 1}, |
4f35f4
|
159 |
on_timer = forcefield_step, |
c6da0a
|
160 |
on_receive_fields = forcefield_receive_fields, |
R |
161 |
on_construct = function(pos) |
4f35f4
|
162 |
minetest.env:get_node_timer(pos):start(forcefield_step_interval) |
c6da0a
|
163 |
local meta = minetest.env:get_meta(pos) |
9a0d3f
|
164 |
meta:set_float("technic_hv_power_machine", 1) |
K |
165 |
meta:set_int("HV_EU_input", 0) |
|
166 |
meta:set_int("HV_EU_demand", 0) |
c6da0a
|
167 |
meta:set_int("range", 10) |
9a0d3f
|
168 |
meta:set_int("enabled", 0) |
K |
169 |
meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"))) |
c6da0a
|
170 |
meta:set_string("infotext", "Forcefield emitter"); |
R |
171 |
end, |
e5d48e
|
172 |
mesecons = mesecons |
c6da0a
|
173 |
}) |
R |
174 |
|
|
175 |
minetest.register_node("technic:forcefield_emitter_on", { |
|
176 |
description = "Forcefield emitter on (you hacker you)", |
|
177 |
tiles = {"technic_forcefield_emitter_on.png"}, |
|
178 |
is_ground_content = true, |
|
179 |
groups = {cracky = 1, not_in_creative_inventory=1}, |
|
180 |
drop='"technic:forcefield_emitter_off" 1', |
4f35f4
|
181 |
on_timer = forcefield_step, |
c6da0a
|
182 |
on_receive_fields = forcefield_receive_fields, |
R |
183 |
on_construct = function(pos) |
4f35f4
|
184 |
minetest.env:get_node_timer(pos):start(forcefield_step_interval) |
c6da0a
|
185 |
local meta = minetest.env:get_meta(pos) |
9a0d3f
|
186 |
-- meta:set_float("technic_hv_power_machine", 1) |
K |
187 |
-- meta:set_float("HV_EU_input", 0) |
|
188 |
-- meta:set_float("HV_EU_demand", 0) |
|
189 |
-- meta:set_int("range", 10) |
|
190 |
-- meta:set_int("enabled", 1) |
|
191 |
meta:set_string("formspec", get_forcefield_formspec(meta:get_int("range"))) |
|
192 |
-- meta:set_string("infotext", "Forcefield emitter"); |
c6da0a
|
193 |
end, |
4f35f4
|
194 |
on_dig = function(pos, node, digger) |
S |
195 |
update_forcefield(pos, minetest.env:get_meta(pos):get_int("range"), false) |
c6da0a
|
196 |
return minetest.node_dig(pos, node, digger) |
R |
197 |
end, |
e5d48e
|
198 |
mesecons = mesecons |
c6da0a
|
199 |
}) |
R |
200 |
|
|
201 |
minetest.register_node("technic:forcefield", { |
|
202 |
description = "Forcefield (you hacker you)", |
|
203 |
sunlight_propagates = true, |
|
204 |
drop = '', |
9a0d3f
|
205 |
light_source = 8, |
30361a
|
206 |
tiles = {{ |
S |
207 |
name = "technic_forcefield_animated.png", |
|
208 |
animation = { |
|
209 |
type = "vertical_frames", |
|
210 |
aspect_w=16, |
|
211 |
aspect_h=16, |
|
212 |
length=2.0, |
|
213 |
}, |
|
214 |
}}, |
c6da0a
|
215 |
is_ground_content = true, |
30361a
|
216 |
groups = { not_in_creative_inventory=1, unbreakable=1 }, |
c6da0a
|
217 |
paramtype = "light", |
R |
218 |
drawtype = "nodebox", |
|
219 |
node_box = { --hacky way to get the field blue and not see through the ground |
|
220 |
type = "fixed", |
|
221 |
fixed={ |
|
222 |
{-.5,-.5,-.5,.5,.5,.5}, |
|
223 |
}, |
|
224 |
}, |
|
225 |
}) |
|
226 |
|
30361a
|
227 |
technic.register_HV_machine("technic:forcefield_emitter_on", "RE") |
S |
228 |
technic.register_HV_machine("technic:forcefield_emitter_off", "RE") |