static int _define_ship(lua_State *L, const char *model_name, std::vector<ShipType::Type> &list, ShipType::Tag stag) { ShipType s; s.tag = stag; s.lmrModelName = model_name; LUA_DEBUG_START(L); _get_string_attrib(L, "name", s.name, model_name); _get_float_attrib(L, "reverse_thrust", s.linThrust[ShipType::THRUSTER_REVERSE], 0.0f); _get_float_attrib(L, "forward_thrust", s.linThrust[ShipType::THRUSTER_FORWARD], 0.0f); _get_float_attrib(L, "up_thrust", s.linThrust[ShipType::THRUSTER_UP], 0.0f); _get_float_attrib(L, "down_thrust", s.linThrust[ShipType::THRUSTER_DOWN], 0.0f); _get_float_attrib(L, "left_thrust", s.linThrust[ShipType::THRUSTER_LEFT], 0.0f); _get_float_attrib(L, "right_thrust", s.linThrust[ShipType::THRUSTER_RIGHT], 0.0f); _get_float_attrib(L, "angular_thrust", s.angThrust, 0.0f); s.angThrust = s.angThrust / 2; // fudge for (int i=0; i<Equip::SLOT_MAX; i++) s.equipSlotCapacity[i] = 0; _get_int_attrib(L, "max_cargo", s.equipSlotCapacity[Equip::SLOT_CARGO], 0); _get_int_attrib(L, "max_engine", s.equipSlotCapacity[Equip::SLOT_ENGINE], 1); _get_int_attrib(L, "max_laser", s.equipSlotCapacity[Equip::SLOT_LASER], 1); _get_int_attrib(L, "max_missile", s.equipSlotCapacity[Equip::SLOT_MISSILE], 0); _get_int_attrib(L, "max_ecm", s.equipSlotCapacity[Equip::SLOT_ECM], 1); _get_int_attrib(L, "max_scanner", s.equipSlotCapacity[Equip::SLOT_SCANNER], 1); _get_int_attrib(L, "max_radarmapper", s.equipSlotCapacity[Equip::SLOT_RADARMAPPER], 1); _get_int_attrib(L, "max_hypercloud", s.equipSlotCapacity[Equip::SLOT_HYPERCLOUD], 1); _get_int_attrib(L, "max_hullautorepair", s.equipSlotCapacity[Equip::SLOT_HULLAUTOREPAIR], 1); _get_int_attrib(L, "max_energybooster", s.equipSlotCapacity[Equip::SLOT_ENERGYBOOSTER], 1); _get_int_attrib(L, "max_atmoshield", s.equipSlotCapacity[Equip::SLOT_ATMOSHIELD], 1); _get_int_attrib(L, "max_fuelscoop", s.equipSlotCapacity[Equip::SLOT_FUELSCOOP], 1); _get_int_attrib(L, "max_lasercooler", s.equipSlotCapacity[Equip::SLOT_LASERCOOLER], 1); _get_int_attrib(L, "max_cargolifesupport", s.equipSlotCapacity[Equip::SLOT_CARGOLIFESUPPORT], 1); _get_int_attrib(L, "max_autopilot", s.equipSlotCapacity[Equip::SLOT_AUTOPILOT], 1); _get_int_attrib(L, "capacity", s.capacity, 0); _get_int_attrib(L, "hull_mass", s.hullMass, 100); _get_int_attrib(L, "price", s.baseprice, 0); s.baseprice *= 100; // in hundredths of credits { int hyperclass; _get_int_attrib(L, "hyperdrive_class", hyperclass, 1); if (!hyperclass) { s.hyperdrive = Equip::NONE; } else { s.hyperdrive = Equip::Type(Equip::DRIVE_CLASS1+hyperclass-1); } } lua_pushstring(L, "gun_mounts"); lua_gettable(L, -2); if (lua_istable(L, -1)) { for (unsigned int i=0; i<lua_objlen(L,-1); i++) { lua_pushinteger(L, i+1); lua_gettable(L, -2); if (lua_istable(L, -1) && lua_objlen(L,-2) == 2) { lua_pushinteger(L, 1); lua_gettable(L, -2); s.gunMount[i].pos = *MyLuaVec::checkVec(L, -1); lua_pop(L, 1); lua_pushinteger(L, 2); lua_gettable(L, -2); s.gunMount[i].dir = *MyLuaVec::checkVec(L, -1); lua_pop(L, 1); } lua_pop(L, 1); } } lua_pop(L, 1); LUA_DEBUG_END(L, 0); ShipType::types[s.name] = s; list.push_back(s.name); return 0; }
int _define_ship(lua_State *L, ShipType::Tag tag, std::vector<ShipType::Type> *list) { if (s_currentShipFile.empty()) return luaL_error(L, "ship file contains multiple ship definitions"); ShipType s; s.tag = tag; LUA_DEBUG_START(L); _get_string_attrib(L, "name", s.name, ""); _get_string_attrib(L, "model", s.lmrModelName, ""); _get_float_attrib(L, "reverse_thrust", s.linThrust[ShipType::THRUSTER_REVERSE], 0.0f); _get_float_attrib(L, "forward_thrust", s.linThrust[ShipType::THRUSTER_FORWARD], 0.0f); _get_float_attrib(L, "up_thrust", s.linThrust[ShipType::THRUSTER_UP], 0.0f); _get_float_attrib(L, "down_thrust", s.linThrust[ShipType::THRUSTER_DOWN], 0.0f); _get_float_attrib(L, "left_thrust", s.linThrust[ShipType::THRUSTER_LEFT], 0.0f); _get_float_attrib(L, "right_thrust", s.linThrust[ShipType::THRUSTER_RIGHT], 0.0f); _get_float_attrib(L, "angular_thrust", s.angThrust, 0.0f); // invert values where necessary s.linThrust[ShipType::THRUSTER_FORWARD] *= -1.f; s.linThrust[ShipType::THRUSTER_LEFT] *= -1.f; s.linThrust[ShipType::THRUSTER_DOWN] *= -1.f; // angthrust fudge (XXX: why?) s.angThrust = s.angThrust / 2; _get_vec_attrib(L, "camera_offset", s.cameraOffset, vector3d(0.0)); for (int i=0; i<Equip::SLOT_MAX; i++) s.equipSlotCapacity[i] = 0; _get_int_attrib(L, "max_cargo", s.equipSlotCapacity[Equip::SLOT_CARGO], 0); _get_int_attrib(L, "max_engine", s.equipSlotCapacity[Equip::SLOT_ENGINE], 1); _get_int_attrib(L, "max_laser", s.equipSlotCapacity[Equip::SLOT_LASER], 1); _get_int_attrib(L, "max_missile", s.equipSlotCapacity[Equip::SLOT_MISSILE], 0); _get_int_attrib(L, "max_ecm", s.equipSlotCapacity[Equip::SLOT_ECM], 1); _get_int_attrib(L, "max_scanner", s.equipSlotCapacity[Equip::SLOT_SCANNER], 1); _get_int_attrib(L, "max_radarmapper", s.equipSlotCapacity[Equip::SLOT_RADARMAPPER], 1); _get_int_attrib(L, "max_hypercloud", s.equipSlotCapacity[Equip::SLOT_HYPERCLOUD], 1); _get_int_attrib(L, "max_hullautorepair", s.equipSlotCapacity[Equip::SLOT_HULLAUTOREPAIR], 1); _get_int_attrib(L, "max_energybooster", s.equipSlotCapacity[Equip::SLOT_ENERGYBOOSTER], 1); _get_int_attrib(L, "max_atmoshield", s.equipSlotCapacity[Equip::SLOT_ATMOSHIELD], 1); _get_int_attrib(L, "max_cabin", s.equipSlotCapacity[Equip::SLOT_CABIN], 50); _get_int_attrib(L, "max_shield", s.equipSlotCapacity[Equip::SLOT_SHIELD], 9999); _get_int_attrib(L, "max_fuelscoop", s.equipSlotCapacity[Equip::SLOT_FUELSCOOP], 1); _get_int_attrib(L, "max_cargoscoop", s.equipSlotCapacity[Equip::SLOT_CARGOSCOOP], 1); _get_int_attrib(L, "max_lasercooler", s.equipSlotCapacity[Equip::SLOT_LASERCOOLER], 1); _get_int_attrib(L, "max_cargolifesupport", s.equipSlotCapacity[Equip::SLOT_CARGOLIFESUPPORT], 1); _get_int_attrib(L, "max_autopilot", s.equipSlotCapacity[Equip::SLOT_AUTOPILOT], 1); _get_int_attrib(L, "capacity", s.capacity, 0); _get_int_attrib(L, "hull_mass", s.hullMass, 100); _get_int_attrib(L, "fuel_tank_mass", s.fuelTankMass, 5); _get_float_attrib(L, "thruster_fuel_use", s.thrusterFuelUse, 1.f); _get_int_attrib(L, "price", s.baseprice, 0); s.baseprice *= 100; // in hundredths of credits s.equipSlotCapacity[Equip::SLOT_ENGINE] = Clamp(s.equipSlotCapacity[Equip::SLOT_ENGINE], 0, 1); { int hyperclass; _get_int_attrib(L, "hyperdrive_class", hyperclass, 1); if (!hyperclass) { s.hyperdrive = Equip::NONE; } else { s.hyperdrive = Equip::Type(Equip::DRIVE_CLASS1+hyperclass-1); } } lua_pushstring(L, "gun_mounts"); lua_gettable(L, -2); if (lua_istable(L, -1)) { for (unsigned int i=0; i<lua_rawlen(L,-1); i++) { lua_pushinteger(L, i+1); lua_gettable(L, -2); if (lua_istable(L, -1) && lua_rawlen(L,-1) == 4) { lua_pushinteger(L, 1); lua_gettable(L, -2); s.gunMount[i].pos = LuaVector::CheckFromLuaF(L, -1); lua_pop(L, 1); lua_pushinteger(L, 2); lua_gettable(L, -2); s.gunMount[i].dir = LuaVector::CheckFromLuaF(L, -1); lua_pop(L, 1); lua_pushinteger(L, 3); lua_gettable(L, -2); s.gunMount[i].sep = lua_tonumber(L,-1); lua_pop(L, 1); lua_pushinteger(L, 4); lua_gettable(L, -2); s.gunMount[i].orient = static_cast<ShipType::DualLaserOrientation>( LuaConstants::GetConstantFromArg(L, "DualLaserOrientation", -1)); lua_pop(L, 1); } lua_pop(L, 1); } } lua_pop(L, 1); LUA_DEBUG_END(L, 0); //sanity check if (s.name.empty()) return luaL_error(L, "Ship has no name"); if (s.lmrModelName.empty()) return luaL_error(L, "Missing model name in ship"); //this shouldn't necessarily be a fatal problem, could just warn+mark ship unusable //or replace with proxy geometry try { LmrLookupModelByName(s.lmrModelName.c_str()); } catch (LmrModelNotFoundException &) { return luaL_error(L, "Model %s is not defined", s.lmrModelName.c_str()); } const std::string& id = s_currentShipFile; typedef std::map<ShipType::Type, ShipType>::iterator iter; std::pair<iter, bool> result = ShipType::types.insert(std::make_pair(id, s)); if (result.second) list->push_back(s_currentShipFile); else return luaL_error(L, "Ship '%s' was already defined by a different file", id.c_str()); s_currentShipFile.clear(); return 0; }