// // #include "oswpt.h" #include "parse_object.h" #include "ship.h" #include "team.h" #include "waypoint.h" #include "wing.h" #include "ship/ship.h" #include "mission/missionparse.h" #include "network/multi.h" #include "network/multimsgs.h" #include "network/multiutil.h" void scripting::internal::ade_serializable_external::serialize(lua_State* /*L*/, const scripting::ade_table_entry& /*tableEntry*/, const luacpp::LuaValue& luaValue, ubyte* data, int& packet_size) { object_ship_wing_point_team oswpt; luaValue.getValue(scripting::api::l_OSWPT.Get(&oswpt)); uint8_t oswpttype = static_cast(oswpt.type); ADD_DATA(oswpttype); switch (oswpt.type) { case oswpt_type::SHIP: case oswpt_type::WAYPOINT: ADD_USHORT(oswpt.objp()->net_signature); break; case oswpt_type::PARSE_OBJECT: ADD_USHORT(oswpt.p_objp()->net_signature); break; case oswpt_type::WING: case oswpt_type::WING_NOT_PRESENT: { ADD_INT(oswpt.wingnum); break; } case oswpt_type::SHIP_ON_TEAM: case oswpt_type::WHOLE_TEAM: ADD_INT(oswpt.team); break; case oswpt_type::NONE: case oswpt_type::EXITED: default: break; } } void scripting::internal::ade_serializable_external::deserialize(lua_State* /*L*/, const scripting::ade_table_entry& /*tableEntry*/, char* data_ptr, ubyte* data, int& offset) { // NOLINT uint8_t oswpttype; GET_DATA(oswpttype); switch (static_cast(oswpttype)) { case oswpt_type::SHIP: case oswpt_type::WAYPOINT: { ushort net_signature; GET_USHORT(net_signature); object_ship_wing_point_team oswpt; oswpt.type = static_cast(oswpttype); //This doesn't constitute a valid waypoint oswpt, but it will work for everything that lua has access to, so it's fine auto objp = multi_get_network_object(net_signature); oswpt.objnum = (objp == nullptr) ? -1 : OBJ_INDEX(objp); new(data_ptr) object_ship_wing_point_team(std::move(oswpt)); break; } case oswpt_type::PARSE_OBJECT: { ushort net_signature; GET_USHORT(net_signature); auto p_objp = mission_parse_get_arrival_ship(net_signature); if (p_objp == nullptr) new(data_ptr) object_ship_wing_point_team; else new(data_ptr) object_ship_wing_point_team(p_objp); break; } case oswpt_type::WING: case oswpt_type::WING_NOT_PRESENT: { int wingidx; GET_INT(wingidx); if((wingidx < 0) || (wingidx >= Num_wings) || (Wings[wingidx].num_waves == -1)) new(data_ptr) object_ship_wing_point_team; else new(data_ptr) object_ship_wing_point_team(&Wings[wingidx]); break; } case oswpt_type::SHIP_ON_TEAM: case oswpt_type::WHOLE_TEAM: { int oswpt_team; GET_INT(oswpt_team); object_ship_wing_point_team oswpt; oswpt.team = oswpt_team; oswpt.type = static_cast(oswpttype); new(data_ptr) object_ship_wing_point_team(std::move(oswpt)); break; } case oswpt_type::NONE: case oswpt_type::EXITED: default: new(data_ptr) object_ship_wing_point_team; break; } } #define OSWPT_TYPE_NONE oswpt_type::NONE #define OSWPT_TYPE_SHIP oswpt_type::SHIP #define OSWPT_TYPE_WING oswpt_type::WING #define OSWPT_TYPE_WAYPOINT oswpt_type::WAYPOINT #define OSWPT_TYPE_SHIP_ON_TEAM oswpt_type::SHIP_ON_TEAM #define OSWPT_TYPE_WHOLE_TEAM oswpt_type::WHOLE_TEAM #define OSWPT_TYPE_PARSE_OBJECT oswpt_type::PARSE_OBJECT #define OSWPT_TYPE_EXITED oswpt_type::EXITED #define OSWPT_TYPE_WING_NOT_PRESENT oswpt_type::WING_NOT_PRESENT namespace scripting { namespace api { //**********HANDLE: Wing ADE_OBJ(l_OSWPT, object_ship_wing_point_team, "oswpt", "Handle for LuaSEXP arguments that can hold different types (Object/Ship/Wing/Waypoint/Team)"); ADE_FUNC(getType, l_OSWPT, nullptr, "The data-type this OSWPT yields on the get method.", "string", "The name of the data type. Either 'ship', 'parseobject' (a yet-to-spawn ship), 'wing' (can include yet-to-arrive wings with 0 current ships), 'team' (both explicit and ship-on-team), 'waypoint', or 'none' (either explicitly specified, a ship that doesn't exist anymore, or invalid OSWPT object).") { object_ship_wing_point_team oswpt; if (!ade_get_args(L, "o", l_OSWPT.Get(&oswpt))) return ade_set_error(L, "s", "none"); switch (oswpt.type) { case OSWPT_TYPE_SHIP: return ade_set_args(L, "s", "ship"); case OSWPT_TYPE_PARSE_OBJECT: return ade_set_args(L, "s", "parseobject"); case OSWPT_TYPE_WING: case OSWPT_TYPE_WING_NOT_PRESENT: return ade_set_args(L, "s", "wing"); case OSWPT_TYPE_SHIP_ON_TEAM: case OSWPT_TYPE_WHOLE_TEAM: return ade_set_args(L, "s", "team"); case OSWPT_TYPE_WAYPOINT: return ade_set_args(L, "s", "waypoint"); case OSWPT_TYPE_NONE: case OSWPT_TYPE_EXITED: default: return ade_set_args(L, "s", "none"); } } ADE_FUNC(get, l_OSWPT, nullptr, "Returns the data held by this OSWPT.", "ship | parse_object | wing | team | waypoint | nil", "Returns the data held by this OSWPT, nil if type is 'none'.") { object_ship_wing_point_team oswpt; if (!ade_get_args(L, "o", l_OSWPT.Get(&oswpt))) return ADE_RETURN_NIL; switch (oswpt.type) { case OSWPT_TYPE_SHIP: return ade_set_args(L, "o", l_Ship.Set(object_h(oswpt.objnum))); case OSWPT_TYPE_PARSE_OBJECT: return ade_set_args(L, "o", l_ParseObject.Set(parse_object_h(oswpt.p_objp()))); case OSWPT_TYPE_WING: case OSWPT_TYPE_WING_NOT_PRESENT: return ade_set_args(L, "o", l_Wing.Set(oswpt.wingnum)); case OSWPT_TYPE_SHIP_ON_TEAM: case OSWPT_TYPE_WHOLE_TEAM: return ade_set_args(L, "o", l_Team.Set(oswpt.team)); case OSWPT_TYPE_WAYPOINT: return ade_set_args(L, "o", l_Waypoint.Set(object_h(oswpt.objnum))); case OSWPT_TYPE_NONE: case OSWPT_TYPE_EXITED: default: return ADE_RETURN_NIL; } } ADE_FUNC(forAllShips, l_OSWPT, "function(ship ship) => void body", "Applies this function to each (present) ship this OSWPT applies to.", nullptr, nullptr) { object_ship_wing_point_team oswpt; luacpp::LuaFunction body; if (!ade_get_args(L, "ou", l_OSWPT.Get(&oswpt), &body)) return ADE_RETURN_NIL; switch (oswpt.type) { case OSWPT_TYPE_SHIP: { luacpp::LuaValueList args; args.push_back(luacpp::LuaValue::createValue(L, l_Ship.Set(object_h(oswpt.objnum)))); body.call(L, args); break; } case OSWPT_TYPE_WING: { auto wp = &Wings[oswpt.wingnum]; for (int i = 0; i < wp->current_count; ++i) { luacpp::LuaValueList args; args.push_back(luacpp::LuaValue::createValue(L, l_Ship.Set(object_h(&Objects[Ships[wp->ship_index[i]].objnum])))); body.call(L, args); } break; } case OSWPT_TYPE_SHIP_ON_TEAM: case OSWPT_TYPE_WHOLE_TEAM: for (auto so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so)) { if (Objects[so->objnum].flags[Object::Object_Flags::Should_be_dead]) continue; if (Ships[Objects[so->objnum].instance].team == oswpt.team) { luacpp::LuaValueList args; args.push_back(luacpp::LuaValue::createValue(L, l_Ship.Set(object_h(&Objects[so->objnum])))); body.call(L, args); } } break; case OSWPT_TYPE_PARSE_OBJECT: case OSWPT_TYPE_WING_NOT_PRESENT: case OSWPT_TYPE_WAYPOINT: case OSWPT_TYPE_NONE: case OSWPT_TYPE_EXITED: default: break; } return ADE_RETURN_NIL; } ADE_FUNC(forAllParseObjects, l_OSWPT, "function(parse_object po) => void body", "Applies this function to each not-yet-present ship (includes not-yet-present wings and not-yet-present ships of a specified team!) this OSWPT applies to.", nullptr, nullptr) { object_ship_wing_point_team oswpt; luacpp::LuaFunction body; if (!ade_get_args(L, "ou", l_OSWPT.Get(&oswpt), &body)) return ADE_RETURN_NIL; switch (oswpt.type) { case OSWPT_TYPE_PARSE_OBJECT: { luacpp::LuaValueList args; args.push_back(luacpp::LuaValue::createValue(L, l_ParseObject.Set(parse_object_h(oswpt.p_objp())))); body.call(L, args); break; } case OSWPT_TYPE_WING_NOT_PRESENT: { for (p_object* p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp)) { if (p_objp->wingnum == oswpt.wingnum) { luacpp::LuaValueList args; args.push_back(luacpp::LuaValue::createValue(L, l_ParseObject.Set(parse_object_h(p_objp)))); body.call(L, args); } } break; } case OSWPT_TYPE_SHIP_ON_TEAM: case OSWPT_TYPE_WHOLE_TEAM: { for (p_object* p_objp = GET_FIRST(&Ship_arrival_list); p_objp != END_OF_LIST(&Ship_arrival_list); p_objp = GET_NEXT(p_objp)) { if (p_objp->team == oswpt.team) { luacpp::LuaValueList args; args.push_back(luacpp::LuaValue::createValue(L, l_ParseObject.Set(parse_object_h(p_objp)))); body.call(L, args); } } break; } case OSWPT_TYPE_SHIP: case OSWPT_TYPE_WING: case OSWPT_TYPE_WAYPOINT: case OSWPT_TYPE_NONE: case OSWPT_TYPE_EXITED: default: break; } return ADE_RETURN_NIL; } } }