// // #include "mc_info.h" #include "model.h" #include "vecmath.h" namespace scripting { namespace api { mc_info_h::mc_info_h(const mc_info& val) : info(val), valid(true) {} mc_info_h::mc_info_h() = default; mc_info* mc_info_h::Get() { return &info; } bool mc_info_h::isValid() const { return valid; } //**********HANDLE: Collision info ADE_OBJ(l_ColInfo, mc_info_h, "collision_info", "Information about a collision"); ADE_VIRTVAR(Model, l_ColInfo, "model", "The model this collision info is about", "model", "The model, or an invalid model if the handle is not valid") { mc_info_h* info; model_h * mh = nullptr; if(!ade_get_args(L, "o|o", l_ColInfo.GetPtr(&info), l_Model.GetPtr(&mh))) return ade_set_error(L, "o", l_Model.Set(model_h())); if (!info->isValid()) return ade_set_error(L, "o", l_Model.Set(model_h())); mc_info *collide = info->Get(); int modelNum = collide->model_num; if (ADE_SETTING_VAR && mh) { if (mh->isValid()) { collide->model_num = mh->GetID(); } } return ade_set_args(L, "o", l_Model.Set(model_h(modelNum))); } ADE_FUNC(getCollisionSubmodel, l_ColInfo, nullptr, "The submodel where the collision occurred, if applicable", "submodel", "The submodel, or nil if none or if the handle is not valid") { mc_info_h *info; submodel_h *sh = nullptr; if (!ade_get_args(L, "o|o", l_ColInfo.GetPtr(&info), l_Submodel.GetPtr(&sh))) return ADE_RETURN_NIL; if (!info->isValid()) return ADE_RETURN_NIL; mc_info *collide = info->Get(); if (collide->hit_submodel < 0) return ADE_RETURN_NIL; return ade_set_args(L, "o", l_Submodel.Set(submodel_h(collide->model_num, collide->hit_submodel))); } ADE_FUNC(getCollisionDistance, l_ColInfo, NULL, "The distance to the closest collision point", "number", "distance or -1 on error") { mc_info_h* info; if(!ade_get_args(L, "o", l_ColInfo.GetPtr(&info))) return ade_set_error(L, "f", -1.0f); if (!info->isValid()) return ade_set_error(L, "f", -1.0f); mc_info *collide = info->Get(); if (collide->num_hits <= 0) { return ade_set_args(L, "f", -1.0f);; } else { return ade_set_args(L, "f", collide->hit_dist); } } ADE_FUNC(getCollisionPoint, l_ColInfo, "[boolean local]", "The collision point of this information (local to the object if boolean is set to true)", "vector", "The collision point, or nil if none or if the handle is not valid") { mc_info_h* info; bool local = false; if(!ade_get_args(L, "o|b", l_ColInfo.GetPtr(&info), &local)) return ADE_RETURN_NIL; if (!info->isValid()) return ADE_RETURN_NIL; mc_info *collide = info->Get(); if (collide->num_hits <= 0) { return ADE_RETURN_NIL; } else { if (local) return ade_set_args(L, "o", l_Vector.Set(collide->hit_point)); else return ade_set_args(L, "o", l_Vector.Set(collide->hit_point_world)); } } ADE_FUNC(getCollisionNormal, l_ColInfo, "[boolean local]", "The collision normal of this information (local to object if boolean is set to true)", "vector", "The collision normal, or nil if none or if the handle is not valid") { mc_info_h* info; bool local = false; if(!ade_get_args(L, "o|b", l_ColInfo.GetPtr(&info), &local)) return ADE_RETURN_NIL; if (!info->isValid()) return ADE_RETURN_NIL; mc_info *collide = info->Get(); if (collide->num_hits <= 0) { return ADE_RETURN_NIL; } else { if (!local) { vec3d normal; auto pmi = model_get_instance(collide->model_instance_num); auto pm = model_get(pmi->model_num); model_instance_local_to_global_dir(&normal, &collide->hit_normal, pm, pmi, collide->hit_submodel, collide->orient); return ade_set_args(L, "o", l_Vector.Set(normal)); } else { return ade_set_args(L, "o", l_Vector.Set(collide->hit_normal)); } } } } }