Skip to content

Commit b57dc70

Browse files
committedNov 11, 2019
[CSM] Expose more env functions
1 parent b0260b5 commit b57dc70

File tree

7 files changed

+124
-11
lines changed

7 files changed

+124
-11
lines changed
 

‎clientmods/preview/init.lua

+16-5
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ core.register_on_item_use(function(itemstack, pointed_thing)
6565
print("The local player used an item!")
6666
print("pointed_thing :" .. dump(pointed_thing))
6767
print("item = " .. itemstack:get_name())
68+
69+
local pos = vector.add(core.localplayer:get_pos(), core.camera:get_offset())
70+
local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 100))
71+
72+
local rc = core.raycast(pos, pos2)
73+
local i = rc:next()
74+
print("[PREVIEW] raycast next: " .. dump(i))
75+
if i then
76+
print("[PREVIEW] line of sight: " .. (core.line_of_sight(pos, i.above) and "yes" or "no"))
77+
78+
local n1 = core.find_nodes_in_area(pos, i.under, {"default:stone"})
79+
local n2 = core.find_nodes_in_area_under_air(pos, i.under, {"default:stone"})
80+
print(("[PREVIEW] found %s nodes, %s nodes under air"):format(
81+
n1 and #n1 or "?", n2 and #n2 or "?"))
82+
end
83+
6884
return false
6985
end)
7086

@@ -90,11 +106,6 @@ core.register_on_damage_taken(function(hp)
90106
print("[PREVIEW] Damage taken " .. hp)
91107
end)
92108

93-
-- This is an example function to ensure it's working properly, should be removed before merge
94-
core.register_globalstep(function(dtime)
95-
-- print("[PREVIEW] globalstep " .. dtime)
96-
end)
97-
98109
-- This is an example function to ensure it's working properly, should be removed before merge
99110
core.register_chatcommand("dump", {
100111
func = function(param)

‎doc/client_lua_api.txt

+61
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,46 @@ Call these functions only at load time!
742742
* Returns the node at the given position as table in the format
743743
`{name="node_name", param1=0, param2=0}`, returns `nil`
744744
for unloaded areas or flavor limited areas.
745+
* `minetest.get_node_light(pos, timeofday)`
746+
* Gets the light value at the given position. Note that the light value
747+
"inside" the node at the given position is returned, so you usually want
748+
to get the light value of a neighbor.
749+
* `pos`: The position where to measure the light.
750+
* `timeofday`: `nil` for current time, `0` for night, `0.5` for day
751+
* Returns a number between `0` and `15` or `nil`
745752
* `minetest.find_node_near(pos, radius, nodenames, [search_center])`: returns pos or `nil`
746753
* `radius`: using a maximum metric
747754
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
748755
* `search_center` is an optional boolean (default: `false`)
749756
If true `pos` is also checked for the nodes
757+
* `minetest.find_nodes_in_area(pos1, pos2, nodenames)`: returns a list of
758+
positions.
759+
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
760+
* First return value: Table with all node positions
761+
* Second return value: Table with the count of each node with the node name
762+
as index.
763+
* Area volume is limited to 4,096,000 nodes
764+
* `minetest.find_nodes_in_area_under_air(pos1, pos2, nodenames)`: returns a
765+
list of positions.
766+
* `nodenames`: e.g. `{"ignore", "group:tree"}` or `"default:dirt"`
767+
* Return value: Table with all node positions with a node air above
768+
* Area volume is limited to 4,096,000 nodes
769+
* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos`
770+
* Checks if there is anything other than air between pos1 and pos2.
771+
* Returns false if something is blocking the sight.
772+
* Returns the position of the blocking node when `false`
773+
* `pos1`: First position
774+
* `pos2`: Second position
775+
* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast`
776+
* Creates a `Raycast` object.
777+
* `pos1`: start of the ray
778+
* `pos2`: end of the ray
779+
* `objects`: if false, only nodes will be returned. Default is `true`.
780+
* `liquids`: if false, liquid nodes won't be returned. Default is `false`.
781+
782+
* `minetest.find_nodes_with_meta(pos1, pos2)`
783+
* Get a table of positions of nodes that have metadata within a region
784+
{pos1, pos2}.
750785
* `minetest.get_meta(pos)`
751786
* Get a `NodeMetaRef` at that position
752787
* `minetest.get_node_level(pos)`
@@ -1073,6 +1108,32 @@ Can be obtained via `minetest.get_meta(pos)`.
10731108
* `fields`: key-value storage
10741109
* `inventory`: `{list1 = {}, ...}}`
10751110

1111+
### `Raycast`
1112+
1113+
A raycast on the map. It works with selection boxes.
1114+
Can be used as an iterator in a for loop as:
1115+
1116+
local ray = Raycast(...)
1117+
for pointed_thing in ray do
1118+
...
1119+
end
1120+
1121+
The map is loaded as the ray advances. If the map is modified after the
1122+
`Raycast` is created, the changes may or may not have an effect on the object.
1123+
1124+
It can be created via `Raycast(pos1, pos2, objects, liquids)` or
1125+
`minetest.raycast(pos1, pos2, objects, liquids)` where:
1126+
1127+
* `pos1`: start of the ray
1128+
* `pos2`: end of the ray
1129+
* `objects`: if false, only nodes will be returned. Default is true.
1130+
* `liquids`: if false, liquid nodes won't be returned. Default is false.
1131+
1132+
#### Methods
1133+
1134+
* `next()`: returns a `pointed_thing` with exact pointing location
1135+
* Returns the next thing pointed by the ray or nil.
1136+
10761137
-----------------
10771138
### Definitions
10781139
* `minetest.get_node_def(nodename)`

‎src/client/client.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,19 @@ int Client::CSMClampRadius(v3s16 pos, int radius)
13371337
return std::min<int>(radius, m_csm_restriction_noderange - distance);
13381338
}
13391339

1340+
v3s16 Client::CSMClampPos(v3s16 pos)
1341+
{
1342+
if (!checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES))
1343+
return pos;
1344+
v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS);
1345+
const int range = m_csm_restriction_noderange;
1346+
return v3s16(
1347+
core::clamp<int>(pos.X, (int)ppos.X - range, (int)ppos.X + range),
1348+
core::clamp<int>(pos.Y, (int)ppos.Y - range, (int)ppos.Y + range),
1349+
core::clamp<int>(pos.Z, (int)ppos.Z - range, (int)ppos.Z + range)
1350+
);
1351+
}
1352+
13401353
void Client::addNode(v3s16 p, MapNode n, bool remove_metadata)
13411354
{
13421355
//TimeTaker timer1("Client::addNode()");

‎src/client/client.h

+1
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
264264
// helpers to enforce CSM restrictions
265265
MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
266266
int CSMClampRadius(v3s16 pos, int radius);
267+
v3s16 CSMClampPos(v3s16 pos);
267268

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

‎src/script/cpp_api/s_item.h

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ class ScriptApiItem
5151
protected:
5252
friend class LuaItemStack;
5353
friend class ModApiItemMod;
54-
friend class LuaRaycast;
5554

5655
bool getItemCallback(const char *name, const char *callbackname, const v3s16 *p = nullptr);
5756
/*!

‎src/script/lua_api/l_env.cpp

+32-5
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,20 @@ void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n)
140140
int LuaRaycast::l_next(lua_State *L)
141141
{
142142
MAP_LOCK_REQUIRED;
143-
144-
ScriptApiItem *script = getScriptApi<ScriptApiItem>(L);
145143
GET_ENV_PTR;
146144

145+
bool csm = false;
146+
#ifndef SERVER
147+
csm = getClient(L) != nullptr;
148+
#endif
149+
147150
LuaRaycast *o = checkobject(L, 1);
148151
PointedThing pointed;
149152
env->continueRaycast(&o->state, &pointed);
150153
if (pointed.type == POINTEDTHING_NOTHING)
151154
lua_pushnil(L);
152155
else
153-
script->pushPointedThing(pointed, true);
156+
push_pointed_thing(L, pointed, csm, true);
154157

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

796-
const NodeDefManager *ndef = getServer(L)->ndef();
797799
v3s16 minp = read_v3s16(L, 1);
798800
v3s16 maxp = read_v3s16(L, 2);
799801
sortBoxVerticies(minp, maxp);
800802

803+
#ifndef SERVER
804+
const NodeDefManager *ndef = getClient(L) ? getClient(L)->ndef() : getServer(L)->ndef();
805+
if (getClient(L)) {
806+
minp = getClient(L)->CSMClampPos(minp);
807+
maxp = getClient(L)->CSMClampPos(maxp);
808+
}
809+
#else
810+
const NodeDefManager *ndef = getServer(L)->ndef();
811+
#endif
812+
801813
v3s16 cube = maxp - minp + 1;
802814
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
803815
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)
861873

862874
GET_ENV_PTR;
863875

864-
const NodeDefManager *ndef = getServer(L)->ndef();
865876
v3s16 minp = read_v3s16(L, 1);
866877
v3s16 maxp = read_v3s16(L, 2);
867878
sortBoxVerticies(minp, maxp);
868879

880+
#ifndef SERVER
881+
const NodeDefManager *ndef = getClient(L) ? getClient(L)->ndef() : getServer(L)->ndef();
882+
if (getClient(L)) {
883+
minp = getClient(L)->CSMClampPos(minp);
884+
maxp = getClient(L)->CSMClampPos(maxp);
885+
}
886+
#else
887+
const NodeDefManager *ndef = getServer(L)->ndef();
888+
#endif
889+
869890
v3s16 cube = maxp - minp + 1;
870891
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
871892
if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 4096000) {
@@ -1326,8 +1347,14 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
13261347

13271348
void ModApiEnvMod::InitializeClient(lua_State *L, int top)
13281349
{
1350+
API_FCT(get_node_light);
13291351
API_FCT(get_timeofday);
13301352
API_FCT(get_node_max_level);
13311353
API_FCT(get_node_level);
1354+
API_FCT(find_nodes_with_meta);
13321355
API_FCT(find_node_near);
1356+
API_FCT(find_nodes_in_area);
1357+
API_FCT(find_nodes_in_area_under_air);
1358+
API_FCT(line_of_sight);
1359+
API_FCT(raycast);
13331360
}

‎src/script/scripting_client.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ void ClientScripting::InitializeModApi(lua_State *L, int top)
6969
{
7070
LuaItemStack::Register(L);
7171
ItemStackMetaRef::Register(L);
72+
LuaRaycast::Register(L);
7273
StorageRef::Register(L);
7374
LuaMinimap::Register(L);
7475
NodeMetaRef::RegisterClient(L);

0 commit comments

Comments
 (0)
Please sign in to comment.