void CameraDirector::SetViewObjectGroup(ListIter<Ship> group, bool quick) { if (!ship) return; Starshatter* stars = Starshatter::GetInstance(); if (!stars->InCutscene()) { // only view solid contacts: while (++group) { Ship* s = group.value(); if (s->GetIFF() != ship->GetIFF()) { Contact* c = ship->FindContact(s); if (!c || !c->ActLock()) return; } if (s->Life() == 0 || s->IsDying() || s->IsDead()) return; } } group.reset(); if (external_group.size() > 1 && external_group.size() == group.size()) { bool same = true; for (int i = 0; same && i < external_group.size(); i++) { if (external_group[i] != group.container()[i]) same = false; } if (same) { SetMode(MODE_ZOOM); return; } } ClearGroup(); if (quick) { mode = MODE_ORBIT; transition = 0; } else { SetMode(MODE_TRANSLATE); } external_group.append(group.container()); ListIter<Ship> iter = external_group; while (++iter) { Ship* s = iter.value(); region = s->GetRegion(); Observe(s); } }
void CameraDirector::CycleViewObject() { if (!ship) return; Ship* current = external_ship; external_ship = 0; ListIter<Contact> iter = ship->ContactList(); while (++iter && !external_ship) { Contact* c = iter.value(); Ship* c_ship = c->GetShip(); if (c_ship && !current) { external_ship = c_ship; } else if (current && c_ship == current) { while (++iter && !external_ship) { c = iter.value(); if (c->ActLock()) external_ship = c->GetShip(); } } } if (external_ship != current) { if (external_ship) { if (external_ship->Life() == 0 || external_ship->IsDying() || external_ship->IsDead()) { external_point = external_ship->Location(); external_ship = 0; } else { Observe(external_ship); } } if (mode == MODE_ORBIT) { SetMode(MODE_TRANSLATE); ExternalRange(1); } } }
void StarshipAI::FireControl() { // identify unknown contacts: if (identify) { if (fabs(ship->GetHelmHeading() - ship->CompassHeading()) < 10*DEGREES) { Contact* contact = ship->FindContact(target); if (contact && !contact->ActLock()) { if (!ship->GetProbe()) { ship->LaunchProbe(); } } } return; } // investigate last known location of enemy ship: if (rumor && !target && ship->GetProbeLauncher() && !ship->GetProbe()) { // is rumor in basket? Point rmr = Transform(rumor->Location()); rmr.Normalize(); double dx = fabs(rmr.x); double dy = fabs(rmr.y); if (dx < 10*DEGREES && dy < 10*DEGREES && rmr.z > 0) { ship->LaunchProbe(); } } // Corvettes and Frigates are anti-air platforms. They need to // target missile threats even when the threat is aimed at another // friendly ship. Forward facing weapons must be on auto fire, // while lateral and aft facing weapons are set to point defense. if (ship->Class() == Ship::CORVETTE || ship->Class() == Ship::FRIGATE) { ListIter<WeaponGroup> iter = ship->Weapons(); while (++iter) { WeaponGroup* group = iter.value(); ListIter<Weapon> w_iter = group->GetWeapons(); while (++w_iter) { Weapon* weapon = w_iter.value(); double az = weapon->GetAzimuth(); if (fabs(az) < 45*DEGREES) { weapon->SetFiringOrders(Weapon::AUTO); weapon->SetTarget(target, 0); } else { weapon->SetFiringOrders(Weapon::POINT_DEFENSE); } } } } // All other starships are free to engage ship targets. Weapon // fire control is managed by the type of weapon. else { System* subtgt = SelectSubtarget(); ListIter<WeaponGroup> iter = ship->Weapons(); while (++iter) { WeaponGroup* weapon = iter.value(); if (weapon->GetDesign()->target_type & Ship::DROPSHIPS) { // anti-air weapon? weapon->SetFiringOrders(Weapon::POINT_DEFENSE); } else if (weapon->IsDrone()) { // torpedoes weapon->SetFiringOrders(Weapon::MANUAL); weapon->SetTarget(target, 0); if (target && target->GetRegion() == ship->GetRegion()) { Point delta = target->Location() - ship->Location(); double range = delta.length(); if (range < weapon->GetDesign()->max_range * 0.9 && !AssessTargetPointDefense()) weapon->SetFiringOrders(Weapon::AUTO); else if (range < weapon->GetDesign()->max_range * 0.5) weapon->SetFiringOrders(Weapon::AUTO); } } else { // anti-ship weapon weapon->SetFiringOrders(Weapon::AUTO); weapon->SetTarget(target, subtgt); weapon->SetSweep(subtgt ? Weapon::SWEEP_NONE : Weapon::SWEEP_TIGHT); } } } }
void CameraDirector::ExecFrame(double seconds) { if (!ship) return; hud = HUDView::GetInstance(); int flight_phase = ship->GetFlightPhase(); if (flight_phase < Ship::LOCKED) SetMode(MODE_DOCKING); if (ship->IsAirborne()) { if (flight_phase >= Ship::DOCKING) SetMode(MODE_DOCKING); } else { if (flight_phase >= Ship::RECOVERY) SetMode(MODE_DOCKING); } if (flight_phase >= Ship::LOCKED && flight_phase < Ship::ACTIVE) { int m = GetMode(); if (m != MODE_COCKPIT && m != MODE_VIRTUAL) SetMode(MODE_COCKPIT); } if (ship->InTransition()) { SetMode(MODE_DROP); } // automatically restore mode after transition: else if (old_mode != MODE_NONE) { mode = old_mode; requested_mode = old_mode; old_mode = MODE_NONE; } int op_mode = mode; if (requested_mode > mode) op_mode = requested_mode; Starshatter* stars = Starshatter::GetInstance(); // if we are in padlock, and have not locked a ship // try to padlock the current target: if (op_mode == MODE_TARGET && !external_ship) { SimObject* tgt = ship->GetTarget(); if (tgt && tgt->Type() == SimObject::SIM_SHIP) SetViewObject((Ship*) tgt); } // if in an external mode, check the external ship: else if (op_mode >= MODE_TARGET && op_mode <= MODE_ZOOM) { if (external_ship && external_ship != ship && !stars->InCutscene()) { Contact* c = ship->FindContact(external_ship); if (!c || !c->ActLock()) { SetViewObject(ship); } } } if (ship->Rep()) { if (op_mode == MODE_COCKPIT) { ship->HideRep(); ship->HideCockpit(); } else if (op_mode == MODE_VIRTUAL || op_mode == MODE_TARGET) { if (ship->Cockpit()) { ship->HideRep(); ship->ShowCockpit(); } else { ship->ShowRep(); } } else { ship->Rep()->SetForeground(op_mode == MODE_DOCKING); ship->ShowRep(); ship->HideCockpit(); } } if (hud && hud->Ambient() != Color::Black) sim->GetScene()->SetAmbient( hud->Ambient() ); else sim->GetScene()->SetAmbient( sim->GetStarSystem()->Ambient() ); switch (op_mode) { default: case MODE_COCKPIT: Cockpit(seconds); break; case MODE_CHASE: Chase(seconds); break; case MODE_TARGET: Target(seconds); break; case MODE_THREAT: Threat(seconds); break; case MODE_VIRTUAL: Virtual(seconds); break; case MODE_ORBIT: case MODE_TRANSLATE: case MODE_ZOOM: Orbit(seconds); break; case MODE_DOCKING: Docking(seconds); break; case MODE_DROP: Drop(seconds); break; } if (ship->Shake() > 0 && (op_mode < MODE_ORBIT || (op_mode == MODE_VIRTUAL && ship->Cockpit()))) { Point vib = ship->Vibration() * 0.2; camera.MoveBy(vib); camera.Aim(0, vib.y, vib.z); } Transition(seconds); DetailSet::SetReference(region, camera.Pos()); }
void CameraDirector::SetViewObject(Ship* obj, bool quick) { if (!ship) return; if (!obj) { obj = ship; region = ship->GetRegion(); } external_body = 0; external_point = Point(); Starshatter* stars = Starshatter::GetInstance(); if (obj->GetIFF() != ship->GetIFF() && !stars->InCutscene()) { // only view solid contacts: Contact* c = ship->FindContact(obj); if (!c || !c->ActLock()) return; } if (mode == MODE_TARGET) { ClearGroup(); if (external_ship) { external_ship = 0; } } else if (mode >= MODE_ORBIT) { if (quick) { mode = MODE_ORBIT; transition = 0; } else { SetMode(MODE_TRANSLATE); } if (external_group.size()) { ClearGroup(); if (external_ship) { external_ship = 0; } } else { if ((obj == external_ship) || (obj==ship && external_ship==0)) { if (!quick) SetMode(MODE_ZOOM); } else if (external_ship) { external_ship = 0; } } } if (external_ship != obj) { external_ship = obj; if (external_ship) { region = external_ship->GetRegion(); if (external_ship->Life() == 0 || external_ship->IsDying() || external_ship->IsDead()) { external_ship = 0; range_min = 100; } else { Observe(external_ship); if (sim) sim->ActivateRegion(external_ship->GetRegion()); range_min = external_ship->Radius() * 1.5; } } Observe(external_ship); ExternalRange(1); } }