Expose collided objects in moveresult
authorsfan5 <sfan5@live.de>
Sun, 26 Apr 2020 20:52:00 +0000 (22:52 +0200)
committersfan5 <sfan5@live.de>
Wed, 6 May 2020 12:03:52 +0000 (14:03 +0200)
closes #9787

doc/lua_api.txt
src/collision.cpp
src/collision.h
src/script/common/c_content.cpp

index b1099ec590c06161fa5b405af5d2f76252487491..948e0f89e1975059403f1b119425d15ca33c6770 100644 (file)
@@ -6632,6 +6632,7 @@ Collision info passed to `on_step`:
                 type = string, -- "node" or "object",
                 axis = string, -- "x", "y" or "z"
                 node_pos = vector, -- if type is "node"
+                object = ObjectRef, -- if type is "object"
                 old_velocity = vector,
                 new_velocity = vector,
             },
index a089f33774d3bb66037b940c454c11ca06527666..3b5e79a66cd1c3416049f58ab4c1c5f7ee2cc336 100644 (file)
@@ -37,18 +37,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #endif
 
 struct NearbyCollisionInfo {
-       NearbyCollisionInfo(bool is_ul, bool is_obj, int bouncy,
-                       const v3s16 &pos, const aabb3f &box) :
+       // node
+       NearbyCollisionInfo(bool is_ul, int bouncy, const v3s16 &pos,
+                       const aabb3f &box) :
                is_unloaded(is_ul),
-               is_object(is_obj),
+               obj(nullptr),
                bouncy(bouncy),
                position(pos),
                box(box)
        {}
 
+       // object
+       NearbyCollisionInfo(ActiveObject *obj, int bouncy,
+                       const aabb3f &box) :
+               is_unloaded(false),
+               obj(obj),
+               bouncy(bouncy),
+               box(box)
+       {}
+
+       inline bool isObject() const { return obj != nullptr; }
+
        bool is_unloaded;
        bool is_step_up = false;
-       bool is_object;
+       ActiveObject *obj;
        int bouncy;
        v3s16 position;
        aabb3f box;
@@ -312,13 +324,13 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                        for (auto box : nodeboxes) {
                                box.MinEdge += posf;
                                box.MaxEdge += posf;
-                               cinfo.emplace_back(false, false, n_bouncy_value, p, box);
+                               cinfo.emplace_back(false, n_bouncy_value, p, box);
                        }
                } else {
                        // Collide with unloaded nodes (position invalid) and loaded
                        // CONTENT_IGNORE nodes (position valid)
                        aabb3f box = getNodeBox(p, BS);
-                       cinfo.emplace_back(true, false, 0, p, box);
+                       cinfo.emplace_back(true, 0, p, box);
                }
        }
 
@@ -383,12 +395,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                iter != objects.end(); ++iter) {
                        ActiveObject *object = *iter;
 
-                       if (object) {
+                       if (object && object->collideWithObjects()) {
                                aabb3f object_collisionbox;
-                               if (object->getCollisionBox(&object_collisionbox) &&
-                                               object->collideWithObjects()) {
-                                       cinfo.emplace_back(false, true, 0, v3s16(), object_collisionbox);
-                               }
+                               if (object->getCollisionBox(&object_collisionbox))
+                                       cinfo.emplace_back(object, 0, object_collisionbox);
                        }
                }
 #ifndef SERVER
@@ -399,7 +409,8 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                v3f lplayer_pos = lplayer->getPosition();
                                lplayer_collisionbox.MinEdge += lplayer_pos;
                                lplayer_collisionbox.MaxEdge += lplayer_pos;
-                               cinfo.emplace_back(false, true, 0, v3s16(), lplayer_collisionbox);
+                               ActiveObject *obj = (ActiveObject*) lplayer->getCAO();
+                               cinfo.emplace_back(obj, 0, lplayer_collisionbox);
                        }
                }
 #endif
@@ -498,12 +509,13 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                is_collision = false;
 
                        CollisionInfo info;
-                       if (nearest_info.is_object)
+                       if (nearest_info.isObject())
                                info.type = COLLISION_OBJECT;
                        else
                                info.type = COLLISION_NODE;
 
                        info.node_p = nearest_info.position;
+                       info.object = nearest_info.obj;
                        info.old_speed = *speed_f;
                        info.plane = nearest_collided;
 
@@ -572,7 +584,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                        if (std::fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.05f) {
                                result.touching_ground = true;
 
-                               if (box_info.is_object)
+                               if (box_info.isObject())
                                        result.standing_on_object = true;
                        }
                }
index fa47cccc12747af0249fed4bf3bc19ad562be1a8..87a50282870c11cb5075bce68a99a50f7c496a95 100644 (file)
@@ -48,6 +48,7 @@ struct CollisionInfo
        CollisionType type = COLLISION_NODE;
        CollisionAxis axis = COLLISION_AXIS_NONE;
        v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE
+       ActiveObject *object = nullptr; // COLLISION_OBJECT
        v3f old_speed;
        v3f new_speed;
        int plane = -1;
index 95364000cf6c1e2f79525a4cecac84d57812d767..dac828316552825eaffa32052e8e1e0947a4e77b 100644 (file)
@@ -2043,6 +2043,9 @@ void push_collision_move_result(lua_State *L, const collisionMoveResult &res)
                if (c.type == COLLISION_NODE) {
                        push_v3s16(L, c.node_p);
                        lua_setfield(L, -2, "node_pos");
+               } else if (c.type == COLLISION_OBJECT) {
+                       push_objectRef(L, c.object->getId());
+                       lua_setfield(L, -2, "object");
                }
 
                push_v3f(L, c.old_speed / BS);