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); } } }
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(); } } }