From 3c487c5cd69c53d6fea948643c0a76df03516605 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 1 Apr 2022 21:23:39 +0200 Subject: Moved Stars45 to StarsEx --- StarsEx/GroundAI.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 StarsEx/GroundAI.cpp (limited to 'StarsEx/GroundAI.cpp') diff --git a/StarsEx/GroundAI.cpp b/StarsEx/GroundAI.cpp new file mode 100644 index 0000000..4435742 --- /dev/null +++ b/StarsEx/GroundAI.cpp @@ -0,0 +1,189 @@ +/* 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 + ======== + Low-Level Artificial Intelligence class for Ground Units +*/ + +#include "GroundAI.h" +#include "SteerAI.h" +#include "System.h" +#include "Ship.h" +#include "ShipDesign.h" +#include "Shield.h" +#include "Sim.h" +#include "Player.h" +#include "CarrierAI.h" +#include "Contact.h" +#include "Weapon.h" +#include "WeaponGroup.h" + +#include "Clock.h" +#include "Physical.h" + +// +----------------------------------------------------------------------+ + +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 CarrierAI(ship, ai_level); +} + + +// +--------------------------------------------------------------------+ + +GroundAI::~GroundAI() +{ + delete carrier_ai; +} + +// +--------------------------------------------------------------------+ + +void +GroundAI::SetTarget(SimObject* targ, System* sub) +{ + if (target != targ) { + target = targ; + + if (target) + Observe(target); + } + + subtarget = sub; +} + +// +--------------------------------------------------------------------+ + +bool +GroundAI::Update(SimObject* obj) +{ + if (obj == target) { + target = 0; + subtarget = 0; + } + + return SimObserver::Update(obj); +} + +const char* +GroundAI::GetObserverName() const +{ + static char name[64]; + sprintf_s(name, "GroundAI(%s)", ship->Name()); + return name; +} + +// +--------------------------------------------------------------------+ + +void +GroundAI::SelectTarget() +{ + SimObject* potential_target = 0; + + // pick the closest combatant ship with a different IFF code: + double target_dist = 1.0e15; + + Ship* current_ship_target = 0; + + ListIter c_iter = ship->ContactList(); + while (++c_iter) { + Contact* contact = c_iter.value(); + int c_iff = contact->GetIFF(ship); + Ship* c_ship = contact->GetShip(); + Shot* c_shot = contact->GetShot(); + bool rogue = false; + + if (c_ship) + rogue = c_ship->IsRogue(); + + if (rogue || c_iff > 0 && c_iff != ship->GetIFF() && c_iff < 1000) { + if (c_ship && !c_ship->InTransition()) { + // found an enemy, check distance: + double dist = (ship->Location() - c_ship->Location()).length(); + + if (!current_ship_target || (c_ship->Class() <= current_ship_target->Class() && + dist < target_dist)) { + current_ship_target = c_ship; + target_dist = dist; + } + } + } + + potential_target = current_ship_target; + } + + SetTarget(potential_target); +} + +// +--------------------------------------------------------------------+ + +int +GroundAI::Type() const +{ + return SteerAI::GROUND; +} + +// +--------------------------------------------------------------------+ + +void +GroundAI::ExecFrame(double secs) +{ + const int exec_period = 1000; + + if ((int) Clock::GetInstance()->GameTime() - exec_time > exec_period) { + exec_time = (int) Clock::GetInstance()->GameTime(); + SelectTarget(); + } + + if (ship) { + Shield* shield = ship->GetShield(); + + if (shield) + shield->SetPowerLevel(100); + + ListIter iter = ship->Weapons(); + while (++iter) { + WeaponGroup* group = (WeaponGroup*) iter.value(); + + if (group->NumWeapons() > 1 && group->CanTarget(Ship::DROPSHIPS)) + group->SetFiringOrders(Weapon::POINT_DEFENSE); + else + group->SetFiringOrders(Weapon::AUTO); + + group->SetTarget((Ship*) target, 0); + } + + if (carrier_ai) + carrier_ai->ExecFrame(secs); + } +} -- cgit v1.1