mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
[CSM] Expose more env functions
This commit is contained in:
parent
b0260b5ec8
commit
b57dc70769
@ -65,6 +65,22 @@ core.register_on_item_use(function(itemstack, pointed_thing)
|
|||||||
print("The local player used an item!")
|
print("The local player used an item!")
|
||||||
print("pointed_thing :" .. dump(pointed_thing))
|
print("pointed_thing :" .. dump(pointed_thing))
|
||||||
print("item = " .. itemstack:get_name())
|
print("item = " .. itemstack:get_name())
|
||||||
|
|
||||||
|
local pos = vector.add(core.localplayer:get_pos(), core.camera:get_offset())
|
||||||
|
local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 100))
|
||||||
|
|
||||||
|
local rc = core.raycast(pos, pos2)
|
||||||
|
local i = rc:next()
|
||||||
|
print("[PREVIEW] raycast next: " .. dump(i))
|
||||||
|
if i then
|
||||||
|
print("[PREVIEW] line of sight: " .. (core.line_of_sight(pos, i.above) and "yes" or "no"))
|
||||||
|
|
||||||
|
local n1 = core.find_nodes_in_area(pos, i.under, {"default:stone"})
|
||||||
|
local n2 = core.find_nodes_in_area_under_air(pos, i.under, {"default:stone"})
|
||||||
|
print(("[PREVIEW] found %s nodes, %s nodes under air"):format(
|
||||||
|
n1 and #n1 or "?", n2 and #n2 or "?"))
|
||||||
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -90,11 +106,6 @@ core.register_on_damage_taken(function(hp)
|
|||||||
print("[PREVIEW] Damage taken " .. hp)
|
print("[PREVIEW] Damage taken " .. hp)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
|
||||||
core.register_globalstep(function(dtime)
|
|
||||||
-- print("[PREVIEW] globalstep " .. dtime)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||||
core.register_chatcommand("dump", {
|
core.register_chatcommand("dump", {
|
||||||
func = function(param)
|
func = function(param)
|
||||||
|
@ -742,11 +742,46 @@ Call these functions only at load time!
|
|||||||
* Returns the node at the given position as table in the format
|
* Returns the node at the given position as table in the format
|
||||||
`{name="node_name", param1=0, param2=0}`, returns `nil`
|
`{name="node_name", param1=0, param2=0}`, returns `nil`
|
||||||
for unloaded areas or flavor limited areas.
|
for unloaded areas or flavor limited areas.
|
||||||
|
* `minetest.get_node_light(pos, timeofday)`
|
||||||
|
* Gets the light value at the given position. Note that the light value
|
||||||
|
"inside" the node at the given position is returned, so you usually want
|
||||||
|
to get the light value of a neighbor.
|
||||||
|
* `pos`: The position where to measure the light.
|
||||||
|
* `timeofday`: `nil` for current time, `0` for night, `0.5` for day
|
||||||
|
* Returns a number between `0` and `15` or `nil`
|
||||||
* `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns pos or `nil`
|
* `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns pos or `nil`
|
||||||
* `radius`: using a maximum metric
|
* `radius`: using a maximum metric
|
||||||
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
||||||
* `search_center` is an optional boolean (default: `false`)
|
* `search_center` is an optional boolean (default: `false`)
|
||||||
If true `pos` is also checked for the nodes
|
If true `pos` is also checked for the nodes
|
||||||
|
* `minetest.find_nodes_in_area(pos1, pos2, nodenames)`: returns a list of
|
||||||
|
positions.
|
||||||
|
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
||||||
|
* First return value: Table with all node positions
|
||||||
|
* Second return value: Table with the count of each node with the node name
|
||||||
|
as index.
|
||||||
|
* Area volume is limited to 4,096,000 nodes
|
||||||
|
* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a
|
||||||
|
list of positions.
|
||||||
|
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
|
||||||
|
* Return value: Table with all node positions with a node air above
|
||||||
|
* Area volume is limited to 4,096,000 nodes
|
||||||
|
* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos`
|
||||||
|
* Checks if there is anything other than air between pos1 and pos2.
|
||||||
|
* Returns false if something is blocking the sight.
|
||||||
|
* Returns the position of the blocking node when `false`
|
||||||
|
* `pos1`: First position
|
||||||
|
* `pos2`: Second position
|
||||||
|
* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast`
|
||||||
|
* Creates a `Raycast` object.
|
||||||
|
* `pos1`: start of the ray
|
||||||
|
* `pos2`: end of the ray
|
||||||
|
* `objects`: if false, only nodes will be returned. Default is `true`.
|
||||||
|
* `liquids`: if false, liquid nodes won't be returned. Default is `false`.
|
||||||
|
|
||||||
|
* `minetest.find_nodes_with_meta(pos1, pos2)`
|
||||||
|
* Get a table of positions of nodes that have metadata within a region
|
||||||
|
{pos1, pos2}.
|
||||||
* `minetest.get_meta(pos)`
|
* `minetest.get_meta(pos)`
|
||||||
* Get a `NodeMetaRef` at that position
|
* Get a `NodeMetaRef` at that position
|
||||||
* `minetest.get_node_level(pos)`
|
* `minetest.get_node_level(pos)`
|
||||||
@ -1073,6 +1108,32 @@ Can be obtained via `minetest.get_meta(pos)`.
|
|||||||
* `fields`: key-value storage
|
* `fields`: key-value storage
|
||||||
* `inventory`: `{list1 = {}, ...}}`
|
* `inventory`: `{list1 = {}, ...}}`
|
||||||
|
|
||||||
|
### `Raycast`
|
||||||
|
|
||||||
|
A raycast on the map. It works with selection boxes.
|
||||||
|
Can be used as an iterator in a for loop as:
|
||||||
|
|
||||||
|
local ray = Raycast(...)
|
||||||
|
for pointed_thing in ray do
|
||||||
|
...
|
||||||
|
end
|
||||||
|
|
||||||
|
The map is loaded as the ray advances. If the map is modified after the
|
||||||
|
`Raycast` is created, the changes may or may not have an effect on the object.
|
||||||
|
|
||||||
|
It can be created via `Raycast(pos1, pos2, objects, liquids)` or
|
||||||
|
`minetest.raycast(pos1, pos2, objects, liquids)` where:
|
||||||
|
|
||||||
|
* `pos1`: start of the ray
|
||||||
|
* `pos2`: end of the ray
|
||||||
|
* `objects`: if false, only nodes will be returned. Default is true.
|
||||||
|
* `liquids`: if false, liquid nodes won't be returned. Default is false.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
* `next()`: returns a `pointed_thing` with exact pointing location
|
||||||
|
* Returns the next thing pointed by the ray or nil.
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
### Definitions
|
### Definitions
|
||||||
* `minetest.get_node_def(nodename)`
|
* `minetest.get_node_def(nodename)`
|
||||||
|
@ -1337,6 +1337,19 @@ int Client::CSMClampRadius(v3s16 pos, int radius)
|
|||||||
return std::min<int>(radius, m_csm_restriction_noderange - distance);
|
return std::min<int>(radius, m_csm_restriction_noderange - distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v3s16 Client::CSMClampPos(v3s16 pos)
|
||||||
|
{
|
||||||
|
if (!checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES))
|
||||||
|
return pos;
|
||||||
|
v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS);
|
||||||
|
const int range = m_csm_restriction_noderange;
|
||||||
|
return v3s16(
|
||||||
|
core::clamp<int>(pos.X, (int)ppos.X - range, (int)ppos.X + range),
|
||||||
|
core::clamp<int>(pos.Y, (int)ppos.Y - range, (int)ppos.Y + range),
|
||||||
|
core::clamp<int>(pos.Z, (int)ppos.Z - range, (int)ppos.Z + range)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::addNode(v3s16 p, MapNode n, bool remove_metadata)
|
void Client::addNode(v3s16 p, MapNode n, bool remove_metadata)
|
||||||
{
|
{
|
||||||
//TimeTaker timer1("Client::addNode()");
|
//TimeTaker timer1("Client::addNode()");
|
||||||
|
@ -264,6 +264,7 @@ public:
|
|||||||
// helpers to enforce CSM restrictions
|
// helpers to enforce CSM restrictions
|
||||||
MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
|
MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
|
||||||
int CSMClampRadius(v3s16 pos, int radius);
|
int CSMClampRadius(v3s16 pos, int radius);
|
||||||
|
v3s16 CSMClampPos(v3s16 pos);
|
||||||
|
|
||||||
void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
|
void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
friend class LuaItemStack;
|
friend class LuaItemStack;
|
||||||
friend class ModApiItemMod;
|
friend class ModApiItemMod;
|
||||||
friend class LuaRaycast;
|
|
||||||
|
|
||||||
bool getItemCallback(const char *name, const char *callbackname, const v3s16 *p = nullptr);
|
bool getItemCallback(const char *name, const char *callbackname, const v3s16 *p = nullptr);
|
||||||
/*!
|
/*!
|
||||||
|
@ -140,17 +140,20 @@ void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n)
|
|||||||
int LuaRaycast::l_next(lua_State *L)
|
int LuaRaycast::l_next(lua_State *L)
|
||||||
{
|
{
|
||||||
MAP_LOCK_REQUIRED;
|
MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
ScriptApiItem *script = getScriptApi<ScriptApiItem>(L);
|
|
||||||
GET_ENV_PTR;
|
GET_ENV_PTR;
|
||||||
|
|
||||||
|
bool csm = false;
|
||||||
|
#ifndef SERVER
|
||||||
|
csm = getClient(L) != nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
LuaRaycast *o = checkobject(L, 1);
|
LuaRaycast *o = checkobject(L, 1);
|
||||||
PointedThing pointed;
|
PointedThing pointed;
|
||||||
env->continueRaycast(&o->state, &pointed);
|
env->continueRaycast(&o->state, &pointed);
|
||||||
if (pointed.type == POINTEDTHING_NOTHING)
|
if (pointed.type == POINTEDTHING_NOTHING)
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
else
|
else
|
||||||
script->pushPointedThing(pointed, true);
|
push_pointed_thing(L, pointed, csm, true);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -793,11 +796,20 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
|||||||
{
|
{
|
||||||
GET_ENV_PTR;
|
GET_ENV_PTR;
|
||||||
|
|
||||||
const NodeDefManager *ndef = getServer(L)->ndef();
|
|
||||||
v3s16 minp = read_v3s16(L, 1);
|
v3s16 minp = read_v3s16(L, 1);
|
||||||
v3s16 maxp = read_v3s16(L, 2);
|
v3s16 maxp = read_v3s16(L, 2);
|
||||||
sortBoxVerticies(minp, maxp);
|
sortBoxVerticies(minp, maxp);
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
const NodeDefManager *ndef = getClient(L) ? getClient(L)->ndef() : getServer(L)->ndef();
|
||||||
|
if (getClient(L)) {
|
||||||
|
minp = getClient(L)->CSMClampPos(minp);
|
||||||
|
maxp = getClient(L)->CSMClampPos(maxp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const NodeDefManager *ndef = getServer(L)->ndef();
|
||||||
|
#endif
|
||||||
|
|
||||||
v3s16 cube = maxp - minp + 1;
|
v3s16 cube = maxp - minp + 1;
|
||||||
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
|
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
|
||||||
if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
|
if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
|
||||||
@ -861,11 +873,20 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
|||||||
|
|
||||||
GET_ENV_PTR;
|
GET_ENV_PTR;
|
||||||
|
|
||||||
const NodeDefManager *ndef = getServer(L)->ndef();
|
|
||||||
v3s16 minp = read_v3s16(L, 1);
|
v3s16 minp = read_v3s16(L, 1);
|
||||||
v3s16 maxp = read_v3s16(L, 2);
|
v3s16 maxp = read_v3s16(L, 2);
|
||||||
sortBoxVerticies(minp, maxp);
|
sortBoxVerticies(minp, maxp);
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
const NodeDefManager *ndef = getClient(L) ? getClient(L)->ndef() : getServer(L)->ndef();
|
||||||
|
if (getClient(L)) {
|
||||||
|
minp = getClient(L)->CSMClampPos(minp);
|
||||||
|
maxp = getClient(L)->CSMClampPos(maxp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const NodeDefManager *ndef = getServer(L)->ndef();
|
||||||
|
#endif
|
||||||
|
|
||||||
v3s16 cube = maxp - minp + 1;
|
v3s16 cube = maxp - minp + 1;
|
||||||
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
|
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
|
||||||
if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
|
if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
|
||||||
@ -1326,8 +1347,14 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
|
|||||||
|
|
||||||
void ModApiEnvMod::InitializeClient(lua_State *L, int top)
|
void ModApiEnvMod::InitializeClient(lua_State *L, int top)
|
||||||
{
|
{
|
||||||
|
API_FCT(get_node_light);
|
||||||
API_FCT(get_timeofday);
|
API_FCT(get_timeofday);
|
||||||
API_FCT(get_node_max_level);
|
API_FCT(get_node_max_level);
|
||||||
API_FCT(get_node_level);
|
API_FCT(get_node_level);
|
||||||
|
API_FCT(find_nodes_with_meta);
|
||||||
API_FCT(find_node_near);
|
API_FCT(find_node_near);
|
||||||
|
API_FCT(find_nodes_in_area);
|
||||||
|
API_FCT(find_nodes_in_area_under_air);
|
||||||
|
API_FCT(line_of_sight);
|
||||||
|
API_FCT(raycast);
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ void ClientScripting::InitializeModApi(lua_State *L, int top)
|
|||||||
{
|
{
|
||||||
LuaItemStack::Register(L);
|
LuaItemStack::Register(L);
|
||||||
ItemStackMetaRef::Register(L);
|
ItemStackMetaRef::Register(L);
|
||||||
|
LuaRaycast::Register(L);
|
||||||
StorageRef::Register(L);
|
StorageRef::Register(L);
|
||||||
LuaMinimap::Register(L);
|
LuaMinimap::Register(L);
|
||||||
NodeMetaRef::RegisterClient(L);
|
NodeMetaRef::RegisterClient(L);
|
||||||
|
Loading…
Reference in New Issue
Block a user