summaryrefslogtreecommitdiffhomepage
path: root/Stars45/GroundAI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Stars45/GroundAI.cpp')
-rw-r--r--Stars45/GroundAI.cpp406
1 files changed, 215 insertions, 191 deletions
diff --git a/Stars45/GroundAI.cpp b/Stars45/GroundAI.cpp
index cd4d68b..d60731c 100644
--- a/Stars45/GroundAI.cpp
+++ b/Stars45/GroundAI.cpp
@@ -1,191 +1,215 @@
-/* Project Starshatter 4.5
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Stars.exe
- FILE: GroundAI.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Low-Level Artificial Intelligence class for Ground Units
-*/
-
-#include "MemDebug.h"
-#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 "Game.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(__FILE__,__LINE__) 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<Contact> 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) Game::GameTime() - exec_time > exec_period) {
- exec_time = (int) Game::GameTime();
- SelectTarget();
- }
-
- if (ship) {
- Shield* shield = ship->GetShield();
-
- if (shield)
- shield->SetPowerLevel(100);
-
- ListIter<WeaponGroup> 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);
- }
-}
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Stars.exe
+ FILE: GroundAI.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Low-Level Artificial Intelligence class for Ground Units
+*/
+
+#include "MemDebug.h"
+#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 "Game.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(__FILE__,__LINE__) 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<Contact> 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) Game::GameTime() - exec_time > exec_period) {
+ exec_time = (int) Game::GameTime();
+ SelectTarget();
+ }
+
+ if (ship) {
+ Shield* shield = ship->GetShield();
+
+ if (shield)
+ shield->SetPowerLevel(100);
+
+ ListIter<WeaponGroup> 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);
+ }
+}