Beispiel #1
0
bool SpaceStation::GetDockingClearance(Ship *s, std::string &outMsg)
{
	assert(m_shipDocking.size() == m_type->NumDockingPorts());
	for (Uint32 i=0; i<m_shipDocking.size(); i++) {
		if (m_shipDocking[i].ship == s) {
			outMsg = stringf(Lang::CLEARANCE_ALREADY_GRANTED_BAY_N, formatarg("bay", i+1));
			return (m_shipDocking[i].stage > 0); // grant docking only if the ship is not already docked/undocking
		}
	}

	const Aabb &bbox = s->GetAabb();
	const double bboxRad = bbox.GetRadius();

	for (Uint32 i=0; i<m_shipDocking.size(); i++) {
		// initial unoccupied check
		if (m_shipDocking[i].ship != 0) continue;

		// size-of-ship vs size-of-bay check
		const SpaceStationType::SPort *const pPort = m_type->FindPortByBay(i);
		if( !pPort ) continue;

		if( pPort->minShipSize < bboxRad && bboxRad < pPort->maxShipSize ) {
			shipDocking_t &sd = m_shipDocking[i];
			sd.ship = s;
			sd.stage = 1;
			sd.stagePos = 0;
			outMsg = stringf(Lang::CLEARANCE_GRANTED_BAY_N, formatarg("bay", i+1));
			return true;
		}
	}
	outMsg = Lang::CLEARANCE_DENIED_NO_BAYS;
	return false;
}
Beispiel #2
0
std::string AxisBinding::Description() const {
	const char *axis_names[] = {Lang::X, Lang::Y, Lang::Z};
	std::ostringstream ossaxisnum;
	ossaxisnum << int(axis);

	return stringf(Lang::JOY_AXIS,
		formatarg("sign", direction == KeyBindings::NEGATIVE ? "-" : ""), // no + sign if positive
		formatarg("signp", direction == KeyBindings::NEGATIVE ? "-" : "+"), // optional with + sign
		formatarg("joynum", joystick),
		formatarg("axis", axis >= 0 && axis < 3 ? axis_names[axis] : ossaxisnum.str())
	);
}
Beispiel #3
0
/*
 * Function: LoadGame
 *
 * Load a saved game.
 *
 * > Game.LoadGame(filename)
 *
 * Parameters:
 *
 *   filename - Filename to load. It will be loaded from the 'savefiles'
 *              directory in the user's game directory.
 *
 * Availability:
 *
 *   alpha 28
 *
 * Status:
 *
 *   experimental
 */
static int l_game_load_game(lua_State *l)
{
	if (Pi::game) {
		luaL_error(l, "can't load a game while a game is already running");
		return 0;
	}

	const std::string filename(luaL_checkstring(l, 1));

	try {
		Pi::game = Game::LoadGame(filename);
	}
	catch (SavedGameCorruptException) {
		luaL_error(l, Lang::GAME_LOAD_CORRUPT);
	}
	catch (SavedGameWrongVersionException) {
		luaL_error(l, Lang::GAME_LOAD_WRONG_VERSION);
	}
	catch (CouldNotOpenFileException) {
		const std::string msg = stringf(Lang::GAME_LOAD_CANNOT_OPEN,
			formatarg("filename", filename));
		luaL_error(l, msg.c_str());
	}

	return 0;
}
Beispiel #4
0
/*
 * Function: SaveGame
 *
 * Save the current game.
 *
 * > path = Game.SaveGame(filename)
 *
 * Parameters:
 *
 *   filename - Filename to save to. The file will be placed the 'savefiles'
 *              directory in the user's game directory.
 *
 * Return:
 *
 *   path - the full path to the saved file (so it can be displayed)
 *
 * Availability:
 *
 *   June 2013
 *
 * Status:
 *
 *   experimental
 */
static int l_game_save_game(lua_State *l)
{
	if (!Pi::game) {
		return luaL_error(l, "can't save when no game is running");
	}

	const std::string filename(luaL_checkstring(l, 1));
	const std::string path = FileSystem::JoinPathBelow(Pi::GetSaveDir(), filename);

	try {
		Game::SaveGame(filename, Pi::game);
		lua_pushlstring(l, path.c_str(), path.size());
		return 1;
	}
	catch (CannotSaveInHyperspace) {
		return luaL_error(l, "%s", Lang::CANT_SAVE_IN_HYPERSPACE);
	}
	catch (CannotSaveDeadPlayer) {
		return luaL_error(l, "%s", Lang::CANT_SAVE_DEAD_PLAYER);
	}
	catch (CouldNotOpenFileException) {
		const std::string message = stringf(Lang::COULD_NOT_OPEN_FILENAME, formatarg("path", path));
		lua_pushlstring(l, message.c_str(), message.size());
		return lua_error(l);
	}
	catch (CouldNotWriteToFileException) {
		return luaL_error(l, "%s", Lang::GAME_SAVE_CANNOT_WRITE);
	}
}
Beispiel #5
0
static int l_format_accel_g(lua_State *l)
{
	double a = luaL_checknumber(l, 1);
	const std::string str = stringf(Lang::NUMBER_G, formatarg("acceleration", a));
	lua_pushlstring(l, str.c_str(), str.size());
	return 1;
}
Beispiel #6
0
static int l_format_mass_tonnes(lua_State *l)
{
	double t = luaL_checknumber(l, 1);
	const std::string str = stringf(Lang::NUMBER_TONNES, formatarg("mass", t));
	lua_pushlstring(l, str.c_str(), str.size());
	return 1;
}
StationShipyardForm::StationShipyardForm(FormController *controller) : FaceForm(controller)
{
	SetTitle(stringf(Lang::SOMEWHERE_SHIPYARD, formatarg("station", Pi::player->GetDockedWith()->GetLabel())));

	Gui::SolidButton *b = new Gui::SolidButton();
	b->SetShortcut(SDLK_1, KMOD_NONE);
	b->onClick.connect(sigc::mem_fun(this, &StationShipyardForm::EquipmentMarket));
	Add(b, 30, 140);
	Gui::Label *l = new Gui::Label(Lang::SHIP_EQUIPMENT);
	Add(l, 55, 140);

	b = new Gui::SolidButton();
	b->SetShortcut(SDLK_2, KMOD_NONE);
	b->onClick.connect(sigc::mem_fun(this, &StationShipyardForm::Repairs));
	Add(b, 30, 200);
	l = new Gui::Label(Lang::REPAIRS_AND_SERVICING);
	Add(l, 55, 200);

	b = new Gui::SolidButton();
	b->SetShortcut(SDLK_3, KMOD_NONE);
	b->onClick.connect(sigc::mem_fun(this, &StationShipyardForm::ShipMarket));
	Add(b, 30, 260);
	l = new Gui::Label(Lang::NEW_AND_RECONDITIONED_SHIPS);
	Add(l, 55, 260);
}
void StationShipMarketForm::UpdateShipList()
{
	m_shiplistBox->DeleteAllChildren();

	float line_height = Gui::Screen::GetFontHeight();

	std::vector<ShipFlavour> &ships = m_station->GetShipsOnSale();

	int num = 0;
	for (std::vector<ShipFlavour>::iterator i = ships.begin(); i!=ships.end(); ++i) {
		Gui::Fixed *f = new Gui::Fixed(450, line_height*1.5f);

		Gui::Label *l = new Gui::Label(ShipType::types[(*i).type].name);
		f->Add(l,0,0);
		f->Add(new Gui::Label(format_money((*i).price)), 200, 0);
		f->Add(new Gui::Label(format_money((*i).price - Pi::player->GetFlavour()->price) ), 275, 0);
		f->Add(new Gui::Label(stringf(Lang::NUMBER_TONNES, formatarg("mass", ShipType::types[(*i).type].capacity))), 370, 0);
		
		Gui::SolidButton *sb = new Gui::SolidButton();
		sb->onClick.connect(sigc::bind(sigc::mem_fun(this, &StationShipMarketForm::ViewShip), num));
		f->Add(sb, 430, 0);

		m_shiplistBox->PackEnd(f);

		num++;
	}
}
Beispiel #9
0
NumberLabel *NumberLabel::SetValue(double v)
{
	m_value = v;
	switch (m_format) {
		case FORMAT_NUMBER_2DP:
			SetText(to_string(v, "f.2"));
			break;

		case FORMAT_INTEGER:
			SetText(to_string(Uint32(v+0.5), "u"));
			break;

		case FORMAT_PERCENT:
			SetText(stringf("%0{f.2}%%", v*100.0));
			break;

		case FORMAT_PERCENT_INTEGER:
			SetText(stringf("%0{u}%%", Uint32(v*100.0+0.5)));
			break;

		case FORMAT_MASS_TONNES:
			SetText(stringf(Lang::NUMBER_TONNES, formatarg("mass", v)));
			break;

		case FORMAT_MONEY:
			SetText(format_money(Sint64(v*100)));
			break;

		case FORMAT_DISTANCE_M:
			SetText(format_distance(v, 3));
			break;

		case FORMAT_DISTANCE_LY:
			SetText(stringf(Lang::NUMBER_LY, formatarg("distance", v)));
			break;

		default:
		case FORMAT_NUMBER:
			SetText(to_string(v, "f"));
			break;
	}

	return this;
}
Beispiel #10
0
static void draw_progress(UI::Gauge *gauge, UI::Label *label, float progress)
{
	gauge->SetValue(progress);
	label->SetText(stringf(Lang::SIMULATING_UNIVERSE_EVOLUTION_N_BYEARS, formatarg("age", progress * 13.7f)));

	Pi::renderer->ClearScreen();
	Pi::ui->Update();
	Pi::ui->Draw();
	Pi::renderer->SwapBuffers();
}
Beispiel #11
0
bool Player::CanSell(Equip::Type t, bool verbose) const
{
	Equip::Slot slot = Equip::types[int(t)].slot;
	bool cansell = (m_equipment.Count(slot, t) > 0);
	if (verbose) {
		if (!cansell) {
			Pi::Message(stringf(Lang::YOU_DO_NOT_HAVE_ANY_X, formatarg("item", Equip::types[int(t)].name)));
		}
	}
	return cansell;
}
Beispiel #12
0
static void draw_progress(float progress)
{
	float w, h;
	Pi::renderer->BeginFrame();
	Pi::renderer->EndFrame();
	Gui::Screen::EnterOrtho();
	std::string msg = stringf(Lang::SIMULATING_UNIVERSE_EVOLUTION_N_BYEARS, formatarg("age", progress * 13.7f));
	Gui::Screen::MeasureString(msg, w, h);
	Gui::Screen::RenderString(msg, 0.5f*(Gui::Screen::GetWidth()-w), 0.5f*(Gui::Screen::GetHeight()-h));
	Gui::Screen::LeaveOrtho();
	Pi::renderer->SwapBuffers();
}
Beispiel #13
0
void SystemView::OnClickObject(SBody *b)
{
	m_selectedObject = b;
	std::string desc;
	std::string data;

	desc += std::string(Lang::NAME);
	desc += ":\n";
	data += b->name+"\n";
	
	desc += std::string(Lang::DAY_LENGTH);
	desc += std::string(Lang::ROTATIONAL_PERIOD);
	desc += ":\n";
	data += stringf(Lang::N_DAYS, formatarg("days", b->rotationPeriod.ToFloat())) + "\n";
	
	desc += std::string(Lang::RADIUS);
	desc += ":\n";
	data += format_distance(b->GetRadius())+"\n";

	if (b->parent) {
		desc += std::string(Lang::SEMI_MAJOR_AXIS);
	desc += ":\n";
		data += format_distance(b->orbit.semiMajorAxis)+"\n";

		desc += std::string(Lang::ORBITAL_PERIOD);
	desc += ":\n";
		data += stringf(Lang::N_DAYS, formatarg("days", b->orbit.period / (24*60*60))) + "\n";
	}
	m_infoLabel->SetText(desc);
	m_infoText->SetText(data);

	if (Pi::KeyState(SDLK_LSHIFT) || Pi::KeyState(SDLK_RSHIFT)) {
		SystemPath path = m_system->GetPathOf(b);
		if (Pi::game->GetSpace()->GetStarSystem()->GetPath() == m_system->GetPath()) {
			Body* body = Pi::game->GetSpace()->FindBodyForPath(&path);
			if (body != 0)
				Pi::player->SetNavTarget(body);
		}
	}
}
Beispiel #14
0
bool SpaceStation::GetDockingClearance(Ship *s, std::string &outMsg)
{
	for (int i=0; i<MAX_DOCKING_PORTS; i++) {
		if (i >= m_type->numDockingPorts) break;
		if ((m_shipDocking[i].ship == s) && (m_shipDocking[i].stage > 0)) {
			outMsg = stringf(Lang::CLEARANCE_ALREADY_GRANTED_BAY_N, formatarg("bay", i+1));
			return true;
		}
	}
	for (int i=0; i<MAX_DOCKING_PORTS; i++) {
		if (i >= m_type->numDockingPorts) break;
		if (m_shipDocking[i].ship != 0) continue;
		shipDocking_t &sd = m_shipDocking[i];
		sd.ship = s;
		sd.stage = 1;
		sd.stagePos = 0;
		outMsg = stringf(Lang::CLEARANCE_GRANTED_BAY_N, formatarg("bay", i+1));
		return true;
	}
	outMsg = Lang::CLEARANCE_DENIED_NO_BAYS;
	return false;
}
Beispiel #15
0
bool Ship::OnCollision(Object *b, Uint32 flags, double relVel)
{
	// hitting space station docking surfaces shouldn't do damage
	if (b->IsType(Object::SPACESTATION) && (flags & 0x10)) {
		return true;
	}

	// hitting cargo scoop surface shouldn't do damage
	int cargoscoop_cap = 0;
	Properties().Get("cargo_scoop_cap", cargoscoop_cap);
	if (cargoscoop_cap > 0 && b->IsType(Object::CARGOBODY) && !dynamic_cast<Body*>(b)->IsDead()) {
		LuaRef item = dynamic_cast<CargoBody*>(b)->GetCargoType();
		if (LuaObject<Ship>::CallMethod<int>(this, "AddEquip", item) > 0) { // try to add it to the ship cargo.
			Pi::game->GetSpace()->KillBody(dynamic_cast<Body*>(b));
			if (this->IsType(Object::PLAYER))
				Pi::game->log->Add(stringf(Lang::CARGO_SCOOP_ACTIVE_1_TONNE_X_COLLECTED, formatarg("item", ScopedTable(item).CallMethod<std::string>("GetName"))));
			// XXX SfxManager::Add(this, TYPE_SCOOP);
			UpdateEquipStats();
			return true;
		}
		if (this->IsType(Object::PLAYER))
			Pi::game->log->Add(Lang::CARGO_SCOOP_ATTEMPTED);
	}

	if (b->IsType(Object::PLANET)) {
		// geoms still enabled when landed
		if (m_flightState != FLYING) return false;
		else {
			if (GetVelocity().Length() < MAX_LANDING_SPEED) {
				m_testLanded = true;
				return true;
			}
		}
	}

	if (
		b->IsType(Object::CITYONPLANET) ||
		b->IsType(Object::SHIP) ||
		b->IsType(Object::PLAYER) ||
		b->IsType(Object::SPACESTATION) ||
		b->IsType(Object::PLANET) ||
		b->IsType(Object::STAR) ||
		b->IsType(Object::CARGOBODY))
	{
		LuaEvent::Queue("onShipCollided", this,
			b->IsType(Object::CITYONPLANET) ? dynamic_cast<CityOnPlanet*>(b)->GetPlanet() : dynamic_cast<Body*>(b));
	}

	return DynamicBody::OnCollision(b, flags, relVel);
}
Beispiel #16
0
void GalacticView::Update()
{
	const float frameTime = Pi::GetFrameTime();
	
	if (m_zoomInButton->IsPressed()) m_zoom *= pow(4.0f, frameTime);
	if (m_zoomOutButton->IsPressed()) m_zoom *= pow(0.25f, frameTime);
	// XXX ugly hack checking for console here
	if (!Pi::IsConsoleActive()) {
		if (Pi::KeyState(SDLK_EQUALS)) m_zoom *= pow(4.0f, frameTime);
		if (Pi::KeyState(SDLK_MINUS)) m_zoom *= pow(0.25f, frameTime);
	}
	m_zoom = Clamp(m_zoom, 0.5f, 100.0f);

	m_scaleReadout->SetText(stringf(Lang::INT_LY, formatarg("scale", int(0.5*Galaxy::GALAXY_RADIUS/m_zoom))));
}
Beispiel #17
0
bool Ship::OnCollision(Object *b, Uint32 flags, double relVel)
{
	// hitting space station docking surfaces shouldn't do damage
	if (b->IsType(Object::SPACESTATION) && (flags & 0x10)) {
		return true;
	}

	// hitting cargo scoop surface shouldn't do damage
	if ((m_equipment.Get(Equip::SLOT_CARGOSCOOP) != Equip::NONE) && b->IsType(Object::CARGOBODY) && m_stats.free_capacity) {
		Equip::Type item = dynamic_cast<CargoBody*>(b)->GetCargoType();
		Pi::game->GetSpace()->KillBody(dynamic_cast<Body*>(b));
		m_equipment.Add(item);
		UpdateEquipStats();
		if (this->IsType(Object::PLAYER))
			Pi::Message(stringf(Lang::CARGO_SCOOP_ACTIVE_1_TONNE_X_COLLECTED, formatarg("item", Equip::types[item].name)));
		// XXX Sfx::Add(this, Sfx::TYPE_SCOOP);
		return true;
	}

	if (b->IsType(Object::PLANET)) {
		// geoms still enabled when landed
		if (m_flightState != FLYING) return false;
		else {
			if (GetVelocity().Length() < MAX_LANDING_SPEED) {
				m_testLanded = true;
				return true;
			}
		}
	}

	if (
		b->IsType(Object::CITYONPLANET) ||
		b->IsType(Object::SHIP) ||
		b->IsType(Object::PLAYER) ||
		b->IsType(Object::SPACESTATION) ||
		b->IsType(Object::PLANET) ||
		b->IsType(Object::STAR) ||
		b->IsType(Object::CARGOBODY))
	{
		LuaEvent::Queue("onShipCollided", this,
			b->IsType(Object::CITYONPLANET) ? dynamic_cast<CityOnPlanet*>(b)->GetPlanet() : dynamic_cast<Body*>(b));
	}

	return DynamicBody::OnCollision(b, flags, relVel);
}
StationShipRepairForm::StationShipRepairForm(FormController *controller) : FaceForm(controller)
{
	m_station = Pi::player->GetDockedWith();

	SetTitle(stringf(Lang::SOMEWHERE_SHIP_REPAIRS, formatarg("station", m_station->GetLabel())));

	m_working = new Gui::Label(Lang::SHIP_IS_ALREADY_FULLY_REPAIRED);
	Add(m_working, 0, 0);

	m_tableBox = new Gui::HBox();
	m_tableBox->SetSpacing(15.0f);
	Add(m_tableBox, 0, 0);

	Gui::VBox *columnBox = new Gui::VBox();
	m_tableBox->PackEnd(columnBox);

	Gui::HBox *buttonBox = new Gui::HBox();
	buttonBox->SetSpacing(5.0f);
	Gui::Button *b = new Gui::SolidButton();
	b->onClick.connect(sigc::bind(sigc::mem_fun(this, &StationShipRepairForm::RepairHull), 1.0f));
	buttonBox->PackEnd(b);
	buttonBox->PackEnd(new Gui::Label(Lang::REPAIR_1_PERCENT_HULL));
	columnBox->PackEnd(buttonBox);

	buttonBox = new Gui::HBox();
	buttonBox->SetSpacing(5.0f);
	b = new Gui::SolidButton();
	b->onClick.connect(sigc::bind(sigc::mem_fun(this, &StationShipRepairForm::RepairHull), 100.0f));
	buttonBox->PackEnd(b);
	m_repairAllDesc = new Gui::Label("");
	buttonBox->PackEnd(m_repairAllDesc);
	columnBox->PackEnd(buttonBox);

	columnBox = new Gui::VBox();
	m_tableBox->PackEnd(columnBox);

	m_repairOneCost = new Gui::Label("");
	columnBox->PackEnd(m_repairOneCost);
	m_repairAllCost = new Gui::Label("");
	columnBox->PackEnd(m_repairAllCost);

	UpdateLabels();
}
StationShipMarketForm::StationShipMarketForm(FormController *controller) : FaceForm(controller)
{
	m_station = Pi::player->GetDockedWith();

	SetTitle(stringf(Lang::SOMEWHERE_SHIP_MARKET, formatarg("station", m_station->GetLabel())));

	Gui::VScrollBar *scroll = new Gui::VScrollBar();
	Gui::VScrollPortal *portal = new Gui::VScrollPortal(450);
	scroll->SetAdjustment(&portal->vscrollAdjust);

	float line_height = Gui::Screen::GetFontHeight();

	m_shiplistBox = new Gui::VBox();
	m_shiplistBox->SetSpacing(line_height*0.5f);
	UpdateShipList();
	m_shiplistBox->ShowAll();

	portal->Add(m_shiplistBox);
	portal->ShowAll();

	Gui::VBox *outerbox = new Gui::VBox();
	outerbox->SetSpacing(line_height);

	Gui::Fixed *heading = new Gui::Fixed(470, Gui::Screen::GetFontHeight());
	const float *col = Gui::Theme::Colors::tableHeading;
	heading->Add((new Gui::Label(Lang::SHIP))->Color(col), 0, 0);
	heading->Add((new Gui::Label(Lang::PRICE))->Color(col), 200, 0);
	heading->Add((new Gui::Label(Lang::PART_EX))->Color(col), 275, 0);
	heading->Add((new Gui::Label(Lang::CAPACITY))->Color(col), 370, 0);
	heading->Add((new Gui::Label(Lang::VIEW))->Color(col), 430, 0);
	outerbox->PackEnd(heading);

	Gui::HBox *body = new Gui::HBox();
	body->PackEnd(portal);
	body->PackEnd(scroll);
	outerbox->PackEnd(body);

	Add(outerbox, 0, 0);
	ShowAll();

	m_onShipsForSaleChangedConnection = m_station->onShipsForSaleChanged.connect(sigc::mem_fun(this, &StationShipMarketForm::OnShipsForSaleChanged));
}
void StationShipRepairForm::UpdateLabels()
{
	float hullPercent = Pi::player->GetPercentHull();

	if (hullPercent >= 100.0f)
	{
		m_working->Show();
		m_tableBox->Hide();
	}

	else {
		m_repairAllDesc->SetText(stringf(Lang::REPAIR_ENTIRE_HULL, formatarg("repairpercent", 100.0f - hullPercent)));
		const float hullDamage = 100.0f - hullPercent;
		m_repairOneCost->SetText(format_money(GetRepairCost(std::min(hullDamage, 1.0f))));
		m_repairAllCost->SetText(format_money(GetRepairCost(hullDamage)));

		m_working->Hide();
		m_tableBox->Show();
	}
}
void MsgLogWidget::ShowNext()
{
    if (m_msgQueue.empty()) {
		// current message expired and queue empty
		m_msgLabel->SetText("");
		m_msgAge = 0;
		onUngrabFocus.emit();
	} else {
		// current message expired and more in queue
		Pi::BoinkNoise();
		Pi::SetTimeAccel(1);
		Pi::RequestTimeAccel(1);
		message_t msg("","",NONE);
		// use MUST_SEE messages first
		for (std::list<message_t>::iterator i = m_msgQueue.begin();
				i != m_msgQueue.end(); ++i) {
			if ((*i).type == MUST_SEE) {
				msg = *i;
				m_msgQueue.erase(i);
				break;
			}
		}
		if (msg.type == NONE) {
			msg = m_msgQueue.front();
			m_msgQueue.pop_front();
		}

		if (msg.sender == "") {
			m_msgLabel->SetText("#0f0" + msg.message);
		} else {
			m_msgLabel->SetText(
				std::string("#ca0") + stringf(Lang::MESSAGE_FROM_X, formatarg("sender", msg.sender)) +
				std::string("\n#0f0") + msg.message);
		}
		m_msgAge = SDL_GetTicks();
		m_curMsgType = msg.type;
		onGrabFocus.emit();
	}
}
Beispiel #22
0
void LuaChatForm::OnClickSell(int t) {
	lua_State *l = Lua::manager->GetLuaState();

	LUA_DEBUG_START(l);

	_get_trade_function(l, GetAdvert()->ref, "onClickSell");

	lua_pushinteger(l, GetAdvert()->ref);
	lua_pushstring(l, EnumStrings::GetString("EquipType", t));
	pi_lua_protected_call(l, 2, 1);

	bool allow_sell = lua_toboolean(l, -1) != 0;
	lua_pop(l, 1);

	LUA_DEBUG_END(l, 0);

	if (allow_sell) {
		if (BuyFrom(Pi::player, static_cast<Equip::Type>(t), true)) {
			Pi::Message(stringf(Lang::SOLD_1T_OF, formatarg("commodity", Equip::types[t].name)));
		}
		m_commodityTradeWidget->UpdateStock(t);
	}
}
Beispiel #23
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 #24
0
void SystemInfoView::SystemChanged(const SystemPath &path)
{
	DeleteAllChildren();
	m_tabs = 0;
	m_bodyIcons.clear();

	if (!path.HasValidSystem())
		return;

	m_system = StarSystemCache::GetCached(path);

	m_sbodyInfoTab = new Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight()-100));

	if (m_system->GetUnexplored()) {
		Add(m_sbodyInfoTab, 0, 0);

		std::string _info =
			Lang::UNEXPLORED_SYSTEM_STAR_INFO_ONLY;

		Gui::Label *l = (new Gui::Label(_info))->Color(255,255,0);
		m_sbodyInfoTab->Add(l, 35, 300);
		m_selectedBodyPath = SystemPath();

		ShowAll();
		return;
	}

	m_econInfoTab = new Gui::Fixed(float(Gui::Screen::GetWidth()), float(Gui::Screen::GetHeight()-100));
	Gui::Fixed *demographicsTab = new Gui::Fixed();

	m_tabs = new Gui::Tabbed();
	m_tabs->AddPage(new Gui::Label(Lang::PLANETARY_INFO), m_sbodyInfoTab);
	m_tabs->AddPage(new Gui::Label(Lang::ECONOMIC_INFO), m_econInfoTab);
	m_tabs->AddPage(new Gui::Label(Lang::DEMOGRAPHICS), demographicsTab);
	Add(m_tabs, 0, 0);

	m_sbodyInfoTab->onMouseButtonEvent.connect(sigc::mem_fun(this, &SystemInfoView::OnClickBackground));

	int majorBodies, starports, onSurface;
	{
		float pos[2] = { 0, 0 };
		float psize = -1;
		majorBodies = starports = onSurface = 0;
		PutBodies(m_system->GetRootBody().Get(), m_econInfoTab, 1, pos, majorBodies, starports, onSurface, psize);

		majorBodies = starports = onSurface = 0;
		pos[0] = pos[1] = 0;
		psize = -1;
		PutBodies(m_system->GetRootBody().Get(), m_sbodyInfoTab, 1, pos, majorBodies, starports, onSurface, psize);

		majorBodies = starports = onSurface = 0;
		pos[0] = pos[1] = 0;
		psize = -1;
		PutBodies(m_system->GetRootBody().Get(), demographicsTab, 1, pos, majorBodies, starports, onSurface, psize);
	}

	std::string _info = stringf(
		Lang::STABLE_SYSTEM_WITH_N_MAJOR_BODIES_STARPORTS,
		formatarg("bodycount", majorBodies),
		formatarg("body(s)", std::string(majorBodies == 1 ? Lang::BODY : Lang::BODIES)),
		formatarg("portcount", starports),
		formatarg("starport(s)", std::string(starports == 1 ? Lang::STARPORT : Lang::COUNT_STARPORTS)));
	if (starports > 0)
		_info += stringf(Lang::COUNT_ON_SURFACE, formatarg("surfacecount", onSurface));
	_info += ".\n\n";
	_info += m_system->GetLongDescription();

	{
		// astronomical body info tab
		m_infoBox = new Gui::VBox();

		Gui::HBox *scrollBox = new Gui::HBox();
		scrollBox->SetSpacing(5);
		m_sbodyInfoTab->Add(scrollBox, 35, 250);

		Gui::VScrollBar *scroll = new Gui::VScrollBar();
		Gui::VScrollPortal *portal = new Gui::VScrollPortal(730);
		scroll->SetAdjustment(&portal->vscrollAdjust);

		Gui::Label *l = (new Gui::Label(_info))->Color(255,255,0);
		m_infoBox->PackStart(l);
		portal->Add(m_infoBox);
		scrollBox->PackStart(scroll);
		scrollBox->PackStart(portal);
	}

	{
		// economy tab
		Gui::HBox *scrollBox2 = new Gui::HBox();
		scrollBox2->SetSpacing(5);
		m_econInfoTab->Add(scrollBox2, 35, 300);
		Gui::VScrollBar *scroll2 = new Gui::VScrollBar();
		Gui::VScrollPortal *portal2 = new Gui::VScrollPortal(730);
		scroll2->SetAdjustment(&portal2->vscrollAdjust);
		scrollBox2->PackStart(scroll2);
		scrollBox2->PackStart(portal2);

		m_econInfo = new Gui::Label("");
		m_econInfoTab->Add(m_econInfo, 35, 250);

		Gui::Fixed *f = new Gui::Fixed();
		m_econMajImport = new Gui::Label("");
		m_econMinImport = new Gui::Label("");
		m_econMajExport = new Gui::Label("");
		m_econMinExport = new Gui::Label("");
		m_econIllegal = new Gui::Label("");
		m_econMajImport->Color(255,255,0);
		m_econMinImport->Color(255,255,0);
		m_econMajExport->Color(255,255,0);
		m_econMinExport->Color(255,255,0);
		m_econIllegal->Color(255,255,0);
		f->Add(m_econMajImport, 0, 0);
		f->Add(m_econMinImport, 150, 0);
		f->Add(m_econMajExport, 300, 0);
		f->Add(m_econMinExport, 450, 0);
		f->Add(m_econIllegal, 600, 0);
		portal2->Add(f);

		UpdateEconomyTab();
	}

	{
		Gui::Fixed *col1 = new Gui::Fixed();
		demographicsTab->Add(col1, 200, 300);
		Gui::Fixed *col2 = new Gui::Fixed();
		demographicsTab->Add(col2, 400, 300);

		const float YSEP = Gui::Screen::GetFontHeight() * 1.2f;

		col1->Add((new Gui::Label(Lang::SYSTEM_TYPE))->Color(255,255,0), 0, 0);
		col2->Add(new Gui::Label(m_system->GetShortDescription()), 0, 0);

		col1->Add((new Gui::Label(Lang::GOVERNMENT_TYPE))->Color(255,255,0), 0, 2*YSEP);
		col2->Add(new Gui::Label(m_system->GetSysPolit().GetGovernmentDesc()), 0, 2*YSEP);

		col1->Add((new Gui::Label(Lang::ECONOMY_TYPE))->Color(255,255,0), 0, 3*YSEP);
		col2->Add(new Gui::Label(m_system->GetSysPolit().GetEconomicDesc()), 0, 3*YSEP);

		col1->Add((new Gui::Label(Lang::ALLEGIANCE))->Color(255,255,0), 0, 4*YSEP);
		col2->Add(new Gui::Label(m_system->GetFaction()->name.c_str()), 0, 4*YSEP);
		col1->Add((new Gui::Label(Lang::POPULATION))->Color(255,255,0), 0, 5*YSEP);
		std::string popmsg;
		fixed pop = m_system->GetTotalPop();
		if (pop >= fixed(1,1)) { popmsg = stringf(Lang::OVER_N_BILLION, formatarg("population", pop.ToInt32())); }
		else if (pop >= fixed(1,1000)) { popmsg = stringf(Lang::OVER_N_MILLION, formatarg("population", (pop*1000).ToInt32())); }
		else if (pop != fixed(0)) { popmsg = Lang::A_FEW_THOUSAND; }
		else { popmsg = Lang::NO_REGISTERED_INHABITANTS; }
		col2->Add(new Gui::Label(popmsg), 0, 5*YSEP);

		col1->Add((new Gui::Label(Lang::SECTOR_COORDINATES))->Color(255,255,0), 0, 6*YSEP);
		col2->Add(new Gui::Label(stringf("%0{d}, %1{d}, %2{d}", path.sectorX, path.sectorY, path.sectorZ)), 0, 6*YSEP);

		col1->Add((new Gui::Label(Lang::SYSTEM_NUMBER))->Color(255,255,0), 0, 7*YSEP);
		col2->Add(new Gui::Label(stringf("%0", path.systemIndex)), 0, 7*YSEP);
	}

	UpdateIconSelections();

	ShowAll();
}
Beispiel #25
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;
		}
	}
}
Beispiel #26
0
void SystemInfoView::OnBodyViewed(SystemBody *b)
{
	std::string desc, data;

	m_infoBox->DeleteAllChildren();

	Gui::Fixed *outer = new Gui::Fixed(600, 200);
	m_infoBox->PackStart(outer);
	Gui::VBox *col1 = new Gui::VBox();
	Gui::VBox *col2 = new Gui::VBox();
	outer->Add(col1, 0, 0);
	outer->Add(col2, 300, 0);

#define _add_label_and_value(label, value) { \
	Gui::Label *l = (new Gui::Label(label))->Color(255,255,0); \
	col1->PackEnd(l); \
	l = (new Gui::Label(value))->Color(255,255,0); \
	col2->PackEnd(l); \
}

	bool multiple = (b->GetSuperType() == SystemBody::SUPERTYPE_STAR &&
					 b->GetParent() && b->GetParent()->GetType() == SystemBody::TYPE_GRAVPOINT && b->GetParent()->GetParent());
	{
		Gui::Label *l = new Gui::Label(b->GetName() + ": " + b->GetAstroDescription() +
			(multiple ? (std::string(" (")+b->GetParent()->GetName() + ")") : ""));
		l->Color(255,255,0);
		m_infoBox->PackStart(l);
	}

	_add_label_and_value(Lang::MASS, stringf(Lang::N_WHATEVER_MASSES, formatarg("mass", b->GetMassAsFixed().ToDouble()),
		formatarg("units", std::string(b->GetSuperType() == SystemBody::SUPERTYPE_STAR ? Lang::SOLAR : Lang::EARTH))));

	_add_label_and_value(Lang::RADIUS, stringf(Lang::N_WHATEVER_RADII, formatarg("radius", b->GetRadiusAsFixed().ToDouble()),
		formatarg("units", std::string(b->GetSuperType() == SystemBody::SUPERTYPE_STAR ? Lang::SOLAR : Lang::EARTH)),
		formatarg("radkm", b->GetRadius() / 1000.0)));

	if (b->GetSuperType() == SystemBody::SUPERTYPE_STAR) {
		_add_label_and_value(Lang::EQUATORIAL_RADIUS_TO_POLAR_RADIUS_RATIO, stringf("%0{f.3}", b->GetAspectRatio()));
	}

	if (b->GetType() != SystemBody::TYPE_STARPORT_ORBITAL) {
		_add_label_and_value(Lang::SURFACE_TEMPERATURE, stringf(Lang::N_CELSIUS, formatarg("temperature", b->GetAverageTemp()-273)));
		_add_label_and_value(Lang::SURFACE_GRAVITY, stringf("%0{f.3} m/s^2", b->CalcSurfaceGravity()));
	}

	if (b->GetParent()) {
		float days = float(b->GetOrbit().Period()) / float(60*60*24);
		if (days > 1000) {
			data = stringf(Lang::N_YEARS, formatarg("years", days/365));
		} else {
			data = stringf(Lang::N_DAYS, formatarg("days", b->GetOrbit().Period() / (60*60*24)));
		}
		if (multiple) {
			float pdays = float(b->GetParent()->GetOrbit().Period()) /float(60*60*24);
			data += " (" + (pdays > 1000 ? stringf(Lang::N_YEARS, formatarg("years", pdays/365))
										 : stringf(Lang::N_DAYS, formatarg("days", b->GetParent()->GetOrbit().Period() / (60*60*24)))) + ")";
		}
		_add_label_and_value(Lang::ORBITAL_PERIOD, data);
		_add_label_and_value(Lang::PERIAPSIS_DISTANCE, format_distance(b->GetOrbMin()*AU, 3) +
			(multiple ? (std::string(" (") + format_distance(b->GetParent()->GetOrbMin()*AU, 3)+ ")") : ""));
		_add_label_and_value(Lang::APOAPSIS_DISTANCE, format_distance(b->GetOrbMax()*AU, 3) +
			(multiple ? (std::string(" (") + format_distance(b->GetParent()->GetOrbMax()*AU, 3)+ ")") : ""));
		_add_label_and_value(Lang::ECCENTRICITY, stringf("%0{f.2}", b->GetOrbit().GetEccentricity()) +
			(multiple ? (std::string(" (") + stringf("%0{f.2}", b->GetParent()->GetOrbit().GetEccentricity()) + ")") : ""));
		if (b->GetType() != SystemBody::TYPE_STARPORT_ORBITAL) {
			_add_label_and_value(Lang::AXIAL_TILT, stringf(Lang::N_DEGREES, formatarg("angle", b->GetAxialTilt() * (180.0/M_PI))));
			if (b->IsRotating()) {
				_add_label_and_value(
					std::string(Lang::DAY_LENGTH)+std::string(Lang::ROTATIONAL_PERIOD),
					stringf(Lang::N_EARTH_DAYS, formatarg("days", b->GetRotationPeriodInDays())));
			}
		}
		int numSurfaceStarports = 0;
		std::string nameList;
		for (const SystemBody* kid : b->GetChildren()) {
			if (kid->GetType() == SystemBody::TYPE_STARPORT_SURFACE) {
				nameList += (numSurfaceStarports ? ", " : "") + kid->GetName();
				numSurfaceStarports++;
			}
		}
		if (numSurfaceStarports) {
			_add_label_and_value(Lang::STARPORTS, nameList);
		}
	}

	m_infoBox->ShowAll();
	m_infoBox->ResizeRequest();
}
Beispiel #27
0
	virtual void UpdateInfo() {
		char buf[512];
		std::string col1, col2;
		const ShipType &stype = Pi::player->GetShipType();
		col1 = std::string(Lang::SHIP_INFORMATION_HEADER)+std::string(stype.name);
		col1 += "\n\n";
        col1 += std::string(Lang::HYPERDRIVE);
		col1 += ":\n\n";
        col1 += std::string(Lang::CAPACITY);
		col1 += ":\n";
        col1 += std::string(Lang::FREE);
		col1 += ":\n";
        col1 += std::string(Lang::USED);
		col1 += ":\n";
        col1 += std::string(Lang::TOTAL_WEIGHT);
		col1 += ":\n\n";
        col1 += std::string(Lang::FRONT_WEAPON);
		col1 += ":\n";
        col1 += std::string(Lang::REAR_WEAPON);
		col1 += ":\n\n";
        col1 += std::string(Lang::HYPERSPACE_RANGE);
        col1 += ":\n\n";
		
		col2 = "\n\n";

		Equip::Type e = Pi::player->m_equipment.Get(Equip::SLOT_ENGINE);
		col2 += std::string(EquipType::types[e].name);

		const shipstats_t *stats;
		stats = Pi::player->CalcStats();
		snprintf(buf, sizeof(buf), "\n\n%dt\n"
					       "%dt\n"
					       "%dt\n"
					       "%dt", stats->max_capacity,
				stats->free_capacity, stats->used_capacity, stats->total_mass);
		col2 += std::string(buf);

		int numLasers = Pi::player->m_equipment.GetSlotSize(Equip::SLOT_LASER);
		if (numLasers >= 1) {
			e = Pi::player->m_equipment.Get(Equip::SLOT_LASER, 0);
			col2 += std::string("\n\n")+EquipType::types[e].name;
		} else {
			col2 += "\n\n";
            col2 += std::string(Lang::NO_MOUNTING);
		}
		if (numLasers >= 2) {
			e = Pi::player->m_equipment.Get(Equip::SLOT_LASER, 1);
			col2 += std::string("\n")+EquipType::types[e].name;
		} else {
			col2 += "\n";
            col2 += std::string(Lang::NO_MOUNTING);
		}

		col2 += "\n\n";
		col2 += stringf(Lang::N_LIGHT_YEARS_N_MAX,
			formatarg("distance", stats->hyperspace_range),
			formatarg("maxdistance", stats->hyperspace_range_max));

		for (int i=Equip::FIRST_SHIPEQUIP; i<=Equip::LAST_SHIPEQUIP; i++) {
			Equip::Type t = Equip::Type(i) ;
			Equip::Slot s = EquipType::types[t].slot;
			if ((s == Equip::SLOT_MISSILE) || (s == Equip::SLOT_ENGINE) || (s == Equip::SLOT_LASER)) continue;
			int num = Pi::player->m_equipment.Count(s, t);
			if (num == 1) {
				col1 += stringf("%0\n", EquipType::types[t].name);
			} else if (num > 1) {
				col1 += stringf("%0{d} %1s\n", num, EquipType::types[t].name);
			}
		}

		info1->SetText(col1);
		info2->SetText(col2);
		this->ResizeRequest();
	}
Beispiel #28
0
	void JettisonCargo(Equip::Type t) {
		if (Pi::player->Jettison(t)) {
			Pi::cpan->MsgLog()->Message("", stringf(Lang::JETTISONED_1T_OF_X, formatarg("commodity", EquipType::types[t].name)));
			m_infoView->UpdateInfo();
		}
	}
Beispiel #29
0
void test_stringf() {
	TEST0("", "");
	TEST0("Hello.", "Hello.");

	TEST0("backslash: \\", "backslash: \\");
	TEST0("2-backslash: \\\\", "2-backslash: \\\\");

	TEST0("%%", "%");
	TEST0("Hello: %%", "Hello: %");
	TEST0("%%: Hello", "%: Hello");
	TEST0("foo %% bar", "foo % bar");

	TEST0("%", "%(err: unfinished reference)");
	TEST0("Hello: %", "Hello: %(err: unfinished reference)");
	TEST0("% xyz", "%(err: unfinished reference) xyz");
	TEST0("%0", "%(err: unknown arg '0')");
	TEST0("%1", "%(err: unknown arg '1')");
	TEST0("%10", "%(err: unknown arg '10')");
	TEST0("%1.", "%(err: unknown arg '1').");
	TEST0("Hello: %1.", "Hello: %(err: unknown arg '1').");
	TEST0("Hello: %xyz", "Hello: %(err: unknown arg 'xyz')");
	TEST0("Hello: %xyz-hello", "Hello: %(err: unknown arg 'xyz')-hello");
	TEST0("Hello: %{xyz-he}llo", "Hello: %(err: unknown arg 'xyz-he')llo");

	TEST0("Hello: %{} end", "Hello: %(err: blank reference) end");
	TEST0("Hello: %_hello end", "Hello: %(err: unknown arg '_hello') end");

	TEST1("Hello: %xyz end", formatarg("x", 42), "Hello: %(err: unknown arg 'xyz') end");
	TEST1("Hello: %x end", formatarg("xyz", 42), "Hello: %(err: unknown arg 'x') end");
	TEST1("Hello: %1 end", formatarg("x", 42), "Hello: %(err: unknown arg '1') end");

	TEST1("Hello: %0 end", formatarg("x", 42), "Hello: 42 end");
	TEST1("Hello: %xyz end", formatarg("xyz", 42), "Hello: 42 end");
	TEST1("Hello: %{xyz} end", formatarg("xyz", 42), "Hello: 42 end");

	TEST1("Hello: %xyz%xyz end", formatarg("xyz", 42), "Hello: 4242 end");
	TEST1("Hello: %xyz %xyz end", formatarg("xyz", 42), "Hello: 42 42 end");

	TEST3("[%x, %y, %z]", formatarg("x", "X"), formatarg("y", "Y"), formatarg("z", "Z"), "[X, Y, Z]");
	TEST3("[%z, %y, %x]", formatarg("x", "X"), formatarg("y", "Y"), formatarg("z", "Z"), "[Z, Y, X]");
	TEST3("[%z, %y, %z]", formatarg("x", "X"), formatarg("y", "Y"), formatarg("z", "Z"), "[Z, Y, Z]");
	TEST3("[%0x, %1y, %2z]", formatarg("x", "X"), formatarg("y", "Y"), formatarg("z", "Z"), "[Xx, Yy, Zz]");

	TEST3("[%0x, %1y, %2z]", formatarg("x", "X"), formatarg("y", "Y"), formatarg("z", "Z"), "[Xx, Yy, Zz]");

	TESTPF1("%0{f}", 42.125, "%f");
	TESTPF1("%0{g}", 42.125, "%g");
	TESTPF1("%0{G}", 42.125, "%G");
	TESTPF1("%0{g}", 42.125e10, "%g");
	TESTPF1("%0{G}", 42.125e10, "%G");
	TESTPF1("%0{e}", 42.125, "%e");
	TESTPF1("%0{E}", 42.125, "%E");

	TESTPF1("%0{f.5}", 42.125, "%.5f");
	TESTPF1("%0{f.0}", 42.125, "%.0f");
	TESTPF1("%0{f8}", 42.125, "%8f");
	TESTPF1("%0{f0}", 42.125, "%0f");
	TESTPF1("%0{f#}", 42.125, "%#f");
	TESTPF1("%0{f+}", 42.125, "%+f");
	TESTPF1("%0{f-8.1}", 42.125, "%-8.1f");
	TESTPF1("%0{f08}", 42.125, "%08f");
	TESTPF1("%0{f+08}", 42.125, "%+08f");
	TESTPF1("%0{f+08.2}", 42.125, "%+08.2f");
	TESTPF1("%0{f08.2}", 42.125, "%08.2f");

	TESTPF1("%0{f.5}", 42.0, "%.5f");
	TESTPF1("%0{f.0}", 42.0, "%.0f");
	TESTPF1("%0{f8}", 42.0, "%8f");
	TESTPF1("%0{f0}", 42.0, "%0f");
	TESTPF1("%0{f#}", 42.0, "%#f");
	TESTPF1("%0{f+}", 42.0, "%+f");
	TESTPF1("%0{f-8.1}", 42.0, "%-8.1f");
	TESTPF1("%0{f08}", 42.0, "%08f");
	TESTPF1("%0{f+08}", 42.0, "%+08f");
	TESTPF1("%0{f+08.2}", 42.0, "%+08.2f");
	TESTPF1("%0{f08.2}", 42.0, "%08.2f");
	TEST1("%0{f }", 42.0, "%(err: bad format)");

	TESTPF1("%0{i8}", 42, "%8i");
	TESTPF1("%0{i0}", 42, "%0i");
	TESTPF1("%0{i+}", 42, "%+i");
	TESTPF1("%0{i-8}", 42, "%-8i");
	TESTPF1("%0{i08}", 42, "%08i");
	TESTPF1("%0{i+08}", 42, "%+08i");
	TESTPF1("%0{i+8}", 42, "%+8i");

	TESTPF1("%0{x02}", 93u, "%02x");

	TEST1("%0{i.0}", 42, "%(err: bad format)");
	TEST1("%0{i }", 42, "%(err: bad format)");
}
Beispiel #30
0
StationShipViewForm::StationShipViewForm(FormController *controller, int marketIndex) :
	BlankForm(controller),
	m_marketIndex(marketIndex)
{
	m_station = Pi::player->GetDockedWith();

	m_flavour = m_station->GetShipsOnSale()[marketIndex];

	const ShipType &type = ShipType::types[m_flavour.type];

	SetTitle(stringf(Lang::SOMEWHERE_SHIP_MARKET, formatarg("station", m_station->GetLabel())));

	Add(new ShipSpinnerWidget(m_flavour, 400, 400), 0, 0);


	Gui::VBox *layoutBox = new Gui::VBox();
	layoutBox->SetSpacing(10.0f);
	Add(layoutBox, 420, 0);

	Gui::HBox *statsBox = new Gui::HBox();
	statsBox->SetSpacing(20.0f);
	layoutBox->PackEnd(statsBox);

	Gui::VBox *labelBox = new Gui::VBox();
	labelBox->PackEnd(new Gui::Label(Lang::SHIP_TYPE));
	labelBox->PackEnd(new Gui::Label(Lang::PRICE));
	labelBox->PackEnd(new Gui::Label(Lang::PART_EX));
	labelBox->PackEnd(new Gui::Label(Lang::REGISTRATION_ID));
	labelBox->PackEnd(new Gui::Label(" "));
	labelBox->PackEnd(new Gui::Label(Lang::WEIGHT_EMPTY));
	labelBox->PackEnd(new Gui::Label(Lang::WEIGHT_FULLY_LADEN));
	labelBox->PackEnd(new Gui::Label(Lang::CAPACITY));
	labelBox->PackEnd(new Gui::Label(" "));
	labelBox->PackEnd(new Gui::Label(Lang::FORWARD_ACCEL_EMPTY));
	labelBox->PackEnd(new Gui::Label(Lang::FORWARD_ACCEL_LADEN));
	labelBox->PackEnd(new Gui::Label(Lang::REVERSE_ACCEL_EMPTY));
	labelBox->PackEnd(new Gui::Label(Lang::REVERSE_ACCEL_LADEN));
	labelBox->PackEnd(new Gui::Label(" "));
	labelBox->PackEnd(new Gui::Label(Lang::HYPERDRIVE_FITTED));
	statsBox->PackEnd(labelBox);

	float forward_accel_empty = type.linThrust[ShipType::THRUSTER_FORWARD] / (-9.81f*1000.0f*(type.hullMass));
	float forward_accel_laden = type.linThrust[ShipType::THRUSTER_FORWARD] / (-9.81f*1000.0f*(type.hullMass+type.capacity));
	float reverse_accel_empty = -type.linThrust[ShipType::THRUSTER_REVERSE] / (-9.81f*1000.0f*(type.hullMass));
	float reverse_accel_laden = -type.linThrust[ShipType::THRUSTER_REVERSE] / (-9.81f*1000.0f*(type.hullMass+type.capacity));

	Gui::VBox *dataBox = new Gui::VBox();
	dataBox->PackEnd(new Gui::Label(type.name));
	dataBox->PackEnd(new Gui::Label(format_money(m_flavour.price)));
	dataBox->PackEnd(new Gui::Label(format_money(m_flavour.price - Pi::player->GetFlavour()->price)));
	dataBox->PackEnd(new Gui::Label(m_flavour.regid));
	dataBox->PackEnd(new Gui::Label(" "));
	dataBox->PackEnd(new Gui::Label(stringf(Lang::NUMBER_TONNES, formatarg("mass", type.hullMass))));
	dataBox->PackEnd(new Gui::Label(stringf(Lang::NUMBER_TONNES, formatarg("mass", type.hullMass + type.capacity))));
	dataBox->PackEnd(new Gui::Label(stringf( Lang::NUMBER_TONNES, formatarg("mass", type.capacity))));
	dataBox->PackEnd(new Gui::Label(" "));
	dataBox->PackEnd(new Gui::Label(stringf(Lang::NUMBER_G, formatarg("acceleration", forward_accel_empty))));
	dataBox->PackEnd(new Gui::Label(stringf(Lang::NUMBER_G, formatarg("acceleration", forward_accel_laden))));
	dataBox->PackEnd(new Gui::Label(stringf(Lang::NUMBER_G, formatarg("acceleration", reverse_accel_empty))));
	dataBox->PackEnd(new Gui::Label(stringf(Lang::NUMBER_G, formatarg("acceleration", reverse_accel_laden))));
	dataBox->PackEnd(new Gui::Label(" "));
	dataBox->PackEnd(new Gui::Label(EquipType::types[type.hyperdrive].name));
	statsBox->PackEnd(dataBox);


	Gui::HBox *row = new Gui::HBox();
	row->SetSpacing(10.0f);

	int row_size = 5, pos = 0;
	for (int drivetype = Equip::DRIVE_CLASS1; drivetype <= Equip::DRIVE_CLASS9; drivetype++) {
		if (type.capacity < EquipType::types[drivetype].mass)
			break;

		int hyperclass = EquipType::types[drivetype].pval;
		// for the sake of hyperspace range, we count ships mass as 60% of original.
		float range = Pi::CalcHyperspaceRange(hyperclass, type.hullMass + type.capacity);

		Gui::VBox *cell = new Gui::VBox();
		row->PackEnd(cell);

		cell->PackEnd(new Gui::Label(stringf(Lang::CLASS_NUMBER, formatarg("class", hyperclass))));
		if (type.capacity < EquipType::types[drivetype].mass)
			cell->PackEnd(new Gui::Label("---"));
		else
			cell->PackEnd(new Gui::Label(stringf(Lang::NUMBER_LY, formatarg("distance", range))));

		if (++pos == row_size) {
			layoutBox->PackEnd(row);

			row = new Gui::HBox();
			row->SetSpacing(15.0f);

			pos = 0;
		}
	}

	if (pos > 0)
		layoutBox->PackEnd(row);


	Gui::HBox *buttonBox = new Gui::HBox();
	buttonBox->SetSpacing(5.0f);

	Gui::SolidButton *b = new Gui::SolidButton();
	b->onClick.connect(sigc::mem_fun(this, &StationShipViewForm::BuyShip));
	buttonBox->PackEnd(b);
	buttonBox->PackEnd(new Gui::Label(Lang::BUY_THIS_SHIP));
	Add(buttonBox, 650, 30);
}