Beispiel #1
0
/*
 * Function: SpawnShipDocked
 *
 * Create a ship and place it inside the given <SpaceStation>.
 *
 * > ship = Space.SpawnShipDocked(type, station)
 *
 * Parameters:
 *
 *   type - the name of the ship
 *
 *   station - the <SpaceStation> to place the ship inside
 *
 * Return:
 *
 *   ship - a <Ship> object for the new ship, or nil if there was no space
 *          inside the station
 *
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   stable
 */
static int l_space_spawn_ship_docked(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);

	SpaceStation *station = LuaSpaceStation::CheckFromLua(2);

	int port = station->GetFreeDockingPort();
	if (port < 0)
		return 0;

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

	ship->SetFrame(station->GetFrame());
	Pi::game->GetSpace()->AddBody(ship);
	ship->SetDockedWith(station, port);

	LuaShip::PushToLua(ship);

	LUA_DEBUG_END(l, 1);

	return 1;
}
Beispiel #2
0
void	PlayerStatusBars :: Update (GameData& GlobalGameData)
{
	PlayerDatabase* playerDb = GlobalGameData.GetPlayerDatabase();
	player = playerDb->GetCurrentPlayer ();
	
	if (player == NULL)
	{
		PlayerName.clear();
		NumberOfStationsBeingTracked = 0;
	}
	else
	{
		PlayerName = player->GetName();
		NumberOfStationsBeingTracked = player->GetNumStations();
		ShipArchetype* ship = player->GetShip ();
		PlayerShipTracking = static_cast<float>( ship->GetHealth () );
		PlayerShipShieldTracking = static_cast<float>( ship->GetShieldLevel () );
		
		for (int i=0; i<NumberOfStationsBeingTracked; i++)
		{
			SpaceStation* station = player->GetStation(i);
			StationTracking[i] = static_cast<float>( station->GetHealth () );
			StationShieldTracking[i] = static_cast<float>( station->GetShieldLevel () );
		}
	}
}
Beispiel #3
0
Game::Game(const SystemPath &path, double time) :
	m_time(time),
	m_state(STATE_NORMAL),
	m_wantHyperspace(false),
	m_timeAccel(TIMEACCEL_1X),
	m_requestedTimeAccel(TIMEACCEL_1X),
	m_forceTimeAccel(false)
{
	Pi::FlushCaches();

	m_space.reset(new Space(this, path));
	SpaceStation *station = static_cast<SpaceStation*>(m_space->FindBodyForPath(&path));
	assert(station);

	m_player.reset(new Player("kanara"));

	m_space->AddBody(m_player.get());

	m_player->SetFrame(station->GetFrame());
	m_player->SetDockedWith(station, 0);

	Polit::Init();

	CreateViews();
}
/*
 * Method: GetEquipmentPrice
 *
 * Get the price of an equipment or cargo item traded at this station
 *
 * > price = station:GetEquipmentPrice(equip)
 *
 * Parameters:
 *
 *   equip - the <Constants.EquipType> string for the equipment or cargo item
 *
 * Returns:
 *
 *   price - the price of the equipment or cargo item
 *
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   experimental
 */
static int l_spacestation_get_equipment_price(lua_State *l)
{
	SpaceStation *s = LuaSpaceStation::GetFromLua(1);
	Equip::Type e = static_cast<Equip::Type>(LuaConstants::GetConstant(l, "EquipType", luaL_checkstring(l, 2)));
	Sint64 cost = s->GetPrice(e);
	lua_pushnumber(l, cost * 0.01);
	return 1;
}
/*
 * Method: GetGroundPosition
 *
 * Get latitude, longitude of a station on the ground or nil if this is an orbital station
 *
 * > latitude, longitude = station:GetGroundPosition()
 *
 * Returns:
 *
 *   latitude - the latitude of the station in radians
 *   longitude - the longitude of the station in radians
 *
 * Examples:
 *
 * > -- Get ground position of L.A. when starting on Earth
 * > local la = Game.player:GetDockedWith()
 * > local lat, long = la:GetGroundPosition()
 * > lat = math.rad2deg(lat)
 * > long = math.rad2deg(long)
 *
 * Availability:
 *
 *   July 2013
 *
 * Status:
 *
 *   experimental
 */
static int l_spacestation_get_ground_position(lua_State *l)
{
	SpaceStation *s = LuaObject<SpaceStation>::CheckFromLua(1);
	if (!s->IsGroundStation())
		return 0;

	vector3d pos = s->GetPosition();
	double latitude = atan2(pos.y, sqrt(pos.x*pos.x + pos.z * pos.z));
	double longitude = atan2(pos.x, pos.z);
	lua_pushnumber(l, latitude);
	lua_pushnumber(l, longitude);
	return 2;
}
/*
 * Method: AddAdvert
 *
 * Add an advertisement to the station's bulletin board
 *
 * > ref = station:AddAdvert(description, chatfunc, deletefunc)
 *
 * Parameters:
 *
 *   description - text to display in the bulletin board
 *
 *   chatfunc - function to call when the ad is activated. The function is
 *              passed three parameters: a <ChatForm> object for the ad
 *              conversation display, the ad reference returned by <AddAdvert>
 *              when the ad was created, and an integer value corresponding to
 *              the action that caused the activation. When the ad is initially
 *              selected from the bulletin board, this value is 0. Additional
 *              actions (and thus values) are defined by the script via
 *              <ChatForm.AddAction>.
 *
 *   deletefunc - optional. function to call when the ad is removed from the
 *                bulletin board. This happens when <RemoveAdvert> is called,
 *                when the ad is cleaned up after
 *                <ChatForm.RemoveAdvertOnClose> is called, and when the
 *                <SpaceStation> itself is destroyed (eg the player leaves the
 *                system).
 *
 * Return:
 *
 *   ref - an integer value for referring to the ad in the future. This value
 *         will be passed to the ad's chat function and should be passed to
 *         <RemoveAdvert> to remove the ad from the bulletin board.
 *
 * Example:
 *
 * > local ref = station:AddAdvert(
 * >     "FAST SHIP to deliver a package to the Epsilon Eridani system.",
 * >     function (ref, opt) ... end,
 * >     function (ref) ... end
 * > )
 *
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   stable
 */
static int l_spacestation_add_advert(lua_State *l)
{
	LUA_DEBUG_START(l);

	SpaceStation *s = LuaSpaceStation::GetFromLua(1);
	std::string description = luaL_checkstring(l, 2);

	if (!lua_isfunction(l, 3))
		luaL_typerror(l, 3, lua_typename(l, LUA_TFUNCTION));
	
	bool have_delete = false;
	if (lua_gettop(l) >= 4) {
		if (!lua_isnil(l, 4) && !lua_isfunction(l, 4))
			luaL_typerror(l, 4, lua_typename(l, LUA_TFUNCTION));
		have_delete = true;
	}

	int ref = s->AddBBAdvert(description, _create_chat_form);

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

	lua_pushinteger(l, ref);

	lua_newtable(l);

	lua_pushstring(l, "onChat");
	lua_pushvalue(l, 3);
	lua_settable(l, -3);

	if (have_delete) {
		lua_pushstring(l, "onDelete");
		lua_pushvalue(l, 4);
		lua_settable(l, -3);
	}

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

	LUA_DEBUG_END(l,0);

	_register_for_station_delete(s);

	lua_pushinteger(l, ref);
	return 1;
} 
/*
 * Method: RemoveAdvert
 *
 * Remove an advertisement from the station's bulletin board
 *
 * > station:RemoveAdvert(ref)
 *
 * If the deletefunc parameter was supplied to <AddAdvert> when the ad was
 * created, it will be called as part of this call.
 *
 * Parameters:
 *
 *   ref - the advert reference number returned by <AddAdvert>
 *
 * Availability:
 *
 *  alpha 10
 *
 * Status:
 *
 *  stable
 */
static int l_spacestation_remove_advert(lua_State *l)
{
	LUA_DEBUG_START(l);

	SpaceStation *s = LuaSpaceStation::GetFromLua(1);
	int ref = luaL_checkinteger(l, 2);

	if (!s->RemoveBBAdvert(ref))
		return 0;

	lua_getfield(l, LUA_REGISTRYINDEX, "PiAdverts");
	if (lua_isnil(l, -1)) {
		lua_pop(l, 1);
		return 0;
	}
	
	lua_pushinteger(l, ref);
	lua_gettable(l, -2);
	if (lua_isnil(l, -1)) {
		lua_pop(l, 2);
		return 0;
	}

	lua_getfield(l, -1, "onDelete");
	if (lua_isnil(l, -1))
		lua_pop(l, 1);
	else {
		lua_pushinteger(l, ref);
		pi_lua_protected_call(l, 1, 0);
	}

	lua_pop(l, 1);

	lua_pushinteger(l, ref);
	lua_pushnil(l);
	lua_settable(l, -3);

	lua_pop(l, 1);

	LUA_DEBUG_END(l,0);

	return 0;
} 
Beispiel #8
0
Game::Game(const SystemPath &path) :
	m_time(0),
	m_state(STATE_NORMAL),
	m_wantHyperspace(false),
	m_timeAccel(TIMEACCEL_1X),
	m_requestedTimeAccel(TIMEACCEL_1X),
	m_forceTimeAccel(false)
{
	m_space.Reset(new Space(this, path));
	SpaceStation *station = static_cast<SpaceStation*>(m_space->FindBodyForPath(&path));
	assert(station);

	CreatePlayer();

	m_space->AddBody(m_player.Get());

	m_player->Enable();
	m_player->SetFrame(station->GetFrame());
	m_player->SetDockedWith(station, 0);

	CreateViews();
}
Beispiel #9
0
/*
 * Function: SpawnShipParked
 *
 * Create a ship and place it in one of the given <SpaceStation's> parking spots.
 *
 * > ship = Space.SpawnShipParked(type, station)
 *
 * For orbital stations the parking spots are some distance from the door, out
 * of the path of ships entering and leaving the station. For group stations
 * the parking spots are directly above the station, usually some distance
 * away.
 *
 * Parameters:
 *
 *   type - the name of the ship
 *
 *   station - the <SpaceStation> to place the near
 *
 * Return:
 *
 *   ship - a <Ship> object for the new ship, or nil if there was no space
 *          inside the station
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   experimental
 */
static int l_space_spawn_ship_parked(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);

    SpaceStation *station = LuaObject<SpaceStation>::CheckFromLua(2);

    int slot;
    if (!station->AllocateStaticSlot(slot))
        return 0;

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

    double parkDist = station->GetStationType()->parkingDistance;
    parkDist -= ship->GetPhysRadius();		// park inside parking radius
    double parkOffset = 0.5 * station->GetStationType()->parkingGapSize;
    parkOffset += ship->GetPhysRadius();	// but outside the docking gap

    double xpos = (slot == 0 || slot == 3) ? -parkOffset : parkOffset;
    double zpos = (slot == 0 || slot == 1) ? -parkOffset : parkOffset;
    vector3d parkPos = vector3d(xpos, parkDist, zpos);
    parkPos = station->GetPosition() + station->GetOrient() * parkPos;

    // orbital stations have Y as axis of rotation
    matrix3x3d rot = matrix3x3d::RotateX(M_PI/2) * station->GetOrient();

    ship->SetFrame(station->GetFrame());
    ship->SetVelocity(vector3d(0.0));
    ship->SetPosition(parkPos);
    ship->SetOrient(rot);

    Pi::game->GetSpace()->AddBody(ship);

    ship->AIHoldPosition();

    LuaObject<Ship>::PushToLua(ship);

    LUA_DEBUG_END(l, 1);

    return 1;
}
Beispiel #10
0
void NotifyOfCrime(Ship *s, enum Crime crime)
{
	// ignore crimes of NPCs for the time being
	if (!s->IsType(Object::PLAYER)) return;
	// find nearest starport to this evil criminal
	SpaceStation *station = static_cast<SpaceStation*>(Pi::game->GetSpace()->FindNearestTo(s, Object::SPACESTATION));
	if (station) {
		double dist = station->GetPositionRelTo(s).Length();
		// too far away for crime to be noticed :)
		if (dist > 100000.0) return;
		const int crimeIdx = GetCrimeIdxFromEnum(crime);
		Pi::cpan->MsgLog()->ImportantMessage(station->GetLabel(),
				stringf(Lang::X_CANNOT_BE_TOLERATED_HERE, formatarg("crime", crimeNames[crimeIdx])));

		float lawlessness = Pi::game->GetSpace()->GetStarSystem()->GetSysPolit().lawlessness.ToFloat();
		Sint64 oldCrimes, oldFine;
		GetCrime(&oldCrimes, &oldFine);
		Sint64 newFine = std::max(1, 1 + int(crimeBaseFine[crimeIdx] * (1.0-lawlessness)));
		// don't keep compounding fines (maybe should for murder, etc...)
		if ( (!(crime & CRIME_MURDER)) && (newFine < oldFine) ) newFine = 0;
		AddCrime(crime, newFine);
	}
}
Beispiel #11
0
void NotifyOfCrime(Ship *s, enum Crime crime)
{
	// ignore crimes of NPCs for the time being
	if (s != (Ship*)Pi::player) return;
	// find nearest starport to this evil criminal
	SpaceStation *station = static_cast<SpaceStation*>(Space::FindNearestTo(s, Object::SPACESTATION));
	if (station) {
		double dist = station->GetPositionRelTo(s).Length();
		// too far away for crime to be noticed :)
		if (dist > 100000.0) return;
		const int crimeIdx = GetCrimeIdxFromEnum(crime);
		Pi::cpan->MsgLog()->ImportantMessage(station->GetLabel(),
				stringf(512, "%s cannot be tolerated here.", crimeNames[crimeIdx]));

		float lawlessness = Pi::currentSystem->GetSysPolit().lawlessness.ToFloat();
		Sint64 oldCrimes, oldFine;
		GetCrime(&oldCrimes, &oldFine);
		Sint64 newFine = std::max(1, 1 + (int)(crimeBaseFine[crimeIdx] * (1.0-lawlessness)));
		// don't keep compounding fines (maybe should for murder, etc...)
		if ( (!(crime & CRIME_MURDER)) && (newFine < oldFine) ) newFine = 0;
		AddCrime(crime, newFine);
	}
}
Beispiel #12
0
void Pi::HandleEvents()
{
	PROFILE_SCOPED()
	SDL_Event event;

	// XXX for most keypresses SDL will generate KEYUP/KEYDOWN and TEXTINPUT
	// events. keybindings run off KEYUP/KEYDOWN. the console is opened/closed
	// via keybinding. the console TextInput widget uses TEXTINPUT events. thus
	// after switching the console, the stray TEXTINPUT event causes the
	// console key (backtick) to appear in the text entry field. we hack around
	// this by setting this flag if the console was switched. if its set, we
	// swallow the TEXTINPUT event this hack must remain until we have a
	// unified input system
	bool skipTextInput = false;

	Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0;
	while (SDL_PollEvent(&event)) {
		if (event.type == SDL_QUIT) {
			if (Pi::game)
				Pi::EndGame();
			Pi::Quit();
		}

		if (skipTextInput && event.type == SDL_TEXTINPUT) {
			skipTextInput = false;
			continue;
		}
		if (ui->DispatchSDLEvent(event))
			continue;

		bool consoleActive = Pi::IsConsoleActive();
		if (!consoleActive)
			KeyBindings::DispatchSDLEvent(&event);
		else
			KeyBindings::toggleLuaConsole.CheckSDLEventAndDispatch(&event);
		if (consoleActive != Pi::IsConsoleActive()) {
			skipTextInput = true;
			continue;
		}

		if (Pi::IsConsoleActive())
			continue;

		Gui::HandleSDLEvent(&event);

		switch (event.type) {
			case SDL_KEYDOWN:
				if (event.key.keysym.sym == SDLK_ESCAPE) {
					if (Pi::game) {
						// only accessible once game started
						if (currentView != 0) {
							if (currentView != Pi::game->GetSettingsView()) {
								Pi::game->SetTimeAccel(Game::TIMEACCEL_PAUSED);
								SetView(Pi::game->GetSettingsView());
							}
							else {
								Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X);
								SetView(Pi::player->IsDead()
										? static_cast<View*>(Pi::game->GetDeathView())
										: static_cast<View*>(Pi::game->GetWorldView()));
							}
						}
					}
					break;
				}
				// special keys. LCTRL+turd
				if ((KeyState(SDLK_LCTRL) || (KeyState(SDLK_RCTRL)))) {
					switch (event.key.keysym.sym) {
						case SDLK_q: // Quit
							if (Pi::game)
								Pi::EndGame();
							Pi::Quit();
							break;
						case SDLK_PRINTSCREEN: // print
						case SDLK_KP_MULTIPLY: // screen
						{
							char buf[256];
							const time_t t = time(0);
							struct tm *_tm = localtime(&t);
							strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.png", _tm);
							Graphics::ScreendumpState sd;
							Pi::renderer->Screendump(sd);
							write_screenshot(sd, buf);
							break;
						}
#if WITH_DEVKEYS
						case SDLK_i: // Toggle Debug info
							Pi::showDebugInfo = !Pi::showDebugInfo;
							break;

#ifdef PIONEER_PROFILER
						case SDLK_p: // alert it that we want to profile
							if (KeyState(SDLK_LSHIFT) || KeyState(SDLK_RSHIFT))
								Pi::doProfileOne = true;
							else {
								Pi::doProfileSlow = !Pi::doProfileSlow;
								Output("slow frame profiling %s\n", Pi::doProfileSlow ? "enabled" : "disabled");
							}
							break;
#endif

						case SDLK_F12:
						{
							if(Pi::game) {
								vector3d dir = -Pi::player->GetOrient().VectorZ();
								/* add test object */
								if (KeyState(SDLK_RSHIFT)) {
									Missile *missile =
										new Missile(ShipType::MISSILE_GUIDED, Pi::player);
									missile->SetOrient(Pi::player->GetOrient());
									missile->SetFrame(Pi::player->GetFrame());
									missile->SetPosition(Pi::player->GetPosition()+50.0*dir);
									missile->SetVelocity(Pi::player->GetVelocity());
									game->GetSpace()->AddBody(missile);
									missile->AIKamikaze(Pi::player->GetCombatTarget());
								} else if (KeyState(SDLK_LSHIFT)) {
									SpaceStation *s = static_cast<SpaceStation*>(Pi::player->GetNavTarget());
									if (s) {
										Ship *ship = new Ship(ShipType::POLICE);
										int port = s->GetFreeDockingPort(ship);
										if (port != -1) {
											Output("Putting ship into station\n");
											// Make police ship intent on killing the player
											ship->AIKill(Pi::player);
											ship->SetFrame(Pi::player->GetFrame());
											ship->SetDockedWith(s, port);
											game->GetSpace()->AddBody(ship);
										} else {
											delete ship;
											Output("No docking ports free dude\n");
										}
									} else {
											Output("Select a space station...\n");
									}
								} else {
									Ship *ship = new Ship(ShipType::POLICE);
									if( KeyState(SDLK_LCTRL) )
										ship->AIFlyTo(Pi::player);	// a less lethal option
									else
										ship->AIKill(Pi::player);	// a really lethal option!
									lua_State *l = Lua::manager->GetLuaState();
									pi_lua_import(l, "Equipment");
									LuaTable equip(l, -1);
									LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("laser").Sub("pulsecannon_dual_1mw"));
									LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("laser_cooling_booster"));
									LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("atmospheric_shielding"));
									lua_pop(l, 5);
									ship->SetFrame(Pi::player->GetFrame());
									ship->SetPosition(Pi::player->GetPosition()+100.0*dir);
									ship->SetVelocity(Pi::player->GetVelocity());
									ship->UpdateEquipStats();
									game->GetSpace()->AddBody(ship);
								}
							}
							break;
						}
#endif /* DEVKEYS */
#if WITH_OBJECTVIEWER
						case SDLK_F10:
							Pi::SetView(Pi::game->GetObjectViewerView());
							break;
#endif
						case SDLK_F11:
							// XXX only works on X11
							//SDL_WM_ToggleFullScreen(Pi::scrSurface);
#if WITH_DEVKEYS
							renderer->ReloadShaders();
#endif
							break;
						case SDLK_F9: // Quicksave
						{
							if(Pi::game) {
								if (Pi::game->IsHyperspace())
									Pi::game->log->Add(Lang::CANT_SAVE_IN_HYPERSPACE);

								else {
									const std::string name = "_quicksave";
									const std::string path = FileSystem::JoinPath(GetSaveDir(), name);
									try {
										Game::SaveGame(name, Pi::game);
										Pi::game->log->Add(Lang::GAME_SAVED_TO + path);
									} catch (CouldNotOpenFileException) {
										Pi::game->log->Add(stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path)));
									}
									catch (CouldNotWriteToFileException) {
										Pi::game->log->Add(Lang::GAME_SAVE_CANNOT_WRITE);
									}
								}
							}
							break;
						}
						default:
							break; // This does nothing but it stops the compiler warnings
					}
				}
				Pi::keyState[event.key.keysym.sym] = true;
				Pi::keyModState = event.key.keysym.mod;
				Pi::onKeyPress.emit(&event.key.keysym);
				break;
			case SDL_KEYUP:
				Pi::keyState[event.key.keysym.sym] = false;
				Pi::keyModState = event.key.keysym.mod;
				Pi::onKeyRelease.emit(&event.key.keysym);
				break;
			case SDL_MOUSEBUTTONDOWN:
				if (event.button.button < COUNTOF(Pi::mouseButton)) {
					Pi::mouseButton[event.button.button] = 1;
					Pi::onMouseButtonDown.emit(event.button.button,
							event.button.x, event.button.y);
				}
				break;
			case SDL_MOUSEBUTTONUP:
				if (event.button.button < COUNTOF(Pi::mouseButton)) {
					Pi::mouseButton[event.button.button] = 0;
					Pi::onMouseButtonUp.emit(event.button.button,
							event.button.x, event.button.y);
				}
				break;
			case SDL_MOUSEWHEEL:
				Pi::onMouseWheel.emit(event.wheel.y > 0); // true = up
				break;
			case SDL_MOUSEMOTION:
				Pi::mouseMotion[0] += event.motion.xrel;
				Pi::mouseMotion[1] += event.motion.yrel;
		//		SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]);
				break;
			case SDL_JOYAXISMOTION:
				if (!joysticks[event.jaxis.which].joystick)
					break;
				if (event.jaxis.value == -32768)
					joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f;
				else
					joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f;
				break;
			case SDL_JOYBUTTONUP:
			case SDL_JOYBUTTONDOWN:
				if (!joysticks[event.jaxis.which].joystick)
					break;
				joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0;
				break;
			case SDL_JOYHATMOTION:
				if (!joysticks[event.jaxis.which].joystick)
					break;
				joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value;
				break;
		}
	}
}
/*
 * Attribute: numShipsDocked
 *
 * The number of ships docked at spacestation
 *
 * Availability:
 *
 *   201404
 *
 * Status:
 *
 *   experimental
 */
static int l_spacestation_attr_num_ships_docked(lua_State *l)
{
	SpaceStation *s = LuaObject<SpaceStation>::CheckFromLua(1);
	lua_pushinteger(l, s->NumShipsDocked());
	return 1;
}
Beispiel #14
0
void Pi::HandleEvents()
{
	SDL_Event event;

	Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0;
	while (SDL_PollEvent(&event)) {
		Gui::HandleSDLEvent(&event);
		switch (event.type) {
			case SDL_KEYDOWN:
				if (event.key.keysym.sym == SDLK_ESCAPE) {
					// only accessible once game started
					if (currentView != 0) {
						if (currentView != gameMenuView) {
							RequestTimeAccel(0);
							SetTimeAccel(0);
							SetView(gameMenuView);
						}
						else
							RequestTimeAccel(1);
					}
					break;
				}
				// special keys. LCTRL+turd
				if ((KeyState(SDLK_LCTRL) || (KeyState(SDLK_RCTRL)))) {
					if (event.key.keysym.sym == SDLK_q) Pi::Quit();
					if (event.key.keysym.sym == SDLK_s) {
						Render::ToggleShaders();
					}
					if (event.key.keysym.sym == SDLK_h) {
						Render::ToggleHDR();
					}
					if (event.key.keysym.sym == SDLK_i) Pi::showDebugInfo = !Pi::showDebugInfo;
					if (event.key.keysym.sym == SDLK_p) {
						Sint64 crime, fine;
						Polit::GetCrime(&crime, &fine);
						printf("Criminal record: %llx, $%lld\n", crime, fine);
						Polit::AddCrime(0x1, 100);
						Polit::GetCrime(&crime, &fine);
						printf("Criminal record now: %llx, $%lld\n", crime, fine);
					}
					if (event.key.keysym.sym == SDLK_PRINT) {
						char buf[256];
						const time_t t = time(0);
						struct tm *_tm = localtime(&t);
						strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.tga", _tm);
						Screendump(buf);
						fprintf(stderr, "Screendump to %s\n", buf);
					}
#ifdef DEBUG
					if (event.key.keysym.sym == SDLK_m) {
						Pi::player->SetMoney(Pi::player->GetMoney() + 10000000);
					}
					if (event.key.keysym.sym == SDLK_F12) {
						matrix4x4d m; Pi::player->GetRotMatrix(m);
						vector3d dir = m*vector3d(0,0,-1);
						/* add test object */
						if (KeyState(SDLK_RSHIFT)) {
							Missile *missile = new Missile(ShipType::MISSILE_GUIDED, Pi::player, Pi::player->GetCombatTarget());
							missile->SetRotMatrix(m);
							missile->SetFrame(Pi::player->GetFrame());
							missile->SetPosition(Pi::player->GetPosition()+50.0*dir);
							missile->SetVelocity(Pi::player->GetVelocity());
							Space::AddBody(missile);
						} else if (KeyState(SDLK_LSHIFT)) {
							SpaceStation *s = static_cast<SpaceStation*>(Pi::player->GetNavTarget());
							if (s) {
								int port = s->GetFreeDockingPort();
								if (port != -1) {
									printf("Putting ship into station\n");
									// Make police ship intent on killing the player
									Ship *ship = new Ship(ShipType::LADYBIRD);
									ship->AIKill(Pi::player);
									ship->SetFrame(Pi::player->GetFrame());
									ship->SetDockedWith(s, port);
									Space::AddBody(ship);
								} else {
									printf("No docking ports free dude\n");
								}
							} else {
								printf("Select a space station...\n");
							}
						} else {
							Ship *ship = new Ship(ShipType::LADYBIRD);
							ship->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::PULSECANNON_1MW);
							ship->AIKill(Pi::player);
							ship->SetFrame(Pi::player->GetFrame());
							ship->SetPosition(Pi::player->GetPosition()+100.0*dir);
							ship->SetVelocity(Pi::player->GetVelocity());
							ship->m_equipment.Add(Equip::DRIVE_CLASS2);
							ship->m_equipment.Add(Equip::RADAR_MAPPER);
							ship->m_equipment.Add(Equip::SCANNER);
							ship->m_equipment.Add(Equip::SHIELD_GENERATOR);
							ship->m_equipment.Add(Equip::HYDROGEN, 10);
							Space::AddBody(ship);
						}
					}
#endif /* DEBUG */
					// XXX only works on X11
					//if (event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(Pi::scrSurface);
					if (event.key.keysym.sym == SDLK_F10) Pi::SetView(Pi::objectViewerView);
					if (event.key.keysym.sym == SDLK_F9) {
						std::string name = join_path(GetFullSavefileDirPath().c_str(), "_quicksave", 0);
						Serializer::SaveGame(name.c_str());
						Pi::cpan->MsgLog()->Message("", "Game saved to "+name);
					}
				}
				Pi::keyState[event.key.keysym.sym] = 1;
				Pi::keyModState = event.key.keysym.mod;
				Pi::onKeyPress.emit(&event.key.keysym);
				break;
			case SDL_KEYUP:
				Pi::keyState[event.key.keysym.sym] = 0;
				Pi::keyModState = event.key.keysym.mod;
				Pi::onKeyRelease.emit(&event.key.keysym);
				break;
			case SDL_MOUSEBUTTONDOWN:
				Pi::mouseButton[event.button.button] = 1;
				Pi::onMouseButtonDown.emit(event.button.button,
						event.button.x, event.button.y);
				break;
			case SDL_MOUSEBUTTONUP:
				Pi::mouseButton[event.button.button] = 0;
				Pi::onMouseButtonUp.emit(event.button.button,
						event.button.x, event.button.y);
				break;
			case SDL_MOUSEMOTION:
				Pi::mouseMotion[0] += event.motion.xrel;
				Pi::mouseMotion[1] += event.motion.yrel;
		//		SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]);
				break;
			case SDL_JOYAXISMOTION:
				if (joysticks[event.jaxis.which].joystick == NULL)
					break;
				if (event.jaxis.value == -32768)
					joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f;
				else
					joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f;
				break;
			case SDL_JOYBUTTONUP:
			case SDL_JOYBUTTONDOWN:
				if (joysticks[event.jaxis.which].joystick == NULL)
					break;
				joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0;
				break;
			case SDL_JOYHATMOTION:
				if (joysticks[event.jaxis.which].joystick == NULL)
					break;
				joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value;
				break;
			case SDL_QUIT:
				Pi::Quit();
				break;
		}
	}
}
Beispiel #15
0
void Pi::Start()
{
	WorldView *view = new WorldView();
	
	Gui::Fixed *splash = new Gui::Fixed(Gui::Screen::GetWidth(), Gui::Screen::GetHeight());
	Gui::Screen::AddBaseWidget(splash, 0, 0);
	splash->SetTransparency(true);

	const float w = Gui::Screen::GetWidth() / 2;
	const float h = Gui::Screen::GetHeight() / 2;
	const int OPTS = 5;
	Gui::ToggleButton *opts[OPTS];
	opts[0] = new Gui::ToggleButton(); opts[0]->SetShortcut(SDLK_1, KMOD_NONE);
	opts[1] = new Gui::ToggleButton(); opts[1]->SetShortcut(SDLK_2, KMOD_NONE);
	opts[2] = new Gui::ToggleButton(); opts[2]->SetShortcut(SDLK_3, KMOD_NONE);
	opts[3] = new Gui::ToggleButton(); opts[3]->SetShortcut(SDLK_4, KMOD_NONE);
	opts[4] = new Gui::ToggleButton(); opts[4]->SetShortcut(SDLK_5, KMOD_NONE);
	splash->Add(opts[0], w, h-64);
	splash->Add(new Gui::Label("New game starting on Earth"), w+32, h-64);
	splash->Add(opts[1], w, h-32);
	splash->Add(new Gui::Label("New game starting on Epsilon Eridani"), w+32, h-32);
	splash->Add(opts[2], w, h);
	splash->Add(new Gui::Label("New game starting on debug point"), w+32, h);
	splash->Add(opts[3], w, h+32);
	splash->Add(new Gui::Label("Load a saved game"), w+32, h+32);
	splash->Add(opts[4], w, h+64);
	splash->Add(new Gui::Label("Quit"), w+32, h+64);

	splash->ShowAll();

	int choice = 0;
	Uint32 last_time = SDL_GetTicks();
	float _time = 0;
	do {
		Pi::HandleEvents();

		Render::PrepareFrame();
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		float fracH = 1.0 / Pi::GetScrAspect();
		glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glClearColor(0,0,0,0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		SDL_ShowCursor(1);
		SDL_WM_GrabInput(SDL_GRAB_OFF);

		draw_intro(view, _time);
		Render::PostProcess();
		Gui::Draw();
		Render::SwapBuffers();
		
		Pi::frameTime = 0.001*(SDL_GetTicks() - last_time);
		_time += Pi::frameTime;
		last_time = SDL_GetTicks();

		// poll ui instead of using callbacks :-J
		for (int i=0; i<OPTS; i++) if (opts[i]->GetPressed()) choice = i+1;
	} while (!choice);
	splash->HideAll();
	
	Gui::Screen::RemoveBaseWidget(splash);
	delete splash;
	delete view;
	
	InitGame();


	if (choice == 1) {
		/* Earth start point */
		SBodyPath path(0,0,0);
		Space::DoHyperspaceTo(&path);
		//Frame *pframe = *(++(++(Space::rootFrame->m_children.begin())));
		//player->SetFrame(pframe);
		// XXX there isn't a sensible way to find stations for a planet.
		SpaceStation *station = 0;
		for (Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) {
			if ((*i)->IsType(Object::SPACESTATION)) { station = (SpaceStation*)*i; break; }
		}
		assert(station);
		player->SetPosition(vector3d(0,0,0));
		player->SetFrame(station->GetFrame());
		player->SetDockedWith(station, 0);
		MainLoop();
	} else if (choice == 2) {
		/* Epsilon Eridani start point */
		SBodyPath path(1,0,2);
		Space::DoHyperspaceTo(&path);
		// XXX there isn't a sensible way to find stations for a planet.
		SpaceStation *station = 0;
		for (Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) {
			if ((*i)->IsType(Object::SPACESTATION)) {
				station = (SpaceStation*)*i;
				if (!station->IsGroundStation()) break;
			}
		}
		assert(station);
		player->SetPosition(vector3d(0,0,0));
		player->SetFrame(station->GetFrame());
		player->SetDockedWith(station, 0);
		MainLoop();
	} else if (choice == 3) {
		/* debug start point */
		SBodyPath path(1,0,2);
		path.sbodyId = 6;
		Space::DoHyperspaceTo(&path);
		player->SetPosition(vector3d(2*EARTH_RADIUS,0,0));
		player->SetVelocity(vector3d(0,0,0));
		player->m_equipment.Add(Equip::HYPERCLOUD_ANALYZER);

		Ship *enemy = new Ship(ShipType::EAGLE_LRF);
		enemy->SetFrame(player->GetFrame());
		enemy->SetPosition(player->GetPosition()+vector3d(0,0,-9000.0));
		enemy->SetVelocity(vector3d(0,0,0));
		enemy->m_equipment.Add(Equip::PULSECANNON_1MW);
		enemy->AIKill(player);
		Space::AddBody(enemy);

		player->SetCombatTarget(enemy);


		const ShipType *shipdef;
		double mass, acc1, acc2, acc3;
		printf("Player ship mass = %.0fkg, Enemy ship mass = %.0fkg\n",
			player->GetMass(), enemy->GetMass());

		shipdef = &player->GetShipType();
		mass = player->GetMass();
		acc1 = shipdef->linThrust[ShipType::THRUSTER_FORWARD] / (9.81*mass);
		acc2 = shipdef->linThrust[ShipType::THRUSTER_REVERSE] / (9.81*mass);
		acc3 = shipdef->linThrust[ShipType::THRUSTER_UP] / (9.81*mass);
		printf("Player ship thrust = %.1fg, %.1fg, %.1fg\n", acc1, acc2, acc3);

		shipdef = &enemy->GetShipType();
		mass = enemy->GetMass();
		acc1 = shipdef->linThrust[ShipType::THRUSTER_FORWARD] / (9.81*mass);
		acc2 = shipdef->linThrust[ShipType::THRUSTER_REVERSE] / (9.81*mass);
		acc3 = shipdef->linThrust[ShipType::THRUSTER_UP] / (9.81*mass);
		printf("Enemy ship thrust = %.1fg, %.1fg, %.1fg\n", acc1, acc2, acc3);


	/*	Frame *stationFrame = new Frame(pframe, "Station frame...");
		stationFrame->SetRadius(5000);
		stationFrame->m_sbody = 0;
		stationFrame->SetPosition(vector3d(0,0,zpos));
		stationFrame->SetAngVelocity(vector3d(0,0,0.5));

		for (int i=0; i<4; i++) {
			Ship *body = new Ship(ShipType::LADYBIRD);
			char buf[64];
			snprintf(buf,sizeof(buf),"X%c-0%02d", 'A'+i, i);
			body->SetLabel(buf);
			body->SetFrame(stationFrame);
			body->SetPosition(vector3d(200*(i+1), 0, 2000));
			Space::AddBody(body);
		}
			
		SpaceStation *station = new SpaceStation(SpaceStation::JJHOOP);
		station->SetLabel("Poemi-chan's Folly");
		station->SetFrame(stationFrame);
		station->SetPosition(vector3d(0,0,0));
		Space::AddBody(station);

		SpaceStation *station2 = new SpaceStation(SpaceStation::GROUND_FLAVOURED);
		station2->SetLabel("Conor's End");
		station2->SetFrame(*pframe->m_children.begin()); // rotating frame of planet
		station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4);
		Space::AddBody(station2);
	*/
	//	player->SetDockedWith(station2, 0);

		MainLoop();
	} else if (choice == 4) {
		if (Pi::player) {
			Pi::player->MarkDead();
			Space::bodies.remove(Pi::player);
			delete Pi::player;
			Pi::player = 0;
		}
		Pi::gameMenuView->OpenLoadDialog();
		do {
			Gui::MainLoopIteration();
		} while (Pi::currentView != Pi::worldView);
		
		if (Pi::isGameStarted) MainLoop();
	} else {
		Pi::Quit();
	}
	UninitGame();
}
Beispiel #16
0
/*
 * Function: SpawnShipParked
 *
 * Create a ship and place it in one of the given <SpaceStation's> parking spots.
 *
 * > ship = Space.SpawnShipParked(type, station)
 *
 * For orbital stations the parking spots are some distance from the door, out
 * of the path of ships entering and leaving the station. For group stations
 * the parking spots are directly above the station, usually some distance
 * away.
 *
 * Parameters:
 *
 *   type - the name of the ship
 *
 *   station - the <SpaceStation> to place the near
 *
 * Return:
 *
 *   ship - a <Ship> object for the new ship, or nil if there was no space
 *          inside the station
 * Availability:
 *
 *   alpha 10
 *
 * Status:
 *
 *   experimental
 */
static int l_space_spawn_ship_parked(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);

	SpaceStation *station = LuaSpaceStation::CheckFromLua(2);

	int slot;
	if (!station->AllocateStaticSlot(slot))
		return 0;

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

	vector3d pos, vel;
	matrix4x4d rot = matrix4x4d::Identity();

	if (station->GetSystemBody()->type == SystemBody::TYPE_STARPORT_SURFACE) {
		vel = vector3d(0.0);

		// XXX on tiny planets eg asteroids force this to be larger so the
		// are out of the docking path
		pos = station->GetPosition() * 1.1;
		station->GetRotMatrix(rot);

		vector3d axis1, axis2;

		axis1 = pos.Cross(vector3d(0.0,1.0,0.0));
		axis2 = pos.Cross(axis1);

		double ang = atan((140 + ship->GetLmrCollMesh()->GetBoundingRadius()) / pos.Length());
		if (slot<2) ang = -ang;

		vector3d axis = (slot == 0 || slot == 3) ? axis1 : axis2;

		pos.ArbRotate(axis, ang);
	}

	else {
		double dist = 100 + ship->GetLmrCollMesh()->GetBoundingRadius();
		double xpos = (slot == 0 || slot == 3) ? -dist : dist;
		double zpos = (slot == 0 || slot == 1) ? -dist : dist;

		pos = vector3d(xpos,5000,zpos);
		vel = vector3d(0.0);
		rot.RotateX(M_PI/2);
	}

	ship->SetFrame(station->GetFrame());

	ship->SetVelocity(vel);
	ship->SetPosition(pos);
	ship->SetRotMatrix(rot);

	Pi::game->GetSpace()->AddBody(ship);

	ship->AIHoldPosition();

	LuaShip::PushToLua(ship);

	LUA_DEBUG_END(l, 1);

	return 1;
}
Beispiel #17
0
void Pi::HandleEvents()
{
	SDL_Event event;

	Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0;
	while (SDL_PollEvent(&event)) {
		if (event.type == SDL_QUIT) {
			if (Pi::game)
				Pi::EndGame();
			Pi::Quit();
		}
		else if (ui->DispatchSDLEvent(event))
			continue;

		Gui::HandleSDLEvent(&event);
		if (!Pi::IsConsoleActive())
			KeyBindings::DispatchSDLEvent(&event);
		else
			KeyBindings::toggleLuaConsole.CheckSDLEventAndDispatch(&event);

		switch (event.type) {
			case SDL_KEYDOWN:
				if (event.key.keysym.sym == SDLK_ESCAPE) {
					if (Pi::game) {
						// only accessible once game started
						if (currentView != 0) {
							if (currentView != gameMenuView) {
								Pi::game->SetTimeAccel(Game::TIMEACCEL_PAUSED);
								SetView(gameMenuView);
							}
							else {
								Pi::game->RequestTimeAccel(Game::TIMEACCEL_1X);
								SetView(Pi::player->IsDead()
										? static_cast<View*>(deathView)
										: static_cast<View*>(worldView));
							}
						}
					}
					break;
				}
				// special keys. LCTRL+turd
				if ((KeyState(SDLK_LCTRL) || (KeyState(SDLK_RCTRL)))) {
					switch (event.key.keysym.sym) {
						case SDLK_q: // Quit
							if (Pi::game)
								Pi::EndGame();
							Pi::Quit();
							break;
						case SDLK_PRINT:	   // print
						case SDLK_KP_MULTIPLY: // screen
						{
							char buf[256];
							const time_t t = time(0);
							struct tm *_tm = localtime(&t);
							strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.png", _tm);
							Screendump(buf, Graphics::GetScreenWidth(), Graphics::GetScreenHeight());
							break;
						}
#if WITH_DEVKEYS
						case SDLK_i: // Toggle Debug info
							Pi::showDebugInfo = !Pi::showDebugInfo;
							break;
						case SDLK_m:  // Gimme money!
							if(Pi::game) {
								Pi::player->SetMoney(Pi::player->GetMoney() + 10000000);
							}
							break;
						case SDLK_F12:
						{
							if(Pi::game) {
								vector3d dir = -Pi::player->GetOrient().VectorZ();
								/* add test object */
								if (KeyState(SDLK_RSHIFT)) {
									Missile *missile =
										new Missile(ShipType::MISSILE_GUIDED, Pi::player, Pi::player->GetCombatTarget());
									missile->SetOrient(Pi::player->GetOrient());
									missile->SetFrame(Pi::player->GetFrame());
									missile->SetPosition(Pi::player->GetPosition()+50.0*dir);
									missile->SetVelocity(Pi::player->GetVelocity());
									game->GetSpace()->AddBody(missile);
								} else if (KeyState(SDLK_LSHIFT)) {
									SpaceStation *s = static_cast<SpaceStation*>(Pi::player->GetNavTarget());
									if (s) {
										int port = s->GetFreeDockingPort();
										if (port != -1) {
											printf("Putting ship into station\n");
											// Make police ship intent on killing the player
											Ship *ship = new Ship(ShipType::LADYBIRD);
											ship->AIKill(Pi::player);
											ship->SetFrame(Pi::player->GetFrame());
											ship->SetDockedWith(s, port);
											game->GetSpace()->AddBody(ship);
										} else {
											printf("No docking ports free dude\n");
										}
									} else {
											printf("Select a space station...\n");
									}
								} else {
									Ship *ship = new Ship(ShipType::LADYBIRD);
									ship->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::PULSECANNON_1MW);
									ship->AIKill(Pi::player);
									ship->SetFrame(Pi::player->GetFrame());
									ship->SetPosition(Pi::player->GetPosition()+100.0*dir);
									ship->SetVelocity(Pi::player->GetVelocity());
									ship->m_equipment.Add(Equip::DRIVE_CLASS2);
									ship->m_equipment.Add(Equip::RADAR_MAPPER);
									ship->m_equipment.Add(Equip::SCANNER);
									ship->m_equipment.Add(Equip::SHIELD_GENERATOR);
									ship->m_equipment.Add(Equip::HYDROGEN, 10);
									ship->UpdateStats();
									game->GetSpace()->AddBody(ship);
								}
							}
							break;
						}
#endif /* DEVKEYS */
#if WITH_OBJECTVIEWER
						case SDLK_F10:
							Pi::SetView(Pi::objectViewerView);
							break;
#endif
						case SDLK_F11:
							// XXX only works on X11
							//SDL_WM_ToggleFullScreen(Pi::scrSurface);
#if WITH_DEVKEYS
							renderer->ReloadShaders();
#endif
							break;
						case SDLK_F9: // Quicksave
						{
							if(Pi::game) {
								if (Pi::game->IsHyperspace())
									Pi::cpan->MsgLog()->Message("", Lang::CANT_SAVE_IN_HYPERSPACE);

								else {
									const std::string name = "_quicksave";
									const std::string path = FileSystem::JoinPath(GetSaveDir(), name);
									try {
										Game::SaveGame(name, Pi::game);
										Pi::cpan->MsgLog()->Message("", Lang::GAME_SAVED_TO + path);
									} catch (CouldNotOpenFileException) {
										Pi::cpan->MsgLog()->Message("", stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path)));
									}
									catch (CouldNotWriteToFileException) {
										Pi::cpan->MsgLog()->Message("", Lang::GAME_SAVE_CANNOT_WRITE);
									}
								}
							}
							break;
						}
						default:
							break; // This does nothing but it stops the compiler warnings
					}
				}
				Pi::keyState[event.key.keysym.sym] = 1;
				Pi::keyModState = event.key.keysym.mod;
				Pi::onKeyPress.emit(&event.key.keysym);
				break;
			case SDL_KEYUP:
				Pi::keyState[event.key.keysym.sym] = 0;
				Pi::keyModState = event.key.keysym.mod;
				Pi::onKeyRelease.emit(&event.key.keysym);
				break;
			case SDL_MOUSEBUTTONDOWN:
				if (event.button.button < COUNTOF(Pi::mouseButton)) {
					Pi::mouseButton[event.button.button] = 1;
					Pi::onMouseButtonDown.emit(event.button.button,
							event.button.x, event.button.y);
				}
				break;
			case SDL_MOUSEBUTTONUP:
				if (event.button.button < COUNTOF(Pi::mouseButton)) {
					Pi::mouseButton[event.button.button] = 0;
					Pi::onMouseButtonUp.emit(event.button.button,
							event.button.x, event.button.y);
				}
				break;
			case SDL_MOUSEMOTION:
				Pi::mouseMotion[0] += event.motion.xrel;
				Pi::mouseMotion[1] += event.motion.yrel;
		//		SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]);
				break;
			case SDL_JOYAXISMOTION:
				if (joysticks[event.jaxis.which].joystick == NULL)
					break;
				if (event.jaxis.value == -32768)
					joysticks[event.jaxis.which].axes[event.jaxis.axis] = 1.f;
				else
					joysticks[event.jaxis.which].axes[event.jaxis.axis] = -event.jaxis.value / 32767.f;
				break;
			case SDL_JOYBUTTONUP:
			case SDL_JOYBUTTONDOWN:
				if (joysticks[event.jaxis.which].joystick == NULL)
					break;
				joysticks[event.jbutton.which].buttons[event.jbutton.button] = event.jbutton.state != 0;
				break;
			case SDL_JOYHATMOTION:
				if (joysticks[event.jaxis.which].joystick == NULL)
					break;
				joysticks[event.jhat.which].hats[event.jhat.hat] = event.jhat.value;
				break;
		}
	}
}
/*
 * Attribute: isGroundStation
 *
 * true if station is on the ground, false if its an orbital
 *
 * Availability:
 *
 *   alpha 30
 *
 * Status:
 *
 *   experimental
 */
static int l_spacestation_attr_is_ground_station(lua_State *l)
{
	SpaceStation *s = LuaObject<SpaceStation>::CheckFromLua(1);
	lua_pushboolean(l, s->IsGroundStation());
	return 1;
}
/*
 * Attribute: numDocks
 *
 * The number of docking ports a spacestation has.
 *
 * Availability:
 *
 *   alpha 21
 *
 * Status:
 *
 *   experimental
 */
static int l_spacestation_attr_num_docks(lua_State *l)
{
	SpaceStation *s = LuaObject<SpaceStation>::CheckFromLua(1);
	lua_pushinteger(l, s->GetDockingPortCount());
	return 1;
}
Beispiel #20
0
void Pi::HandleKeyDown(SDL_Keysym *key)
{
	if (key->sym == SDLK_ESCAPE) {
		if (Pi::game) {
			// only accessible once game started
			HandleEscKey();
		}
		return;
	}
	const bool CTRL = input.KeyState(SDLK_LCTRL) || input.KeyState(SDLK_RCTRL);

	// special keys.
	if (CTRL) {
		switch (key->sym) {
		case SDLK_q: // Quit
			Pi::RequestQuit();
			break;
		case SDLK_PRINTSCREEN: // print
		case SDLK_KP_MULTIPLY: // screen
		{
			char buf[256];
			const time_t t = time(0);
			struct tm *_tm = localtime(&t);
			strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.png", _tm);
			Graphics::ScreendumpState sd;
			Pi::renderer->Screendump(sd);
			write_screenshot(sd, buf);
			break;
		}

		case SDLK_SCROLLLOCK: // toggle video recording
			Pi::isRecordingVideo = !Pi::isRecordingVideo;
			if (Pi::isRecordingVideo) {
				char videoName[256];
				const time_t t = time(0);
				struct tm *_tm = localtime(&t);
				strftime(videoName, sizeof(videoName), "pioneer-%Y%m%d-%H%M%S", _tm);
				const std::string dir = "videos";
				FileSystem::userFiles.MakeDirectory(dir);
				const std::string fname = FileSystem::JoinPathBelow(FileSystem::userFiles.GetRoot() + "/" + dir, videoName);
				Output("Video Recording started to %s.\n", fname.c_str());
				// start ffmpeg telling it to expect raw rgba 720p-60hz frames
				// -i - tells it to read frames from stdin
				// if given no frame rate (-r 60), it will just use vfr
				char cmd[256] = { 0 };
				snprintf(cmd, sizeof(cmd), "ffmpeg -f rawvideo -pix_fmt rgba -s %dx%d -i - -threads 0 -preset fast -y -pix_fmt yuv420p -crf 21 -vf vflip %s.mp4", config->Int("ScrWidth"), config->Int("ScrHeight"), fname.c_str());

				// open pipe to ffmpeg's stdin in binary write mode
#if defined(_MSC_VER) || defined(__MINGW32__)
				Pi::ffmpegFile = _popen(cmd, "wb");
#else
				Pi::ffmpegFile = _popen(cmd, "w");
#endif
			} else {
				Output("Video Recording ended.\n");
				if (Pi::ffmpegFile != nullptr) {
					_pclose(Pi::ffmpegFile);
					Pi::ffmpegFile = nullptr;
				}
			}
			break;
#if WITH_DEVKEYS
		case SDLK_i: // Toggle Debug info
			Pi::showDebugInfo = !Pi::showDebugInfo;
			break;

#ifdef PIONEER_PROFILER
		case SDLK_p: // alert it that we want to profile
			if (input.KeyState(SDLK_LSHIFT) || input.KeyState(SDLK_RSHIFT))
				Pi::doProfileOne = true;
			else {
				Pi::doProfileSlow = !Pi::doProfileSlow;
				Output("slow frame profiling %s\n", Pi::doProfileSlow ? "enabled" : "disabled");
			}
			break;
#endif

		case SDLK_F12: {
			if (Pi::game) {
				vector3d dir = -Pi::player->GetOrient().VectorZ();
				/* add test object */
				if (input.KeyState(SDLK_RSHIFT)) {
					Missile *missile =
						new Missile(ShipType::MISSILE_GUIDED, Pi::player);
					missile->SetOrient(Pi::player->GetOrient());
					missile->SetFrame(Pi::player->GetFrame());
					missile->SetPosition(Pi::player->GetPosition() + 50.0 * dir);
					missile->SetVelocity(Pi::player->GetVelocity());
					game->GetSpace()->AddBody(missile);
					missile->AIKamikaze(Pi::player->GetCombatTarget());
				} else if (input.KeyState(SDLK_LSHIFT)) {
					SpaceStation *s = static_cast<SpaceStation *>(Pi::player->GetNavTarget());
					if (s) {
						Ship *ship = new Ship(ShipType::POLICE);
						int port = s->GetFreeDockingPort(ship);
						if (port != -1) {
							Output("Putting ship into station\n");
							// Make police ship intent on killing the player
							ship->AIKill(Pi::player);
							ship->SetFrame(Pi::player->GetFrame());
							ship->SetDockedWith(s, port);
							game->GetSpace()->AddBody(ship);
						} else {
							delete ship;
							Output("No docking ports free dude\n");
						}
					} else {
						Output("Select a space station...\n");
					}
				} else {
					Ship *ship = new Ship(ShipType::POLICE);
					if (!input.KeyState(SDLK_LALT)) { //Left ALT = no AI
						if (!input.KeyState(SDLK_LCTRL))
							ship->AIFlyTo(Pi::player); // a less lethal option
						else
							ship->AIKill(Pi::player); // a really lethal option!
					}
					lua_State *l = Lua::manager->GetLuaState();
					pi_lua_import(l, "Equipment");
					LuaTable equip(l, -1);
					LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("laser").Sub("pulsecannon_dual_1mw"));
					LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("laser_cooling_booster"));
					LuaObject<Ship>::CallMethod<>(ship, "AddEquip", equip.Sub("misc").Sub("atmospheric_shielding"));
					lua_pop(l, 5);
					ship->SetFrame(Pi::player->GetFrame());
					ship->SetPosition(Pi::player->GetPosition() + 100.0 * dir);
					ship->SetVelocity(Pi::player->GetVelocity());
					ship->UpdateEquipStats();
					game->GetSpace()->AddBody(ship);
				}
			}
			break;
		}
#endif /* DEVKEYS */
#if WITH_OBJECTVIEWER
		case SDLK_F10:
			Pi::SetView(Pi::game->GetObjectViewerView());
			break;
#endif
		case SDLK_F11:
			// XXX only works on X11
			//SDL_WM_ToggleFullScreen(Pi::scrSurface);
#if WITH_DEVKEYS
			renderer->ReloadShaders();
#endif
			break;
		case SDLK_F9: // Quicksave
		{
			if (Pi::game) {
				if (Pi::game->IsHyperspace())
					Pi::game->log->Add(Lang::CANT_SAVE_IN_HYPERSPACE);

				else {
					const std::string name = "_quicksave";
					const std::string path = FileSystem::JoinPath(GetSaveDir(), name);
					try {
						Game::SaveGame(name, Pi::game);
						Pi::game->log->Add(Lang::GAME_SAVED_TO + path);
					} catch (CouldNotOpenFileException) {
						Pi::game->log->Add(stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path)));
					} catch (CouldNotWriteToFileException) {
						Pi::game->log->Add(Lang::GAME_SAVE_CANNOT_WRITE);
					}
				}
			}
			break;
		}
		default:
			break; // This does nothing but it stops the compiler warnings
		}
	}
}