Ejemplo n.º 1
0
Archivo: Game.cpp Proyecto: m1h4/Xetrix
bool UpdateGame(void)
{
	Matrix2 orientation(gameShip.m_orientation);

	Vector2 gravity(0.0f,-0.004f);

	//gameShip.AddBodyForce(gravity);

	float k = 0.001f;

	if(debugSpring1)
	{
		Vector2 force = gameSpring1 - (gameShip.m_position + orientation * gameAnchor1);
		gameShip.AddBodyForce(force * k,gameShip.m_position + orientation * gameAnchor1);
	}
	
	if(debugSpring2)
	{
		Vector2 force = gameSpring2 - (gameShip.m_position + orientation * gameAnchor2);
		gameShip.AddBodyForce(force * k,gameShip.m_position + orientation * gameAnchor2);
	}

	if(HIWORD(GetAsyncKeyState(VK_LEFT)))
	{
		gameShip.m_rearEngineOrientation += GetElapsedTime() / 50.0f;
		gameShip.m_frontEngineOrientation += GetElapsedTime() / 50.0f;
	}

	if(HIWORD(GetAsyncKeyState(VK_RIGHT)))
	{
		gameShip.m_rearEngineOrientation -= GetElapsedTime() / 50.0f;
		gameShip.m_frontEngineOrientation -= GetElapsedTime() / 50.0f;
	}

	if(HIWORD(GetAsyncKeyState('B')))
	{
		gameShip.m_mainEngineOrientation += GetElapsedTime() / 50.0f;
	}

	if(HIWORD(GetAsyncKeyState('N')))
	{
		gameShip.m_mainEngineOrientation -= GetElapsedTime() / 50.0f;
	}

	if(HIWORD(GetAsyncKeyState(VK_UP)))
	{
		Matrix2 rotation(gameShip.m_frontEngineOrientation + gameShip.m_orientation);
		gameShip.AddBodyForce(rotation * Vector2(0.0f,0.002f),gameShip.m_position + orientation * gameShip.m_frontEnginePosition);
		gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_frontEnginePosition);
	}

	if(HIWORD(GetAsyncKeyState(VK_SPACE)))
	{
		Matrix2 rotation(gameShip.m_mainEngineOrientation + gameShip.m_orientation);
		gameShip.AddBodyForce(rotation * Vector2(0.0f,0.004f),gameShip.m_position + orientation * gameShip.m_mainEnginePosition);
		gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_mainEnginePosition);
		gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_mainEnginePosition);
	}

	if(HIWORD(GetAsyncKeyState(VK_UP)))
	{
		Matrix2 rotation(gameShip.m_rearEngineOrientation + gameShip.m_orientation);
		gameShip.AddBodyForce(rotation * Vector2(0.0f,0.001f),gameShip.m_position + orientation * gameShip.m_rearEnginePosition);
		gameEmitter.AddParticle(rotation * -Vector2(randf() / 60.0f,0.1f),gameShip.m_position + Vector2(randf(),randf())/50.0f + orientation * gameShip.m_rearEnginePosition);
	}
	
	gameShip.UpdateBody();
	gameEmitter.UpdateParticles();

	for(unsigned long i = 0; i < gameMissles.GetSize(); ++i)
	{
		Matrix2 orientation(gameMissles[i]->m_orientation);

		gameMissles[i]->AddBodyForce(gravity);

		Vector2 target = Matrix2(-gameMissles[i]->m_orientation) * (gameMissles[i]->m_target - gameMissles[i]->m_position);

		bool left = false,right = false;

		if(gameMissles[i]->m_life > 50.0f)
		{
			if(target.x > -0.1f && target.x < 0.1f && target.y > 0)
				left = right = true;
			else if(target.x < 0)
				right = true;
			else
				left = true;
		}
		
		if(left)
		{
			gameMissles[i]->AddBodyForce(orientation * Vector2(0.0f,0.008f),gameMissles[i]->m_position + orientation * gameMissles[i]->m_engines[0]);
			gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[0]);
			gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[0]);
		}

		if(right)
		{
			gameMissles[i]->AddBodyForce(orientation * Vector2(0.0f,0.008f),gameMissles[i]->m_position + orientation * gameMissles[i]->m_engines[1]);
			gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[1]);
			gameEmitter.AddParticle(orientation * -Vector2(randf() / 60.0f,0.1f),gameMissles[i]->m_position + Vector2(randf(),randf())/50.0f + orientation * gameMissles[i]->m_engines[1]);
		}

		gameMissles[i]->UpdateBody();
		gameMissles[i]->m_life += GetElapsedTime();

		if(gameMissles[i]->m_spring)
		{
			Vector2 force = *gameMissles[i]->m_spring - gameMissles[i]->m_position;
			gameMissles[i]->AddBodyForce(force * k);
		}

		if(gameMissles[i]->m_life > 1500.0f || target.GetLength() < 0.4f)
		{
			for(unsigned long j = 0; j < 256; ++j)
				gameEmitter.AddParticle(Vector2Normalize(Vector2(randf(),randf())) * randf() / 6.0f,gameMissles[i]->m_position);

			delete gameMissles[i];
			gameMissles.Erase(i);

			--i;
		}
	}

	return true;
}
bool
NetGameClient::DoJoinBacklog(NetJoinAnnounce* join_ann)
{
	bool finished = false;

	if (!join_ann)
	return finished;

	Sim* sim = Sim::GetSim();
	if (!sim)
	return finished;

	DWORD nid       = join_ann->GetNetID();
	DWORD oid       = join_ann->GetObjID();
	Text  name      = join_ann->GetName();
	Text  elem_name = join_ann->GetElement();
	Text  region    = join_ann->GetRegion();
	Point loc       = join_ann->GetLocation();
	Point velocity  = join_ann->GetVelocity();
	int   index     = join_ann->GetIndex();
	int   shld_lvl  = join_ann->GetShield();
	Ship* ship      = 0;
	char  ship_name[128];

	strcpy_s(ship_name, Game::GetText("NetGameClient.no-ship").data());

	if (nid && oid) {
		NetPlayer* remote_player = FindPlayerByObjID(oid);
		if (remote_player) {
			remote_player->SetName(name);
			remote_player->SetObjID(oid);

			if (index > 0)
			sprintf_s(ship_name, "%s %d", elem_name.data(), index);
			else
			sprintf_s(ship_name, "%s", elem_name.data());
		}
		else {
			Element* element = sim->FindElement(elem_name);

			if (element) {
				ship = element->GetShip(index);
			}

			if (ship) {
				strcpy_s(ship_name, ship->Name());

				SimRegion* rgn = ship->GetRegion();
				if (rgn && region != rgn->Name()) {
					SimRegion* dst = sim->FindRegion(region);
					if (dst) dst->InsertObject(ship);
				}

				ship->MoveTo(loc);
				ship->SetVelocity(velocity);

				Shield* shield = ship->GetShield();
				if (shield)
				shield->SetNetShieldLevel(shld_lvl);

				NetPlayer* remote_player = new(__FILE__,__LINE__) NetPlayer(nid);
				remote_player->SetName(name);
				remote_player->SetObjID(oid);
				remote_player->SetShip(ship);

				players.append(remote_player);
				finished = true;

				if (name == "Server A.I. Ship") {
					Print("NetGameClient::DoJoinBacklog() Remote Player '%s' has joined as '%s' with ID %d\n", name.data(), ship_name, oid);
				}
				else {
					HUDView::Message(Game::GetText("NetGameClient.remote-join").data(), name.data(), ship_name);
				}
			}
		}
	}

	return finished;
}
void
NetGameClient::DoElemCreate(NetMsg* msg)
{
	if (!msg) return;

	NetElemCreate elem_create;
	elem_create.Unpack(msg->Data());

	const char* elem_name = elem_create.GetName().data();

	::Print("NetGameClient::DoElemCreate name: %s iff: %d type %s\n",
	elem_name,
	elem_create.GetIFF(),
	Mission::RoleName(elem_create.GetType()));

	Sim*     sim   = Sim::GetSim();
	Element* elem  = sim->FindElement(elem_name);
	if (elem) {
		::Print("  element '%' already exists - ignored\n", elem_name);
		return;
	}

	elem = sim->CreateElement(elem_name,
	elem_create.GetIFF(),
	elem_create.GetType());

	int*     load     = elem_create.GetLoadout();
	int*     slots    = elem_create.GetSlots();
	int      squadron = elem_create.GetSquadron();
	int      code     = elem_create.GetObjCode();
	Text     target   = elem_create.GetObjective();
	bool     alert    = elem_create.GetAlert();
	bool     active   = elem_create.GetInFlight();

	elem->SetIntelLevel(elem_create.GetIntel());
	elem->SetLoadout(load);

	if (code > Instruction::RTB || target.length() > 0) {
		Instruction* obj  = new(__FILE__,__LINE__) Instruction(code, target);
		elem->AddObjective(obj);
	}

	Ship* carrier = sim->FindShip(elem_create.GetCarrier());
	if (carrier) {
		elem->SetCarrier(carrier);

		Hangar* hangar = carrier->GetHangar();
		if (hangar) {
			Text squadron_name = hangar->SquadronName(squadron);
			elem->SetSquadron(squadron_name);

			if (active) {
				for (int i = 0; i < 4; i++) {
					int slot = slots[i];
					if (slot > -1) {
						hangar->GotoActiveFlight(squadron, slot, elem, load);
					}
				}
			}

			else {
				FlightDeck* deck   = 0;
				int         queue  = 1000;

				for (int i = 0; i < carrier->NumFlightDecks(); i++) {
					FlightDeck* d = carrier->GetFlightDeck(i);

					if (d && d->IsLaunchDeck()) {
						int dq = hangar->PreflightQueue(d);

						if (dq < queue) {
							queue = dq;
							deck  = d;
						}
					}
				}

				for (int i = 0; i < 4; i++) {
					int slot = slots[i];
					if (slot > -1) {
						hangar->GotoAlert(squadron, slot, deck, elem, load, !alert);
					}
				}
			}
		}
	}
}
Ejemplo n.º 4
0
/*
 * Method: GetInvulnerable
 *
 * Find out whether a ship can take damage or not.
 *
 * > is_invulnerable = ship:GetInvulnerable()
 *
 * Return:
 *
 *   is_invulnerable - boolean; true if the ship is invulnerable to damage
 *
 * Availability:
 *
 *  November 2013
 *
 * Status:
 *
 *  experimental
 */
static int l_ship_get_invulnerable(lua_State *l)
{
	Ship *s = LuaObject<Ship>::CheckFromLua(1);
	lua_pushboolean(l, s->IsInvulnerable());
	return 1;
}
Ejemplo n.º 5
0
// Check if the given ship is within this projectile's blast radius. (The
// projectile will not explode unless it is also within the trigger radius.)
bool Projectile::InBlastRadius(const Ship &ship, int step) const
{
	const Mask &mask = ship.GetSprite().GetMask(step);
	return mask.WithinRange(position - ship.Position(), ship.Facing(), weapon->BlastRadius());
}
Ejemplo n.º 6
0
void MapPanel::DrawTravelPlan() const
{
	Color defaultColor(.5, .4, 0., 0.);
	Color outOfFlagshipFuelRangeColor(.55, .1, .0, 0.);
	Color withinFleetFuelRangeColor(.2, .5, .0, 0.);
	Color wormholeColor(0.5, 0.2, 0.9, 1.);
	
	Ship *ship = player.Flagship();
	bool hasHyper = ship ? ship->Attributes().Get("hyperdrive") : false;
	bool hasJump = ship ? ship->Attributes().Get("jump drive") : false;
	
	// Find out how much fuel your ship and your escorts use per jump.
	double flagshipCapacity = 0.;
	if(ship)
		flagshipCapacity = ship->Attributes().Get("fuel capacity") * ship->Fuel();
	double flagshipJumpFuel = 0.;
	if(ship)
		flagshipJumpFuel = hasHyper ? ship->Attributes().Get("scram drive") ? 150. : 100. : 200.;
	double escortCapacity = 0.;
	double escortJumpFuel = 1.;
	bool escortHasJump = false;
	// Skip your flagship, parked ships, and fighters.
	for(const shared_ptr<Ship> &it : player.Ships())
		if(it.get() != ship && !it->IsParked() && !it->CanBeCarried())
		{
			double capacity = it->Attributes().Get("fuel capacity") * it->Fuel();
			double jumpFuel = it->Attributes().Get("hyperdrive") ?
				it->Attributes().Get("scram drive") ? 150. : 100. : 200.;
			if(escortJumpFuel < 100. || capacity / jumpFuel < escortCapacity / escortJumpFuel)
			{
				escortCapacity = capacity;
				escortJumpFuel = jumpFuel;
				escortHasJump = it->Attributes().Get("jump drive");
			}
		}
	
	// Draw your current travel plan.
	if(!playerSystem)
		return;
	const System *previous = playerSystem;
	for(int i = player.TravelPlan().size() - 1; i >= 0; --i)
	{
		const System *next = player.TravelPlan()[i];
		
		// Figure out what kind of jump this is, and check if the player is able
		// to make jumps of that kind.
		bool isHyper = 
			(find(previous->Links().begin(), previous->Links().end(), next)
				!= previous->Links().end());
		bool isJump = isHyper ||
			(find(previous->Neighbors().begin(), previous->Neighbors().end(), next)
				!= previous->Neighbors().end());
		bool isWormhole = false;
		if(!((isHyper && hasHyper) || (isJump && hasJump)))
		{
			for(const StellarObject &object : previous->Objects())
				isWormhole |= (object.GetPlanet() && object.GetPlanet()->WormholeDestination(previous) == next);
			if(!isWormhole)
				break;
		}
		
		Point from = Zoom() * (next->Position() + center);
		Point to = Zoom() * (previous->Position() + center);
		Point unit = (from - to).Unit() * 7.;
		from -= unit;
		to += unit;
		
		if(isWormhole)
		{
			// Wormholes cost no fuel to travel through.
		}
		else if(!isHyper)
		{
			if(!escortHasJump)
				escortCapacity = 0.;
			flagshipCapacity -= 200.;
			escortCapacity -= 200.;
		}
		else
		{
			flagshipCapacity -= flagshipJumpFuel;
			escortCapacity -= escortJumpFuel;
		}
		
		Color drawColor = outOfFlagshipFuelRangeColor;
		if(isWormhole)
			drawColor = wormholeColor;
		else if(flagshipCapacity >= 0. && escortCapacity >= 0.)
			drawColor = withinFleetFuelRangeColor;
		else if(flagshipCapacity >= 0. || escortCapacity >= 0.)
			drawColor = defaultColor;
        
		LineShader::Draw(from, to, 3., drawColor);
		
		previous = next;
	}
}
Ejemplo n.º 7
0
static int l_ship_get_skin(lua_State *l)
{
	Ship *s = LuaObject<Ship>::CheckFromLua(1);
	LuaObject<SceneGraph::ModelSkin>::PushToLua(s->GetSkin());
	return 1;
}
/**
* Update cycle
*
* Checks for keypresses:
*   - Esc - Quits the game
*   - Left - Rotates ship left
*   - Right - Rotates ship right
*   - Up - Accelerates the ship
*   - Down - Deccelerates the ship
*
* Also calls Update() on all the ships in the universe
*/
bool Application::Update()
{
	float timedelta = hge_->Timer_GetDelta();
	if (bulletShootTimer < S_BULLET_SHOOT_INTERVAL)
	{
		bulletShootTimer += timedelta;
	}
	if (missileShootTimer < S_MISSILE_SHOOT_INTERVAL)
	{
		missileShootTimer += timedelta;
	}

	ships_.at(0)->SetAngularVelocity(0.0f);

	// Lab 13 Task 4 : Add a key to shoot missiles
	/*if (hge_->Input_GetKeyState(HGEK_ENTER))
	{
		if (!keydown_enter)
		{
			CreateMissile(ships_.at(0)->GetX(), ships_.at(0)->GetY(), ships_.at(0)->GetW(), ships_.at(0)->GetID());
			keydown_enter = true;
		}
	}
	else
	{
		if (keydown_enter)
		{
			keydown_enter = false;
		}
	}*/

	static const float MAX_ENTER_TIMER = 0.5f;
	static float enterTimer;

	if (enterTimer < MAX_ENTER_TIMER)
	{
		enterTimer += timedelta;
	}

	// Chat
	if (chatMode)
	{
		char input = hge_->Input_GetKey();

		if (input == HGEK_ESCAPE)
		{
			chatMode = false;
			typingMsg = "";
		}
		else if (input == HGEK_ENTER && enterTimer >= MAX_ENTER_TIMER)
		{
			// Send
			if (typingMsg != "")
			{
				RakNet::BitStream chatBS;
				chatBS.Write((unsigned char)ID_CHAT_SEND);
				chatBS.Write(typingMsg.c_str());
				rakpeer_->Send(&chatBS, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
				chatList.push_back(typingMsg);
			}

			// Reset
			chatMode = false;
			typingMsg = "";
			enterTimer = 0.f;
			chatShowTimer = 5.f;
		}
		else if (input >= 32 && input <= 126)
		{
			typingMsg += input;
		}
	}
	else
	{
		if (chatShowTimer > 0.f)
		{
			chatShowTimer -= timedelta;
		}

		if (hge_->Input_GetKeyState(HGEK_ENTER) && enterTimer >= MAX_ENTER_TIMER)
		{
			chatMode = true;
			enterTimer = 0.f;
		}

		// Ship controls
		if (hge_->Input_GetKeyState(HGEK_LEFT))
		{
			ships_.at(0)->SetAngularVelocity(ships_.at(0)->GetAngularVelocity() - DEFAULT_ANGULAR_VELOCITY);
		}

		if (hge_->Input_GetKeyState(HGEK_RIGHT))
		{
			ships_.at(0)->SetAngularVelocity(ships_.at(0)->GetAngularVelocity() + DEFAULT_ANGULAR_VELOCITY);
		}

		if (hge_->Input_GetKeyState(HGEK_UP))
		{
			ships_.at(0)->Accelerate(DEFAULT_ACCELERATION, timedelta);
		}

		if (hge_->Input_GetKeyState(HGEK_DOWN))
		{
			ships_.at(0)->Accelerate(-DEFAULT_ACCELERATION, timedelta);
		}

		// Shooting
		if (hge_->Input_GetKeyState(HGEK_1))
		{
			if (missileShootTimer >= S_MISSILE_SHOOT_INTERVAL)
			{
				Shoot(Projectile::PROJ_SEEKING_MISSLE);
			}
		}
		if (hge_->Input_GetKeyState(HGEK_2))
		{
			if (bulletShootTimer >= S_BULLET_SHOOT_INTERVAL)
			{
				Shoot(Projectile::PROJ_BULLET);
			}
		}

		if (hge_->Input_GetKeyState(HGEK_ESCAPE))
		{
			return true;
		}
	}

	// Update all ships
	for (ShipList::iterator ship = ships_.begin();
	ship != ships_.end(); ship++)
	{
		(*ship)->Update(timedelta);

		//collisions
		/*if ((*ship) == ships_.at(0))
			checkCollisions((*ship));*/
	}

	// Lab 13 Task 5 : Updating the missile
	/*if (mymissile)
	{
		if (mymissile->Update(ships_, timedelta))
		{
			//havecollision
			delete mymissile;
			mymissile = 0;
		}
	}*/

	// Lab 13 Task 13 : Update network missiles
	/*for (MissileList::iterator missile = missiles_.begin(); missile != missiles_.end(); missile++)
	{
		if ((*missile)->Update(ships_, timedelta))
		{
			//havecollision
			delete*missile;
			missiles_.erase(missile);
			break;
		}
	}*/

	// Update enemies
	/*for (vector<Enemy*>::iterator it = enemyList.begin(); it != enemyList.end(); ++it)
	{
		Enemy* e = *it;
		if (e->GetActive())
		{
			bool reset = e->Update(timedelta);
			if (reset)
			{
				RakNet::BitStream bs;
				bs.Write((unsigned char)ID_DESTROY_ENEMY);
				bs.Write(e->GetID());
				rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
			}
		}
	}*/

	// Update projectile
	for (vector<Projectile*>::iterator it = projectileList.begin(); it != projectileList.end(); ++it)
	{
		Projectile* p = *it;
		if (/*p->GetOwner() == ships_.at(0) && */p->GetActive()) // Only update your own projectile
		{
			bool reset = p->Update(timedelta);
			RakNet::BitStream bs;
			if (reset)
			{
				DestroyProjectile(p);
				bs.Write((unsigned char)ID_DESTROY_PROJECTILE);
				bs.Write(p->GetID());
				rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
			}
			else
			{
				for (vector<Enemy*>::iterator it2 = enemyList.begin(); it2 != enemyList.end(); ++it2)
				{
					Enemy* e = *it2;
					if (e->GetActive())
					{
						bool collision = p->CollideWith(e);
						if (collision)
						{
							int newHP = e->Injure(p->GetDamage());
							if (newHP <= 0)
							{
								RakNet::BitStream bs;
								// Add score to player
								p->GetOwner()->AddScore(100);

								bs.Write((unsigned char)ID_UPDATE_SCORE);
								bs.Write(p->GetOwner()->GetID());
								bs.Write(p->GetOwner()->GetScore());
								rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);

								// Destroy enemy
								DestroyEnemy(e);

								// Send to server to destroy enemy
								bs.ResetWritePointer();
								bs.Write((unsigned char)ID_DESTROY_ENEMY);
								bs.Write(e->GetID());
								rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
							}
							else
							{
								// Send to server to injure enemy
								RakNet::BitStream bs;
								bs.ResetWritePointer();
								bs.Write((unsigned char)ID_INJURE_ENEMY);
								bs.Write(e->GetID());
								bs.Write(e->GetHP());
								rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
							}

							// Reset projectile
							DestroyProjectile(p);
							bs.ResetWritePointer();
							bs.Write((unsigned char)ID_DESTROY_PROJECTILE);
							bs.Write(p->GetID());
							rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
						}
					}
				}
				/*int max = projectileUpdateList.size();
				int count = 0;
				for (vector<Projectile*>::iterator it2 = projectileUpdateList.begin(); it2 != projectileUpdateList.end(); ++it2)
				{
					Projectile* p2 = *it2;
					if (p == p2)
					{
						break;
					}
					else
					{
						++count;
					}
				}
				if (count == max)
				{
					projectileUpdateList.push_back(p);
				}*/
				/*bs.Write((unsigned char)ID_UPDATE_PROJECTILE);
				bs.Write(p->GetID());
				bs.Write(p->GetActive());
				bs.Write(p->GetType());
				bs.Write(p->GetX());
				bs.Write(p->GetY());
				bs.Write(p->GetVelocityX());
				bs.Write(p->GetVelocityY());
				bs.Write(p->GetSpeed());
				bs.Write(p->GetDamage());
				bs.Write(p->GetOwner()->GetID());
				// Send target id if available
				if (p->GetTarget())
				{
					bs.Write(p->GetTarget()->GetID());
				}
				else
				{
					bs.Write(-1);
				}
				rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);*/
			}
		}
	}

	// Update explosions
	for (vector<Explosion*>::iterator it = explosionList.begin(); it != explosionList.end(); ++it)
	{
		Explosion* e = *it;
		if ( e->isActive())
		{
			e->Update(timedelta);
		}
	}

	// Update boom
	for (vector<Boom*>::iterator it = boomList.begin(); it != boomList.end(); ++it)
	{
		Boom* b = *it;
		if (b->isActive())
		{
			b->Update(timedelta);
		}
	}

	// Packet receive
	if (Packet* packet = rakpeer_->Receive())
	{
		RakNet::BitStream bs(packet->data, packet->length, false);
		
		unsigned char msgid = 0;
		RakNetTime timestamp = 0;

		bs.Read(msgid);

		if (msgid == ID_TIMESTAMP)
		{
			bs.Read(timestamp);
			bs.Read(msgid);
		}

		switch(msgid)
		{
		case ID_CONNECTION_REQUEST_ACCEPTED:
			{
				std::cout << "Connected to Server" << std::endl;
				SendScreenSize();
				InitEnemyList();
				InitExplosionList();
				InitBoomList();
				InitProjectileList();
				InitBackground();
				InitBase();
				InitScore();
				chatMsg = new hgeFont("font1.fnt");
				chatMsg->SetScale(1);
				
			}
			break;

		case ID_NO_FREE_INCOMING_CONNECTIONS:
		case ID_CONNECTION_LOST:
		case ID_DISCONNECTION_NOTIFICATION:
			std::cout << "Lost Connection to Server" << std::endl;
			rakpeer_->DeallocatePacket(packet);
			return true;

		case ID_WELCOME:
			{
				unsigned int shipcount, id;
				float x_, y_;
				int type_;
				std::string temp;
				char chartemp[5];

				bs.Read(id);
				ships_.at(0)->setID( id );
				bs.Read(shipcount);

				for (unsigned int i = 0; i < shipcount; ++ i)
				{
					bs.Read(id);
					bs.Read(x_);
					bs.Read(y_);
					bs.Read(type_);
					std::cout << "New Ship pos" << x_ << " " << y_ << std::endl;
					Ship* ship = new Ship(type_, x_, y_ ); 
					temp = "Ship ";
					temp += _itoa(id, chartemp, 10);
					ship->SetName(temp.c_str());
					ship->setID( id );
					ships_.push_back(ship);
				}

				for (vector<Enemy*>::iterator it = enemyList.begin(); it != enemyList.end(); ++it)
				{
					int id, hp;
					bool active;
					Enemy::ENEMY_TYPE type;
					float x, y, vel_x, vel_y, speed;
					bs.Read(id);
					bs.Read(active);
					bs.Read(type);
					bs.Read(x);
					bs.Read(y);
					bs.Read(vel_x);
					bs.Read(vel_y);
					bs.Read(speed);
					bs.Read(hp);
					Enemy* e = FindEnemyByID(id);
					if (e)
					{
						float w = CalcW(Vector2(vel_x, vel_y));
						/*if (speed != 0)
						{
							w = acosf(vel_x / speed);
						}
						else
						{
							w = 0.f;
						}*/
						e->Init(type, x, y, w, active);
						e->SetVelocityX(vel_x);
						e->SetVelocityY(vel_y);
						e->SetSpeed(speed);
						e->SetHP(hp);
					}
				}
				
				// Base hp
				bs.Read(base_hp);

				SendInitialPosition();
			}
			break;
		case ID_REJECT_PLAYER:
			{
				std::cout << "Rejected player" << std::endl;
				return true;
			}
			break;

		case ID_NEWSHIP:
			{
				unsigned int id;
				bs.Read(id);

				if( id == ships_.at(0)->GetID() )
				{
					// if it is me
					break;
				}
				else
				{
					float x_, y_;
					int type_;
					std::string temp;
					char chartemp[5];

					bs.Read( x_ );
					bs.Read( y_ );
					bs.Read( type_ );
					std::cout << "New Ship pos" << x_ << " " << y_ << std::endl;
					Ship* ship = new Ship(type_, x_, y_);
					temp = "Ship "; 
					temp += _itoa(id, chartemp, 10);
					ship->SetName(temp.c_str());
					ship->setID( id );
					ships_.push_back(ship);
				}

			}
			break;

		case ID_LOSTSHIP:
			{
				unsigned int shipid;
				bs.Read(shipid);
				for (ShipList::iterator itr = ships_.begin(); itr != ships_.end(); ++itr)
				{
					if ((*itr)->GetID() == shipid)
					{
						delete *itr;
						ships_.erase(itr);
						break;
					}
				}
			}
			break;

		case ID_INITIALPOS:
			break;

		case ID_MOVEMENT:
			{
				unsigned int shipid;
				float temp;
				float x,y,w;
				bs.Read(shipid);
				for (ShipList::iterator itr = ships_.begin(); itr != ships_.end(); ++itr)
				{
					if ((*itr)->GetID() == shipid)
					{
						// this portion needs to be changed for it to work
#ifdef INTERPOLATEMOVEMENT
						bs.Read(x);
						bs.Read(y);
						bs.Read(w);

						(*itr)->SetServerLocation( x, y, w ); 

						bs.Read(temp);
						(*itr)->SetServerVelocityX( temp );
						bs.Read(temp);
						(*itr)->SetServerVelocityY( temp );
						bs.Read(temp);
						(*itr)->SetAngularVelocity( temp );

						(*itr)->DoInterpolateUpdate();
#else
						bs.Read(x);
						bs.Read(y);
						bs.Read(w);
						(*itr)->setLocation( x, y, w ); 

						// Lab 7 Task 1 : Read Extrapolation Data velocity x, velocity y & angular velocity
						bs.Read(temp);
						(*itr)->SetVelocityX( temp );
						bs.Read(temp);
						(*itr)->SetVelocityY( temp );
						bs.Read(temp);
						(*itr)->SetAngularVelocity( temp );
#endif

						break;
					}
				}
			}
			break;

		case ID_COLLIDE:
			{
				unsigned int shipid;
				float x, y;
				bs.Read(shipid);
				
				if( shipid == ships_.at(0)->GetID() )
				{
					std::cout << "collided with someone!" << std::endl;
					bs.Read(x);
					bs.Read(y);
					ships_.at(0)->SetX( x );
					ships_.at(0)->SetY( y );
					bs.Read(x);
					bs.Read(y);
					ships_.at(0)->SetVelocityX( x );
					ships_.at(0)->SetVelocityY( y );
#ifdef INTERPOLATEMOVEMENT
					bs.Read(x);
					bs.Read(y);
					ships_.at(0)->SetServerVelocityX( x );
					ships_.at(0)->SetServerVelocityY( y );
#endif	
				}
			}
			break;


		// Lab 13 Task 10 : new cases to handle missile on application side
		case ID_NEWMISSILE:
			{
				float x, y, w;
				int id;
				bs.Read(id);
				bs.Read(x);
				bs.Read(y);
				bs.Read(w);
				missiles_.push_back(new Missile("missile.png", x, y, w, id));
			}
			break;
		case ID_UPDATEMISSILE:
			{
				float x, y, w;
				int id;
				char deleted;
				bs.Read(id);
				bs.Read(deleted);
				for (MissileList::iterator itr = missiles_.begin(); itr !=
					missiles_.end(); ++itr)
				{
					if ((*itr)->GetOwnerID() == id)
					{
						if (deleted == 1)
						{
							delete*itr;
							missiles_.erase(itr);
						}
						else
						{
							bs.Read(x);
							bs.Read(y);
							bs.Read(w);
							(*itr)->UpdateLoc(x, y, w);
							bs.Read(x);
							(*itr)->SetVelocityX(x);
							bs.Read(y);
							(*itr)->SetVelocityY(y);
						}
						break;
					}
				}
			}
			break;
		case ID_NEW_ENEMY:
			{
				int id, hp;
				Enemy::ENEMY_TYPE type;
				float x, y, vel_x, vel_y, speed;
				bs.Read(id);
				bs.Read(type);
				bs.Read(x);
				bs.Read(y);
				bs.Read(vel_x);
				bs.Read(vel_y);
				bs.Read(speed);
				bs.Read(hp);
				Enemy* e = FindEnemyByID(id);
				if (e)
				{
					float w = CalcW(Vector2(vel_x, vel_y));
					e->Init(type, x, y, w);
					e->SetVelocityX(vel_x);
					e->SetVelocityY(vel_y);
					e->SetSpeed(speed);
					e->SetHP(hp);
				}
			}
			break;
		case ID_UPDATE_ENEMY:
			{
				int id;
				bs.Read(id);
				Enemy* e = FindEnemyByID(id);
				if (e)
				{
					float x, y;
					bs.Read(x);
					bs.Read(y);
					e->SetX(x);
					e->SetY(y);
				}
			}
			break;
		case ID_INJURE_ENEMY:
			{
				int id, hp;
				bs.Read(id);
				Enemy* e = FindEnemyByID(id);
				if (e && e->GetActive())
				{
					bs.Read(hp);
					e->SetHP(hp);
				}
			}
			break;
		case ID_DESTROY_ENEMY:
			{
				int id;
				bs.Read(id);
				Enemy* e = FindEnemyByID(id);

				DestroyEnemy(e);
			}
			break;
		case ID_SHOOT:
			{
				int id, damage, owner, target;
				Projectile::PROJECTILE_TYPE type;
				float x, y, w, vel_x, vel_y, speed;
				bs.Read(id);

				Projectile* p = FindProjectileByID(id);
				if (p)
				{
					bs.Read(type);
					bs.Read(x);
					bs.Read(y);
					bs.Read(w);
					bs.Read(vel_x);
					bs.Read(vel_y);
					bs.Read(speed);
					bs.Read(damage);
					bs.Read(owner);
					bs.Read(target);
					
					Ship* sOwner = FindShipByID(owner);
					if (sOwner)
					{
						p->Init(sOwner, type, x, y, w);
						p->SetVelocityX(vel_x);
						p->SetVelocityY(vel_y);
						p->SetSpeed(speed);
						p->SetDamage(damage);
						if (target != -1)
						{
							Enemy* sTarget = FindEnemyByID(target);
							if (sTarget)
							{
								p->SetTarget(sTarget);
							}
						}
					}
				}
			}
			break;
		case ID_UPDATE_PROJECTILE:
			{
				int id, damage, owner, target;
				Projectile::PROJECTILE_TYPE type;
				float x, y, vel_x, vel_y, speed;
				bool active;
				bs.Read(id);

				Projectile* p = FindProjectileByID(id);
				if (p)
				{
					bs.Read(active);
					bs.Read(type);
					bs.Read(x);
					bs.Read(y);
					bs.Read(vel_x);
					bs.Read(vel_y);
					bs.Read(speed);
					bs.Read(damage);
					bs.Read(owner);
					bs.Read(target);

					Ship* sOwner = FindShipByID(owner);
					if (sOwner)
					{
						p->SetOwner(sOwner);
						p->SetType(type);
						p->SetX(x);
						p->SetY(y);
						p->SetActive(active);
						p->SetVelocityX(vel_x);
						p->SetVelocityY(vel_y);
						p->SetSpeed(speed);
						p->SetDamage(damage);
						if (target != -1)
						{
							Enemy* sTarget = FindEnemyByID(target);
							if (sTarget)
							{
								p->SetTarget(sTarget);
							}
						}
					}
				}
			}
			break;
		case ID_DESTROY_PROJECTILE:
			{
				int id;
				bs.Read(id);
				Projectile* p = FindProjectileByID(id);
				if (p && p->GetActive())
				{
					// Reset projectile
					//DestroyProjectile(p);
					p->Reset();
				}
			}
			break;
		case ID_UPDATE_BASE:
			{
				bs.Read(base_hp);
			}
			break;
		case ID_UPDATE_SCORE:
			{
				int id, score;
				bs.Read(id);
				Ship* s = FindShipByID(id);
				if (s)
				{
					bs.Read(score);
					s->SetScore(score);
				}
			}
			break;
		case ID_CHAT_SEND:
			{
				char cMsg[256];
				bs.Read(cMsg);
				chatList.push_back(cMsg);
				chatShowTimer = 5.f;
			}
			break;

		default:
			std::cout << "Unhandled Message Identifier: " << (int)msgid << std::endl;

		}
		rakpeer_->DeallocatePacket(packet);
	}

	if (base_hp <= 0)
	{
		return true;
	}

	// Send projectile updates
	/*static const int SYNCS_PER_SEC = 24;
	static const float TIME_PER_SYNC = 1 / SYNCS_PER_SEC;
	static float projSendTimer = TIME_PER_SYNC;
	if (projSendTimer < TIME_PER_SYNC)
	{
		projSendTimer += timedelta;
	}
	else
	{
		for (vector<Projectile*>::iterator it = projectileList.begin(); it != projectileList.end(); ++it)
		{
			Projectile* p = *it;
			if (p->GetActive() && p->GetOwner() == ships_.at(0))
			{
				RakNet::BitStream sendProj;
				sendProj.Write((unsigned char)ID_UPDATE_PROJECTILE);
				sendProj.Write(p->GetID());
				sendProj.Write(p->GetActive());
				sendProj.Write(p->GetType());
				sendProj.Write(p->GetX());
				sendProj.Write(p->GetY());
				sendProj.Write(p->GetVelocityX());
				sendProj.Write(p->GetVelocityY());
				sendProj.Write(p->GetSpeed());
				sendProj.Write(p->GetDamage());
				sendProj.Write(p->GetOwner()->GetID());
				// Send target id if available
				if (p->GetTarget())
				{
					sendProj.Write(p->GetTarget()->GetID());
				}
				else
				{
					sendProj.Write(-1);
				}
				rakpeer_->Send(&sendProj, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
				std::cout << p->GetX() << " | " << p->GetY() << std::endl;
			}
		}
		projSendTimer = 0.f;
	}*/

	// Send data
	float timeToSync = 1000 / 24; // Sync 24 times in a second (Millisecond)
	if (RakNet::GetTime() - timer_ > timeToSync)
	{
		timer_ = RakNet::GetTime(); // Store previous time
		RakNet::BitStream bs2;
		unsigned char msgid = ID_MOVEMENT;
		bs2.Write(msgid);

#ifdef INTERPOLATEMOVEMENT
		bs2.Write(ships_.at(0)->GetID());
		bs2.Write(ships_.at(0)->GetServerX());
		bs2.Write(ships_.at(0)->GetServerY());
		bs2.Write(ships_.at(0)->GetServerW());
		bs2.Write(ships_.at(0)->GetServerVelocityX());
		bs2.Write(ships_.at(0)->GetServerVelocityY());
		bs2.Write(ships_.at(0)->GetAngularVelocity());

#else
		bs2.Write(ships_.at(0)->GetID());
		bs2.Write(ships_.at(0)->GetX());
		bs2.Write(ships_.at(0)->GetY());
		bs2.Write(ships_.at(0)->GetW());
		// Lab 7 Task 1 : Add Extrapolation Data velocity x, velocity y & angular velocity
		bs2.Write(ships_.at(0)->GetVelocityX());
		bs2.Write(ships_.at(0)->GetVelocityY());
		bs2.Write(ships_.at(0)->GetAngularVelocity());
#endif

		rakpeer_->Send(&bs2, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true);


		// Lab 13 Task 11 : send missile update 
		/*if (mymissile)
		{
			RakNet::BitStream bs3;
			unsigned char msgid2 = ID_UPDATEMISSILE;
			unsigned char deleted = 0;
			bs3.Write(msgid2);
			bs3.Write(mymissile->GetOwnerID());
			bs3.Write(deleted);
			bs3.Write(mymissile->GetX());
			bs3.Write(mymissile->GetY());
			bs3.Write(mymissile->GetW());
			bs3.Write(mymissile->GetVelocityX());
			bs3.Write(mymissile->GetVelocityY());
			rakpeer_->Send(&bs3, HIGH_PRIORITY, UNRELIABLE_SEQUENCED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
		}*/

		// Send update projectile
		/*for (int i = 0; i < projectileUpdateList.size(); ++i)
		{
			Projectile* p = projectileList[i];
			if (p && p->GetActive())
			{
				RakNet::BitStream sendProj;
				sendProj.Write((unsigned char)ID_UPDATE_PROJECTILE);
				sendProj.Write(p->GetID());
				sendProj.Write(p->GetActive());
				sendProj.Write(p->GetType());
				sendProj.Write(p->GetX());
				sendProj.Write(p->GetY());
				sendProj.Write(p->GetVelocityX());
				sendProj.Write(p->GetVelocityY());
				sendProj.Write(p->GetSpeed());
				sendProj.Write(p->GetDamage());
				sendProj.Write(p->GetOwner()->GetID());
				// Send target id if available
				if (p->GetTarget())
				{
					sendProj.Write(p->GetTarget()->GetID());
				}
				else
				{
					sendProj.Write(-1);
				}
				rakpeer_->Send(&sendProj, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
			}
		}
		projectileUpdateList.clear();*/
	}

	return false;
}
void ScannerWidget::Update()
{
	m_contacts.clear();

	if (Pi::player->m_equipment.Get(Equip::SLOT_SCANNER) != Equip::SCANNER) {
		m_mode = SCANNER_MODE_AUTO;
		m_currentRange = m_manualRange = m_targetRange = SCANNER_RANGE_MIN;
		return;
	}

	enum { RANGE_MAX, RANGE_FAR_OTHER, RANGE_NAV, RANGE_FAR_SHIP, RANGE_COMBAT } range_type = RANGE_MAX;
	float combat_dist = 0, far_ship_dist = 0, nav_dist = 0, far_other_dist = 0;

	// collect the bodies to be displayed, and if AUTO, distances
	for (Space::bodiesIter_t i = Space::bodies.begin(); i != Space::bodies.end(); ++i) {
		if ((*i) == Pi::player) continue;

		float dist = float((*i)->GetPositionRelTo(Pi::player).Length());
		if (dist > SCANNER_RANGE_MAX) continue;

		Contact c;
		c.type = (*i)->GetType();
		c.pos = (*i)->GetPositionRelTo(Pi::player);
		c.isSpecial = false;

		switch ((*i)->GetType()) {

			case Object::MISSILE:
				// player's own missiles are ignored for range calc but still shown
				if (static_cast<Missile*>(*i)->GetOwner() == Pi::player) {
					c.isSpecial = true;
					break;
				}

				// fall through

			case Object::SHIP: {
				Ship *s = static_cast<Ship*>(*i);
				if (s->GetFlightState() != Ship::FLYING && s->GetFlightState() != Ship::LANDED)
					continue;

				if (m_mode == SCANNER_MODE_AUTO && range_type != RANGE_COMBAT) {
					if ((*i) == Pi::player->GetCombatTarget()) {
						c.isSpecial = true;
						combat_dist = dist;
						range_type = RANGE_COMBAT;
					}
					else if (dist > far_ship_dist) {
						far_ship_dist = dist;
						range_type = RANGE_FAR_SHIP;
					}
				}
				break;
			}

			case Object::SPACESTATION:
			case Object::CARGOBODY:
			case Object::HYPERSPACECLOUD:

				// XXX could maybe add orbital stations
				if (m_mode == SCANNER_MODE_AUTO && range_type != RANGE_NAV && range_type != RANGE_COMBAT) {
					if ((*i) == Pi::player->GetNavTarget()) {
						c.isSpecial = true;
						nav_dist = dist;
						range_type = RANGE_NAV;
					}
					else if (dist > far_other_dist) {
						far_other_dist = dist;
						range_type = RANGE_FAR_OTHER;
					}
				}
				break;

			default:
				continue;
		}

		m_contacts.push_back(c);
	}

	if (KeyBindings::increaseScanRange.IsActive()) {
		if (m_mode == SCANNER_MODE_AUTO) {
			m_manualRange = m_targetRange;
			m_mode = SCANNER_MODE_MANUAL;
		}
		else
			m_manualRange = m_currentRange;
		m_manualRange = Clamp(m_manualRange * 1.05f, SCANNER_RANGE_MIN, SCANNER_RANGE_MAX);
	}
	else if (KeyBindings::decreaseScanRange.IsActive() && m_manualRange > SCANNER_RANGE_MIN) {
		if (m_mode == SCANNER_MODE_AUTO) {
			m_manualRange = m_targetRange;
			m_mode = SCANNER_MODE_MANUAL;
		}
		else
			m_manualRange = m_currentRange;
		m_manualRange = Clamp(m_manualRange * 0.95f, SCANNER_RANGE_MIN, SCANNER_RANGE_MAX);
	}

	// range priority is combat target > ship/missile > nav target > other
	if (m_mode == SCANNER_MODE_AUTO) {
		switch (range_type) {
			case RANGE_COMBAT:
				m_targetRange = Clamp(combat_dist * A_BIT, SCANNER_RANGE_MIN, SCANNER_RANGE_MAX);
				break;
			case RANGE_FAR_SHIP:
				m_targetRange = Clamp(far_ship_dist * A_BIT, SCANNER_RANGE_MIN, SCANNER_RANGE_MAX);
				break;
			case RANGE_NAV:
				m_targetRange = Clamp(nav_dist * A_BIT, SCANNER_RANGE_MIN, SCANNER_RANGE_MAX);
				break;
			case RANGE_FAR_OTHER:
				m_targetRange = Clamp(far_other_dist * A_BIT, SCANNER_RANGE_MIN, SCANNER_RANGE_MAX);
				break;
			default:
				m_targetRange = SCANNER_RANGE_MAX;
				break;
		}
	}
	
	else
		m_targetRange = m_manualRange;
}
void Engine::CalculateStep()
{
	FrameTimer loadTimer;
	
	// Clear the list of objects to draw.
	draw[calcTickTock].Clear(step);
	radar[calcTickTock].Clear();
	
	if(!player.GetSystem())
		return;
	
	// Now, all the ships must decide what they are doing next.
	ai.Step(ships, player);
	const Ship *flagship = player.Flagship();
	bool wasHyperspacing = (flagship && flagship->IsEnteringHyperspace());
	
	// Now, move all the ships. We must finish moving all of them before any of
	// them fire, or their turrets will be targeting where a given ship was
	// instead of where it is now. This is also where ships get deleted, and
	// where they may create explosions if they are dying.
	for(auto it = ships.begin(); it != ships.end(); )
	{
		int hyperspaceType = (*it)->HyperspaceType();
		bool wasHere = (flagship && (*it)->GetSystem() == flagship->GetSystem());
		bool wasHyperspacing = (*it)->IsHyperspacing();
		// Give the ship the list of effects so that it can draw explosions,
		// ion sparks, jump drive flashes, etc.
		if(!(*it)->Move(effects, flotsam))
		{
			// If Move() returns false, it means the ship should be removed from
			// play. That may be because it was destroyed, because it is an
			// ordinary ship that has been out of system for long enough to be
			// "forgotten," or because it is a fighter that just docked with its
			// mothership. Report it destroyed if that's really what happened:
			if((*it)->IsDestroyed())
				eventQueue.emplace_back(nullptr, *it, ShipEvent::DESTROY);
			it = ships.erase(it);
		}
		else
		{
			if(&**it != flagship)
			{
				// Did this ship just begin hyperspacing?
				if(wasHere && !wasHyperspacing && (*it)->IsHyperspacing())
					Audio::Play(
						Audio::Get(hyperspaceType >= 200 ? "jump out" : "hyperdrive out"),
						(*it)->Position());
				
				// Did this ship just jump into the player's system?
				if(!wasHere && flagship && (*it)->GetSystem() == flagship->GetSystem())
					Audio::Play(
						Audio::Get(hyperspaceType >= 200 ? "jump in" : "hyperdrive in"),
						(*it)->Position());
			}
			
			// Boarding:
			bool autoPlunder = !(*it)->GetGovernment()->IsPlayer();
			shared_ptr<Ship> victim = (*it)->Board(autoPlunder);
			if(victim)
				eventQueue.emplace_back(*it, victim,
					(*it)->GetGovernment()->IsEnemy(victim->GetGovernment()) ?
						ShipEvent::BOARD : ShipEvent::ASSIST);
			++it;
		}
	}
	
	if(!wasHyperspacing && flagship && flagship->IsEnteringHyperspace())
		Audio::Play(Audio::Get(flagship->HyperspaceType() >= 200 ? "jump drive" : "hyperdrive"));
	
	if(flagship && player.GetSystem() != flagship->GetSystem())
	{
		// Wormhole travel:
		if(!wasHyperspacing)
			for(const auto &it : player.GetSystem()->Objects())
				if(it.GetPlanet() && it.GetPlanet()->IsWormhole() &&
						it.GetPlanet()->WormholeDestination(player.GetSystem()) == flagship->GetSystem())
					player.Visit(it.GetPlanet());
		
		doFlash = Preferences::Has("Show hyperspace flash");
		player.SetSystem(flagship->GetSystem());
		EnterSystem();
	}
	
	// Draw the planets.
	Point newCenter = center;
	Point newCenterVelocity;
	if(flagship)
	{
		newCenter = flagship->Position();
		newCenterVelocity = flagship->Velocity();
	}
	else
		doClick = false;
	draw[calcTickTock].SetCenter(newCenter, newCenterVelocity);
	radar[calcTickTock].SetCenter(newCenter);
	
	for(const StellarObject &object : player.GetSystem()->Objects())
		if(object.HasSprite())
		{
			// Don't apply motion blur to very large planets and stars.
			if(object.Width() >= 280.)
				draw[calcTickTock].AddUnblurred(object);
			else
				draw[calcTickTock].Add(object);
			
			double r = max(2., object.Radius() * .03 + .5);
			radar[calcTickTock].Add(RadarType(object), object.Position(), r, r - 1.);
			
			if(object.GetPlanet())
				object.GetPlanet()->DeployDefense(ships);
			
			Point position = object.Position() - newCenter;
			if(doClick && object.GetPlanet() && (clickPoint - position).Length() < object.Radius())
			{
				if(&object == player.Flagship()->GetTargetPlanet())
				{
					if(!object.GetPlanet()->CanLand())
						Messages::Add("The authorities on " + object.GetPlanet()->Name() +
							" refuse to let you land.");
					else
					{
						clickCommands |= Command::LAND;
						Messages::Add("Landing on " + object.GetPlanet()->Name() + ".");
					}
				}
				else
					player.Flagship()->SetTargetPlanet(&object);
			}
		}
	
	// Add all neighboring systems to the radar.
	const System *targetSystem = flagship ? flagship->GetTargetSystem() : nullptr;
	const vector<const System *> &links = (flagship && flagship->Attributes().Get("jump drive")) ?
		player.GetSystem()->Neighbors() : player.GetSystem()->Links();
	for(const System *system : links)
		radar[calcTickTock].AddPointer(
			(system == targetSystem) ? Radar::SPECIAL : Radar::INACTIVE,
			system->Position() - player.GetSystem()->Position());
	
	// Now that the planets have been drawn, we can draw the asteroids on top
	// of them. This could be done later, as long as it is done before the
	// collision detection.
	asteroids.Step();
	asteroids.Draw(draw[calcTickTock], newCenter);
	
	// Move existing projectiles. Do this before ships fire, which will create
	// new projectiles, since those should just stay where they are created for
	// this turn. This is also where projectiles get deleted, which may also
	// result in a "die" effect or a sub-munition being created. We could not
	// move the projectiles before this because some of them are homing and need
	// to know the current positions of the ships.
	list<Projectile> newProjectiles;
	for(auto it = projectiles.begin(); it != projectiles.end(); )
	{
		if(!it->Move(effects))
		{
			it->MakeSubmunitions(newProjectiles);
			it = projectiles.erase(it);
		}
		else
			++it;
	}
	projectiles.splice(projectiles.end(), newProjectiles);
	
	// Move the flotsam, which should be drawn underneath the ships.
	for(auto it = flotsam.begin(); it != flotsam.end(); )
	{
		if(!it->Move(effects))
		{
			it = flotsam.erase(it);
			continue;
		}
		
		Ship *collector = nullptr;
		for(const shared_ptr<Ship> &ship : ships)
		{
			if(ship->GetSystem() != player.GetSystem() || ship->CannotAct())
				continue;
			if(ship.get() == it->Source() || ship->Cargo().Free() < it->UnitSize())
				continue;
			
			const Mask &mask = ship->GetMask(step);
			if(mask.Contains(it->Position() - ship->Position(), ship->Facing()))
			{
				collector = ship.get();
				break;
			}
		}
		if(collector)
		{
			string name;
			if(collector->IsYours())
			{
				if(collector->GetParent())
					name = "Your ship \"" + collector->Name() + "\" picked up ";
				else
					name = "You picked up ";
			}
			string commodity;
			int amount = 0;
			if(it->OutfitType())
			{
				amount = collector->Cargo().Add(it->OutfitType(), it->Count());
				if(!name.empty())
				{
					if(it->OutfitType()->Get("installable") < 0.)
						commodity = it->OutfitType()->Name();
					else
						Messages::Add(name + Format::Number(amount) + " " + it->OutfitType()->Name()
							+ (amount == 1 ? "." : "s."));
				}
			}
			else
			{
				amount = collector->Cargo().Add(it->CommodityType(), it->Count());
				if(!name.empty())
					commodity = it->CommodityType();
					
			}
			if(!commodity.empty())
				Messages::Add(name + (amount == 1 ? "a ton" : Format::Number(amount) + " tons")
					+ " of " + Format::LowerCase(commodity) + ".");
			
			it = flotsam.erase(it);
			continue;
		}
		
		// Draw this flotsam.
		draw[calcTickTock].Add(*it);
		++it;
	}
	
	// Keep track of the relative strength of each government in this system. Do
	// not add more ships to make a winning team even stronger. This is mostly
	// to avoid having the player get mobbed by pirates, say, if they hang out
	// in one system for too long.
	map<const Government *, int64_t> strength;
	// Now, ships fire new projectiles, which includes launching fighters. If an
	// anti-missile system is ready to fire, it does not actually fire unless a
	// missile is detected in range during collision detection, below.
	vector<Ship *> hasAntiMissile;
	double clickRange = 50.;
	const Ship *previousTarget = nullptr;
	const Ship *clickTarget = nullptr;
	if(player.Flagship() && player.Flagship()->GetTargetShip())
		previousTarget = &*player.Flagship()->GetTargetShip();
	
	bool showFlagship = false;
	bool hasHostiles = false;
	for(shared_ptr<Ship> &ship : ships)
		if(ship->GetSystem() == player.GetSystem())
		{
			strength[ship->GetGovernment()] += ship->Cost();
			
			// Note: if a ship "fires" a fighter, that fighter was already in
			// existence and under the control of the same AI as the ship, but
			// its system was null to mark that it was not active.
			ship->Launch(ships);
			if(ship->Fire(projectiles, effects))
				hasAntiMissile.push_back(ship.get());
			
			int scan = ship->Scan();
			if(scan)
			{
				shared_ptr<Ship> target = ship->GetTargetShip();
				if(target && target->IsTargetable())
					eventQueue.emplace_back(ship, target, scan);
			}
			
			// This is a good opportunity to draw all the ships in system.
			if(!ship->HasSprite())
				continue;
			
			// Draw the flagship separately, on top of everything else.
			if(ship.get() != flagship)
			{
				AddSprites(*ship);
				if(ship->IsThrusting())
				{
					for(const auto &it : ship->Attributes().FlareSounds())
						if(it.second > 0)
							Audio::Play(it.first, ship->Position());
				}
			}
			else
				showFlagship = true;
			
			// Do not show cloaked ships on the radar, except the player's ships.
			bool isPlayer = ship->GetGovernment()->IsPlayer();
			if(ship->Cloaking() == 1. && !isPlayer)
				continue;
			
			if(doClick && &*ship != player.Flagship() && ship->IsTargetable())
			{
				Point position = ship->Position() - newCenter;
				const Mask &mask = ship->GetMask(step);
				double range = mask.Range(clickPoint - position, ship->Facing());
				if(range <= clickRange)
				{
					clickRange = range;
					clickTarget = ship.get();
					player.Flagship()->SetTargetShip(ship);
					// If we've found an enemy within the click zone, favor
					// targeting it rather than any other ship. Otherwise, keep
					// checking for hits because another ship might be an enemy.
					if(!range && ship->GetGovernment()->IsEnemy())
						doClick = false;
				}
			}
			
			double size = sqrt(ship->Width() + ship->Height()) * .14 + .5;
			bool isYourTarget = (flagship && ship == flagship->GetTargetShip());
			int type = RadarType(*ship);
			hasHostiles |= (type == Radar::HOSTILE);
			radar[calcTickTock].Add(isYourTarget ? Radar::SPECIAL : type, ship->Position(), size);
		}
	if(flagship && showFlagship)
	{
		AddSprites(*flagship);
		if(flagship->IsThrusting())
		{
			for(const auto &it : flagship->Attributes().FlareSounds())
				if(it.second > 0)
					Audio::Play(it.first);
		}
	}
	if(clickTarget && clickTarget == previousTarget)
		clickCommands |= Command::BOARD;
	if(alarmTime)
		--alarmTime;
	else if(hasHostiles && !hadHostiles)
	{
		if(Preferences::Has("Warning siren"))
			Audio::Play(Audio::Get("alarm"));
		alarmTime = 180;
		hadHostiles = true;
	}
	else if(!hasHostiles)
		hadHostiles = false;
	
	// Collision detection:
	if(grudgeTime)
		--grudgeTime;
	for(Projectile &projectile : projectiles)
	{
		// The asteroids can collide with projectiles, the same as any other
		// object. If the asteroid turns out to be closer than the ship, it
		// shields the ship (unless the projectile has a blast radius).
		Point hitVelocity;
		double closestHit = 0.;
		shared_ptr<Ship> hit;
		const Government *gov = projectile.GetGovernment();
		
		// If this "projectile" is a ship explosion, it always explodes.
		if(gov)
		{
			closestHit = asteroids.Collide(projectile, step, &hitVelocity);
			// Projectiles can only collide with ships that are in the current
			// system and are not landing, and that are hostile to this projectile.
			for(shared_ptr<Ship> &ship : ships)
				if(ship->GetSystem() == player.GetSystem() && !ship->IsLanding() && ship->Cloaking() < 1.)
				{
					if(ship.get() != projectile.Target() && !gov->IsEnemy(ship->GetGovernment()))
						continue;
					
					// This returns a value of 0 if the projectile has a trigger
					// radius and the ship is within it.
					double range = projectile.CheckCollision(*ship, step);
					if(range < closestHit)
					{
						closestHit = range;
						hit = ship;
						hitVelocity = ship->Velocity();
					}
				}
		}
		
		if(closestHit < 1.)
		{
			// Create the explosion the given distance along the projectile's
			// motion path for this step.
			projectile.Explode(effects, closestHit, hitVelocity);
			
			// If this projectile has a blast radius, find all ships within its
			// radius. Otherwise, only one is damaged.
			if(projectile.HasBlastRadius())
			{
				// Even friendly ships can be hit by the blast.
				for(shared_ptr<Ship> &ship : ships)
					if(ship->GetSystem() == player.GetSystem() && ship->Zoom() == 1.)
						if(projectile.InBlastRadius(*ship, step, closestHit))
						{
							int eventType = ship->TakeDamage(projectile, ship != hit);
							if(eventType)
								eventQueue.emplace_back(
									projectile.GetGovernment(), ship, eventType);
						}
			}
			else if(hit)
			{
				int eventType = hit->TakeDamage(projectile);
				if(eventType)
					eventQueue.emplace_back(
						projectile.GetGovernment(), hit, eventType);
			}
			
			if(hit)
				DoGrudge(hit, projectile.GetGovernment());
		}
		else if(projectile.MissileStrength())
		{
			bool isEnemy = projectile.GetGovernment() && projectile.GetGovernment()->IsEnemy();
			radar[calcTickTock].Add(
				isEnemy ? Radar::SPECIAL : Radar::INACTIVE, projectile.Position(), 1.);
			
			// If the projectile did not hit anything, give the anti-missile
			// systems a chance to shoot it down.
			for(Ship *ship : hasAntiMissile)
				if(ship == projectile.Target()
						|| gov->IsEnemy(ship->GetGovernment())
						|| ship->GetGovernment()->IsEnemy(gov))
					if(ship->FireAntiMissile(projectile, effects))
					{
						projectile.Kill();
						break;
					}
		}
		else if(projectile.HasBlastRadius())
			radar[calcTickTock].Add(Radar::SPECIAL, projectile.Position(), 1.8);
		
		// Now, we can draw the projectile. The motion blur should be reduced
		// depending on how much motion blur is in the sprite itself:
		double innateVelocity = 2. * projectile.GetWeapon().Velocity();
		Point relativeVelocity = projectile.Velocity() - projectile.Unit() * innateVelocity;
		draw[calcTickTock].AddProjectile(projectile, relativeVelocity, closestHit);
	}
	
	// Finally, draw all the effects, and then move them (because their motion
	// is not dependent on anything else, and this way we do all the work on
	// them in a single place.
	for(auto it = effects.begin(); it != effects.end(); )
	{
		draw[calcTickTock].AddUnblurred(*it);
		
		if(!it->Move())
			it = effects.erase(it);
		else
			++it;
	}
	
	// Add incoming ships.
	for(const System::FleetProbability &fleet : player.GetSystem()->Fleets())
		if(!Random::Int(fleet.Period()))
		{
			const Government *gov = fleet.Get()->GetGovernment();
			if(!gov)
				continue;
			
			int64_t enemyStrength = 0;
			for(const auto &it : strength)
				if(gov->IsEnemy(it.first))
					enemyStrength += it.second;
			if(enemyStrength && strength[gov] > 2 * enemyStrength)
				continue;
			
			fleet.Get()->Enter(*player.GetSystem(), ships);
		}
	if(!Random::Int(36000) && !player.GetSystem()->Links().empty())
	{
		// Loop through all persons once to see if there are any who can enter
		// this system.
		int sum = 0;
		for(const auto &it : GameData::Persons())
			sum += it.second.Frequency(player.GetSystem());
		
		if(sum)
		{
			// Adjustment factor: special persons will appear once every ten
			// minutes, but much less frequently if the game only specifies a
			// few of them. This way, they will become more common as I add
			// more, without needing to change the 10-minute constant above.
			sum = Random::Int(sum + 1000);
			for(const auto &it : GameData::Persons())
			{
				const Person &person = it.second;
				sum -= person.Frequency(player.GetSystem());
				if(sum < 0)
				{
					shared_ptr<Ship> ship = person.GetShip();
					ship->Recharge();
					ship->SetName(it.first);
					ship->SetGovernment(person.GetGovernment());
					ship->SetPersonality(person.GetPersonality());
					ship->SetHail(person.GetHail());
					Fleet::Enter(*player.GetSystem(), *ship);
					
					ships.push_front(ship);
					
					break;
				}
			}
		}
	}
	
	// Occasionally have some ship hail you.
	if(!Random::Int(600) && !ships.empty())
	{
		shared_ptr<Ship> source;
		unsigned i = Random::Int(ships.size());
		for(const shared_ptr<Ship> &it : ships)
			if(!i--)
			{
				source = it;
				break;
			}
		if(source->GetGovernment() && !source->GetGovernment()->IsPlayer()
				&& !source->IsDisabled() && source->Crew())
		{
			string message = source->GetHail();
			if(!message.empty() && source->GetSystem() == player.GetSystem())
				Messages::Add(source->GetGovernment()->GetName() + " ship \""
					+ source->Name() + "\": " + message);
		}
	}
	
	// A mouse click should only be active for a single step.
	doClick = false;
	
	// Keep track of how much of the CPU time we are using.
	loadSum += loadTimer.Time();
	if(++loadCount == 60)
	{
		load = loadSum;
		loadSum = 0.;
		loadCount = 0;
	}
}
Ejemplo n.º 11
0
EscortDisplay::Icon::Icon(const Ship &ship, bool isHere)
	: sprite(ship.GetSprite().GetSprite()),
	isHere(isHere && !ship.IsDisabled()),
	isReadyToJump(ship.CheckHyperspace()),
	stackSize(1),
	cost(ship.Cost()),
	system((!isHere && ship.GetSystem()) ? ship.GetSystem()->Name() : ""),
	low{ship.Shields(), ship.Hull(), ship.Energy(), ship.Heat(), ship.Fuel()},
	high(low)
{
}
void Engine::AddSprites(const Ship &ship)
{
	bool hasFighters = ship.PositionFighters();
	double cloak = ship.Cloaking();
	bool drawCloaked = (cloak && ship.GetGovernment()->IsPlayer());
	
	if(ship.IsThrusting())
		for(const Point &point : ship.EnginePoints())
		{
			Point pos = ship.Facing().Rotate(point) * ship.Zoom() + ship.Position();
			// If multiple engines with the same flare are installed, draw up to
			// three copies of the flare sprite.
			for(const auto &it : ship.Attributes().FlareSprites())
				for(int i = 0; i < it.second && i < 3; ++i)
				{
					Body sprite(it.first, pos, ship.Velocity(), ship.Facing());
					draw[calcTickTock].Add(sprite, cloak);
				}
		}
	
	if(hasFighters)
		for(const Ship::Bay &bay : ship.Bays())
			if(bay.side == Ship::Bay::UNDER && bay.ship)
			{
				if(drawCloaked)
					draw[calcTickTock].AddSwizzled(*bay.ship, 7);
				draw[calcTickTock].Add(*bay.ship, cloak);
			}
	
	if(drawCloaked)
		draw[calcTickTock].AddSwizzled(ship, 7);
	draw[calcTickTock].Add(ship, cloak);

	if(hasFighters)
		for(const Ship::Bay &bay : ship.Bays())
			if(bay.side == Ship::Bay::OVER && bay.ship)
			{
				if(drawCloaked)
					draw[calcTickTock].AddSwizzled(*bay.ship, 7);
				draw[calcTickTock].Add(*bay.ship, cloak);
			}
}
Ejemplo n.º 13
0
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 (Uint32 i=0; i<m_shipDocking.size(); i++) {
			if (m_shipDocking[i].ship == s) { port = i; break; }
		}
		if (port == -1) return false;					// no permission
		if (IsPortLocked(port)) {
			return false;
		}
		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());
			LockPort(port, 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;
	}
}
Ejemplo n.º 14
0
Archivo: Game.cpp Proyecto: m1h4/Xetrix
bool DrawGame(void)
{
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//glTranslatef(0.0f,0.0f,-8.0f);
	gluLookAt(0.0f,0.0f,18.0,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f);

	glPushAttrib(GL_CURRENT_BIT);

	glBegin(GL_LINES);
		Matrix2 orientation(gameShip.m_orientation);

#ifdef _DEBUG
		if(debugDraw)
		{
			glColor3f(1.0f,0.0f,0.0f);

			glVertex2f(0.0f,0.0f);
			glVertex2f(1.0f,0.0f);

			glColor3f(0.0f,1.0f,0.0f);

			glVertex2f(0.0f,0.0f);
			glVertex2f(0.0f,1.0f);
		}
#endif

		glColor3f(0.0f,0.0f,1.0f);

		if(debugSpring1)
		{
			glVertex2fv(gameSpring1);
			glVertex2fv(gameShip.m_position + orientation * gameAnchor1);
		}

		if(debugSpring2)
		{
			glVertex2fv(gameSpring2);
			glVertex2fv(gameShip.m_position + orientation * gameAnchor2);
		}

		for(unsigned long i = 0; i < gameMissles.GetSize(); ++i)
		{
			if(gameMissles[i]->m_spring)
			{
				glVertex2fv(*gameMissles[i]->m_spring);
				glVertex2fv(gameMissles[i]->m_position);
			}
		}
	glEnd();

	glPopAttrib();

	gameShip.DrawShip();
	gameEmitter.DrawParticles();

	for(unsigned long i = 0; i < gameMissles.GetSize(); ++i)
		gameMissles[i]->DrawMissle();

	return true;
}
Ejemplo n.º 15
0
void BasicApp::draw()
{

	// this pair of lines is the standard way to clear the screen in OpenGL
	gl::clear( Color( 0.0f, 0.0f, 0.0f ) );
	gl::setMatricesWindow( getWindowSize() );

	if(game_state == Game_Demo)
	{
		gl::enableAlphaBlending( true );
		for (list<Asteroid>::iterator itr = asteroids.begin(); itr!=asteroids.end(); itr++)
		{
			if(itr->m_bHit)
			{

			}
			itr->Draw();
		}

		Font font  = Font( "Times New Roman", 50 );
		gl::drawString("Atari Asteroids Clone" , Vec2f(app::getWindowWidth()/4,app::getWindowHeight()/4),cinder::ColorA(1,1,1,1), font);
		gl::drawString("Presse SpaceBar to Play" , Vec2f(app::getWindowWidth()/4,app::getWindowHeight()/2 + 100),cinder::ColorA(1,1,1,1), font);

	}
	else if(game_state == GAME_Play)
	{

		for (list<Asteroid>::iterator itr = asteroids.begin(); itr!=asteroids.end(); itr++)
		{
			if(itr->m_bHit)
			{

			}
			itr->Draw();

		}
		enemy.Draw();
		particleManager.Move();
		particleManager.Draw();
		particleLineManager.Update();
		particleLineManager.Draw();
		currentShip.Draw();

		for (std::vector<Ship>::iterator itrShip = ships.begin(); itrShip!=ships.end();itrShip++)
		{
			if(itrShip->m_state== Ship::Ship_Alive)
			{
				itrShip->Draw();
			}
		}
		stringstream scoreString;
		scoreString<< score;
		gl::drawString("   " + scoreString.str(), Vec2f(10,10),cinder::ColorA(1,1,1,1), mFont);
	}

	else if (game_state == GAME_End)
	{

		gl::drawString("Game Over", Vec2f(getWindowWidth()/2,getWindowHeight()/2),cinder::ColorA(1,1,1,1), mFont);
	}
}
Ejemplo n.º 16
0
Ship* ShipFactory::buildShip(Vector const location, XMLShipBlueprint const blueprint, bool const isPlayer){
	Ship* ship = new Ship(location, blueprint);
	ship->setGun(this->fGunFactory->build(blueprint.gun, ship, isPlayer));
	return ship;
}
Ejemplo n.º 17
0
Archivo: Pi.cpp Proyecto: larbb/pioneer
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);
									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) {
										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;
		}
	}
}
Ejemplo n.º 18
0
int AttackWeakestEnemy::validateTactic(list<Action*> &newActions, Unit* squad, const vector<Unit*>& enemyUnits,
        const vector<Unit*>& alliedUnits)
{
	squad->setTarget(-1);
	if (enemyUnits.size() == 0)
	{
		return 0;
	}

	int Ret = 0;
	float minHP = 100;
	Coordinates enemyAvrg;
	int sumHP;

	Coordinates myPos = squad->getAveragePos();
	if (squad->getNShipsAlive() == 0)
		return 0;

	Unit *wekeastUnit = NULL;

	vector<Unit*> enemyNear;
	//cria uma lista com a unidades dentro do alcançe
	for (unsigned int i = 0; i < enemyUnits.size(); i++)
	{
		Coordinates enemyAvrg = enemyUnits[i]->getAveragePos();
		if (enemyUnits[i]->getNShipsAlive() > 0)
		{
			float dist = myPos.distance(enemyAvrg);
			if (dist < squad->getSquadBaseStats().range)
			{
				enemyNear.push_back(enemyUnits[i]);
			}
		}
	}

	//percorre a lista de unidades inimigas no alçance um busca da mais fraca
	for (unsigned int i = 0; i < enemyNear.size(); i++)
	{
        enemyAvrg = enemyNear[i]->getAveragePos();
		if (enemyNear[i]->getNShipsAlive() > 0)
		{
			sumHP = 0;
			for (unsigned int j = 0; j < enemyNear[i]->nShips(); ++j)
			{
				sumHP += enemyNear[i]->getShip(j)->getHP();
			}

			int maxHP = enemyNear[i]->getUnitInfo()->squadSize * enemyNear[i]->getUnitInfo()->stats.maxHP;

			// Considerar apenas o inteiro
			int percent = (sumHP / maxHP) * 100;
			if (percent < minHP)
			{
				minHP = percent;
				wekeastUnit = enemyNear[i];
				squad->setTarget( i );
			}
		}

	}

	//ataca as naves do esquadrao de maneira aleatoria
	if (wekeastUnit)
	{
		for (unsigned int i = 0; i < squad->nShips(); ++i)
		{
			Ship *iShip = squad->getShip(i);

			if (iShip->isAlive() && iShip->getStats().currentAtkCD == 0)
			{
				while (1)
				{
					int s = rand() % wekeastUnit->nShips();
					if (wekeastUnit->getShip(s)->isAlive())
					{
						iShip->getStats().currentAtkCD = iShip->getBaseStats().maxAtkCD;
						newActions.push_back(new AttackAction(iShip, wekeastUnit->getShip(s), squad->getUnitInfo(), wekeastUnit->getUnitInfo()));
						++Ret;
						break;
					}
				}
			}
		}
	}

    // TODO: Se eu nao conseguir atacar, devo desconsiderar o target?
//	if (Ret == 0)
//        squad->setTarget(-1);

	return Ret;
}
Ejemplo n.º 19
0
/*
 * Method: CancelAI
 *
 * Cancel the current AI command
 *
 * > ship:CancelAI()
 *
 * This ship is left with the orientation and velocity it had when <CancelAI>
 * was called. The engines are switched off.
 *
 * Note that <Event.onAICompleted> will not be triggered by calling
 * <CancelAI>, as the AI did not actually complete.
 *
 * You do not need to call this if you intend to immediately invoke another AI
 * method. Calling an AI method will replace the previous command if one
 * exists.
 *
 * Availability:
 *
 *  alpha 10
 *
 * Status:
 *
 *  experimental
 */
static int l_ship_cancel_ai(lua_State *l)
{
	Ship *s = LuaObject<Ship>::CheckFromLua(1);
	s->AIClearInstructions();
	return 0;
}
Ejemplo n.º 20
0
int AttackCollab::validateTactic(list<Action*> &newActions, Unit* squad, const vector<Unit*>& enemyUnits, const vector<Unit*>& alliedUnits)
{
	squad->setTarget(-1);

    // TODO: Algumas unidades chegam aqui com aliados invalidos! arrumar!
	if (info.allyUnitID >= alliedUnits.size())
        return 0;

	Unit *allyUnit = alliedUnits[info.allyUnitID];
	if (allyUnit->getTarget() == -1)
        return 0;

    int target = allyUnit->getTarget();

    if (target >= enemyUnits.size() || target < 0)
        return 0;

	squad->setTarget(target);

	Unit *enemyUnit = enemyUnits[target];
	if (enemyUnit->getNShipsAlive() == 0){
		return 0;
	}

	/// TODO: Adicionar restricao de distancia?

    float dist = squad->getAveragePos().distance(enemyUnit->getAveragePos());
    if (dist < squad->getUnitInfo()->stats.range)
    {
        for (unsigned int i = 0; i < squad->nShips(); ++i)
		{
			Ship *iShip = squad->getShip(i);

			if (iShip->isAlive() && iShip->getStats().currentAtkCD == 0)
			{
				while (1)
				{
					int s = rand() % enemyUnit->nShips();
					if (enemyUnit->getShip(s)->isAlive())
					{
						iShip->getStats().currentAtkCD = iShip->getBaseStats().maxAtkCD;
						newActions.push_back(new AttackAction(iShip, enemyUnit->getShip(s), squad->getUnitInfo(), enemyUnit->getUnitInfo()));
						break;
					}
				}
			}
		}
    }
    else
    {
        Coordinates coord = squad->getAveragePos();
        float direction = atan2(enemyUnit->getAveragePos().y - coord.y, enemyUnit->getAveragePos().x - coord.x);

        for (unsigned int i = 0; i < squad->nShips(); ++i)
		{
		    Ship *iShip = squad->getShip(i);

            if (iShip->isAlive())
            {
                coord = iShip->getPosition();
                coord.x += cos(direction)*SPACIAL_UNIT;
                coord.y += sin(direction)*SPACIAL_UNIT;

                newActions.push_back(new MoveAction( iShip, coord ) );
            }
		}
    }

	return 1;
}
Ejemplo n.º 21
0
/*
 * Method: SpawnCargo
 *
 * Spawns a container right next to the ship.
 *
 * > success = ship:SpawnCargo(item)
 *
 * Parameters:
 *
 *  item - the item to put in the container.
 *
 * Result:
 *
 *   success: true if the container was spawned, false otherwise.
 *
 * Availability:
 *
 *   alpha 26
 *
 * Status:
 *
 *   experimental
 */
static int l_ship_spawn_cargo(lua_State *l) {
	Ship *s = LuaObject<Ship>::CheckFromLua(1);
	CargoBody * c_body = new CargoBody(static_cast<Equip::Type>(LuaConstants::GetConstantFromArg(l, "EquipType", 2)));
    lua_pushboolean(l, s->SpawnCargo(c_body));
    return 1;
}
Ejemplo n.º 22
0
int DefenseCollab::validateTactic(list<Action*> &newActions, Unit* squad, const vector<Unit*>& enemyUnits, const vector<Unit*>& alliedUnits)
{
	int Ret = 0;
	Unit *enemyUnit = NULL;

	for (unsigned int j = 0; j < enemyUnits.size(); j++)
	{
		//interrompe caso tenha encontrado unimigo a quem atacar
		if (enemyUnits[j]->getTarget() == info.allyUnitID)
		{
			enemyUnit = enemyUnits[j];
			squad->setTarget(j);
			break;
		}
	}

	if (enemyUnit == NULL || enemyUnit->getNShipsAlive() == 0)
		return 0;

	for (unsigned int i = 0; i < squad->nShips(); i++)
	{
		Ship *iShip = squad->getShip(i);
		if (iShip->isAlive() && iShip->getStats().currentAtkCD == 0)
		{
			Coordinates shipPos = iShip->getPosition();
			Ship *nearestShip = NULL;
			float dist_ = 99999;

			for (unsigned int u = 0; u < enemyUnit->nShips(); ++u)
			{
				Ship *eShip = enemyUnit->getShip(u);

				if (eShip->isAlive())
				{
					float d = shipPos.distance(enemyUnit->getShip(u)->getPosition());
					if (d < dist_)
					{
						nearestShip = eShip;
						dist_ = d;
					}
				}
			}

            if (nearestShip)
            {
                if (dist_ < iShip->getBaseStats().range)
                {
                    iShip->getStats().currentAtkCD = iShip->getBaseStats().maxAtkCD;
                    newActions.push_back(new AttackAction(iShip, nearestShip, squad->getUnitInfo(), enemyUnit->getUnitInfo()));
                    ++Ret;
                }
                else
                {
                    float direction = atan2(iShip->getY() - nearestShip->getPosition().y, iShip->getX() - nearestShip->getPosition().x);
                    iShip->move(-iShip->getBaseStats().speed * cos(direction), -iShip->getBaseStats().speed * sin(direction));
                }
            }

		}

	}
	return Ret;
}
Ejemplo n.º 23
0
void Game::SwitchToNormalSpace()
{
	// remove the player from hyperspace
	m_space->RemoveBody(m_player.Get());

	// create a new space for the system
	const SystemPath &dest = m_player->GetHyperspaceDest();
	m_space.Reset(new Space(this, dest));

	// put the player in it
	m_player->SetFrame(m_space->GetRootFrame());
	m_space->AddBody(m_player.Get());

	// place it
	m_player->SetPosition(m_space->GetHyperspaceExitPoint(m_hyperspaceSource));
	m_player->SetVelocity(vector3d(0,0,-100.0));
	m_player->SetRotMatrix(matrix4x4d::Identity());

	// place the exit cloud
	HyperspaceCloud *cloud = new HyperspaceCloud(0, Pi::game->GetTime(), true);
	cloud->SetFrame(m_space->GetRootFrame());
	cloud->SetPosition(m_player->GetPosition());
	m_space->AddBody(cloud);

	for (std::list<HyperspaceCloud*>::iterator i = m_hyperspaceClouds.begin(); i != m_hyperspaceClouds.end(); ++i) {
		cloud = *i;

		cloud->SetFrame(m_space->GetRootFrame());
		cloud->SetPosition(m_space->GetHyperspaceExitPoint(m_hyperspaceSource));

		m_space->AddBody(cloud);

		if (cloud->GetDueDate() < Pi::game->GetTime()) {
			// they emerged from hyperspace some time ago
			Ship *ship = cloud->EvictShip();

			ship->SetFrame(m_space->GetRootFrame());
			ship->SetVelocity(vector3d(0,0,-100.0));
			ship->SetRotMatrix(matrix4x4d::Identity());
			ship->Enable();
			ship->SetFlightState(Ship::FLYING);

			const SystemPath &sdest = ship->GetHyperspaceDest();
			if (sdest.IsSystemPath()) {
				// travelling to the system as a whole, so just dump them on
				// the cloud - we can't do any better in this case
				ship->SetPosition(cloud->GetPosition());
			}

			else {
				// on their way to a body. they're already in-system so we
				// want to simulate some travel to their destination. we
				// naively assume full accel for half the distance, flip and
				// full brake for the rest.
				Body *target_body = m_space->FindBodyForPath(&sdest);
				double dist_to_target = cloud->GetPositionRelTo(target_body).Length();
				double half_dist_to_target = dist_to_target / 2.0;
				double accel = -(ship->GetShipType().linThrust[ShipType::THRUSTER_FORWARD] / ship->GetMass());
				double travel_time = Pi::game->GetTime() - cloud->GetDueDate();

				// I can't help but feel some actual math would do better here
				double speed = 0;
				double dist = 0;
				while (travel_time > 0 && dist <= half_dist_to_target) {
					speed += accel;
					dist += speed;
					travel_time--;
				}
				while (travel_time > 0 && dist < dist_to_target) {
					speed -= accel;
					dist += speed;
					travel_time--;
				}

				if (travel_time <= 0) {
					vector3d pos =
						target_body->GetPositionRelTo(m_space->GetRootFrame()) +
						cloud->GetPositionRelTo(target_body).Normalized() * (dist_to_target - dist);
					ship->SetPosition(pos);
				}

				else {
					// ship made it with time to spare. just put it somewhere
					// near the body. the script should be issuing a dock or
					// flyto command in onEnterSystem so it should sort it
					// itself out long before the player can get near

					SystemBody *sbody = m_space->GetStarSystem()->GetBodyByPath(&sdest);
					if (sbody->type == SystemBody::TYPE_STARPORT_ORBITAL) {
						ship->SetFrame(target_body->GetFrame());
						ship->SetPosition(MathUtil::RandomPointOnSphere(1000.0)*1000.0); // somewhere 1000km out
					}

					else {
						if (sbody->type == SystemBody::TYPE_STARPORT_SURFACE) {
							sbody = sbody->parent;
							SystemPath path = m_space->GetStarSystem()->GetPathOf(sbody);
							target_body = m_space->FindBodyForPath(&path);
						}

						double sdist = sbody->GetRadius()*2.0;

						ship->SetFrame(target_body->GetFrame());
						ship->SetPosition(MathUtil::RandomPointOnSphere(sdist));
					}
				}
			}

			m_space->AddBody(ship);

			LuaEvent::Queue("onEnterSystem", ship);
		}
	}
	m_hyperspaceClouds.clear();

	m_state = STATE_NORMAL;
}
Ejemplo n.º 24
0
/*
 * Method: UpdateEquipStats
 *
 * Update the ship's statistics with regards to equipment changes
 *
 * > ship:UpdateEquipStats()
 *
 * Availability:
 *
 *  June 2014
 *
 * Status:
 *
 *  experimental
 */
static int l_ship_update_equip_stats(lua_State *l)
{
	Ship *s = LuaObject<Ship>::CheckFromLua(1);
	s->UpdateLuaStats();
	return 0;
}
void
NetGameClient::DoJoinAnnounce(NetMsg* msg)
{
	if (!msg) return;

	Sim* sim = Sim::GetSim();
	if (!sim) return;

	NetJoinAnnounce*  join_ann = new(__FILE__,__LINE__) NetJoinAnnounce;
	bool              saved    = false;

	if (join_ann->Unpack(msg->Data())) {
		DWORD nid       = msg->NetID();
		DWORD oid       = join_ann->GetObjID();
		Text  name      = join_ann->GetName();
		Text  elem_name = join_ann->GetElement();
		Text  region    = join_ann->GetRegion();
		Point loc       = join_ann->GetLocation();
		Point velocity  = join_ann->GetVelocity();
		int   index     = join_ann->GetIndex();
		int   shld_lvl  = join_ann->GetShield();
		join_ann->SetNetID(nid);
		Ship* ship      = 0;
		char  ship_name[128];

		strcpy_s(ship_name, Game::GetText("NetGameClient.no-ship").data());

		if (local_player && player_name == name) {
			HUDView::Message(Game::GetText("NetGameClient.local-accept"), name.data(), local_player->Name());

			objid = oid;
			netid = nid;
			local_player->SetObjID(oid);
			local_player->SetNetObserver(false);
			Observe(local_player);

			SimRegion* rgn = local_player->GetRegion();
			if (rgn && region != rgn->Name()) {
				SimRegion* dst = sim->FindRegion(region);
				if (dst) dst->InsertObject(local_player);
			}

			local_player->MoveTo(loc);
			local_player->SetVelocity(velocity);

			Shield* shield = local_player->GetShield();
			if (shield)
			shield->SetNetShieldLevel(shld_lvl);
		}
		else {
			NetPlayer* remote_player = FindPlayerByObjID(oid);
			if (remote_player) {
				remote_player->SetName(name);
				remote_player->SetObjID(oid);

				if (index > 0)
				sprintf_s(ship_name, "%s %d", elem_name.data(), index);
				else
				sprintf_s(ship_name, "%s", elem_name.data());
			}
			else {
				Element* element = sim->FindElement(elem_name);

				if (element) {
					ship = element->GetShip(index);
				}
				else {
					Print("NetGameClient::DoJoinAnnounce() could not find elem %s for player '%s' objid %d\n",
					elem_name.data(), name.data(), oid);

					NetUtil::SendElemRequest(elem_name.data());
				}

				if (!ship) {
					// save it for later:
					join_backlog.append(join_ann);
					saved = true;
				}
				else {
					strcpy_s(ship_name, ship->Name());

					SimRegion* rgn = ship->GetRegion();
					if (rgn && region != rgn->Name()) {
						SimRegion* dst = sim->FindRegion(region);
						if (dst) dst->InsertObject(ship);
					}

					ship->MoveTo(loc);
					ship->SetVelocity(velocity);

					Shield* shield = ship->GetShield();
					if (shield)
					shield->SetNetShieldLevel(shld_lvl);

					NetPlayer* remote_player = new(__FILE__,__LINE__) NetPlayer(nid);
					remote_player->SetName(name);
					remote_player->SetObjID(oid);
					remote_player->SetShip(ship);

					players.append(remote_player);

					if (name == "Server A.I. Ship") {
						Print("Remote Player '%s' has joined as '%s' with ID %d\n", name.data(), ship_name, oid);
					}
					else {
						HUDView::Message(Game::GetText("NetGameClient.remote-join").data(), name.data(), ship_name);
					}
				}
			}
		}
	}

	if (!saved)
	delete join_ann;
}
Ejemplo n.º 26
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
		}
	}
}
void
NetGameClient::DoObjKill(NetMsg* msg)
{
	if (!msg) return;

	NetObjKill obj_kill;
	obj_kill.Unpack(msg->Data());

	Ship* ship = FindShipByObjID(obj_kill.GetObjID());
	if (ship) {
		Ship* killer = FindShipByObjID(obj_kill.GetKillerID());
		Text  killer_name = Game::GetText("NetGameClient.unknown");

		if (killer)
		killer_name = killer->Name();

		// log the kill:
		switch (obj_kill.GetKillType()) {
		default:
		case NetObjKill::KILL_MISC:
			Print("Ship '%s' destroyed (misc) (%s)\n", ship->Name(), FormatGameTime());
			break;

		case NetObjKill::KILL_PRIMARY:
		case NetObjKill::KILL_SECONDARY:
			Print("Ship '%s' killed by '%s' (%s)\n", ship->Name(), killer_name.data(), FormatGameTime());
			break;

		case NetObjKill::KILL_COLLISION:
			Print("Ship '%s' killed in collision with '%s' (%s)\n", ship->Name(), killer_name.data(), FormatGameTime());
			break;

		case NetObjKill::KILL_CRASH:
			Print("Ship '%s' destroyed (crash) (%s)\n", ship->Name(), FormatGameTime());

		case NetObjKill::KILL_DOCK:
			Print("Ship '%s' docked (%s)\n", ship->Name(), FormatGameTime());
		}

		// record the kill in the stats:
		if (killer && obj_kill.GetKillType() != NetObjKill::KILL_DOCK) {
			ShipStats* kstats = ShipStats::Find(killer->Name());
			if (kstats) {
				if (obj_kill.GetKillType() == NetObjKill::KILL_PRIMARY)
				kstats->AddEvent(SimEvent::GUNS_KILL, ship->Name());
				
				else if (obj_kill.GetKillType() == NetObjKill::KILL_SECONDARY)
				kstats->AddEvent(SimEvent::MISSILE_KILL, ship->Name());
			}

			if (killer && killer->GetIFF() != ship->GetIFF()) {
				if (ship->GetIFF() > 0 || killer->GetIFF() > 1)
				kstats->AddPoints(ship->Value());
			}
		}

		ShipStats* killee = ShipStats::Find(ship->Name());
		if (killee) {
			if (obj_kill.GetKillType() == NetObjKill::KILL_DOCK)
			killee->AddEvent(SimEvent::DOCK, killer_name);
			else 
			killee->AddEvent(SimEvent::DESTROYED, killer_name);
		}

		if (obj_kill.GetKillType() == NetObjKill::KILL_DOCK) {
			FlightDeck* deck = killer->GetFlightDeck(obj_kill.GetFlightDeck());
			sim->NetDockShip(ship, killer, deck);
		}
		else {
			ship->InflictNetDamage(ship->Integrity());
			ship->DeathSpiral();

			if (!obj_kill.GetRespawn())
			ship->SetRespawnCount(0);
			else
			ship->SetRespawnLoc(obj_kill.GetRespawnLoc());
		}
	}

	// this shouldn't happen in practice, 
	// but if it does, this is what should be done:
	else {
		Shot* shot = FindShotByObjID(obj_kill.GetObjID());

		if (shot) {
			::Print("NetGameClient::DoObjKill destroying shot '%s'\n", shot->Name());
			shot->Destroy();
		}
	}
}
Ejemplo n.º 28
0
void BasicApp::update()
{

	if (game_state == Game_Demo)
	{

		for (list<Asteroid>::iterator itr = asteroids.begin(); itr!=asteroids.end(); itr++)
		{
			itr->Update();

		}

	}
	else if(game_state == GAME_Play)
	{
		for (list<Asteroid>::iterator itr = asteroids.begin(); itr!=asteroids.end(); itr++)
		{
			itr->Update();

		}

		for (list<Bullet>::iterator itr_bullet = currentShip.m_Bullets.begin(); itr_bullet!=currentShip.m_Bullets.end();)
		{

			for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end();)
			{
				if(checkCollision(itr_bullet->getCenter(),itr_astroid->getCenter(), itr_bullet->getRadius(), itr_astroid->getRadius()))
				{

					particleManager.Start_Explosion(itr_astroid->getCenter(),10,1.0f,1.0f);
				
					engine->play2D("explode_high.wav");
				

					if(itr_astroid->m_size >= 0.5)
					{
						Asteroid asteroid_1, asteroid_2;

						asteroid_1.m_state = Asteroid_Medium;
						asteroid_1.Init(rand()%2+1, 0.3);
						asteroid_1.m_Vel.y = -itr_astroid->m_Vel.y*1.5;
						asteroid_1.m_Vel.x = -itr_astroid->m_Vel.x*1.5;
						asteroid_1.m_Pos = itr_astroid->m_Pos;

						asteroid_2.m_state = Asteroid_Medium;
						asteroid_2.Init(rand()%2+1, 0.3);
						asteroid_2.m_Vel.y = itr_astroid->m_Vel.y*1.5;
						asteroid_2.m_Vel.x = itr_astroid->m_Vel.x*1.5;
						asteroid_2.m_Pos = itr_astroid->m_Pos;


						asteroids.push_back(asteroid_1);
						asteroids.push_back(asteroid_2);


						itr_astroid = asteroids.erase(itr_astroid);
						itr_astroid->m_bHit = true;

						score +=100;

					}
					else if(itr_astroid->m_state == Asteroid_Medium)
					{
						Asteroid asteroid_1, asteroid_2;
						asteroid_1.m_state = Asteroid_Small;
						asteroid_1.Init(rand()%2+1, 0.1);
						asteroid_1.m_Vel.y = -itr_astroid->m_Vel.y*2;
						asteroid_1.m_Vel.x = -itr_astroid->m_Vel.x*2;
						asteroid_1.m_Pos = itr_astroid->m_Pos;
						asteroid_2.m_state = Asteroid_Small;
						asteroid_2.Init(rand()%2+1, 0.1);
						asteroid_2.m_Vel.y = itr_astroid->m_Vel.y*2;
						asteroid_2.m_Vel.x = itr_astroid->m_Vel.x*2;
						asteroid_2.m_Pos = itr_astroid->m_Pos;
						asteroids.push_back(asteroid_1);
						asteroids.push_back(asteroid_2);
						itr_astroid = asteroids.erase(itr_astroid);
						itr_astroid->m_bHit = true;

						score +=100;

					}
					else
					{
						score +=50;
						itr_astroid->m_bHit = true; 
						itr_astroid = asteroids.erase(itr_astroid);
					}

					itr_bullet->m_Hit = true;

					break;
				}
				else
				{
					itr_astroid++;

				}
			}
			if(itr_bullet->m_Hit)
			{
				itr_bullet = currentShip.m_Bullets.erase(itr_bullet);
			}
			else
			{
				itr_bullet++;

			}

		}

		if(shipCollision)
		{
			for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end(); )
			{
				if(currentShip.m_state == Ship::Ship_Alive)
				{

					if(checkCollision(itr_astroid->getCenter(), currentShip.getCenter(), itr_astroid->getRadius(), currentShip.getRadius() ))
					{

						particleManager.Start_Explosion(currentShip.getCenter(),10,0.3f,1.0f);
						particleLineManager.Init(currentShip.getCenter());

						engine->play2D("explode_high.wav");

						currentShip.m_state = Ship::Ship_Dead;
						currentShip.m_Pos.x = -getWindowWidth()/2;
						currentShip.m_Pos.y = -getWindowHeight()/2;

						if(ships.size()>0)
						{
							ships.pop_back();
						}

						if(itr_astroid->m_size >= 0.5)
						{
							Asteroid asteroid_1, asteroid_2;

							asteroid_1.m_state = Asteroid_Medium;
							asteroid_1.Init(rand()%2+1, 0.3);
							asteroid_1.m_Vel.y = -itr_astroid->m_Vel.y*1.5;
							asteroid_1.m_Vel.x = -itr_astroid->m_Vel.x*1.5;
							asteroid_1.m_Pos = itr_astroid->m_Pos;

							asteroid_2.m_state = Asteroid_Medium;
							asteroid_2.Init(rand()%2+1, 0.3);
							asteroid_2.m_Vel.y = itr_astroid->m_Vel.y*1.5;
							asteroid_2.m_Vel.x = itr_astroid->m_Vel.x*1.5;
							asteroid_2.m_Pos = itr_astroid->m_Pos;


							asteroids.push_back(asteroid_1);
							asteroids.push_back(asteroid_2);


							itr_astroid = asteroids.erase(itr_astroid);
							itr_astroid->m_bHit = true;

							score +=100;

						}
						else if(itr_astroid->m_state == Asteroid_Medium)
						{
							Asteroid asteroid_1, asteroid_2;

							asteroid_1.m_state = Asteroid_Small;
							asteroid_1.Init(rand()%2+1, 0.1);
							asteroid_1.m_Vel.y = -itr_astroid->m_Vel.y*2;
							asteroid_1.m_Vel.x = -itr_astroid->m_Vel.x*2;
							asteroid_1.m_Pos = itr_astroid->m_Pos;

							asteroid_2.m_state = Asteroid_Small;
							asteroid_2.Init(rand()%2+1, 0.1);
							asteroid_2.m_Vel.y = itr_astroid->m_Vel.y*2;
							asteroid_2.m_Vel.x = itr_astroid->m_Vel.x*2;
							asteroid_2.m_Pos = itr_astroid->m_Pos;


							asteroids.push_back(asteroid_1);
							asteroids.push_back(asteroid_2);


							itr_astroid = asteroids.erase(itr_astroid);
							itr_astroid->m_bHit = true;

							score +=100;
						}
						else
						{
							score +=50;
							itr_astroid->m_bHit = true; 
							itr_astroid = asteroids.erase(itr_astroid);
						}
						break;
					}
					else
					{
						itr_astroid++;

					} 
				}
				else
				{
					itr_astroid++;
				}
			}	
		}
	 
		currentShip.m_saveField = currentShip.m_state == Ship::Ship_Dead;

		if (currentShip.m_saveField)
		{
			for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end(); itr_astroid++) 
			{
				float distance = itr_astroid->getCenter().distance(Vec2f(getWindowWidth() / 2, getWindowHeight() / 2));
				if (distance < 100) 
				{
					currentShip.m_saveField = false;
					break;
				}
			}        
		}

		if(ships.size()<1)
		{
			game_state = GAME_End;
		}
		if(asteroids.size()<1)
		{
			game_state = GAME_End;
		}

		currentShip.Update();
		enemy.Update();
	}


	else if ( game_state == GAME_End)
	{



	}

	Sleep(delay);

}
Ejemplo n.º 29
0
void GameLearn::learnInvisible()
{
    const unsigned int TIME_WAITING = 60.f; // in sec

    window.setFramerateLimit(0);

    enemies.push_back(model);
    Ship* body = &enemies.back();

    std::vector<ShipEvolutive> evo;
    for(int i=0;i<NB_INDIVIDUALS;i++){
        std::string str = "P"+ttos(i);
        evo.push_back(ShipEvolutive(body,str));
    }
    for(unsigned int i=0;i<evo.size();i++){
        evo[i].setBulletPlayer(&bulletPlayer);
    }
    int current = 0;
    float bestTime = 0.f;
    float bestTimeCumul = 0.f;

    dt = 1.f/FR_LIMIT;

    sf::Text info;
    info.setFont(*FontManager::getFont("ressources/Symtext.ttf"));
    info.setCharacterSize(12);
    info.setPosition(window.getSize().x/2,10);

    static const float offsetsecurity = body->getVelocity()*dt*1.2f+10.f;
    float tcounter = -2.f;
    int gencounter = 1; // generation counter
    int ncounter = 0;
    bool end = false;

    initPlayer();

    sf::Clock telapsed;
    while (window.isOpen() && !end && telapsed.getElapsedTime().asSeconds() < TIME_WAITING){
        while (window.pollEvent(event)){
            if (event.type == sf::Event::Closed)
                window.close();

            if (event.type == sf::Event::KeyPressed){
                if (event.key.code == sf::Keyboard::Escape)
                    end = true;
            }
        }

        // update data

        if(body->getLives() <= LIFE_SECURITY-LIFE_INDIVIDUALS){
            // next individual
            current++;
            if(current >= (int)evo.size()){
                current = 0;
                bestTime = ShipEvolutive::reproduction(evo);
                bestTimeCumul += bestTime;
                gencounter++;
            }

            body->addLife(LIFE_SECURITY-body->getLives());
            body->setPosition(layer_game.getSize().x/2.f,100.f);
            body->setV(0.f,0.f);

            //ennemies.push_back(model3);
            //body = &ennemies.back();

            evo[current].reset();
        }
        if(body->getSprite().getPosition().x < offsetsecurity)
            body->setPosition(offsetsecurity,body->getSprite().getPosition().y);
        if(body->getSprite().getPosition().y < offsetsecurity)
            body->setPosition(body->getSprite().getPosition().x,offsetsecurity);
        if(body->getSprite().getPosition().x > layer_game.getSize().x-offsetsecurity)
            body->setPosition(layer_game.getSize().x-offsetsecurity,body->getSprite().getPosition().y);
        if(body->getSprite().getPosition().y > layer_game.getSize().y-offsetsecurity)
            body->setPosition(body->getSprite().getPosition().x,layer_game.getSize().y-offsetsecurity);
        evo[current].update(dt);

        // move the player
        player.update(dt);

        for (std::list<ShipEnemy>::iterator it=enemies.begin(); it != enemies.end(); ++it){
            it->update(dt);
            // out of screen
            if(it->getSprite().getGlobalBounds().top > layer_game.getSize().y){
                //it = ennemies.erase(it);
            }
        }
        // detect bullet collisions
        manageBulletCollision();

        for(int i=(int)bulletPlayer.size()-1;i>=0;i--){
            bulletPlayer[i].update(dt);
        }

        if(bullet.size() > 0)
            for(int i=(int)(bullet.size())-1;i>=0;i--){
                bullet[i].update(dt);
            }


        if(elapsed.getElapsedTime().asSeconds()-tcounter > 1.f){
            window.clear();

            // snapshot
            layer_game.clear();
            layer_game.draw(player);
            for (std::list<ShipEnemy>::iterator it=enemies.begin(); it != enemies.end(); ++it){
                layer_game.draw(*it);
            }

            for(int i=(int)bulletPlayer.size()-1;i>=0;i--){
                layer_game.draw(bulletPlayer[i]);
            }

            if(bullet.size() > 0)
                for(int i=(int)(bullet.size())-1;i>=0;i--){
                    layer_game.draw(bullet[i]);
                }

            layer_game.display();
            window.draw(sf::Sprite(layer_game.getTexture()));
            // ---

            std::string info2("");
            for(unsigned int i=0;i<evo.size();i++)
                info2 += evo[i].getName()+">"+ttos(evo[i].getTime())+"\n";
            info.setString("Temps : "+ttos(telapsed.getElapsedTime().asSeconds())+"\n"+
                            "Step : "+ttos(ncounter)+"\n"+
                           "Generation Max : "+ttos(gencounter)+
                           "\nBestTime : "+ttos(bestTime)+
                           "\nAvg : "+ttos(bestTimeCumul/(float)gencounter)
                           //+"\nfps : "+ttos(getFrameRate())+"\n---\n"+info2
                           );
            window.draw(info);
            window.display();
            tcounter = elapsed.getElapsedTime().asSeconds();
        }else
            getFrameRate();
        ncounter++;
    }

    for(unsigned int i=0;i<evo.size();++i){
        evo[i].writeGenome();
    }
    clear();
    enemies.clear();
}
Ejemplo n.º 30
0
Archivo: Game.cpp Proyecto: m1h4/Xetrix
bool InitializeGame(void)
{
	gameShip.InitializeShip();

	return true;
}