3 ws
.registered_globalhacks
= {}
11 function ws
.s(name
,value
)
13 return ws
.c
.settings
:get(name
)
15 ws
.c
.settings
:set(name
,value
)
16 return ws
.c
.settings
:get(name
)
21 return minetest
.display_chat_message(msg
)
23 function ws
.set_bool_bulk(settings
,value
)
24 if type(settings
) ~= 'table' then return false end
25 for k
,v
in pairs(settings
) do
26 minetest
.settings
:set_bool(v
,value
)
31 function ws
.shuffle(tbl
)
32 for i
= #tbl
, 2, -1 do
33 local j
= math
.random(i
)
34 tbl
[i
], tbl
[j
] = tbl
[j
], tbl
[i
]
39 function ws
.in_list(val
, list
)
40 if type(list
) ~= "table" then return false end
41 for i
, v
in ipairs(list
) do
49 function ws
.globalhacktemplate(setting
,func
,funcstart
,funcstop
,daughters
)
50 funcstart
= funcstart
or function() end
51 funcstop
= funcstop
or function() end
53 if not minetest
.localplayer
then return end
54 if minetest
.settings
:get_bool(setting
) then
55 if nextact
[setting
] and nextact
[setting
] > os
.clock() then return end
56 nextact
[setting
] = os
.clock() + 0.1
57 if not ghwason
[setting
] then
58 if not funcstart() then
59 ws
.set_bool_bulk(daughters
,true)
60 ghwason
[setting
] = true
61 ws
.dcm(setting
.. " activated")
62 else minetest
.settings
:set_bool(setting
,false)
68 elseif ghwason
[setting
] then
69 ghwason
[setting
] = false
71 ws
.set_bool_bulk(daughters
,false)
72 ws
.dcm(setting
.. " deactivated")
77 function ws
.register_globalhack(func
)
78 table.insert(ws
.registered_globalhacks
,func
)
81 function ws
.register_globalhacktemplate(name
,category
,setting
,func
,funcstart
,funcstop
,daughters
)
82 ws
.register_globalhack(ws
.globalhacktemplate(setting
,func
,funcstart
,funcstop
,daughters
))
83 minetest
.register_cheat(name
,category
,setting
)
86 ws
.rg
=ws
.register_globalhacktemplate
88 function ws
.step_globalhacks()
89 for i
, v
in ipairs(ws
.registered_globalhacks
) do
94 minetest
.register_globalstep(ws
.step_globalhacks
)
96 function ws
.get_reachable_positions(range
)
99 local lp
=minetest
.localplayer
:get_pos()
100 for x
= -range
,range
,1 do
101 for y
= -range
,range
,1 do
102 for z
= -range
,range
,1 do
103 table.insert(rt
,vector
.add(lp
,vector
.new(x
,y
,z
)))
110 function ws
.do_area(radius
,func
,plane
)
111 for k
,v
in pairs(ws
.get_reachable_positions(range
)) do
112 if not plane
or v
.y
== minetest
.localplayer
:get_pos().y
-1 then
119 function ws
.display_wp(pos
,name
)
120 table.insert(ws
.displayed_wps
,minetest
.localplayer
:hud_add({
121 hud_elem_type
= 'waypoint',
129 function ws
.clear_wps()
130 for k
,v
in pairs(ws
.displayed_wps
) do
131 minetest
.localplayer
:hud_remove(v
)
132 table.remove(ws
.displayed_wps
,k
)
136 function ws
.register_chatcommand_alias(old
, ...)
137 local def
= assert(minetest
.registered_chatcommands
[old
])
139 for i
= 1, select('#', ...) do
140 minetest
.register_chatcommand(select(i
, ...), table.copy(def
))
144 function ws
.round2(num
, numDecimalPlaces
)
145 return tonumber(string.format("%." .. (numDecimalPlaces
or 0) .. "f", num
))
148 function ws
.pos_to_string(pos
)
149 if type(pos
) == 'table' then
150 pos
= minetest
.pos_to_string(vector
.round(pos
))
152 if type(pos
) == 'string' then
157 function ws
.string_to_pos(pos
)
158 if type(pos
) == 'string' then
159 pos
= minetest
.string_to_pos(pos
)
161 if type(pos
) == 'table' then
162 return vector
.round(pos
)
166 function ws
.on_connect(func
)
167 if not minetest
.localplayer
then minetest
.after(0,function() ws
.on_connect(func
) end) return end
168 if func
then func() end
171 function ws
.find_item(items
,rnd
)
172 if type(items
) == 'string' then
173 return minetest
.find_item(items
)
175 if type(nodename
) ~= 'table' then return end
176 if rnd
then items
=ws
.shuffle(items
) end
177 for i
, v
in pairs(items
) do
178 local n
= minetest
.find_item(v
)
186 local function find_named(inv
, name
)
187 if not inv
then return -1 end
188 for i
, v
in ipairs(inv
) do
189 --minetest.display_chat_message(name)
190 if v
:get_name():find(name
) then
195 function ws
.switch_inv_or_echest(name
,max_count
)
196 if not minetest
.localplayer
then return false end
197 local plinv
= minetest
.get_inventory("current_player")
199 local pos
= find_named(plinv
.main
, name
)
201 minetest
.localplayer
:set_wield_index(pos
)
205 local epos
= find_named(plinv
.enderchest
, name
)
208 for i
, v
in ipairs(plinv
.main
) do
216 local mv
= InventoryAction("move")
217 mv
:from("current_player", "enderchest", epos
)
218 mv
:to("current_player", "main", tpos
)
220 mv
:set_count(max_count
)
223 minetest
.localplayer
:set_wield_index(tpos
)
231 local function check_tool(stack
, node_groups
, old_best_time
)
232 local toolcaps
= stack
:get_tool_capabilities()
233 if not toolcaps
then return end
234 local best_time
= old_best_time
235 for group
, groupdef
in pairs(toolcaps
.groupcaps
) do
236 local level
= node_groups
[group
]
238 local this_time
= groupdef
.times
[level
]
239 if this_time
and this_time
< best_time
then
240 best_time
= this_time
244 return best_time
< old_best_time
, best_time
247 local function find_best_tool(nodename
, switch
)
248 local player
= minetest
.localplayer
249 local inventory
= minetest
.get_inventory("current_player")
250 local node_groups
= minetest
.get_node_def(nodename
).groups
251 local new_index
= player
:get_wield_index()
252 local is_better
, best_time
= false, math
.huge
254 is_better
, best_time
= check_tool(player
:get_wielded_item(), node_groups
, best_time
)
255 if inventory
.hand
then
256 is_better
, best_time
= check_tool(inventory
.hand
[1], node_groups
, best_time
)
259 for index
, stack
in ipairs(inventory
.main
) do
260 is_better
, best_time
= check_tool(stack
, node_groups
, best_time
)
269 function ws
.select_best_tool(pos
)
270 local nd
=minetest
.get_node_or_nil(pos
)
272 if nd
then nodename
=nd
.name
end
273 minetest
.localplayer
:set_wield_index(find_best_tool(nodename
))
277 function ws
.coord(x
, y
, z
)
278 return vector
.new(x
,y
,z
)
280 function ws
.ordercoord(c
)
282 return {x
= c
[1], y
= c
[2], z
= c
[3]}
288 -- x or {x,y,z} or {x=x,y=y,z=z}
289 function ws
.optcoord(x
, y
, z
)
291 return ws
.coord(x
, y
, z
)
293 return ws
.ordercoord(x
)
296 function ws
.cadd(c1
, c2
)
297 return ws
.coord(c1
.x
+ c2
.x
, c1
.y
+ c2
.y
, c1
.z
+ c2
.z
)
300 function ws
.relcoord(x
, y
, z
)
301 local pos
= minetest
.localplayer
:get_pos()
302 pos
.y
=math
.ceil(pos
.y
)
303 return ws
.cadd(pos
, ws
.optcoord(x
, y
, z
))
306 local function between(x
, y
, z
) -- x is between y and z (inclusive)
307 return y
<= x
and x
<= z
310 function ws
.getdir() --
311 local rot
= minetest
.localplayer
:get_yaw() % 360
312 if between(rot
, 315, 360) or between(rot
, 0, 45) then
314 elseif between(rot
, 135, 225) then
316 elseif between(rot
, 225, 315) then
318 elseif between(rot
, 45, 135) then
322 function ws
.setdir(dir
) --
323 if dir
== "north" then
324 minetest
.localplayer
:set_yaw(0)
325 elseif dir
== "south" then
326 minetest
.localplayer
:set_yaw(180)
327 elseif dir
== "east" then
328 minetest
.localplayer
:set_yaw(270)
329 elseif dir
== "west" then
330 minetest
.localplayer
:set_yaw(90)
334 function ws
.dircoord(f
, y
, r
)
335 local dir
=ws
.getdir()
336 local coord
= ws
.optcoord(f
, y
, r
)
340 local lp
=minetest
.localplayer
:get_pos()
341 if dir
== "north" then
342 return ws
.relcoord(r
, y
, f
)
343 elseif dir
== "south" then
344 return ws
.relcoord(-r
, y
, -f
)
345 elseif dir
== "east" then
346 return ws
.relcoord(f
, y
, -r
)
347 elseif dir
== "west" then
348 return ws
.relcoord(-f
, y
, r
)
350 return ws
.relcoord(0, 0, 0)
353 function ws
.aim(tpos
)
354 local ppos
=minetest
.localplayer
:get_pos()
355 local dir
=vector
.direction(ppos
,tpos
)
359 yyaw
= math
.atan2(-dir
.x
, dir
.z
) + (math
.pi
* 2)
361 yyaw
= math
.atan2(-dir
.x
, dir
.z
)
363 yyaw
= ws
.round2(math
.deg(yyaw
),2)
364 pitch
= ws
.round2(math
.deg(math
.asin(-dir
.y
) * 1),2);
365 minetest
.localplayer
:set_yaw(yyaw
)
366 minetest
.localplayer
:set_pitch(pitch
)
369 function ws
.gaim(tpos
,v
,g
)
372 local ppos
=minetest
.localplayer
:get_pos()
373 local dir
=vector
.direction(ppos
,tpos
)
377 yyaw
= math
.atan2(-dir
.x
, dir
.z
) + (math
.pi
* 2)
379 yyaw
= math
.atan2(-dir
.x
, dir
.z
)
381 yyaw
= ws
.round2(math
.deg(yyaw
),2)
384 local x
= vector
.length(dir
)
385 pitch
=math
.atan(math
.pow(v
, 2) / (g
* x
) + math
.sqrt(math
.pow(v
, 4)/(math
.pow(g
, 2) * math
.pow(x
, 2)) - 2 * math
.pow(v
, 2) * y
/(g
* math
.pow(x
, 2)) - 1))
386 --pitch = ws.round2(math.deg(math.asin(-dir.y) * 1),2);
387 minetest
.localplayer
:set_yaw(yyaw
)
388 minetest
.localplayer
:set_pitch(math
.deg(pitch
))
391 function ws
.place(pos
,nodename
)
392 local it
=ws
.find_item(nodename
)
393 if not it
then return end
394 minetest
.localplayer
:set_wield_index(it
)
395 --ws.switch_inv_or_echest(ws.find_item(nodem),1)
400 local nd
=minetest
.get_node_or_nil(pos
)
401 if nd
and minetest
.get_node_def(nd
.name
).diggable
then
402 ws
.select_best_tool(pos
)
403 minetest
.dig_node(pos
)
407 function ws
.dignodes(poss
)
408 for k
,v
in pairs(poss
) do