Skip to content
Permalink
Browse files

[CSM] Expose more env functions

  • Loading branch information
sfan5 committed Nov 8, 2019
1 parent b0260b5 commit b57dc70769873e00ca7a7642862eb209a5528ce2
@@ -65,6 +65,22 @@ core.register_on_item_use(function(itemstack, pointed_thing)
print("The local player used an item!")
print("pointed_thing :" .. dump(pointed_thing))
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
end)

@@ -90,11 +106,6 @@ core.register_on_damage_taken(function(hp)
print("[PREVIEW] Damage taken " .. hp)
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
core.register_chatcommand("dump", {
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
`{name="node_name", param1=0, param2=0}`, returns `nil`
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`
* `radius`: using a maximum metric
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
* `search_center` is an optional boolean (default: `false`)
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)`
* Get a `NodeMetaRef` at that position
* `minetest.get_node_level(pos)`
@@ -1073,6 +1108,32 @@ Can be obtained via `minetest.get_meta(pos)`.
* `fields`: key-value storage
* `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
* `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);
}

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)
{
//TimeTaker timer1("Client::addNode()");
@@ -264,6 +264,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
// helpers to enforce CSM restrictions
MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
int CSMClampRadius(v3s16 pos, int radius);
v3s16 CSMClampPos(v3s16 pos);

void addNode(v3s16 p, MapNode n, bool remove_metadata = true);

@@ -51,7 +51,6 @@ class ScriptApiItem
protected:
friend class LuaItemStack;
friend class ModApiItemMod;
friend class LuaRaycast;

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)
{
MAP_LOCK_REQUIRED;

ScriptApiItem *script = getScriptApi<ScriptApiItem>(L);
GET_ENV_PTR;

bool csm = false;
#ifndef SERVER
csm = getClient(L) != nullptr;
#endif

LuaRaycast *o = checkobject(L, 1);
PointedThing pointed;
env->continueRaycast(&o->state, &pointed);
if (pointed.type == POINTEDTHING_NOTHING)
lua_pushnil(L);
else
script->pushPointedThing(pointed, true);
push_pointed_thing(L, pointed, csm, true);

return 1;
}
@@ -793,11 +796,20 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
{
GET_ENV_PTR;

const NodeDefManager *ndef = getServer(L)->ndef();
v3s16 minp = read_v3s16(L, 1);
v3s16 maxp = read_v3s16(L, 2);
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;
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
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;

const NodeDefManager *ndef = getServer(L)->ndef();
v3s16 minp = read_v3s16(L, 1);
v3s16 maxp = read_v3s16(L, 2);
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;
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
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)
{
API_FCT(get_node_light);
API_FCT(get_timeofday);
API_FCT(get_node_max_level);
API_FCT(get_node_level);
API_FCT(find_nodes_with_meta);
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);
ItemStackMetaRef::Register(L);
LuaRaycast::Register(L);
StorageRef::Register(L);
LuaMinimap::Register(L);
NodeMetaRef::RegisterClient(L);

0 comments on commit b57dc70

Please sign in to comment.
You can’t perform that action at this time.