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); } } } } } }
/* * 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; }
// 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()); }
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; } }
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; } }
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); } }
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; } }
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; }
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); } }
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; }
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; } } }
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; }
/* * 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; }
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; }
/* * 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; }
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; }
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; }
/* * 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; }
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(); } } }
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); }
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(); }
bool InitializeGame(void) { gameShip.InitializeShip(); return true; }