GroundAI::GroundAI(SimObject* s) : ship((Ship*) s), target(0), subtarget(0), exec_time(0), carrier_ai(0) { Sim* sim = Sim::GetSim(); Ship* pship = sim->GetPlayerShip(); int player_team = 1; int ai_level = 1; if (pship) player_team = pship->GetIFF(); Player* player = Player::GetCurrentPlayer(); if (player) { if (ship && ship->GetIFF() && ship->GetIFF() != player_team) { ai_level = player->AILevel(); } else if (player->AILevel() == 0) { ai_level = 1; } } // evil alien ships are *always* smart: if (ship && ship->GetIFF() > 1 && ship->Design()->auto_roll > 1) { ai_level = 2; } if (ship && ship->GetHangar() && ship->GetCommandAILevel() > 0) carrier_ai = new(__FILE__,__LINE__) CarrierAI(ship, ai_level); }
TacticalAI::TacticalAI(ShipAI* ai) : ship(0), ship_ai(0), carrier_ai(0), navpt(0), orders(0), action(0), threat_level(0), support_level(1), directed_tgtid(0) { if (ai) { ship_ai = ai; ship = ai->GetShip(); Sim* sim = Sim::GetSim(); if (ship && ship->GetHangar() && ship->GetCommandAILevel() > 0 && ship != sim->GetPlayerShip()) carrier_ai = new(__FILE__,__LINE__) CarrierAI(ship, ship_ai->GetAILevel()); } agression = 0; roe = FLEXIBLE; element_index = 1; exec_time = exec_time_seed; exec_time_seed += 17; }
void RadioTraffic::SendMessage(RadioMessage* msg) { if (!msg) return; Sim* sim = Sim::GetSim(); Ship* player = sim->GetPlayerShip(); int iff = 0; if (player) iff = player->GetIFF(); if (msg->DestinationShip()) { traffic.append(msg); if (msg->Channel() == 0 || msg->Channel() == iff) DisplayMessage(msg); if (!NetGame::IsNetGameClient()) msg->DestinationShip()->HandleRadioMessage(msg); } else if (msg->DestinationElem()) { traffic.append(msg); if (msg->Channel() == 0 || msg->Channel() == iff) DisplayMessage(msg); if (!NetGame::IsNetGameClient()) msg->DestinationElem()->HandleRadioMessage(msg); } else { if (msg->Channel() == 0 || msg->Channel() == iff) DisplayMessage(msg); delete msg; } }
void Instruction::Evaluate(Ship* ship) { Sim* sim = Sim::GetSim(); switch (action) { case VECTOR: break; case LAUNCH: if (ship->GetFlightPhase() == Ship::ACTIVE) SetStatus(COMPLETE); break; case DOCK: case RTB: if (sim->GetPlayerShip() == ship && (ship->GetFlightPhase() == Ship::DOCKING || ship->GetFlightPhase() == Ship::DOCKED)) SetStatus(COMPLETE); else if (ship->Integrity() < 1) SetStatus(FAILED); break; case DEFEND: case ESCORT: { bool found = false; bool safe = true; ListIter<Element> iter = sim->GetElements(); while (++iter && !found) { Element* e = iter.value(); if (e->IsFinished() || e->IsSquadron()) continue; if (e->Name() == tgt_name || (e->GetCommander() && e->GetCommander()->Name() == tgt_name)) { found = true; for (int i = 0; i < e->NumShips(); i++) { Ship* s = e->GetShip(i+1); if (s && s->Integrity() < 1) SetStatus(FAILED); } if (status == PENDING) { // if the element had a flight plan, and all nav points // have been addressed, then the element is safe if (e->FlightPlanLength() > 0) { if (e->GetNextNavPoint() == 0) SetStatus(COMPLETE); else safe = false; } } } } if (status == PENDING && safe && sim->GetPlayerShip() == ship && (ship->GetFlightPhase() == Ship::DOCKING || ship->GetFlightPhase() == Ship::DOCKED)) { SetStatus(COMPLETE); } } break; case PATROL: case SWEEP: { Sim* sim = Sim::GetSim(); bool alive = false; ListIter<Element> iter = sim->GetElements(); while (++iter) { Element* e = iter.value(); if (e->IsFinished() || e->IsSquadron()) continue; if (e->GetIFF() && e->GetIFF() != ship->GetIFF()) { for (int i = 0; i < e->NumShips(); i++) { Ship* s = e->GetShip(i+1); if (s && s->Integrity() >= 1) alive = true; } } } if (status == PENDING && !alive) { SetStatus(COMPLETE); } } break; case INTERCEPT: case STRIKE: case ASSAULT: { Sim* sim = Sim::GetSim(); bool alive = false; ListIter<Element> iter = sim->GetElements(); while (++iter) { Element* e = iter.value(); if (e->IsFinished() || e->IsSquadron()) continue; if (e->Name() == tgt_name) { for (int i = 0; i < e->NumShips(); i++) { Ship* s = e->GetShip(i+1); if (s && s->Integrity() >= 1) alive = true; } } } if (status == PENDING && !alive) { SetStatus(COMPLETE); } } break; case RECON: break; default: break; } }
void MissionEvent::Execute(bool silent) { Starshatter* stars = Starshatter::GetInstance(); HUDView* hud = HUDView::GetInstance(); Sim* sim = Sim::GetSim(); Ship* player = sim->GetPlayerShip(); Ship* ship = 0; Ship* src = 0; Ship* tgt = 0; Element* elem = 0; int pan = 0; bool end_mission = false; if (event_ship.length()) ship = sim->FindShip(event_ship); else ship = player; if (event_source.length()) src = sim->FindShip(event_source); if (event_target.length()) tgt = sim->FindShip(event_target); if (ship) elem = ship->GetElement(); else if (event_ship.length()) { elem = sim->FindElement(event_ship); if (elem) ship = elem->GetShip(1); } // expire the delay, if any remains delay = 0; // fire the event action switch (event) { case MESSAGE: if (event_message.length() > 0) { if (ship) { RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(ship, src, event_param[0]); msg->SetInfo(event_message); msg->SetChannel(ship->GetIFF()); if (tgt) msg->AddTarget(tgt); RadioTraffic::Transmit(msg); } else if (elem) { RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(elem, src, event_param[0]); msg->SetInfo(event_message); msg->SetChannel(elem->GetIFF()); if (tgt) msg->AddTarget(tgt); RadioTraffic::Transmit(msg); } } if (event_sound.length() > 0) { pan = event_param[0]; } break; case OBJECTIVE: if (elem) { if (event_param[0]) { elem->ClearInstructions(); elem->ClearObjectives(); } Instruction* obj = new(__FILE__,__LINE__) Instruction(event_param[0], 0); obj->SetTarget(event_target); elem->AddObjective(obj); if (elem->Contains(player)) { HUDView* hud = HUDView::GetInstance(); if (hud) hud->ShowHUDInst(); } } break; case INSTRUCTION: if (elem) { if (event_param[0]) elem->ClearInstructions(); elem->AddInstruction(event_message); if (elem->Contains(player) && event_message.length() > 0) { HUDView* hud = HUDView::GetInstance(); if (hud) hud->ShowHUDInst(); } } break; case IFF: if (elem) { elem->SetIFF(event_param[0]); } else if (ship) { ship->SetIFF(event_param[0]); } break; case DAMAGE: if (ship) { ship->InflictDamage(event_param[0]); if (ship->Integrity() < 1) { NetUtil::SendObjKill(ship, 0, NetObjKill::KILL_MISC); ship->DeathSpiral(); Print(" %s Killed By Scripted Event %d (%s)\n", (const char*) ship->Name(), id, FormatGameTime()); } } else { Print(" EVENT %d: Could not apply damage to ship '%s' (not found).\n", id, (const char*) event_ship); } break; case JUMP: if (ship) { SimRegion* rgn = sim->FindRegion(event_target); if (rgn && ship->GetRegion() != rgn) { if (rgn->IsOrbital()) { QuantumDrive* quantum_drive = ship->GetQuantumDrive(); if (quantum_drive) { quantum_drive->SetDestination(rgn, Point(0,0,0)); quantum_drive->Engage(true); // request immediate jump } else if (ship->IsAirborne()) { ship->MakeOrbit(); } } else { ship->DropOrbit(); } } } break; case HOLD: if (elem) elem->SetHoldTime(event_param[0]); break; case SKIP: { for (int i = 0; i < event_nparams; i++) { int skip_id = event_param[i]; ListIter<MissionEvent> iter = sim->GetEvents(); while (++iter) { MissionEvent* e = iter.value(); if (e->EventID() == skip_id) { if (e->status != COMPLETE) e->status = SKIPPED; } } } } break; case END_MISSION: Print(" END MISSION By Scripted Event %d (%s)\n", id, FormatGameTime()); end_mission = true; break; // // NOTE: CUTSCENE EVENTS DO NOT APPLY IN MULTIPLAYER // case BEGIN_SCENE: Print(" ------------------------------------\n"); Print(" Begin Cutscene '%s'\n", event_message.data()); stars->BeginCutscene(); break; case END_SCENE: Print(" End Cutscene '%s'\n", event_message.data()); Print(" ------------------------------------\n"); stars->EndCutscene(); break; case CAMERA: if (stars->InCutscene()) { CameraDirector* cam_dir = CameraDirector::GetInstance(); if (!cam_dir->GetShip()) cam_dir->SetShip(player); switch (event_param[0]) { case 1: if (cam_dir->GetMode() != CameraDirector::MODE_COCKPIT) cam_dir->SetMode(CameraDirector::MODE_COCKPIT, event_rect.x); break; case 2: if (cam_dir->GetMode() != CameraDirector::MODE_CHASE) cam_dir->SetMode(CameraDirector::MODE_CHASE, event_rect.x); break; case 3: if (cam_dir->GetMode() != CameraDirector::MODE_ORBIT) cam_dir->SetMode(CameraDirector::MODE_ORBIT, event_rect.x); break; case 4: if (cam_dir->GetMode() != CameraDirector::MODE_TARGET) cam_dir->SetMode(CameraDirector::MODE_TARGET, event_rect.x); break; } if (event_target.length()) { ::Print("Mission Event %d: setting camera target to %s\n", id, (const char*) event_target); Ship* s_tgt = 0; if (event_target.indexOf("body:") < 0) s_tgt = sim->FindShip(event_target); if (s_tgt) { ::Print(" found ship %s\n", s_tgt->Name()); cam_dir->SetViewOrbital(0); if (cam_dir->GetViewObject() != s_tgt) { if (event_param[0] == 6) { s_tgt->DropCam(event_param[1], event_param[2]); cam_dir->SetShip(s_tgt); cam_dir->SetMode(CameraDirector::MODE_DROP, 0); } else { Ship* cam_ship = cam_dir->GetShip(); if (cam_ship && cam_ship->IsDropCam()) { cam_ship->CompleteTransition(); } if (cam_dir->GetShip() != sim->GetPlayerShip()) cam_dir->SetShip(sim->GetPlayerShip()); cam_dir->SetViewObject(s_tgt, true); // immediate, no transition } } } else { const char* body_name = event_target.data(); if (!strncmp(body_name, "body:", 5)) body_name += 5; Orbital* orb = sim->FindOrbitalBody(body_name); if (orb) { ::Print(" found body %s\n", orb->Name()); cam_dir->SetViewOrbital(orb); } } } if (event_param[0] == 3) { cam_dir->SetOrbitPoint(event_point.x, event_point.y, event_point.z); } else if (event_param[0] == 5) { cam_dir->SetOrbitRates(event_point.x, event_point.y, event_point.z); } } break; case VOLUME: if (stars->InCutscene()) { AudioConfig* audio_cfg = AudioConfig::GetInstance(); audio_cfg->SetEfxVolume(event_param[0]); audio_cfg->SetWrnVolume(event_param[0]); } break; case DISPLAY: if (stars->InCutscene()) { DisplayView* disp_view = DisplayView::GetInstance(); if (disp_view) { Color color; color.Set(event_param[0]); if (event_message.length() && event_source.length()) { if (event_message.contains('$')) { Campaign* campaign = Campaign::GetCampaign(); Player* user = Player::GetCurrentPlayer(); CombatGroup* group = campaign->GetPlayerGroup(); if (user) { event_message = FormatTextReplace(event_message, "$NAME", user->Name().data()); event_message = FormatTextReplace(event_message, "$RANK", Player::RankName(user->Rank())); } if (group) { event_message = FormatTextReplace(event_message, "$GROUP", group->GetDescription()); } if (event_message.contains("$TIME")) { char timestr[32]; FormatDayTime(timestr, campaign->GetTime(), true); event_message = FormatTextReplace(event_message, "$TIME", timestr); } } disp_view->AddText( event_message, FontMgr::Find(event_source), color, event_rect, event_point.y, event_point.x, event_point.z); } else if (event_target.length()) { DataLoader* loader = DataLoader::GetLoader(); if (loader) { loader->SetDataPath(0); loader->LoadBitmap(event_target, image, 0, true); } if (image.Width() && image.Height()) disp_view->AddImage( &image, color, Video::BLEND_ALPHA, event_rect, event_point.y, event_point.x, event_point.z); } } } break; case FIRE_WEAPON: if (ship) { // fire single weapon: if (event_param[0] >= 0) { ship->FireWeapon(event_param[0]); } // fire all weapons: else { ListIter<WeaponGroup> g_iter = ship->Weapons(); while (++g_iter) { ListIter<Weapon> w_iter = g_iter->GetWeapons(); while (++w_iter) { Weapon* w = w_iter.value(); w->Fire(); } } } } break; default: break; } sim->ProcessEventTrigger(TRIGGER_EVENT, id); if (!silent && !sound && event_sound.length()) { DataLoader* loader = DataLoader::GetLoader(); bool use_fs = loader->IsFileSystemEnabled(); DWORD flags = pan ? Sound::LOCKED|Sound::LOCALIZED : Sound::LOCKED|Sound::AMBIENT; loader->UseFileSystem(true); loader->SetDataPath("Sounds/"); loader->LoadSound(event_sound, sound, flags); loader->SetDataPath(0); if (!sound) { loader->SetDataPath("Mods/Sounds/"); loader->LoadSound(event_sound, sound, flags); loader->SetDataPath(0); } if (!sound) { loader->LoadSound(event_sound, sound, flags); } loader->UseFileSystem(use_fs); // fire and forget: if (sound) { if (sound->GetFlags() & Sound::STREAMED) { sound->SetFlags(flags | sound->GetFlags()); sound->SetVolume(AudioConfig::VoxVolume()); sound->Play(); } else { sound->SetFlags(flags); sound->SetVolume(AudioConfig::VoxVolume()); sound->SetPan(pan); sound->SetFilename(event_sound); sound->AddToSoundCard(); sound->Play(); } } } status = COMPLETE; if (end_mission) { StarServer* server = StarServer::GetInstance(); if (stars) { stars->EndMission(); } else if (server) { // end mission event uses event_target member // to forward server to next mission in the chain: if (event_target.length()) server->SetNextMission(event_target); server->SetGameMode(StarServer::MENU_MODE); } } }