コード例 #1
0
ファイル: SpaceStation.cpp プロジェクト: Nikoraito/pioneer
// Fill the list of starships on sale. Ships that
// can't fit atmo shields are only available in
// atmosphereless environments
void SpaceStation::UpdateShipyard()
{
	bool atmospheric = false;
	if (IsGroundStation()) {
		Body *planet = GetFrame()->m_astroBody;
		atmospheric = planet->GetSystemBody()->HasAtmosphere();
	}

	if (m_shipsOnSale.size() == 0) {
		// fill shipyard
		for (int i=Pi::rng.Int32(20); i; i--) {
			ShipFlavour s;
			ShipFlavour::MakeTrulyRandom(s, atmospheric);
			m_shipsOnSale.push_back(s);
		}
	} else if (Pi::rng.Int32(2)) {
		// add one
		ShipFlavour s;
		ShipFlavour::MakeTrulyRandom(s, atmospheric);
		m_shipsOnSale.push_back(s);
	} else {
		// remove one
		int pos = Pi::rng.Int32(m_shipsOnSale.size());
		m_shipsOnSale.erase(m_shipsOnSale.begin() + pos);
	}
	onShipsForSaleChanged.emit();
}
コード例 #2
0
ファイル: SpaceStation.cpp プロジェクト: abramhindle/pioneer
bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel)
{
	if ((flags & 0x10) && (b->IsType(Object::SHIP))) {
		Ship *s = static_cast<Ship*>(b);

		int port = -1;
		for (int i=0; i<MAX_DOCKING_PORTS; i++) {
			if (m_shipDocking[i].ship == s) { port = i; break; }
		}
		if (port == -1) return false;					// no permission
		if (!m_type->dockOneAtATimePlease) {
			if (port != int(flags & 0xf)) return false;		// wrong port
		}
		if (m_shipDocking[port].stage != 1) return false;	// already docking?

		SpaceStationType::positionOrient_t dport;
		// why stage 2? Because stage 1 is permission to dock
		// granted, stage 2 is start of docking animation.
		PiVerify(m_type->GetDockAnimPositionOrient(port, 2, 0.0, vector3d(0.0), dport, s));

		// must be oriented sensibly and have wheels down
		if (IsGroundStation()) {
			vector3d dockingNormal = GetOrient()*dport.yaxis;
			const double dot = s->GetOrient().VectorY().Dot(dockingNormal);
			if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return false;	// <0.99 harsh?
			if (s->GetVelocity().Length() > MAX_LANDING_SPEED) return false;
		}

		// if there is more docking port anim to do, don't set docked yet
		if (m_type->numDockingStages >= 2) {
			shipDocking_t &sd = m_shipDocking[port];
			sd.ship = s;
			sd.stage = 2;
			sd.stagePos = 0;
			sd.fromPos = (s->GetPosition() - GetPosition()) * GetOrient();	// station space
			sd.fromRot = Quaterniond::FromMatrix3x3(GetOrient().Transpose() * s->GetOrient());
			if (m_type->dockOneAtATimePlease) m_dockingLock = true;

			s->SetFlightState(Ship::DOCKING);
			s->SetVelocity(vector3d(0.0));
			s->SetAngVelocity(vector3d(0.0));
			s->ClearThrusterState();
		} else {
			s->SetDockedWith(this, port);				// bounces back to SS::SetDocked()
			LuaEvent::Queue("onShipDocked", s, this);
		}
		return false;
	} else {
		return true;
	}
}
コード例 #3
0
ファイル: SpaceStation.cpp プロジェクト: abramhindle/pioneer
// find an empty position for a static ship and mark it as used. these aren't
// saved and are only needed to help modules place bulk ships. this isn't a
// great place for this, but its gotta be tracked somewhere
bool SpaceStation::AllocateStaticSlot(int& slot)
{
	// no slots at ground stations
	if (IsGroundStation())
		return false;

	for (int i=0; i<NUM_STATIC_SLOTS; i++) {
		if (!m_staticSlot[i]) {
			m_staticSlot[i] = true;
			slot = i;
			return true;
		}
	}

	return false;
}
コード例 #4
0
ファイル: SpaceStation.cpp プロジェクト: abramhindle/pioneer
// Fill the list of starships on sale. Ships that
// can't fit atmo shields are only available in
// atmosphereless environments
void SpaceStation::UpdateShipyard()
{
	bool atmospheric = false;
	if (IsGroundStation()) {
		Body *planet = GetFrame()->GetBody();
		atmospheric = planet->GetSystemBody()->HasAtmosphere();
	}

	const std::vector<ShipType::Id> &ships = atmospheric ? ShipType::playable_atmospheric_ships : ShipType::player_ships;

	unsigned int toAdd = 0, toRemove = 0;

	if (m_shipsOnSale.size() == 0)
		// fill shipyard
		toAdd = Pi::rng.Int32(20);

	else if (Pi::rng.Int32(2))
		// add one
		toAdd = 1;

	else if(m_shipsOnSale.size() > 0)
		// remove one
		toRemove = 1;

	else
		// nothing happens
		return;

	for (; toAdd > 0; toAdd--) {
		ShipType::Id id = ships[Pi::rng.Int32(ships.size())];
		std::string regId = Ship::MakeRandomLabel();
		SceneGraph::ModelSkin skin;
		skin.SetRandomColors(Pi::rng);
		skin.SetPattern(Pi::rng.Int32(0, Pi::FindModel(id)->GetNumPatterns()));
		skin.SetLabel(regId);
		ShipOnSale sos(id, regId, skin);
		m_shipsOnSale.push_back(sos);
	}

	for (; toRemove > 0; toRemove--) {
		int pos = Pi::rng.Int32(m_shipsOnSale.size());
		m_shipsOnSale.erase(m_shipsOnSale.begin() + pos);
	}

	onShipsForSaleChanged.emit();
}
コード例 #5
0
ファイル: SpaceStation.cpp プロジェクト: Nikoraito/pioneer
bool SpaceStation::OnCollision(Object *b, Uint32 flags, double relVel)
{
	if ((flags & 0x10) && (b->IsType(Object::SHIP))) {
		Ship *s = static_cast<Ship*>(b);
		matrix4x4d rot;
		GetRotMatrix(rot);

		bool canDock = true;
		int port = -1;
		for (int i=0; i<MAX_DOCKING_PORTS; i++) {
			if (m_shipDocking[i].ship == s) { port = i; break; }
		}
		if (m_type->dockOneAtATimePlease) {
			for (int i=0; i<m_type->numDockingPorts; i++) {
				if (m_shipDocking[i].ship && m_shipDocking[i].stage != 1 &&
				    (m_shipDocking[i].stage != m_type->numDockingStages+1)) {
					canDock = false;
					break;
				}
			}
		} else {
			// for non-dockOneAtATimePlease, the ship is expected
			// to hit the right docking trigger surface for that port
			if (m_shipDocking[flags&0xf].ship != s) canDock = false;
		}
		if (port == -1) canDock = false;

		// hitting docking area of a station
		if (canDock) {
			SpaceStationType::positionOrient_t dport;
			// why stage 2? Because stage 1 is permission to dock
			// granted, stage 2 is start of docking animation.
			PiVerify(m_type->GetDockAnimPositionOrient(port, 2, 0.0f, vector3d(0.0), dport, s));

			double speed = s->GetVelocity().Length();

			// must be oriented sensibly and have wheels down
			if (IsGroundStation()) {
				matrix4x4d shiprot;
				s->GetRotMatrix(shiprot);
				matrix4x4d invShipRot = shiprot.InverseOf();

				vector3d dockingNormal = rot*dport.yaxis;

				// check player is sortof sensibly oriented for landing
				const double dot = vector3d(invShipRot[1], invShipRot[5], invShipRot[9]).Dot(dockingNormal);
				if ((dot < 0.99) || (s->GetWheelState() < 1.0)) return false;
			}

			if ((speed < MAX_LANDING_SPEED) &&
			    (!s->GetDockedWith()) &&
			    (m_shipDocking[port].stage == 1)) {
				// if there is more docking port anim to do,
				// don't set docked yet
				if (m_type->numDockingStages >= 2) {
					shipDocking_t &sd = m_shipDocking[port];
					sd.ship = s;
					sd.stage = 2;
					sd.stagePos = 0;
					sd.fromPos = rot.InverseOf() * (s->GetPosition() - GetPosition());
					matrix4x4d temp;
					s->GetRotMatrix(temp);
					sd.fromRot = Quaterniond::FromMatrix4x4(temp);
					s->Disable();
					s->ClearThrusterState();
					s->SetFlightState(Ship::DOCKING);
				} else {
					s->SetDockedWith(this, port);
					LuaEvent::Queue("onShipDocked", s, this);
				}
			}
		}
		return false;
	} else {
		return true;
	}
}