Esempio n. 1
0
void ShipType::Init()
{
	static bool isInitted = false;
	if (isInitted) return;
	isInitted = true;

	lua_State *l = luaL_newstate();

	LUA_DEBUG_START(l);

	luaL_requiref(l, "_G", &luaopen_base, 1);
	luaL_requiref(l, LUA_DBLIBNAME, &luaopen_debug, 1);
	luaL_requiref(l, LUA_MATHLIBNAME, &luaopen_math, 1);
	lua_pop(l, 3);

	LuaConstants::Register(l);
	LuaVector::Register(l);
	LUA_DEBUG_CHECK(l, 0);

	// provide shortcut vector constructor: v = vector.new
	lua_getglobal(l, LuaVector::LibName);
	lua_getfield(l, -1, "new");
	assert(lua_iscfunction(l, -1));
	lua_setglobal(l, "v");
	lua_pop(l, 1); // pop the vector library table

	LUA_DEBUG_CHECK(l, 0);

	// register ship definition functions
	lua_register(l, "define_ship", define_ship);
	lua_register(l, "define_static_ship", define_static_ship);
	lua_register(l, "define_missile", define_missile);

	LUA_DEBUG_CHECK(l, 0);

	// load all ship definitions
	namespace fs = FileSystem;
	for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse);
			!files.Finished(); files.Next()) {
		const fs::FileInfo &info = files.Current();
		if (ends_with(info.GetPath(), ".lua")) {
			const std::string name = info.GetName();
			s_currentShipFile = name.substr(0, name.size()-4);
			pi_lua_dofile(l, info.GetPath());
			s_currentShipFile.clear();
		}
	}

	LUA_DEBUG_END(l, 0);

	lua_close(l);

	if (ShipType::player_ships.empty())
		Error("No playable ships have been defined! The game cannot run.");

	//collect ships that can fit atmospheric shields
	for (std::vector<ShipType::Type>::const_iterator it = ShipType::player_ships.begin();
		it != ShipType::player_ships.end(); ++it) {
		const ShipType &ship = ShipType::types[*it];
		if (ship.equipSlotCapacity[Equip::SLOT_ATMOSHIELD] != 0)
			ShipType::playable_atmospheric_ships.push_back(*it);
	}

	if (ShipType::playable_atmospheric_ships.empty())
		Error("No ships can fit atmospheric shields! The game cannot run.");
}
Esempio n. 2
0
int _define_ship(lua_State *L, ShipType::Tag tag, std::vector<ShipType::Id> *list)
{
	if (s_currentShipFile.empty())
		return luaL_error(L, "ship file contains multiple ship definitions");

	Json::Value data;

	ShipType s;
	s.tag = tag;
	s.id = s_currentShipFile;

	LUA_DEBUG_START(L);
	LuaTable t(L, -1);

	s.name = t.Get("name", "");
	s.shipClass = t.Get("ship_class", "unknown");
	s.manufacturer = t.Get("manufacturer", "unknown");
	s.modelName = t.Get("model", "");

	data["name"] = s.name;
	data["ship_class"] = s.shipClass;
	data["manufacturer"] = s.manufacturer;
	data["model"] = s.modelName;

	s.cockpitName = t.Get("cockpit", "");
	s.linThrust[ShipType::THRUSTER_REVERSE] = t.Get("reverse_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_FORWARD] = t.Get("forward_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_UP] = t.Get("up_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_DOWN] = t.Get("down_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_LEFT] = t.Get("left_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_RIGHT] = t.Get("right_thrust", 0.0f);
	s.angThrust = t.Get("angular_thrust", 0.0f);

	data["cockpit"] = s.cockpitName;
	data["reverse_thrust"] = s.linThrust[ShipType::THRUSTER_REVERSE];
	data["forward_thrust"] = s.linThrust[ShipType::THRUSTER_FORWARD];
	data["up_thrust"] = s.linThrust[ShipType::THRUSTER_UP];
	data["down_thrust"] = s.linThrust[ShipType::THRUSTER_DOWN];
	data["left_thrust"] = s.linThrust[ShipType::THRUSTER_LEFT];
	data["right_thrust"] = s.linThrust[ShipType::THRUSTER_RIGHT];
	data["angular_thrust"] = s.angThrust;

	// 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;

	s.capacity = t.Get("capacity", 0);
	s.hullMass = t.Get("hull_mass", 100);
	s.fuelTankMass = t.Get("fuel_tank_mass", 5);

	data["capacity"] = s.capacity;
	data["hull_mass"] = s.hullMass;
	data["fuel_tank_mass"] = s.fuelTankMass;

	LuaTable slot_table = t.Sub("slots");
	if (slot_table.GetLua()) {
		s.slots = slot_table.GetMap<std::string, int>();
	}
	lua_pop(L, 1);

	{
		const auto it = s.slots.find("engine");
		if (it != s.slots.end()) { it->second = Clamp(it->second, 0, 1); }
	}

	for( auto slot : s.slots ) {
		data["slots"][slot.first] = slot.second;
	}

	// fuel_use_rate can be given in two ways
	float thruster_fuel_use = 0;
	s.effectiveExhaustVelocity = t.Get("effective_exhaust_velocity", -1.0f);
	thruster_fuel_use = t.Get("thruster_fuel_use", -1.0f);

	data["effective_exhaust_velocity"] = s.effectiveExhaustVelocity;
	data["thruster_fuel_use"] = thruster_fuel_use;

	if(s.effectiveExhaustVelocity < 0 && thruster_fuel_use < 0) {
		// default value of v_c is used
		s.effectiveExhaustVelocity = 55000000;
	} else if(s.effectiveExhaustVelocity < 0 && thruster_fuel_use >= 0) {
		// v_c undefined and thruster fuel use defined -- use it!
		s.effectiveExhaustVelocity = GetEffectiveExhaustVelocity(s.fuelTankMass, thruster_fuel_use, s.linThrust[ShipType::THRUSTER_FORWARD]);
	} else {
		if(thruster_fuel_use >= 0)
			Output("Warning: Both thruster_fuel_use and effective_exhaust_velocity defined for %s, using effective_exhaust_velocity.\n", s.modelName.c_str());
	}

	s.baseprice = t.Get("price", 0.0);

	s.minCrew = t.Get("min_crew", 1);
	s.maxCrew = t.Get("max_crew", 1);

	s.hyperdriveClass = t.Get("hyperdrive_class", 1);

	data["price"] = s.baseprice;
	data["min_crew"] = s.minCrew;
	data["max_crew"] = s.maxCrew;
	data["hyperdrive_class"] = s.hyperdriveClass;

	Json::StyledWriter writer;
	const std::string saveMe = writer.write( data );

	const std::string path("ships/" + s_currentShipFile + ".json");
	FileSystem::FileSourceFS newFS(FileSystem::GetDataDir());
	FILE *f = newFS.OpenWriteStream(path);
	if (!f) {
		Output("couldn't open file for writing '%s'\n", path.c_str());
		abort();
	}
	fwrite(saveMe.data(), saveMe.length(), 1, f);
	fclose(f);

	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.modelName.empty())
		return luaL_error(L, "Missing model name in ship");

	if (s.minCrew < 1 || s.maxCrew < 1 || s.minCrew > s.maxCrew)
		return luaL_error(L, "Invalid values for min_crew and max_crew");

	const std::string& id = s_currentShipFile;
	typedef std::map<std::string, const 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;
}
Esempio n. 3
0
void ShipType::Init()
{
	static bool isInitted = false;
	if (isInitted)
		return;
	isInitted = true;

	// load all ship definitions
	namespace fs = FileSystem;
	for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse); !files.Finished(); files.Next()) {
		const fs::FileInfo &info = files.Current();
		if (ends_with_ci(info.GetPath(), ".json")) {
			const std::string id(info.GetName().substr(0, info.GetName().size()-5));
			try {
				ShipType st = ShipType(id, info.GetPath());
				types.insert(std::make_pair(st.id, st));

				// assign the names to the various lists
				switch( st.tag ) {
				case TAG_SHIP:				player_ships.push_back(id);				break;
				case TAG_STATIC_SHIP:		static_ships.push_back(id);				break;
				case TAG_MISSILE:			missile_ships.push_back(id);			break;
					break;
				case TAG_NONE:
				default:
					break;
				}
			} catch (ShipTypeLoadError) {
				// TODO: Actual error handling would be nice.
				Error("Error while loading Ship data (check stdout/output.txt).\n");
			}
		}
	}

#if ALLOW_LUA_SHIP_DEF
	lua_State *l = luaL_newstate();

	LUA_DEBUG_START(l);

	luaL_requiref(l, "_G", &luaopen_base, 1);
	luaL_requiref(l, LUA_DBLIBNAME, &luaopen_debug, 1);
	luaL_requiref(l, LUA_MATHLIBNAME, &luaopen_math, 1);
	lua_pop(l, 3);

	LuaConstants::Register(l);
	LuaVector::Register(l);
	LUA_DEBUG_CHECK(l, 0);

	// provide shortcut vector constructor: v = vector.new
	lua_getglobal(l, LuaVector::LibName);
	lua_getfield(l, -1, "new");
	assert(lua_iscfunction(l, -1));
	lua_setglobal(l, "v");
	lua_pop(l, 1); // pop the vector library table

	LUA_DEBUG_CHECK(l, 0);

	// register ship definition functions
	lua_register(l, "define_ship", define_ship);
	lua_register(l, "define_static_ship", define_static_ship);
	lua_register(l, "define_missile", define_missile);

	LUA_DEBUG_CHECK(l, 0);

	// load all ship definitions
	namespace fs = FileSystem;
	for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse); !files.Finished(); files.Next()) {
		const fs::FileInfo &info = files.Current();
		if (ends_with_ci(info.GetPath(), ".lua")) {
			const std::string name = info.GetName();
			s_currentShipFile = name.substr(0, name.size() - 4);
			if (ShipType::types.find(s_currentShipFile) == ShipType::types.end())
			{
				pi_lua_dofile(l, info.GetPath());
				s_currentShipFile.clear();
			}
		}
	}

	LUA_DEBUG_END(l, 0);

	lua_close(l);
#endif

	//remove unbuyable ships from player ship list
	ShipType::player_ships.erase(
		std::remove_if(ShipType::player_ships.begin(), ShipType::player_ships.end(), ShipIsUnbuyable),
		ShipType::player_ships.end());

	if (ShipType::player_ships.empty())
		Error("No playable ships have been defined! The game cannot run.");
}
Esempio n. 4
0
const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
{
	LUA_DEBUG_START(l);

	char type = *pos++;

	switch (type) {

		case 'f': {
			char *end;
			double f = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			lua_pushnumber(l, f);
			pos = end+1; // skip newline
			break;
		}

		case 'b': {
			if (*pos != '0' && *pos != '1') throw SavedGameCorruptException();
			bool b = (*pos == '0') ? false : true;
			lua_pushboolean(l, b);
			pos++;
			break;
		}

		case 's': {
			char *end;
			int len = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			end++; // skip newline
			lua_pushlstring(l, end, len);
			pos = end + len;
			break;
		}
			
		case 't': {
			lua_newtable(l);
			while (*pos != 'n') {
				pos = unpickle(l, pos);
				pos = unpickle(l, pos);
				lua_rawset(l, -3);
			}
			pos++;
			break;
		}

		case 'u': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) {
				pos = end;

				Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 systemNum = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sbodyId = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId);
				LuaSystemPath::PushToLuaGC(sbp);

				break;
			}

			if (len == 4 && strncmp(pos, "Body", 4) == 0) {
				pos = end;

				int n = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Body *body = Serializer::LookupBody(n);
				if (pos == end) throw SavedGameCorruptException();

				switch (body->GetType()) {
					case Object::BODY:
						LuaBody::PushToLua(body);
						break;
					case Object::SHIP:
						LuaShip::PushToLua(dynamic_cast<Ship*>(body));
						break;
					case Object::SPACESTATION:
						LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body));
						break;
					case Object::PLANET:
						LuaPlanet::PushToLua(dynamic_cast<Planet*>(body));
						break;
					case Object::STAR:
						LuaStar::PushToLua(dynamic_cast<Star*>(body));
						break;
					case Object::PLAYER:
						LuaPlayer::PushToLua(dynamic_cast<Player*>(body));
						break;
					default:
						throw SavedGameCorruptException();
				}

				break;
			}

			throw SavedGameCorruptException();
		}

		default:
			throw SavedGameCorruptException();
	}

	LUA_DEBUG_END(l, 1);

	return pos;
}
Esempio n. 5
0
void LuaConstants::Register(lua_State *l)
{
	LUA_DEBUG_START(l);


	/*
	 * Constants: BodyType
	 *
	 * Describe different kinds of system bodies such as stars, planets and
	 * space stations.
	 *
	 * GRAVPOINT - a pseudo-type for a gravitational point that multiple
	 *             bodies may orbit
	 * BROWN_DWARF - brown dwarf sub-stellar object
	 * STAR_M - type 'M' red star
	 * STAR_K - type 'K' orange star
	 * STAR_G - type 'G' yellow star
	 * STAR_F - type 'F' white star
	 * STAR_A - type 'A' hot white star
	 * STAR_B - type 'B' blue star
	 * STAR_O - type 'O' hot blue star
	 * WHITE_DWARF - white dwarf stellar remnant
	 * STAR_M_GIANT - red giant star
	 * STAR_K_GIANT - orange giant star
	 * STAR_G_GIANT - yellow giant star
	 * STAR_F_GIANT - white giant star
	 * STAR_A_GIANT - hot white giant star
	 * STAR_B_GIANT - blue giant star
	 * STAR_O_GIANT - hot blue giant star
	 * STAR_M_SUPER_GIANT - red supergiant star
	 * STAR_K_SUPER_GIANT - orange supergiant star
	 * STAR_G_SUPER_GIANT - yellow supergiant star
	 * STAR_F_SUPER_GIANT - white supergiant star
	 * STAR_A_SUPER_GIANT - hot white supergiant star
	 * STAR_B_SUPER_GIANT - blue supergiant star
	 * STAR_O_SUPER_GIANT - hot blue supergiant star
	 * STAR_M_HYPER_GIANT - red hypergiant star
	 * STAR_K_HYPER_GIANT - orange hypergiant star
	 * STAR_G_HYPER_GIANT - yellow hypergiant star
	 * STAR_F_HYPER_GIANT - white hypergiant star
	 * STAR_A_HYPER_GIANT - hot white hypergiant star
	 * STAR_B_HYPER_GIANT - blue hypergiant star
	 * STAR_O_HYPER_GIANT - hot blue hypergiant star
	 * STAR_M_WF - Wolf-Rayet star (unstable)
	 * STAR_B_WF - Wolf-Rayet star (risk of collapse)
	 * STAR_O_WF - Wolf-Rayet star (imminent collapse)
	 * STAR_S_BH - stellar black hole
	 * STAR_IM_BH - intermediate-mass black hole
	 * STAR_SM_BH - supermassive black hole
	 * PLANET_GAS_GIANT - gas giant
	 * PLANET_ASTEROID - asteroid
	 * PLANET_TERRESTRIAL - terrestrial planet
	 * STARPORT_ORBITAL - orbital starport (space station)
	 * STARPORT_SURFACE - surface starport
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */
	_create_constant_table_nonconsecutive(l, "BodyType", ENUM_BodyType);


	/*
	 * Constants: BodySuperType
	 *
	 * Describe general categories of system bodies.
	 *
	 * NONE - uncategorised
	 * STAR - star
	 * ROCKY_PLANET - a solid planet (terrestrial or asteroid)
	 * GAS_GIANT - gas giant
	 * STARPORT - surface or orbital starport
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */
	_create_constant_table_nonconsecutive(l, "BodySuperType", ENUM_BodySuperType);


	/*
	 * Constants: PolitCrime
	 *
	 * Crimes
	 *
	 * TRADING_ILLEGAL_GOODS - .
	 * WEAPON_DISCHARGE - .
	 * PIRACY - .
	 * MURDER - .
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "PolitCrime", ENUM_PolitCrime);

	/*
	 * Constants: PolitEcon
	 *
	 * Economy type
	 *
	 * NONE - .
	 * VERY_CAPITALIST - .
	 * CAPITALIST - .
	 * MIXED - .
	 * PLANNED - .
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "PolitEcon", ENUM_PolitEcon);

	/*
	 * Constants: PolitGovType
	 *
	 * Government type
	 *
	 * NONE - .
	 * EARTHCOLONIAL - .
	 * EARTHDEMOC - .
	 * EMPIRERULE - .
	 * CISLIBDEM - .
	 * CISSOCDEM - .
	 * LIBDEM - .
	 * CORPORATE - .
	 * SOCDEM - .
	 * EARTHMILDICT - .
	 * MILDICT1 - .
	 * MILDICT2 - .
	 * EMPIREMILDICT - .
	 * COMMUNIST - .
	 * PLUTOCRATIC - .
	 * DISORDER - .
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "PolitGovType", ENUM_PolitGovType);


	/*
	 * Constants: EquipSlot
	 *
	 * Equipment slots. Every equipment or cargo type has a corresponding
	 * "slot" that it fits in to. Each slot has an independent capacity.
	 *
	 * CARGO - any cargo (commodity) item
	 * ENGINE - hyperdrives and military drives
	 * LASER - lasers and plasma accelerators
	 * MISSILE - missile
	 * ECM - ECM system
	 * SCANNER - scanner
	 * RADARMAPPER - radar mapper
	 * HYPERCLOUD - hyperspace cloud analyser
	 * HULLAUTOREPAIR - hull auto-repair system
	 * ENERGYBOOSTER - shield energy booster unit
	 * ATMOSHIELD - atmospheric shielding
	 * CABIN - cabin
	 * SHIELD - shield
	 * FUELSCOOP - fuel scoop
	 * CARGOSCOOP - cargo scoop
	 * LASERCOOLER - laser cooling booster
	 * CARGOLIFESUPPORT - cargo bay life support
	 * AUTOPILOT - autopilot
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "EquipSlot", ENUM_EquipSlot);

	/*
	 * Constants: EquipType
	 *
	 * Equipment and cargo types. Because of the slot arrangement described
	 * under <EquipType> means that cargo is treated as a special type of
	 * equipment.
	 *
	 * NONE - no equipment. Usually used to indicate the absence of equipment
	 * HYDROGEN - hydrogen (CARGO)
	 * LIQUID_OXYGEN - liquid oxygen (CARGO)
	 * METAL_ORE - metal ore (CARGO)
	 * CARBON_ORE - carbon ore (CARGO)
	 * METAL_ALLOYS - metal alloys (CARGO)
	 * PLASTICS - plastics (CARGO)
	 * FRUIT_AND_VEG - fruit and vegetables (CARGO)
	 * ANIMAL_MEAT - animal meat (CARGO)
	 * LIVE_ANIMALS - live animals (CARGO)
	 * LIQUOR - liquor (CARGO)
	 * GRAIN - grain (CARGO)
	 * TEXTILES - textiles (CARGO)
	 * FERTILIZER - fertilizer (CARGO)
	 * WATER - water (CARGO)
	 * MEDICINES - medicines (CARGO)
	 * CONSUMER_GOODS - consumer goods (CARGO)
	 * COMPUTERS - computers (CARGO)
	 * ROBOTS - robots (CARGO)
	 * PRECIOUS_METALS - precious metals (CARGO)
	 * INDUSTRIAL_MACHINERY - industrial machinery (CARGO)
	 * FARM_MACHINERY - farm machinery (CARGO)
	 * MINING_MACHINERY - mining machinery (CARGO
	 * AIR_PROCESSORS - air processors (CARGO)
	 * SLAVES - slaves (CARGO)
	 * HAND_WEAPONS - hand weapons (CARGO)
	 * BATTLE_WEAPONS - battle weapons (CARGO)
	 * NERVE_GAS - nerve gas (CARGO)
	 * NARCOTICS - narcotics (CARGO)
	 * MILITARY_FUEL - military fuel (CARGO)
	 * RUBBISH - rubbish (CARGO)
	 * RADIOACTIVES - radioactives (CARGO)
	 * MISSILE_UNGUIDED - unguided rocket (MISSILE)
	 * MISSILE_GUIDED - guided missile (MISSILE)
	 * MISSILE_SMART - smart missile (MISSILE)
	 * MISSILE_NAVAL - naval missile (MISSILE)
	 * ATMOSPHERIC_SHIELDING - atmospheric shielding (ATMOSHIELD)
	 * ECM_BASIC - basic ECM system (ECM)
	 * SCANNER - scanner (SCANNER)
	 * ECM_ADVANCED - advanced ECM system (ECM)
	 * UNOCCUPIED_CABIN - unoccupied passenger cabin (CABIN)
	 * PASSENGER_CABIN - occupied passenger cabin (CABIN)
	 * SHIELD_GENERATOR - shield generator (SHIELD)
	 * LASER_COOLING_BOOSTER - laser cooling booster (LASERCOOLER)
	 * CARGO_LIFE_SUPPORT - cargo bay life support (CARGOLIFESUPPORT)
	 * AUTOPILOT - autopilot (AUTOPILOT)
	 * RADAR_MAPPER - radar mapper (RADARMAPPER)
	 * FUEL_SCOOP - fuel scoop (FUELSCOOP)
	 * CARGO_SCOOP - cargo scoop (CARGOSCOOP)
	 * HYPERCLOUD_ANALYZER - hyperspace cloud analyser (HYPERCLOUD)
	 * HULL_AUTOREPAIR - hull auto-repair system (HULLAUTOREPAIR)
	 * SHIELD_ENERGY_BOOSTER - shield energy booster unit (ENERGYBOOSTER)
	 * DRIVE_CLASS1 - class 1 hyperdrive (ENGINE)
	 * DRIVE_CLASS2 - class 2 hyperdrive (ENGINE)
	 * DRIVE_CLASS3 - class 3 hyperdrive (ENGINE)
	 * DRIVE_CLASS4 - class 4 hyperdrive (ENGINE)
	 * DRIVE_CLASS5 - class 5 hyperdrive (ENGINE)
	 * DRIVE_CLASS6 - class 6 hyperdrive (ENGINE)
	 * DRIVE_CLASS7 - class 7 hyperdrive (ENGINE)
	 * DRIVE_CLASS8 - class 8 hyperdrive (ENGINE)
	 * DRIVE_CLASS9 - class 9 hyperdrive (ENGINE)
	 * DRIVE_MIL1 - class 1 military drive (ENGINE)
	 * DRIVE_MIL2 - class 2 military drive (ENGINE)
	 * DRIVE_MIL3 - class 3 military drive (ENGINE)
	 * DRIVE_MIL4 - class 4 military drive (ENGINE)
	 * PULSECANNON_1MW - 1MW pulse cannon (LASER)
	 * PULSECANNON_DUAL_1MW - 1MW dual-fire pulse cannon (LASER)
	 * PULSECANNON_2MW - 2MW pulse cannon (LASER)
	 * PULSECANNON_RAPID_2MW - 2MW rapid-fire pulse cannon (LASER)
	 * PULSECANNON_4MW - 4MW pulse cannon (LASER)
	 * PULSECANNON_10MW - 10MW pulse cannon (LASER)
	 * PULSECANNON_20MW - 20MW pulse cannon (LASER)
	 * MININGCANNON_17MW - 17MW blast-mining cannon (LASER)
	 * SMALL_PLASMA_ACCEL - small plasma accelerator (LASER)
	 * LARGE_PLASMA_ACCEL - large plasma accelerator (LASER)
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "EquipType", ENUM_EquipType);

	/*
	 * Constants: DualLaserOrientation
	 *
	 * The orientation of dual laser mountings.
	 *
	 * HORIZONTAL - Lasers are mounted left and right
	 * VERTICAL   - Lasers are mounted top and bottom
	 *
	 * Availability:
	 *
	 *   alpha 27
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "DualLaserOrientation", ENUM_DualLaserOrientation);

	/*
	 * Constants: ShipTypeTag
	 *
	 * Ship tags mark whether a ship is suitable for a particular use. Used
	 * with <ShipType.GetShipTypes> to select which set of ships to search.
	 *
	 * NONE - no tags
	 * SHIP - standard ships. These are the ones available to the player and
	 *        used for regular game functions (trade, combat, etc)
	 * STATIC_SHIP - static ships. These are not available to the player and
	 *               are used for mission specific functions (large supply
	 *               ships, warships, etc)
	 * MISSILE - missiles. Correspond directly to the <EquipType> constants of
	 *           the same name.
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */
	_create_constant_table_nonconsecutive(l, "ShipTypeTag", ENUM_ShipTypeTag);

	/*
	 * Constants: ShipTypeThruster
	 *
	 * Thruster types. Used by <ShipType.GetLinearThrust>. The name
	 * corresponds to the direction the ship moves when the thruster is fired.
	 *
	 * REVERSE - front (fore) thruster
	 * FORWARD - main/rear (aft) thruster
	 * UP - bottom/underbelly (ventral) thruster
	 * DOWN - top/back (dorsal) thruster
	 * LEFT - right-side (starboard) thruster
	 * RIGHT - left-side (port) thruster
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */
	_create_constant_table_nonconsecutive(l, "ShipTypeThruster", ENUM_ShipTypeThruster);


	/*
	 * Constants: ShipJumpStatus
	 *
	 * Reasons that that a hyperspace jump might succeed or fail. Returned by
	 * <Ship.HyperspaceTo>, <Ship.CheckHyperspaceTo> and <Ship.GetHyperspaceDetails>.
	 *
	 * OK - jump successful
	 * CURRENT_SYSTEM - ship is already in the target system
	 * NO_DRIVE - ship has no drive
	 * DRIVE_ACTIVE - ship is already in hyperspace
	 * OUT_OF_RANGE - target system is out of range
	 * INSUFFICIENT_FUEL - target system is in range but the ship doesn't have
	 *                     enough fuel
	 * SAFETY_LOCKOUT - drive locked out for safety reasons
	 *                  (currently this happens if landed, docked or docking)
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */
	_create_constant_table_nonconsecutive(l, "ShipJumpStatus", ENUM_ShipJumpStatus);

	/*
	 * Constants: ShipAlertStatus
	 *
	 * Current alert status. Based on proximity and actions of nearby ships.
	 *
	 * NONE - no alert. All is well (green)
	 * SHIP_NEARBY - ship within 100km (yellow)
	 * SHIP_FIRING - ship within 100km is firing lasers (though not
	 * necessarily at us) (red)
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "ShipAlertStatus", ENUM_ShipAlertStatus);

	/*
	 * Constants: ShipFuelStatus
	 *
	 * Current fuel status.
	 *
	 * OK - more than 5% fuel remaining
	 * WARNING - less than 5% fuel remaining
	 * EMPTY - no fuel remaining
	 *
	 * Availability:
	 *
	 *   alpha 20
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "ShipFuelStatus", ENUM_ShipFuelStatus);

	/*
	 * Constants: ShipFlightState
	 *
	 * Ship flight state (used by LMR)
	 *
	 * FLYING     - open flight (includes autopilot)
	 * DOCKING    - in docking animation
	 * DOCKED     - docked with station
	 * LANDED     - rough landed (not docked)
	 * HYPERSPACE - in hyperspace
	 *
	 * Availability:
	 *
	 *   alpha 16
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "ShipFlightState", ENUM_ShipFlightState);

	/*
	 * Constants: ShipAIError
	 *
	 * AI command error/result code passed to Event.onAICompleted
	 *
	 * NONE             - AI completed successfully
	 * GRAV_TOO_HIGH    - AI can not compensate for gravity
	 * REFUSED_PERM     - AI was refused docking permission
	 * ORBIT_IMPOSSIBLE - AI was asked to enter an impossible orbit (orbit is
	 *                    outside target's frame)
	 *
	 * Availability:
	 *
	 *   alpha 17
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "ShipAIError", ENUM_ShipAIError);

	/*
	 * Constants: ShipAnimation
	 *
	 * Animation code used by LMR. Pass one of these constants to
	 * get_animation_stage() or get_animation_position() in a model script.
	 *
	 * WHEEL_STATE  - animation state unused; position gives position of undercarriage
	 *
	 * Availability:
	 *
	 *   alpha 16
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "ShipAnimation", ENUM_ShipAnimation);

	/*
	 * Constants: SpaceStationAnimation
	 *
	 * Animation code used by LMR. Pass one of these constants to
	 * get_animation_stage() or get_animation_position() in a model script.
	 *
	 * WHEEL_STATE  - animation state unused; position gives position of undercarriage
	 *
	 * Availability:
	 *
	 *   alpha 16
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "SpaceStationAnimation", ENUM_SpaceStationAnimation);

    /*
     * Constants: MissionStatus
     *
     * Status of a mission.
     *
     * ACTIVE - mission in progress
     * COMPLETED - mission completed
     * FAILED - mission failed
     *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */
	_create_constant_table_nonconsecutive(l, "MissionStatus", ENUM_MissionStatus);

	/*
	 * Constants: FileSystemRoot
	 *
	 * Specifier of filesystem base.
	 *
	 * USER - directory containing Pioneer's config, savefiles, mods and other
	 * user-specific data
	 * DATA - directory containing Pioneer's data files
	 *
	 * Availability:
	 *
	 *   alpha 25
	 *
	 * Status:
	 *
	 *   experimental
	 */
	_create_constant_table_nonconsecutive(l, "FileSystemRoot", ENUM_FileSystemRoot);

	// XXX document these
	_create_constant_table_nonconsecutive(l, "UIAlignDirection", ENUM_UIAlignDirection);
	_create_constant_table_nonconsecutive(l, "UIMarginDirection", ENUM_UIMarginDirection);
	_create_constant_table_nonconsecutive(l, "UIFont", ENUM_UIFont);
	_create_constant_table_nonconsecutive(l, "UISizeControl", ENUM_UISizeControl);
	_create_constant_table_nonconsecutive(l, "UIEventType", ENUM_UIEventType);
	_create_constant_table_nonconsecutive(l, "UIGradientDirection", ENUM_UIGradientDirection);
	_create_constant_table_nonconsecutive(l, "UIExpandDirection", ENUM_UIExpandDirection);
	_create_constant_table_nonconsecutive(l, "UIKeyboardAction", ENUM_UIKeyboardAction);
	_create_constant_table_nonconsecutive(l, "UIMouseButtonAction", ENUM_UIMouseButtonAction);
	_create_constant_table_nonconsecutive(l, "UIMouseButtonType", ENUM_UIMouseButtonType);
	_create_constant_table_nonconsecutive(l, "UIMouseWheelDirection", ENUM_UIMouseWheelDirection);

	_create_constant_table_nonconsecutive(l, "GameUIFaceFlags", ENUM_GameUIFaceFlags);


	LUA_DEBUG_END(l, 0);
}
Esempio n. 6
0
void LuaEngine::Register()
{
	lua_State *l = Lua::manager->GetLuaState();

	LUA_DEBUG_START(l);

	static const luaL_Reg l_methods[] = {
		{ "Quit", l_engine_quit },

		{ "GetVideoModeList", l_engine_get_video_mode_list },
		{ "GetVideoResolution", l_engine_get_video_resolution },
		{ "SetVideoResolution", l_engine_set_video_resolution },
		{ "GetFullscreen", l_engine_get_fullscreen },
		{ "SetFullscreen", l_engine_set_fullscreen },
		{ "GetVSyncEnabled", l_engine_get_vsync_enabled },
		{ "SetVSyncEnabled", l_engine_set_vsync_enabled },
		{ "GetTextureCompressionEnabled", l_engine_get_texture_compression_enabled },
		{ "SetTextureCompressionEnabled", l_engine_set_texture_compression_enabled },
		{ "GetMultisampling", l_engine_get_multisampling },
		{ "SetMultisampling", l_engine_set_multisampling },

		{ "GetPlanetDetailLevel", l_engine_get_planet_detail_level },
		{ "SetPlanetDetailLevel", l_engine_set_planet_detail_level },
		{ "GetCityDetailLevel", l_engine_get_city_detail_level },
		{ "SetCityDetailLevel", l_engine_set_city_detail_level },
		{ "GetFractalDetailLevel", l_engine_get_fractal_detail_level },
		{ "SetFractalDetailLevel", l_engine_set_fractal_detail_level },
		{ "GetPlanetFractalColourEnabled", l_engine_get_planet_fractal_colour_enabled },
		{ "SetPlanetFractalColourEnabled", l_engine_set_planet_fractal_colour_enabled },

		{ "GetDisplayNavTunnels", l_engine_get_display_nav_tunnels },
		{ "SetDisplayNavTunnels", l_engine_set_display_nav_tunnels },

		{ "GetDisplaySpeedLines", l_engine_get_display_speed_lines },
		{ "SetDisplaySpeedLines", l_engine_set_display_speed_lines },

		{ "GetCockpitEnabled", l_engine_get_cockpit_enabled },
		{ "SetCockpitEnabled", l_engine_set_cockpit_enabled },

		{ "GetDisplayHudTrails", l_engine_get_display_hud_trails },
		{ "SetDisplayHudTrails", l_engine_set_display_hud_trails },

		{ "GetCompactScanner", l_engine_get_compact_scanner },
		{ "SetCompactScanner", l_engine_set_compact_scanner },

		{ "GetConfirmQuit", l_engine_get_confirm_quit },
		{ "SetConfirmQuit", l_engine_set_confirm_quit },

		{ "GetMasterMuted", l_engine_get_master_muted },
		{ "SetMasterMuted", l_engine_set_master_muted },
		{ "GetMasterVolume", l_engine_get_master_volume },
		{ "SetMasterVolume", l_engine_set_master_volume },
		{ "GetEffectsMuted", l_engine_get_effects_muted },
		{ "SetEffectsMuted", l_engine_set_effects_muted },
		{ "GetEffectsVolume", l_engine_get_effects_volume },
		{ "SetEffectsVolume", l_engine_set_effects_volume },
		{ "GetMusicMuted", l_engine_get_music_muted },
		{ "SetMusicMuted", l_engine_set_music_muted },
		{ "GetMusicVolume", l_engine_get_music_volume },
		{ "SetMusicVolume", l_engine_set_music_volume },

		{ "GetKeyBindings", l_engine_get_key_bindings },
		{ "SetKeyBinding", l_engine_set_key_binding },
		{ "GetMouseYInverted", l_engine_get_mouse_y_inverted },
		{ "SetMouseYInverted", l_engine_set_mouse_y_inverted },
		{ "GetJoystickEnabled", l_engine_get_joystick_enabled },
		{ "SetJoystickEnabled", l_engine_set_joystick_enabled },

		{ "GetModel", l_engine_get_model },

		{ 0, 0 }
	};

	static const luaL_Reg l_attrs[] = {
		{ "rand",    l_engine_attr_rand    },
		{ "ticks",   l_engine_attr_ticks   },
		{ "ui",      l_engine_attr_ui      },
		{ "version", l_engine_attr_version },
		{ 0, 0 }
	};

	lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports");
	LuaObjectBase::CreateObject(l_methods, l_attrs, 0);
	lua_setfield(l, -2, "Engine");
	lua_pop(l, 1);

	LUA_DEBUG_END(l, 0);
}
Esempio n. 7
0
/*
 * Method: GetNearbySystems
 *
 * Get a list of nearby <StarSystems> that match some criteria
 *
 * > systems = system:GetNearbySystems(range, filter)
 *
 * Parameters:
 *
 *   range - distance from this system to search, in light years
 *
 *   filter - an optional function. If specified the function will be called
 *            once for each candidate system with the <StarSystem> object
 *            passed as the only parameter. If the filter function returns
 *            true then the system will be included in the array returned by
 *            <GetNearbySystems>, otherwise it will be omitted. If no filter
 *            function is specified then all systems in range are returned.
 *
 * Return:
 *
 *  systems - an array of systems in range that matched the filter
 *
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   experimental
 */
static int l_starsystem_get_nearby_systems(lua_State *l)
{
	LUA_DEBUG_START(l);

	StarSystem *s = LuaStarSystem::CheckFromLua(1);
	double dist_ly = luaL_checknumber(l, 2);

	bool filter = false;
	if (lua_gettop(l) >= 3) {
		luaL_checktype(l, 3, LUA_TFUNCTION); // any type of function
		filter = true;
	}

	lua_newtable(l);

	SystemPath here = s->GetPath();

	int here_x = here.sectorX;
	int here_y = here.sectorY;
	int here_z = here.sectorZ;
	Uint32 here_idx = here.systemIndex;
	Sector here_sec(here_x, here_y, here_z);

	int diff_sec = int(ceil(dist_ly/Sector::SIZE));

	for (int x = here_x-diff_sec; x <= here_x+diff_sec; x++) {
		for (int y = here_y-diff_sec; y <= here_y+diff_sec; y++) {
			for (int z = here_z-diff_sec; z <= here_z+diff_sec; z++) {
				Sector sec(x, y, z);

				for (unsigned int idx = 0; idx < sec.m_systems.size(); idx++) {
					if (x == here_x && y == here_y && z == here_z && idx == here_idx)
						continue;

					if (Sector::DistanceBetween(&here_sec, here_idx, &sec, idx) > dist_ly)
						continue;

					RefCountedPtr<StarSystem> sys = StarSystem::GetCached(SystemPath(x, y, z, idx));
					if (filter) {
						lua_pushvalue(l, 3);
						LuaStarSystem::PushToLua(sys.Get());
						lua_call(l, 1, 1);
						if (!lua_toboolean(l, -1)) {
							lua_pop(l, 1);
							continue;
						}
						lua_pop(l, 1);
					}

					lua_pushinteger(l, lua_rawlen(l, -1)+1);
					LuaStarSystem::PushToLua(sys.Get());
					lua_rawset(l, -3);
				}
			}
		}
	}

	LUA_DEBUG_END(l, 1);

	return 1;
}
Esempio n. 8
0
const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
{
	LUA_DEBUG_START(l);

	// tables are also unpickled recursively, so we can run out of Lua stack space if we're not careful
	// start by ensuring we have enough (this grows the stack if necessary)
	// (20 is somewhat arbitrary)
	if (!lua_checkstack(l, 20))
		luaL_error(l, "The Lua stack couldn't be extended (not enough memory?)");

	char type = *pos++;

	switch (type) {

		case 'f': {
			char *end;
			double f = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			lua_pushnumber(l, f);
			pos = end+1; // skip newline
			break;
		}

		case 'b': {
			if (*pos != '0' && *pos != '1') throw SavedGameCorruptException();
			bool b = (*pos == '0') ? false : true;
			lua_pushboolean(l, b);
			pos++;
			break;
		}

		case 's': {
			char *end;
			int len = strtol(pos, const_cast<char**>(&end), 0);
			if (pos == end) throw SavedGameCorruptException();
			end++; // skip newline
			lua_pushlstring(l, end, len);
			pos = end + len;
			break;
		}

		case 't': {
			lua_newtable(l);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			pos = unpickle(l, pos);
			lua_pushvalue(l, -3);
			lua_rawset(l, -3);
			lua_pop(l, 1);

			while (*pos != 'n') {
				pos = unpickle(l, pos);
				pos = unpickle(l, pos);
				lua_rawset(l, -3);
			}
			pos++;

			break;
		}

		case 'r': {
			pos = unpickle(l, pos);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			lua_pushvalue(l, -2);
			lua_rawget(l, -2);

			if (lua_isnil(l, -1))
				throw SavedGameCorruptException();

			lua_insert(l, -3);
			lua_pop(l, 2);

			break;
		}

		case 'u': {
			const char *end;
			if (!LuaObjectBase::Deserialize(pos, &end))
				throw SavedGameCorruptException();
			pos = end;
			break;
		}

		case 'o': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			const char *cl = pos;

			// unpickle the object, and insert it beneath the method table value
			pos = unpickle(l, end);

			// If it is a reference, don't run the unserializer. It has either
			// already been run, or the data is still building (cyclic
			// references will do that to you.)
			if (*end != 'r') {
				// get PiSerializerClasses[typename]
				lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses");
				lua_pushlstring(l, cl, len);
				lua_gettable(l, -2);
				lua_remove(l, -2);

				if (lua_isnil(l, -1)) {
					lua_pop(l, 2);
					break;
				}

				lua_getfield(l, -1, "Unserialize");
				if (lua_isnil(l, -1)) {
					lua_pushlstring(l, cl, len);
					luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1));
				}

				lua_insert(l, -3);
				lua_pop(l, 1);

				pi_lua_protected_call(l, 1, 1);
			}

			break;
		}

		default:
			throw SavedGameCorruptException();
	}

	LUA_DEBUG_END(l, 1);

	return pos;
}
Esempio n. 9
0
void LuaSerializer::pickle(lua_State *l, int to_serialize, std::string &out, std::string key)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	// tables are pickled recursively, so we can run out of Lua stack space if we're not careful
	// start by ensuring we have enough (this grows the stack if necessary)
	// (20 is somewhat arbitrary)
	if (!lua_checkstack(l, 20))
		luaL_error(l, "The Lua stack couldn't be extended (out of memory?)");

	to_serialize = lua_absindex(l, to_serialize);
	int idx = to_serialize;

	if (lua_getmetatable(l, idx)) {
		lua_getfield(l, -1, "class");
		if (lua_isnil(l, -1))
			lua_pop(l, 2);

		else {
			const char *cl = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "o%s\n", cl);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses");

			lua_getfield(l, -1, cl);
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_getfield(l, -1, "Serialize");
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_pushvalue(l, idx);
			pi_lua_protected_call(l, 1, 1);

			idx = lua_gettop(l);

			if (lua_isnil(l, idx)) {
				lua_pop(l, 5);
				LUA_DEBUG_END(l, 0);
				return;
			}

			out += buf;
		}
	}

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			size_t len;
			const char *str = lua_tolstring(l, -1, &len);
			snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", len);
			out += buf;
			out.append(str, len);
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			lua_pushinteger(l, lua_Integer(lua_topointer(l, to_serialize)));         // ptr

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");    // ptr reftable
			lua_pushvalue(l, -2);                                           // ptr reftable ptr
			lua_rawget(l, -2);                                              // ptr reftable ???

			if (!lua_isnil(l, -1)) {
				out += "r";
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]
			}

			else {
				out += "t";

				lua_pushvalue(l, -3);                                       // ptr reftable nil ptr
				lua_pushvalue(l, to_serialize);                                      // ptr reftable nil ptr table
				lua_rawset(l, -4);                                          // ptr reftable nil
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]

				lua_pushvalue(l, idx);
				lua_pushnil(l);
				while (lua_next(l, -2)) {

					lua_pushvalue(l, -2);
					const char *k = lua_tostring(l, -1);
					std::string new_key = key + "." + (k? std::string(k) : "<" + std::string(lua_typename(l, lua_type(l, -1))) + ">");
					lua_pop(l, 1);

					// Copy the values to pickle, as they might be mutated by the pickling process.
					pickle(l, -2, out, new_key);
					pickle(l, -1, out, new_key);
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
				out += "n";
			}

			break;
		}

		case LUA_TUSERDATA: {
			out += "u";

			LuaObjectBase *lo = static_cast<LuaObjectBase*>(lua_touserdata(l, idx));
			void *o = lo->GetObject();
			if (!o)
				Error("Lua serializer '%s' tried to serialize an invalid '%s' object", key.c_str(), lo->GetType());

			out += lo->Serialize();
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key.c_str(), lua_typename(l, lua_type(l, idx)));
			break;
	}

	if (idx != lua_absindex(l, to_serialize)) // It means we called a transformation function on the data, so we clean it up.
		lua_pop(l, 5);

	LUA_DEBUG_END(l, 0);
}
Esempio n. 10
0
int _define_ship(lua_State *L, ShipType::Tag tag, std::vector<ShipType::Id> *list)
{
	if (s_currentShipFile.empty())
		return luaL_error(L, "ship file contains multiple ship definitions");

	ShipType s;
	s.tag = tag;
	s.id = s_currentShipFile;

	LUA_DEBUG_START(L);
	LuaTable t(L, -1);

	s.name = t.Get("name", "");
	s.modelName = t.Get("model", "");
	s.linThrust[ShipType::THRUSTER_REVERSE] = t.Get("reverse_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_FORWARD] = t.Get("forward_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_UP] = t.Get("up_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_DOWN] = t.Get("down_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_LEFT] = t.Get("left_thrust", 0.0f);
	s.linThrust[ShipType::THRUSTER_RIGHT] = t.Get("right_thrust", 0.0f);
	s.angThrust = t.Get("angular_thrust", 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;

	lua_pushstring(L, "camera_offset");
	lua_gettable(L, -2);
	if (!lua_isnil(L, -1))
		fprintf(stderr, "ship definition for '%s' has deprecated 'camera_offset' field\n", s.id.c_str());
	lua_pop(L, 1);
	s.cameraOffset = t.Get("camera_offset", vector3d(0.0));

	for (int i=0; i<Equip::SLOT_MAX; i++) s.equipSlotCapacity[i] = 0;
	s.equipSlotCapacity[Equip::SLOT_CARGO] = t.Get("max_cargo", 0);
	s.equipSlotCapacity[Equip::SLOT_ENGINE] = t.Get("max_engine", 1);
	s.equipSlotCapacity[Equip::SLOT_LASER] = t.Get("max_laser", 1);
	s.equipSlotCapacity[Equip::SLOT_MISSILE] = t.Get("max_missile", 0);
	s.equipSlotCapacity[Equip::SLOT_ECM] = t.Get("max_ecm", 1);
	s.equipSlotCapacity[Equip::SLOT_SCANNER] = t.Get("max_scanner", 1);
	s.equipSlotCapacity[Equip::SLOT_RADARMAPPER] = t.Get("max_radarmapper", 1);
	s.equipSlotCapacity[Equip::SLOT_HYPERCLOUD] = t.Get("max_hypercloud", 1);
	s.equipSlotCapacity[Equip::SLOT_HULLAUTOREPAIR] = t.Get("max_hullautorepair", 1);
	s.equipSlotCapacity[Equip::SLOT_ENERGYBOOSTER] = t.Get("max_energybooster", 1);
	s.equipSlotCapacity[Equip::SLOT_ATMOSHIELD] = t.Get("max_atmoshield", 1);
	s.equipSlotCapacity[Equip::SLOT_CABIN] = t.Get("max_cabin", 50);
	s.equipSlotCapacity[Equip::SLOT_SHIELD] = t.Get("max_shield", 9999);
	s.equipSlotCapacity[Equip::SLOT_FUELSCOOP] = t.Get("max_fuelscoop", 1);
	s.equipSlotCapacity[Equip::SLOT_CARGOSCOOP] = t.Get("max_cargoscoop", 1);
	s.equipSlotCapacity[Equip::SLOT_LASERCOOLER] = t.Get("max_lasercooler", 1);
	s.equipSlotCapacity[Equip::SLOT_CARGOLIFESUPPORT] = t.Get("max_cargolifesupport", 1);
	s.equipSlotCapacity[Equip::SLOT_AUTOPILOT] = t.Get("max_autopilot", 1);

	s.capacity = t.Get("capacity", 0);
	s.hullMass = t.Get("hull_mass", 100);
	s.fuelTankMass = t.Get("fuel_tank_mass", 5);

	// fuel_use_rate can be given in two ways
	float thruster_fuel_use = 0;
	s.effectiveExhaustVelocity = t.Get("effective_exhaust_velocity", -1.0f);
	thruster_fuel_use = t.Get("thruster_fuel_use", -1.0f);
	if(s.effectiveExhaustVelocity < 0 && thruster_fuel_use < 0) {
		// default value of v_c is used
		s.effectiveExhaustVelocity = 55000000;
	} else if(s.effectiveExhaustVelocity < 0 && thruster_fuel_use >= 0) {
		// v_c undefined and thruster fuel use defined -- use it!
		s.effectiveExhaustVelocity = GetEffectiveExhaustVelocity(s.fuelTankMass, thruster_fuel_use, s.linThrust[ShipType::THRUSTER_FORWARD]);
	} else {
		if(thruster_fuel_use >= 0)
			printf("Warning: Both thruster_fuel_use and effective_exhaust_velocity defined for %s, using effective_exhaust_velocity.\n", s.modelName.c_str());
	}

	s.baseprice = t.Get("price", 0);
	s.baseprice *= 100; // in hundredths of credits

	s.minCrew = t.Get("min_crew", 1);
	s.maxCrew = t.Get("max_crew", 1);

	s.equipSlotCapacity[Equip::SLOT_ENGINE] = Clamp(s.equipSlotCapacity[Equip::SLOT_ENGINE], 0, 1);

	{
		int hyperclass;
		hyperclass = t.Get("hyperdrive_class", 1);
		if (!hyperclass) {
			s.hyperdrive = Equip::NONE;
		} else {
			s.hyperdrive = Equip::Type(Equip::DRIVE_CLASS1+hyperclass-1);
		}
	}

	for (int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
		s.gunMount[i].pos = vector3f(0,0,0);
		s.gunMount[i].dir = vector3f(0,0,1);
		s.gunMount[i].sep = 5;
		s.gunMount[i].orient = ShipType::DUAL_LASERS_HORIZONTAL;
	}

	lua_pushstring(L, "gun_mounts");
	lua_gettable(L, -2);
	if (lua_istable(L, -1)) {
		fprintf(stderr, "ship definition for '%s' has deprecated 'gun_mounts' field\n", s.id.c_str());
		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.modelName.empty())
		return luaL_error(L, "Missing model name in ship");

	if (s.minCrew < 1 || s.maxCrew < 1 || s.minCrew > s.maxCrew)
		return luaL_error(L, "Invalid values for min_crew and max_crew");

	const std::string& id = s_currentShipFile;
	typedef std::map<ShipType::Id, 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;
}
Esempio n. 11
0
void pi_lua_dofile_recursive(lua_State *l, const std::string &basepath)
{
	DIR *dir;
	struct dirent *entry;
	std::string path;
	struct stat info;
	// putting directory contents into sorted order so order of
	// model definition is consistent
	std::set<std::string> entries;

	LUA_DEBUG_START(l);

	// XXX CurrentDirectory stuff has to go
	lua_getglobal(l, "CurrentDirectory");
	std::string save_dir = luaL_checkstring(l, -1);
	lua_pop(l, 1);

	lua_pushstring(l, basepath.c_str());
	lua_setglobal(l, "CurrentDirectory");

	if ((dir = opendir(basepath.c_str())) == NULL) {
		fprintf(stderr, "opendir: couldn't open directory '%s': %s\n", basepath.c_str(), strerror(errno));
		return;
	}

	while ((entry = readdir(dir)) != NULL) {
		if (entry->d_name[0] != '.') {
			entries.insert(entry->d_name);
		}
	}
	closedir(dir);

	for (std::set<std::string>::iterator i = entries.begin(); i!=entries.end(); ++i) {
		const std::string &name = *i;
		path = basepath + "/" + name;

		if (stat(path.c_str(), &info) != 0) {
			fprintf(stderr, "stat: couldn't get info for '%s': %s\n", path.c_str(), strerror(errno));
			continue;
		}

		if (S_ISDIR(info.st_mode)) {
			pi_lua_dofile_recursive(l, path.c_str());
			continue;
		}

		if ( name.size() >= 4 && name.find(".lua") == name.size() - 4 ) {
			// XXX panic stuff can be removed once the global lua is used everywhere
			lua_pushcfunction(l, pi_lua_panic);
			if (luaL_loadfile(l, path.c_str())) {
				pi_lua_panic(l);
			} else {
				lua_pcall(l, 0, 0, -2);
			}
			lua_pop(l, 1);
		}
	}

	lua_pushstring(l, save_dir.c_str());
	lua_setglobal(l, "CurrentDirectory");

	LUA_DEBUG_END(l, 0);
}
Esempio n. 12
0
/*
 * Function: SpawnShipLandedNear
 *
 * Create a ship and place it on the surface near the given <Body>.
 *
 * > ship = Space.SpawnShipLandedNear(type, body, min, max)
 *
 * Parameters:
 *
 *   type - the name of the ship
 *
 *   body - the <Body> near which the ship should be spawned. It must be on the ground or close to it,
 *          i.e. it must be in the rotating frame of the planetary body.
 *
 *   min - minimum distance from the surface point below the body to place the ship, in Km
 *
 *   max - maximum distance to place the ship
 *
 * Return:
 *
 *   ship - a <Ship> object for the new ship
 *
 * Example:
 *
 * > -- spawn a ship 10km from the player
 * > local ship = Ship.SpawnShipLandedNear("viper_police", Game.player, 10, 10)
 *
 * Availability:
 *
 *   July 2013
 *
 * Status:
 *
 *   experimental
 */
static int l_space_spawn_ship_landed_near(lua_State *l)
{
	if (!Pi::game)
		luaL_error(l, "Game is not started");

	LUA_DEBUG_START(l);

	const char *type = luaL_checkstring(l, 1);
	if (! ShipType::Get(type))
		luaL_error(l, "Unknown ship type '%s'", type);

	Body *nearbody = LuaObject<Body>::CheckFromLua(2);
	const float min_dist = luaL_checknumber(l, 3);
	const float max_dist = luaL_checknumber(l, 4);
	if (min_dist > max_dist)
		luaL_error(l, "min_dist must not be larger than max_dist");

	Ship *ship = new Ship(type);
	assert(ship);

	// XXX protect against spawning inside the body
	Frame * newframe = nearbody->GetFrame()->GetRotFrame();
	if (!newframe->IsRotFrame())
		luaL_error(l, "Body must be in rotating frame");
	SystemBody *sbody = newframe->GetSystemBody();
	if (sbody->GetSuperType() != SystemBody::SUPERTYPE_ROCKY_PLANET)
		luaL_error(l, "Body is not on a rocky planet");
	if (max_dist > sbody->GetRadius())
		luaL_error(l, "max_dist too large for planet radius");
	// We assume that max_dist is much smaller than the planet radius, i.e. that our area is reasonably flat
	// So, we
	const vector3d up = nearbody->GetPosition().Normalized();
	vector3d x;
	vector3d y;
	// Calculate a orthonormal basis for a horizontal plane. For numerical reasons we do that determining the smallest
	// coordinate and take the cross product with (1,0,0), (0,1,0) or (0,0,1) respectively to calculate the first vector.
	// The second vector is just the cross product of the up-vector and out first vector.
	if (up.x <= up.y && up.x <= up.z) {
		x = vector3d(0.0, up.z, -up.y).Normalized();
		y = vector3d(-up.y*up.y - up.z*up.z, up.x*up.y, up.x*up.z).Normalized();
	} else if (up.y <= up.x && up.y <= up.z) {
		x = vector3d(-up.z, 0.0, up.x).Normalized();
		y = vector3d(up.x*up.y, -up.x*up.x - up.z*up.z, up.y*up.z).Normalized();
	} else {
		x = vector3d(up.y, -up.x, 0.0).Normalized();
		y = vector3d(up.x*up.z, up.y*up.z, -up.x*up.x - up.y*up.y).Normalized();
	}
	Planet *planet = static_cast<Planet*>(newframe->GetBody());
	const double radius = planet->GetSystemBody()->GetRadius();
	const vector3d planar = MathUtil::RandomPointInCircle(min_dist * 1000.0, max_dist * 1000.0);
	vector3d pos = (radius * up + x * planar.x + y * planar.y).Normalized();
	float latitude = atan2(pos.y, sqrt(pos.x*pos.x + pos.z * pos.z));
	float longitude = atan2(pos.x, pos.z);

	Pi::game->GetSpace()->AddBody(ship);
	ship->SetLandedOn(planet, latitude, longitude);

	LuaObject<Ship>::PushToLua(ship);

	LUA_DEBUG_END(l, 1);

	return 1;
}
Esempio n. 13
0
int ShipType::define_ship(lua_State *L, const char *model_name)
{
	ShipType s;
	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[THRUSTER_REVERSE], 0.0f);
	_get_float_attrib(L, "forward_thrust", s.linThrust[THRUSTER_FORWARD], 0.0f);
	_get_float_attrib(L, "up_thrust", s.linThrust[THRUSTER_UP], 0.0f);
	_get_float_attrib(L, "down_thrust", s.linThrust[THRUSTER_DOWN], 0.0f);
	_get_float_attrib(L, "left_thrust", s.linThrust[THRUSTER_LEFT], 0.0f);
	_get_float_attrib(L, "right_thrust", s.linThrust[THRUSTER_RIGHT], 0.0f);
	_get_float_attrib(L, "angular_thrust", s.angThrust, 0.0f);

	for (int i=0; i<(int)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)((int)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)

	types[s.name] = s;
	return 0;
}
Esempio n. 14
0
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			const char *str = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "s%lu\n", strlen(str));
			out += buf;
			out += str;
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			out += "t";
			lua_pushvalue(l, idx);
			lua_pushnil(l);
			while (lua_next(l, -2)) {
				if (key) {
					pickle(l, -2, out, key);
					pickle(l, -1, out, key);
				}
				else {
					lua_pushvalue(l, -2);
					const char *k = lua_tostring(l, -1);
					pickle(l, -3, out, k);
					pickle(l, -2, out, k);
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
			}
			lua_pop(l, 1);
			out += "n";
			break;
		}

		case LUA_TUSERDATA: {
			out += "u";
			lid *idp = static_cast<lid*>(lua_touserdata(l, idx));
			LuaObjectBase *lo = LuaObjectBase::Lookup(*idp);
			if (!lo)
				Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp);

			// XXX object wrappers should really have Serialize/Unserialize
			// methods to deal with this
			if (lo->Isa("SystemPath")) {
				SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object);
				snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%d\n%d\n",
					sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex);
				out += buf;
				break;
			}

			if (lo->Isa("Body")) {
				Body *b = dynamic_cast<Body*>(lo->m_object);
				snprintf(buf, sizeof(buf), "Body\n%d\n", Serializer::LookupBody(b));
				out += buf;
				break;
			}

			Error("Lua serializer '%s' tried to serialize unsupported userdata value", key);
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx)));
			break;
	}

	LUA_DEBUG_END(l, 0);
}
Esempio n. 15
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;
}
Esempio n. 16
0
const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
{
	LUA_DEBUG_START(l);

	char type = *pos++;

	switch (type) {

		case 'f': {
			char *end;
			double f = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			lua_pushnumber(l, f);
			pos = end+1; // skip newline
			break;
		}

		case 'b': {
			if (*pos != '0' && *pos != '1') throw SavedGameCorruptException();
			bool b = (*pos == '0') ? false : true;
			lua_pushboolean(l, b);
			pos++;
			break;
		}

		case 's': {
			char *end;
			int len = strtol(pos, const_cast<char**>(&end), 0);
			if (pos == end) throw SavedGameCorruptException();
			end++; // skip newline
			lua_pushlstring(l, end, len);
			pos = end + len;
			break;
		}

		case 't': {
			lua_newtable(l);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			pos = unpickle(l, pos);
			lua_pushvalue(l, -3);
			lua_rawset(l, -3);
			lua_pop(l, 1);

			while (*pos != 'n') {
				pos = unpickle(l, pos);
				pos = unpickle(l, pos);
				lua_rawset(l, -3);
			}
			pos++;

			break;
		}

		case 'r': {
			pos = unpickle(l, pos);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			lua_pushvalue(l, -2);
			lua_rawget(l, -2);

			if (lua_isnil(l, -1))
				throw SavedGameCorruptException();

			lua_insert(l, -3);
			lua_pop(l, 2);

			break;
		}

		case 'u': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) {
				pos = end;

				Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Uint32 systemNum = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Uint32 sbodyId = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId);
				LuaSystemPath::PushToLuaGC(sbp);

				break;
			}

			if (len == 4 && strncmp(pos, "Body", 4) == 0) {
				pos = end;

				Uint32 n = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Body *body = Pi::game->GetSpace()->GetBodyByIndex(n);
				if (pos == end) throw SavedGameCorruptException();

				switch (body->GetType()) {
					case Object::BODY:
						LuaBody::PushToLua(body);
						break;
					case Object::SHIP:
						LuaShip::PushToLua(dynamic_cast<Ship*>(body));
						break;
					case Object::SPACESTATION:
						LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body));
						break;
					case Object::PLANET:
						LuaPlanet::PushToLua(dynamic_cast<Planet*>(body));
						break;
					case Object::STAR:
						LuaStar::PushToLua(dynamic_cast<Star*>(body));
						break;
					case Object::PLAYER:
						LuaPlayer::PushToLua(dynamic_cast<Player*>(body));
						break;
					default:
						throw SavedGameCorruptException();
				}

				break;
			}

			throw SavedGameCorruptException();
		}

		case 'o': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			const char *cl = pos;

			// unpickle the object, and insert it beneath the method table value
			pos = unpickle(l, end);

			// get _G[typename]
			lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
			lua_pushlstring(l, cl, len);
			lua_gettable(l, -2);
			lua_remove(l, -2);

			if (lua_isnil(l, -1)) {
				lua_pop(l, 2);
				break;
			}

			lua_getfield(l, -1, "Unserialize");
			if (lua_isnil(l, -1)) {
				lua_pushlstring(l, cl, len);
				luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1));
			}

			lua_insert(l, -3);
			lua_pop(l, 1);

			pi_lua_protected_call(l, 1, 1);

			break;
		}

		default:
			throw SavedGameCorruptException();
	}

	LUA_DEBUG_END(l, 1);

	return pos;
}
Esempio n. 17
0
static void push_bindings(lua_State *l, const KeyBindings::BindingPrototype *protos) {
	LUA_DEBUG_START(l);

	lua_newtable(l); // [-1] bindings
	lua_pushnil(l); // [-2] bindings, [-1] group (no current group)

	assert(!protos[0].function); // first entry should be a group header

	int group_idx = 1;
	int binding_idx = 1;
	for (const KeyBindings::BindingPrototype *proto = protos; proto->label; ++proto) {
		if (! proto->function) {
			// start a new named binding group

			// [-2] bindings, [-1] group
			lua_pop(l, 1);
			// [-1] bindings
			lua_newtable(l);
			lua_pushstring(l, proto->label);
			lua_setfield(l, -2, "label");
			// [-2] bindings, [-1] group
			lua_pushvalue(l, -1);
			// [-3] bindings, [-2] group, [-1] group copy
			lua_rawseti(l, -3, group_idx);
			++group_idx;

			binding_idx = 1;
		} else {
			// key or axis binding prototype

			// [-2] bindings, [-1] group
			lua_createtable(l, 0, 5);
			// [-3] bindings, [-2] group, [-1] binding

			// fields are: type ('KEY' or 'AXIS'), id ('BindIncreaseSpeed'), label ('Increase Speed'), binding ('Key13'), bindingDescription ('')
			lua_pushstring(l, (proto->kb ? "KEY" : "AXIS"));
			lua_setfield(l, -2, "type");
			lua_pushstring(l, proto->function);
			lua_setfield(l, -2, "id");
			lua_pushstring(l, proto->label);
			lua_setfield(l, -2, "label");
			if (proto->kb) {
				const KeyBindings::KeyBinding kb1 = proto->kb->binding1;
				if (kb1.Enabled()) {
					lua_pushstring(l, kb1.ToString().c_str());
					lua_setfield(l, -2, "binding1");
					lua_pushstring(l, kb1.Description().c_str());
					lua_setfield(l, -2, "bindingDescription1");
				}
				const KeyBindings::KeyBinding kb2 = proto->kb->binding2;
				if (kb2.Enabled()) {
					lua_pushstring(l, kb2.ToString().c_str());
					lua_setfield(l, -2, "binding2");
					lua_pushstring(l, kb2.Description().c_str());
					lua_setfield(l, -2, "bindingDescription2");
				}
			} else if (proto->ab) {
				const KeyBindings::AxisBinding &ab = *proto->ab;
				lua_pushstring(l, ab.ToString().c_str());
				lua_setfield(l, -2, "binding1");
				lua_pushstring(l, ab.Description().c_str());
				lua_setfield(l, -2, "bindingDescription1");
			} else {
				assert(0); // invalid prototype binding
			}

			// [-3] bindings, [-2] group, [-1] binding
			lua_rawseti(l, -2, binding_idx);
			++binding_idx;
		}

		LUA_DEBUG_CHECK(l, 2); // [-2] bindings, [-1] group
	}

	// pop the group table (which should already have been put in the bindings table)
	lua_pop(l, 1);

	LUA_DEBUG_END(l, 1);
}
Esempio n. 18
0
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	idx = lua_absindex(l, idx);

	if (lua_getmetatable(l, idx)) {
		lua_getfield(l, -1, "class");
		if (lua_isnil(l, -1))
			lua_pop(l, 2);

		else {
			const char *cl = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "o%s\n", cl);

			lua_getglobal(l, cl);
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_getfield(l, -1, "Serialize");
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_pushvalue(l, idx);
			pi_lua_protected_call(l, 1, 1);

			lua_remove(l, idx);
			lua_insert(l, idx);

			lua_pop(l, 3);

			if (lua_isnil(l, idx)) {
				LUA_DEBUG_END(l, 0);
				return;
			}

			out += buf;
		}
	}

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			const char *str = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", strlen(str));
			out += buf;
			out += str;
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			lua_pushinteger(l, lua_Integer(lua_topointer(l, idx)));         // ptr

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");    // ptr reftable
			lua_pushvalue(l, -2);                                           // ptr reftable ptr
			lua_rawget(l, -2);                                              // ptr reftable ???

			if (!lua_isnil(l, -1)) {
				out += "r";
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]
			}

			else {
				out += "t";

				lua_pushvalue(l, -3);                                       // ptr reftable nil ptr
				lua_pushvalue(l, idx);                                      // ptr reftable nil ptr table
				lua_rawset(l, -4);                                          // ptr reftable nil
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]

				lua_pushvalue(l, idx);
				lua_pushnil(l);
				while (lua_next(l, -2)) {
					if (key) {
						pickle(l, -2, out, key);
						pickle(l, -1, out, key);
					}
					else {
						lua_pushvalue(l, -2);
						const char *k = lua_tostring(l, -1);
						pickle(l, -3, out, k);
						pickle(l, -2, out, k);
						lua_pop(l, 1);
					}
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
				out += "n";
			}

			break;
		}

		case LUA_TUSERDATA: {
			out += "u";
			lid *idp = static_cast<lid*>(lua_touserdata(l, idx));
			LuaObjectBase *lo = LuaObjectBase::Lookup(*idp);
			if (!lo)
				Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp);

			// XXX object wrappers should really have Serialize/Unserialize
			// methods to deal with this
			if (lo->Isa("SystemPath")) {
				SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object);
				snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%u\n%u\n",
					sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex);
				out += buf;
				break;
			}

			if (lo->Isa("Body")) {
				Body *b = dynamic_cast<Body*>(lo->m_object);
				snprintf(buf, sizeof(buf), "Body\n%u\n", Pi::game->GetSpace()->GetIndexForBody(b));
				out += buf;
				break;
			}

			Error("Lua serializer '%s' tried to serialize unsupported userdata value", key);
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx)));
			break;
	}

	LUA_DEBUG_END(l, 0);
}
Esempio n. 19
0
void LuaConstants::Register(lua_State *l)
{
	LUA_DEBUG_START(l);

	for (const EnumTable *table = ENUM_TABLES_PUBLIC; table->name; table++)
		_create_constant_table(l, table->name, table->first);

	/*
	 * Constants: BodyType
	 *
	 * Describe different kinds of system bodies such as stars, planets and
	 * space stations.
	 *
	 * GRAVPOINT - a pseudo-type for a gravitational point that multiple
	 *             bodies may orbit
	 * BROWN_DWARF - brown dwarf sub-stellar object
	 * STAR_M - type 'M' red star
	 * STAR_K - type 'K' orange star
	 * STAR_G - type 'G' yellow star
	 * STAR_F - type 'F' white star
	 * STAR_A - type 'A' hot white star
	 * STAR_B - type 'B' blue star
	 * STAR_O - type 'O' hot blue star
	 * WHITE_DWARF - white dwarf stellar remnant
	 * STAR_M_GIANT - red giant star
	 * STAR_K_GIANT - orange giant star
	 * STAR_G_GIANT - yellow giant star
	 * STAR_F_GIANT - white giant star
	 * STAR_A_GIANT - hot white giant star
	 * STAR_B_GIANT - blue giant star
	 * STAR_O_GIANT - hot blue giant star
	 * STAR_M_SUPER_GIANT - red supergiant star
	 * STAR_K_SUPER_GIANT - orange supergiant star
	 * STAR_G_SUPER_GIANT - yellow supergiant star
	 * STAR_F_SUPER_GIANT - white supergiant star
	 * STAR_A_SUPER_GIANT - hot white supergiant star
	 * STAR_B_SUPER_GIANT - blue supergiant star
	 * STAR_O_SUPER_GIANT - hot blue supergiant star
	 * STAR_M_HYPER_GIANT - red hypergiant star
	 * STAR_K_HYPER_GIANT - orange hypergiant star
	 * STAR_G_HYPER_GIANT - yellow hypergiant star
	 * STAR_F_HYPER_GIANT - white hypergiant star
	 * STAR_A_HYPER_GIANT - hot white hypergiant star
	 * STAR_B_HYPER_GIANT - blue hypergiant star
	 * STAR_O_HYPER_GIANT - hot blue hypergiant star
	 * STAR_M_WF - Wolf-Rayet star (unstable)
	 * STAR_B_WF - Wolf-Rayet star (risk of collapse)
	 * STAR_O_WF - Wolf-Rayet star (imminent collapse)
	 * STAR_S_BH - stellar black hole
	 * STAR_IM_BH - intermediate-mass black hole
	 * STAR_SM_BH - supermassive black hole
	 * PLANET_GAS_GIANT - gas giant
	 * PLANET_ASTEROID - asteroid
	 * PLANET_TERRESTRIAL - terrestrial planet
	 * STARPORT_ORBITAL - orbital starport (space station)
	 * STARPORT_SURFACE - surface starport
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */

	/*
	 * Constants: BodySuperType
	 *
	 * Describe general categories of system bodies.
	 *
	 * NONE - uncategorised
	 * STAR - star
	 * ROCKY_PLANET - a solid planet (terrestrial or asteroid)
	 * GAS_GIANT - gas giant
	 * STARPORT - surface or orbital starport
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */

	/*
	 * Constants: PhysicsObjectType
	 *
	 * General physical objects
	 *
	 *   BODY - .
	 *	  MODELBODY - .
	 *	  SHIP - .
	 *	  PLAYER - .
	 *	  SPACESTATION - .
	 *	  PLANET - .
	 *	  STAR - .
	 *	  CARGOBODY - .
	 *	  MISSILE - .
	 *
	 * Availability:
	 *
	 *   2014 April
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: PolitEcon
	 *
	 * Economy type
	 *
	 * NONE - .
	 * VERY_CAPITALIST - .
	 * CAPITALIST - .
	 * MIXED - .
	 * PLANNED - .
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: PolitGovType
	 *
	 * Government type
	 *
	 * NONE - .
	 * EARTHCOLONIAL - .
	 * EARTHDEMOC - .
	 * EMPIRERULE - .
	 * CISLIBDEM - .
	 * CISSOCDEM - .
	 * LIBDEM - .
	 * CORPORATE - .
	 * SOCDEM - .
	 * EARTHMILDICT - .
	 * MILDICT1 - .
	 * MILDICT2 - .
	 * EMPIREMILDICT - .
	 * COMMUNIST - .
	 * PLUTOCRATIC - .
	 * DISORDER - .
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: CommodityType
	 *
	 * Cargo/commodity types.
	 *
	 * HYDROGEN - hydrogen
	 * LIQUID_OXYGEN - liquid oxygen
	 * METAL_ORE - metal ore
	 * CARBON_ORE - carbon ore
	 * METAL_ALLOYS - metal alloys
	 * PLASTICS - plastics
	 * FRUIT_AND_VEG - fruit and vegetables
	 * ANIMAL_MEAT - animal meat
	 * LIVE_ANIMALS - live animals
	 * LIQUOR - liquor
	 * GRAIN - grain
	 * TEXTILES - textiles
	 * FERTILIZER - fertilizer
	 * WATER - water
	 * MEDICINES - medicines
	 * CONSUMER_GOODS - consumer goods
	 * COMPUTERS - computers
	 * ROBOTS - robots
	 * PRECIOUS_METALS - precious metals
	 * INDUSTRIAL_MACHINERY - industrial machinery
	 * FARM_MACHINERY - farm machinery
	 * MINING_MACHINERY - mining machinery (CARGO
	 * AIR_PROCESSORS - air processors
	 * SLAVES - slaves
	 * HAND_WEAPONS - hand weapons
	 * BATTLE_WEAPONS - battle weapons
	 * NERVE_GAS - nerve gas
	 * NARCOTICS - narcotics
	 * MILITARY_FUEL - military fuel
	 * RUBBISH - rubbish
	 * RADIOACTIVES - radioactives
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: DualLaserOrientation
	 *
	 * The orientation of dual laser mountings.
	 *
	 * HORIZONTAL - Lasers are mounted left and right
	 * VERTICAL   - Lasers are mounted top and bottom
	 *
	 * Availability:
	 *
	 *   alpha 27
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: ShipTypeTag
	 *
	 * Ship tags mark whether a ship is suitable for a particular use. Used
	 * with <ShipType.GetShipTypes> to select which set of ships to search.
	 *
	 * NONE - no tags
	 * SHIP - standard ships. These are the ones available to the player and
	 *        used for regular game functions (trade, combat, etc)
	 * STATIC_SHIP - static ships. These are not available to the player and
	 *               are used for mission specific functions (large supply
	 *               ships, warships, etc)
	 * MISSILE - missiles.
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */

	/*
	 * Constants: ShipTypeThruster
	 *
	 * Thruster types. Used by <ShipType.GetLinearThrust>. The name
	 * corresponds to the direction the ship moves when the thruster is fired.
	 *
	 * REVERSE - front (fore) thruster
	 * FORWARD - main/rear (aft) thruster
	 * UP - bottom/underbelly (ventral) thruster
	 * DOWN - top/back (dorsal) thruster
	 * LEFT - right-side (starboard) thruster
	 * RIGHT - left-side (port) thruster
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */

	/*
	 * Constants: ShipJumpStatus
	 *
	 * Reasons that that a hyperspace jump might succeed or fail. Returned by
	 * <Ship.HyperspaceTo>, <Ship.CheckHyperspaceTo> and <Ship.GetHyperspaceDetails>.
	 *
	 * OK - jump successful
	 * CURRENT_SYSTEM - ship is already in the target system
	 * NO_DRIVE - ship has no drive
	 * DRIVE_ACTIVE - ship is already in hyperspace
	 * OUT_OF_RANGE - target system is out of range
	 * INSUFFICIENT_FUEL - target system is in range but the ship doesn't have
	 *                     enough fuel
	 * SAFETY_LOCKOUT - drive locked out for safety reasons
	 *                  (currently this happens if landed, docked or docking)
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   stable
	 */

	/*
	 * Constants: ShipAlertStatus
	 *
	 * Current alert status. Based on proximity and actions of nearby ships.
	 *
	 * NONE - no alert. All is well (green)
	 * SHIP_NEARBY - ship within 100km (yellow)
	 * SHIP_FIRING - ship within 100km is firing lasers (though not
	 * necessarily at us) (red)
	 *
	 * Availability:
	 *
	 *   alpha 10
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: ShipFuelStatus
	 *
	 * Current fuel status.
	 *
	 * OK - more than 5% fuel remaining
	 * WARNING - less than 5% fuel remaining
	 * EMPTY - no fuel remaining
	 *
	 * Availability:
	 *
	 *   alpha 20
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: ShipFlightState
	 *
	 * Ship flight state
	 *
	 * FLYING     - open flight (includes autopilot)
	 * DOCKING    - in docking animation
	 * UNDOCKING  - in docking animation
	 * DOCKED     - docked with station
	 * LANDED     - rough landed (not docked)
	 * JUMPING    - just initiating hyperjump (as of February 2014)
	 * HYPERSPACE - in hyperspace
	 *
	 * Availability:
	 *
	 *   alpha 16
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: ShipAIError
	 *
	 * AI command error/result code passed to Event.onAICompleted
	 *
	 * NONE             - AI completed successfully
	 * GRAV_TOO_HIGH    - AI can not compensate for gravity
	 * REFUSED_PERM     - AI was refused docking permission
	 * ORBIT_IMPOSSIBLE - AI was asked to enter an impossible orbit (orbit is
	 *                    outside target's frame)
	 *
	 * Availability:
	 *
	 *   alpha 17
	 *
	 * Status:
	 *
	 *   experimental
	 */

	/*
	 * Constants: FileSystemRoot
	 *
	 * Specifier of filesystem base.
	 *
	 * USER - directory containing Pioneer's config, savefiles, mods and other
	 * user-specific data
	 * DATA - directory containing Pioneer's data files
	 *
	 * Availability:
	 *
	 *   alpha 25
	 *
	 * Status:
	 *
	 *   experimental
	 */

	// XXX document UI tables

	LUA_DEBUG_END(l, 0);
}
Esempio n. 20
0
static void _create_constant_table(lua_State *l, const char *ns, const EnumItem *c, bool consecutive)
{
	LUA_DEBUG_START(l);

	lua_getglobal(l, "Constants");
	if (lua_isnil(l, -1)) {
		lua_pop(l, 1);
		lua_newtable(l);

		// publish a read-only proxy wrapper
		lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
		lua_pushstring(l, "Constants");
		pi_lua_readonly_table_proxy(l, -3);
		lua_rawset(l, -3);
		lua_pop(l, 1);
	} else {
		pi_lua_readonly_table_original(l, -1);
		lua_remove(l, -2);
	}
	assert(lua_istable(l, -1));

	lua_newtable(l); // 'Constants' table, enum table
	int enum_table_idx = lua_gettop(l);

	// publish a read-only proxy to the enum table
	lua_pushstring(l, ns);
	pi_lua_readonly_table_proxy(l, enum_table_idx);
	lua_rawset(l, -4);

	lua_getfield(l, LUA_REGISTRYINDEX, "PiConstants");
	if (lua_isnil(l, -1)) {
		lua_pop(l, 1);
		lua_newtable(l);
		lua_pushstring(l, "PiConstants");
		lua_pushvalue(l, -2);
		lua_rawset(l, LUA_REGISTRYINDEX);
	}
	assert(lua_istable(l, -1));

	lua_newtable(l); // 'Constants' table, enum table, 'PiConstants' table, mapping table
	lua_pushstring(l, ns);
	lua_pushvalue(l, -2);
	lua_rawset(l, -4);

	int value = 0;
	int index = 1;
	for (; c->name; c++) {
		if (! consecutive)
			value = c->value;
		pi_lua_settable(l, c->name, value);
		pi_lua_settable(l, value, c->name);
		++value;

		lua_pushinteger(l, index);
		lua_pushstring(l, c->name);
		lua_rawset(l, enum_table_idx);
		++index;
	}

	lua_pop(l, 4);

	LUA_DEBUG_END(l, 0);
}
Esempio n. 21
0
static int l_lang_get_resource(lua_State *l)
{
	LUA_DEBUG_START(l);

	const std::string resourceName(luaL_checkstring(l, 1));
	const std::string langCode(lua_isnoneornil(l, 2) ? Lang::GetCore().GetLangCode() : lua_tostring(l, 2));

	const std::string key = resourceName + "_" + langCode;

	lua_getfield(l, LUA_REGISTRYINDEX, "LangCache");
	if (lua_isnil(l, -1)) {
		lua_pop(l, 1);
		lua_newtable(l);
		lua_pushvalue(l, -1);
		lua_setfield(l, LUA_REGISTRYINDEX, "LangCache");
	}

	// find it in the cache
	lua_getfield(l, -1, key.c_str());
	if (!lua_isnil(l, -1)) {
		lua_remove(l, -2);
		return 1;
	}
	lua_pop(l, 1);

	Lang::Resource res(resourceName, langCode);
	if (!res.Load()) {
		lua_pushnil(l);
		return 1;
	}

	lua_newtable(l);
	lua_pushstring(l, "langCode");
	lua_pushstring(l, langCode.c_str());
	lua_settable(l, -3);
	lua_pushstring(l, "resourceName");
	lua_pushstring(l, resourceName.c_str());
	lua_settable(l, -3);

	for (auto i : res.GetStrings()) {
		const std::string token(i.first);
		const std::string text(i.second.empty() ? token : i.second);
		lua_pushlstring(l, token.c_str(), token.size());
		lua_pushlstring(l, text.c_str(), text.size());
		lua_rawset(l, -3);
	}

	lua_pushstring(l, "get");
	lua_pushcfunction(l, _get);
	lua_rawset(l, -3);

	lua_newtable(l);
	lua_pushstring(l, "__index");
	lua_pushcfunction(l, _resource_index);
	lua_rawset(l, -3);
	lua_pushstring(l, "__newindex");
	lua_pushcfunction(l, _resource_newindex);
	lua_rawset(l, -3);
	lua_setmetatable(l, -2);

	// insert into cache
	lua_pushvalue(l, -1);
	lua_setfield(l, -3, key.c_str());
	lua_remove(l, -2);

	LUA_DEBUG_END(l, 1);
	return 1;
}
Esempio n. 22
0
void LuaShipDef::Register()
{
	lua_State *l = Lua::manager->GetLuaState();

	LUA_DEBUG_START(l);

	lua_newtable(l);

	for (auto iter : ShipType::types)
	{
		const ShipType &st = iter.second;
		lua_newtable(l);

		pi_lua_settable(l, "id",                iter.first.c_str());
		pi_lua_settable(l, "name",              st.name.c_str());
		pi_lua_settable(l, "shipClass",         st.shipClass.c_str());
		pi_lua_settable(l, "manufacturer",      st.manufacturer.c_str());
		pi_lua_settable(l, "modelName",         st.modelName.c_str());
		pi_lua_settable(l, "cockpitName",		st.cockpitName.c_str());
		pi_lua_settable(l, "tag",               EnumStrings::GetString("ShipTypeTag", st.tag));
		pi_lua_settable(l, "angularThrust",     st.angThrust);
		pi_lua_settable(l, "capacity",          st.capacity);
		pi_lua_settable(l, "hullMass",          st.hullMass);
		pi_lua_settable(l, "fuelTankMass",      st.fuelTankMass);
		pi_lua_settable(l, "basePrice",         st.baseprice);
		pi_lua_settable(l, "minCrew",           st.minCrew);
		pi_lua_settable(l, "maxCrew",           st.maxCrew);
		pi_lua_settable(l, "hyperdriveClass",   st.hyperdriveClass);
		pi_lua_settable(l, "effectiveExhaustVelocity", st.effectiveExhaustVelocity);
		pi_lua_settable(l, "thrusterFuelUse",   st.GetFuelUseRate());

		lua_newtable(l);
		for (int t = Thruster::THRUSTER_REVERSE; t < Thruster::THRUSTER_MAX; t++)
			pi_lua_settable(l, EnumStrings::GetString("ShipTypeThruster", t), st.linThrust[t]);
		pi_lua_readonly_table_proxy(l, -1);
		lua_setfield(l, -3, "linearThrust");
		lua_pop(l, 1);

		lua_newtable(l);
		for (auto it = st.slots.cbegin(); it != st.slots.cend(); ++it) {
			pi_lua_settable(l, it->first.c_str(), it->second);
		}
		pi_lua_readonly_table_proxy(l, -1);
		luaL_getmetafield(l, -1, "__index");
		if (!lua_getmetatable(l, -1)) {
			lua_newtable(l);
		}
		pi_lua_import(l, "EquipSet");
		luaL_getsubtable(l, -1, "default");
		lua_setfield(l, -3, "__index");
		lua_pop(l, 1);
		lua_setmetatable(l, -2);
		lua_pop(l, 1);
		lua_setfield(l, -3, "equipSlotCapacity");
		lua_pop(l, 1);

		lua_newtable(l);
		for (auto it = st.roles.cbegin(); it != st.roles.cend(); ++it) {
			pi_lua_settable(l, it->first.c_str(), it->second);
		}
		pi_lua_readonly_table_proxy(l, -1);
		lua_setfield(l, -3, "roles");
		lua_pop(l, 1);

		pi_lua_readonly_table_proxy(l, -1);
		lua_setfield(l, -3, iter.first.c_str());
		lua_pop(l, 1);
	}

	lua_getfield(l, LUA_REGISTRYINDEX, "CoreImports");
	pi_lua_readonly_table_proxy(l, -2);
	lua_setfield(l, -2, "ShipDef");
	lua_pop(l, 2);

	LUA_DEBUG_END(l, 0);
}