summaryrefslogtreecommitdiffhomepage
path: root/Stars45/RadioHandler.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-04-01 21:23:39 +0200
committerAki <please@ignore.pl>2022-04-01 21:23:39 +0200
commit3c487c5cd69c53d6fea948643c0a76df03516605 (patch)
tree72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /Stars45/RadioHandler.cpp
parent8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff)
downloadstarshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2
Moved Stars45 to StarsEx
Diffstat (limited to 'Stars45/RadioHandler.cpp')
-rw-r--r--Stars45/RadioHandler.cpp557
1 files changed, 0 insertions, 557 deletions
diff --git a/Stars45/RadioHandler.cpp b/Stars45/RadioHandler.cpp
deleted file mode 100644
index b395c6e..0000000
--- a/Stars45/RadioHandler.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/* Starshatter: The Open Source Project
- Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors
- Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
- Copyright (c) 1997-2006, Destroyer Studios LLC.
-
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Radio message handler class implementation
-*/
-
-#include "RadioHandler.h"
-#include "RadioMessage.h"
-#include "RadioTraffic.h"
-#include "Instruction.h"
-
-#include "Contact.h"
-#include "Element.h"
-#include "Mission.h"
-#include "Ship.h"
-#include "ShipDesign.h"
-#include "Sim.h"
-#include "StarSystem.h"
-#include "Power.h"
-#include "Drive.h"
-#include "Shield.h"
-#include "Hangar.h"
-#include "FlightDeck.h"
-#include "WeaponGroup.h"
-#include "SteerAI.h"
-
-#include "Text.h"
-#include "Game.h"
-#include "ContentBundle.h"
-
-// +----------------------------------------------------------------------+
-
-RadioHandler::RadioHandler()
-{ }
-
-RadioHandler::~RadioHandler()
-{ }
-
-// +----------------------------------------------------------------------+
-
-bool
-RadioHandler::ProcessMessage(RadioMessage* msg, Ship* s)
-{
- if (!s || !msg || !msg->Sender())
- return false;
-
- if (s->Class() >= Ship::FARCASTER && s->Class() <= Ship::C3I)
- return false;
-
- if (msg->Sender()->IsRogue()) {
- Ship* sender = (Ship*) msg->Sender(); // cast-away const
- RadioMessage* nak = new RadioMessage(sender, s, RadioMessage::NACK);
- RadioTraffic::Transmit(nak);
- return false;
- }
-
- bool respond = (s != msg->Sender());
-
- // SPECIAL CASE:
- // skip navpoint must be processed by elem leader,
- // even if the elem leader sent the message:
-
- if (msg->Action() == RadioMessage::SKIP_NAVPOINT && !respond)
- ProcessMessageAction(msg, s);
-
- if (!ProcessMessageOrders(msg, s))
- respond = respond && ProcessMessageAction(msg, s);
-
- return respond;
-}
-
-// +----------------------------------------------------------------------+
-
-bool
-RadioHandler::IsOrder(int action)
-{
- bool result = false;
-
- switch (action) {
- default:
- case RadioMessage::NONE:
- case RadioMessage::ACK:
- case RadioMessage::NACK: result = false; break;
-
- // target mgt:
- case RadioMessage::ATTACK:
- case RadioMessage::ESCORT:
- case RadioMessage::BRACKET:
- case RadioMessage::IDENTIFY: result = true; break;
-
- // combat mgt:
- case RadioMessage::COVER_ME:
- case RadioMessage::WEP_HOLD:
- case RadioMessage::FORM_UP: result = true; break;
-
- case RadioMessage::WEP_FREE:
- case RadioMessage::SAY_POSITION:
- case RadioMessage::LAUNCH_PROBE: result = false; break;
-
- // formation mgt:
- case RadioMessage::GO_DIAMOND:
- case RadioMessage::GO_SPREAD:
- case RadioMessage::GO_BOX:
- case RadioMessage::GO_TRAIL: result = true; break;
-
- // mission mgt:
- case RadioMessage::MOVE_PATROL: result = true; break;
- case RadioMessage::SKIP_NAVPOINT: result = false; break;
- case RadioMessage::RESUME_MISSION: result = true; break;
-
- case RadioMessage::RTB:
- case RadioMessage::DOCK_WITH:
- case RadioMessage::QUANTUM_TO:
- case RadioMessage::FARCAST_TO: result = true; break;
-
- // sensor mgt:
- case RadioMessage::GO_EMCON1:
- case RadioMessage::GO_EMCON2:
- case RadioMessage::GO_EMCON3: result = true; break;
-
- // support:
- case RadioMessage::REQUEST_PICTURE:
- case RadioMessage::REQUEST_SUPPORT:
- case RadioMessage::PICTURE: result = false; break;
-
- // traffic control:
- case RadioMessage::CALL_INBOUND:
- case RadioMessage::CALL_APPROACH:
- case RadioMessage::CALL_CLEARANCE:
- case RadioMessage::CALL_FINALS:
- case RadioMessage::CALL_WAVE_OFF: result = false; break;
- }
-
- return result;
-}
-
-// +----------------------------------------------------------------------+
-
-bool
-RadioHandler::ProcessMessageOrders(RadioMessage* msg, Ship* ship)
-{
- Instruction* instruction = ship->GetRadioOrders();
- int action = 0;
-
- if (msg && msg->Action() == RadioMessage::RESUME_MISSION) {
- instruction->SetAction(RadioMessage::NONE);
- instruction->SetFormation(-1);
- instruction->SetWeaponsFree(true);
- if (instruction->GetTarget()) {
- instruction->ClearTarget();
- ship->DropTarget();
- }
- return true;
- }
-
- if (msg && IsOrder(msg->Action())) {
- int posture_only = false;
-
- action = msg->Action();
-
- if (action == RadioMessage::FORM_UP)
- action = RadioMessage::WEP_HOLD;
-
- // target orders => drop current target:
- if (action >= RadioMessage::ATTACK &&
- action <= RadioMessage::COVER_ME ||
- action == RadioMessage::WEP_HOLD ||
- action >= RadioMessage::DOCK_WITH &&
- action <= RadioMessage::FARCAST_TO) {
-
- if (ship != msg->Sender())
- ship->DropTarget();
-
- Director* dir = ship->GetDirector();
- if (dir && dir->Type() >= SteerAI::SEEKER && dir->Type() <= SteerAI::GROUND) {
- SteerAI* ai = (SteerAI*) dir;
- ai->SetTarget(0);
- }
-
- // farcast and quantum jump radio messages:
- if (action >= RadioMessage::QUANTUM_TO) {
- Sim* sim = Sim::GetSim();
-
- if (sim) {
- SimRegion* rgn = sim->FindRegion(msg->Info());
-
- if (rgn) {
- instruction->SetAction(action);
- instruction->SetLocation(Point(0,0,0));
- instruction->SetRegion(rgn);
- instruction->SetFarcast(action == RadioMessage::FARCAST_TO);
- instruction->SetWeaponsFree(false);
- return true;
- }
- }
- }
- }
-
- // formation orders => set formation:
- if (action >= RadioMessage::GO_DIAMOND &&
- action <= RadioMessage::GO_TRAIL) {
-
- switch (action) {
- case RadioMessage::GO_DIAMOND: instruction->SetFormation(Instruction::DIAMOND); break;
- case RadioMessage::GO_SPREAD: instruction->SetFormation(Instruction::SPREAD); break;
- case RadioMessage::GO_BOX: instruction->SetFormation(Instruction::BOX); break;
- case RadioMessage::GO_TRAIL: instruction->SetFormation(Instruction::TRAIL); break;
- }
-
- posture_only = true;
- }
-
- // emcon orders => set emcon:
- if (action >= RadioMessage::GO_EMCON1 &&
- action <= RadioMessage::GO_EMCON3) {
-
- switch (msg->Action()) {
- case RadioMessage::GO_EMCON1: instruction->SetEMCON(1); break;
- case RadioMessage::GO_EMCON2: instruction->SetEMCON(2); break;
- case RadioMessage::GO_EMCON3: instruction->SetEMCON(3); break;
- }
-
- posture_only = true;
- }
-
- if (!posture_only) {
- instruction->SetAction(action);
- instruction->ClearTarget();
-
- if (msg->TargetList().size() > 0) {
- SimObject* msg_tgt = msg->TargetList().at(0);
- instruction->SetTarget(msg_tgt);
- instruction->SetLocation(msg_tgt->Location());
- }
-
- else if (action == RadioMessage::COVER_ME) {
- instruction->SetTarget((Ship*) msg->Sender());
- instruction->SetLocation(msg->Sender()->Location());
- }
-
- else if (action == RadioMessage::MOVE_PATROL) {
- instruction->SetLocation(msg->Location());
- }
-
- // handle element engagement:
- if (action == RadioMessage::ATTACK && msg->TargetList().size() > 0) {
- Element* elem = msg->DestinationElem();
-
- if (!elem && msg->DestinationShip())
- elem = msg->DestinationShip()->GetElement();
-
- if (elem) {
- SimObject* msg_tgt = msg->TargetList().at(0);
- if (msg_tgt && msg_tgt->Type() == SimObject::SIM_SHIP) {
- Element* tgt = ((Ship*) msg_tgt)->GetElement();
- elem->SetAssignment(tgt);
-
- if (msg->TargetList().size() > 1)
- instruction->SetTarget(tgt->Name().data());
- else
- instruction->SetTarget(msg_tgt);
- }
- else {
- elem->ResumeAssignment();
- }
- }
- }
-
- else if (action == RadioMessage::RESUME_MISSION) {
- Element* elem = msg->DestinationElem();
-
- if (!elem && msg->DestinationShip())
- elem = msg->DestinationShip()->GetElement();
-
- if (elem) {
- elem->ResumeAssignment();
- }
- }
- }
-
- instruction->SetWeaponsFree(action <= RadioMessage::WEP_FREE);
- return true;
- }
-
- return false;
-}
-
-// +----------------------------------------------------------------------+
-
-bool
-RadioHandler::ProcessMessageAction(RadioMessage* msg, Ship* ship)
-{
- if (!msg) return false;
-
- if (msg->Action() == RadioMessage::CALL_INBOUND)
- return Inbound(msg, ship);
-
- if (msg->Action() == RadioMessage::CALL_FINALS)
- return true; // acknowledge
-
- if (msg->Action() == RadioMessage::REQUEST_PICTURE)
- return Picture(msg, ship);
-
- if (msg->Action() == RadioMessage::REQUEST_SUPPORT)
- return Support(msg, ship);
-
- if (msg->Action() == RadioMessage::SKIP_NAVPOINT)
- return SkipNavpoint(msg, ship);
-
- if (msg->Action() == RadioMessage::LAUNCH_PROBE)
- return LaunchProbe(msg, ship);
-
- return false;
-}
-
-bool
-RadioHandler::SkipNavpoint(RadioMessage* msg, Ship* ship)
-{
- // Find next Instruction:
- Instruction* navpt = ship->GetNextNavPoint();
- int elem_index = ship->GetElementIndex();
-
- if (navpt && elem_index < 2) {
- ship->SetNavptStatus(navpt, Instruction::SKIPPED);
- }
-
- return true;
-}
-
-bool
-RadioHandler::LaunchProbe(RadioMessage* msg, Ship* ship)
-{
- if (ship && ship->GetProbeLauncher()) {
- ship->LaunchProbe();
- return ship->GetProbe() != 0;
- }
-
- return false;
-}
-
-bool
-RadioHandler::Inbound(RadioMessage* msg, Ship* ship)
-{
- Ship* inbound = (Ship*) msg->Sender();
- Hangar* hangar = ship->GetHangar();
- FlightDeck* deck = 0;
- int squadron = -1;
- int slot = -1;
- bool same_rgn = false;
-
- if (inbound && inbound->GetRegion() == ship->GetRegion())
- same_rgn = true;
-
- // is the sender already inbound to us?
- if (inbound->GetInbound() &&
- inbound->GetInbound()->GetDeck() &&
- inbound->GetInbound()->GetDeck()->GetCarrier() == ship) {
- InboundSlot* islot = inbound->GetInbound();
- deck = islot->GetDeck();
- squadron = islot->Squadron();
- slot = islot->Index();
- }
-
- // otherwise, find space for sender:
- else {
- if (hangar && same_rgn) {
- if (hangar->FindSlot(inbound, squadron, slot)) {
- int shortest_queue = 1000;
-
- for (int i = 0; i < ship->NumFlightDecks(); i++) {
- FlightDeck* d = ship->GetFlightDeck(i);
- if (d->IsRecoveryDeck()) {
- int nwaiting = d->GetRecoveryQueue().size();
-
- if (nwaiting < shortest_queue) {
- deck = d;
- shortest_queue = nwaiting;
- }
- }
- }
- }
- }
- }
-
- // if no space (or not a carrier!) wave sender off:
- if (!deck || !same_rgn || squadron < 0 || slot < 0) {
- RadioMessage* wave_off = new RadioMessage(inbound, ship, RadioMessage::NACK);
- if (!hangar)
- wave_off->SetInfo(ContentBundle::GetInstance()->GetText("RadioHandler.no-hangar"));
-
- else if (!same_rgn) {
- char info[256];
- sprintf_s(info, ContentBundle::GetInstance()->GetText("RadioHandler.too-far-away").data(), ship->GetRegion()->Name());
- wave_off->SetInfo(info);
- }
-
- else
- wave_off->SetInfo(ContentBundle::GetInstance()->GetText("RadioHandler.all-full"));
-
- RadioTraffic::Transmit(wave_off);
- return false;
- }
-
- // put sender in recovery queue, if not already there:
- InboundSlot* inbound_slot = inbound->GetInbound();
- int sequence = 0;
-
- if (!inbound_slot) {
- inbound_slot = new InboundSlot(inbound, deck, squadron, slot);
- sequence = deck->Inbound(inbound_slot);
- }
- else {
- sequence = inbound_slot->Index();
- }
-
- // inform sender of status:
- RadioMessage* approach = new RadioMessage(inbound, ship, RadioMessage::CALL_APPROACH);
-
- if (inbound_slot->Cleared()) {
- char info[256];
- sprintf_s(info, ContentBundle::GetInstance()->GetText("RadioHandler.cleared").data(), deck->Name());
- approach->SetInfo(info);
- }
- else if (sequence) {
- char info[256];
- sprintf_s(info, ContentBundle::GetInstance()->GetText("RadioHandler.sequenced").data(), sequence, deck->Name());
- approach->SetInfo(info);
- }
-
- RadioTraffic::Transmit(approach);
-
- return false;
-}
-
-bool
-RadioHandler::Picture(RadioMessage* msg, Ship* ship)
-{
- if (!ship) return false;
-
- // try to find some enemy fighters in the area:
- Ship* tgt = 0;
- double range = 1e9;
-
- ListIter<Contact> iter = ship->ContactList();
- while (++iter) {
- Contact* c = iter.value();
- int iff = c->GetIFF(ship);
- Ship* s = c->GetShip();
-
- if (s && s->IsDropship() && s->IsHostileTo(ship)) {
- double s_range = Point(msg->Sender()->Location() - s->Location()).length();
- if (!tgt || s_range < range) {
- tgt = s;
- range = s_range;
- }
- }
- }
-
- // found some:
- if (tgt) {
- Element* sender = msg->Sender()->GetElement();
- Element* tgt_elem = tgt->GetElement();
- RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::ATTACK);
-
- if (tgt_elem) {
- for (int i = 1; i <= tgt_elem->NumShips(); i++)
- response->AddTarget(tgt_elem->GetShip(i));
- }
- else {
- response->AddTarget(tgt);
- }
-
- RadioTraffic::Transmit(response);
- }
-
- // nobody worth killin':
- else {
- Ship* sender = (Ship*) msg->Sender(); // cast-away const
- RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::PICTURE);
- RadioTraffic::Transmit(response);
- }
-
- return false;
-}
-
-bool
-RadioHandler::Support(RadioMessage* msg, Ship* ship)
-{
- if (!ship) return false;
-
- // try to find some fighters with time on their hands...
- Element* help = 0;
- Element* cmdr = ship->GetElement();
- Element* baby = msg->Sender()->GetElement();
- SimRegion* rgn = msg->Sender()->GetRegion();
-
- for (int i = 0; i < rgn->Ships().size(); i++) {
- Ship* s = rgn->Ships().at(i);
- Element* e = s->GetElement();
-
- if (e && s->IsDropship() &&
- e->Type() == Mission::PATROL &&
- e != baby &&
- cmdr->CanCommand(e) &&
- s->GetRadioOrders()->Action() == RadioMessage::NONE) {
- help = e;
- break;
- }
- }
-
- // found some:
- if (help) {
- RadioMessage* escort = new RadioMessage(help, ship, RadioMessage::ESCORT);
- escort->TargetList().append(msg->Sender());
- RadioTraffic::Transmit(escort);
-
- Text ok = ContentBundle::GetInstance()->GetText("RadioHandler.help-enroute");
- Ship* sender = (Ship*) msg->Sender(); // cast-away const
- RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::ACK);
- response->SetInfo(ok);
- RadioTraffic::Transmit(response);
- }
-
- // no help in sight:
- else {
- Text nope = ContentBundle::GetInstance()->GetText("RadioHandler.no-help-for-you");
- Ship* sender = (Ship*) msg->Sender(); // cast-away const
- RadioMessage* response = new RadioMessage(sender, ship, RadioMessage::NACK);
- response->SetInfo(nope);
- RadioTraffic::Transmit(response);
- }
-
- return false;
-}
-
-// +----------------------------------------------------------------------+
-
-void
-RadioHandler::AcknowledgeMessage(RadioMessage* msg, Ship* s)
-{
- if (s && msg && msg->Sender() && msg->Action()) {
- if (msg->Action() >= RadioMessage::ACK && msg->Action() <= RadioMessage::NACK)
- return; // nothing to say here
-
- Ship* sender = (Ship*) msg->Sender(); // cast-away const
- RadioMessage* ack = new RadioMessage(sender, s, RadioMessage::ACK);
- RadioTraffic::Transmit(ack);
- }
-}
-