]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Add minetest.interact
authorElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 7 Jan 2021 11:09:09 +0000 (12:09 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 7 Jan 2021 11:09:09 +0000 (12:09 +0100)
doc/client_lua_api.txt
src/script/lua_api/l_client.cpp
src/script/lua_api/l_client.h
src/script/lua_api/l_clientobject.cpp
src/script/lua_api/l_clientobject.h

index 3ee2cfba360fcf120c696e423844329c73526a44..c7bbe160981e23c4d0391d603513fee5cd0f43c9 100644 (file)
@@ -793,6 +793,16 @@ Call these functions only at load time!
     * Returns the time of day: `0` for midnight, `0.5` for midday
 
 ### Map
+* `minetest.interact(action, pointed_thing)`
+    * Sends an interaction to the server
+    * `pointed_thing` is a pointed_thing
+    * `action` is one of
+        * "start_digging": Use to punch nodes / objects
+        * "stop_digging": Use to abort digging a "start_digging" command
+        * "digging_completed": Use to finish a "start_digging" command or dig a node instantly
+        * "place": Use to rightclick nodes and objects
+        * "use": Use to leftclick an item in air (pointed_thing.type is usually "nothing")
+        * "activate": Same as "use", but rightclick
 * `minetest.place_node(pos)`
     * Places the wielded node/item of the player at pos.
 * `minetest.dig_node(pos)`
index 5e69d55dd0371d443d633ea561be320224378997..dac2febaed7bb1eef5b177daecb0a5c2e6cde8f2 100644 (file)
@@ -422,7 +422,7 @@ int ModApiClient::l_send_damage(lua_State *L)
 {
        u16 damage = luaL_checknumber(L, 1);
        getClient(L)->sendDamage(damage);
-       return 0;       
+       return 0;
 }
 
 // place_node(pos)
@@ -465,7 +465,7 @@ int ModApiClient::l_get_inventory(lua_State *L)
        InventoryLocation inventory_location;
        Inventory *inventory;
        std::string location;
-       
+
        location = readParam<std::string>(L, 1);
 
        try {
@@ -477,7 +477,7 @@ int ModApiClient::l_get_inventory(lua_State *L)
        } catch (SerializationError &) {
                lua_pushnil(L);
        }
-       
+
        return 1;
 }
 
@@ -510,13 +510,13 @@ int ModApiClient::l_drop_selected_item(lua_State *L)
 int ModApiClient::l_get_objects_inside_radius(lua_State *L)
 {
        ClientEnvironment &env = getClient(L)->getEnv();
-       
+
        v3f pos = checkFloatPos(L, 1);
        float radius = readParam<float>(L, 2) * BS;
-       
+
        std::vector<DistanceSortedActiveObject> objs;
        env.getActiveObjects(pos, radius, objs);
-       
+
        int i = 0;
        lua_createtable(L, objs.size(), 0);
        for (const auto obj : objs) {
@@ -526,12 +526,99 @@ int ModApiClient::l_get_objects_inside_radius(lua_State *L)
        return 1;
 }
 
-//make_screenshot()
+// make_screenshot()
 int ModApiClient::l_make_screenshot(lua_State *L)
 {
-  getClient(L)->makeScreenshot();
-  lua_pushboolean(L, true);
-  return 1;
+       getClient(L)->makeScreenshot();
+       return 0;
+}
+
+/*
+`pointed_thing`
+---------------
+
+* `{type="nothing"}`
+* `{type="node", under=pos, above=pos}`
+    * Indicates a pointed node selection box.
+    * `under` refers to the node position behind the pointed face.
+    * `above` refers to the node position in front of the pointed face.
+* `{type="object", ref=ObjectRef}`
+
+Exact pointing location (currently only `Raycast` supports these fields):
+
+* `pointed_thing.intersection_point`: The absolute world coordinates of the
+  point on the selection box which is pointed at. May be in the selection box
+  if the pointer is in the box too.
+* `pointed_thing.box_id`: The ID of the pointed selection box (counting starts
+  from 1).
+* `pointed_thing.intersection_normal`: Unit vector, points outwards of the
+  selected selection box. This specifies which face is pointed at.
+  Is a null vector `{x = 0, y = 0, z = 0}` when the pointer is inside the
+  selection box.
+*/
+
+// interact(action, pointed_thing)
+int ModApiClient::l_interact(lua_State *L)
+{
+       std::string action_str = readParam<std::string>(L, 1);
+       InteractAction action;
+
+       if (action_str == "start_digging")
+               action = INTERACT_START_DIGGING;
+       else if (action_str == "stop_digging")
+               action = INTERACT_STOP_DIGGING;
+       else if (action_str == "digging_completed")
+               action = INTERACT_DIGGING_COMPLETED;
+       else if (action_str == "place")
+               action = INTERACT_PLACE;
+       else if (action_str == "use")
+               action = INTERACT_USE;
+       else if (action_str == "activate")
+               action = INTERACT_ACTIVATE;
+       else
+               return 0;
+
+       lua_getfield(L, 2, "type");
+       if (! lua_isstring(L, -1))
+               return 0;
+       std::string type_str = lua_tostring(L, -1);
+       lua_pop(L, 1);
+
+       PointedThingType type;
+
+       if (type_str == "nothing")
+               type = POINTEDTHING_NOTHING;
+       else if (type_str == "node")
+               type = POINTEDTHING_NODE;
+       else if (type_str == "object")
+               type = POINTEDTHING_OBJECT;
+       else
+               return 0;
+
+       PointedThing pointed;
+       pointed.type = type;
+       ClientObjectRef *obj;
+
+       switch (type) {
+       case POINTEDTHING_NODE:
+               lua_getfield(L, 2, "under");
+               pointed.node_undersurface = check_v3s16(L, -1);
+
+               lua_getfield(L, 2, "above");
+               pointed.node_abovesurface = check_v3s16(L, -1);
+               break;
+       case POINTEDTHING_OBJECT:
+               lua_getfield(L, 2, "ref");
+               obj = ClientObjectRef::checkobject(L, -1);
+               pointed.object_id = obj->getClientActiveObject()->getId();
+               break;
+       default:
+               break;
+       }
+
+       getClient(L)->interact(action, pointed);
+       lua_pushboolean(L, true);
+       return 1;
 }
 
 void ModApiClient::Initialize(lua_State *L, int top)
@@ -569,5 +656,5 @@ void ModApiClient::Initialize(lua_State *L, int top)
        API_FCT(drop_selected_item);
        API_FCT(get_objects_inside_radius);
        API_FCT(make_screenshot);
-
+       API_FCT(interact);
 }
index 845f09bc9c1a5b56e0a722d14787082fa13605fb..03a42e0225ed2064fadb5639a44da3374b4b8c5c 100644 (file)
@@ -129,6 +129,9 @@ class ModApiClient : public ModApiBase
        // make_screenshot()
        static int l_make_screenshot(lua_State *L);
 
+       // interact(action, pointed_thing)
+       static int l_interact(lua_State *L);
+
 public:
        static void Initialize(lua_State *L, int top);
 };
index 70151ba402278d71939d093f618c7f1ee784360c..521aba02355cdabfbb40b2317e6ebbcfc042911b 100644 (file)
@@ -24,6 +24,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "object_properties.h"
 #include "util/pointedthing.h"
 
+ClientActiveObject *ClientObjectRef::getClientActiveObject()
+{
+       return m_object;
+}
+
 ClientObjectRef *ClientObjectRef::checkobject(lua_State *L, int narg)
 {
        luaL_checktype(L, narg, LUA_TUSERDATA);
index d622dc3b2837c9ec5f96182c91a4bdacc87d2848..1ff22407f97b20c6b2de2785b2a3a19c4e91c298 100644 (file)
@@ -28,6 +28,8 @@ class ClientObjectRef : public ModApiBase
 
        ~ClientObjectRef() = default;
 
+       ClientActiveObject *getClientActiveObject();
+
        static void Register(lua_State *L);
 
        static void create(lua_State *L, ClientActiveObject *object);