/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
*/
////////////////////////////////////////////////////////////////////////////////
// //
// (c) 2001-2003 Electronic Arts Inc. //
// //
////////////////////////////////////////////////////////////////////////////////
// FILE: Squad.cpp
/*---------------------------------------------------------------------------*/
/* EA Pacific */
/* Confidential Information */
/* Copyright (C) 2001 - All Rights Reserved */
/* DO NOT DISTRIBUTE */
/*---------------------------------------------------------------------------*/
/* Project: RTS3 */
/* File name: Squad.cpp */
/* Created: John K. McDonald, Jr., 4/19/2002 */
/* Desc: // @todo */
/* Revision History: */
/* 4/19/2002 : Initial creation */
/*---------------------------------------------------------------------------*/
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
#include "GameLogic/Squad.h"
#include "Common/GameState.h"
#include "Common/Team.h"
#include "Common/Xfer.h"
#include "GameLogic/AI.h"
#include "GameLogic/GameLogic.h"
#include "GameLogic/Object.h"
#ifdef _INTERNAL
// for occasional debugging...
//#pragma optimize("", off)
//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
#endif
// addObject //////////////////////////////////////////////////////////////////////////////////////
void Squad::addObject(Object *objectToAdd)
{
if (objectToAdd) {
m_objectIDs.push_back(objectToAdd->getID());
}
}
// addObjectID ////////////////////////////////////////////////////////////////////////////////////
void Squad::addObjectID(ObjectID objectID) {
m_objectIDs.push_back(objectID);
}
// removeObject ///////////////////////////////////////////////////////////////////////////////////
void Squad::removeObject(Object *objectToRemove)
{
if (objectToRemove) {
ObjectID objID;
objID = objectToRemove->getID();
VecObjectIDIt it = std::find(m_objectIDs.begin(), m_objectIDs.end(), objID);
if (it != m_objectIDs.end()) {
m_objectIDs.erase(it);
}
}
}
// clearSquad /////////////////////////////////////////////////////////////////////////////////////
void Squad::clearSquad() {
m_objectIDs.clear();
m_objectsCached.clear();
}
// getAllObjects //////////////////////////////////////////////////////////////////////////////////
const VecObjectPtr& Squad::getAllObjects(void) // Not a const function cause we clear away dead object here too
{
// prunes all NULL objects
m_objectsCached.clear();
for (VecObjectIDIt it = m_objectIDs.begin(); it != m_objectIDs.end(); ) {
Object *obj = TheGameLogic->findObjectByID(*it);
if (obj) {
m_objectsCached.push_back(obj);
++it;
} else {
it = m_objectIDs.erase(it);
}
}
return m_objectsCached;
}
// getLiveObjects /////////////////////////////////////////////////////////////////////////////////
const VecObjectPtr& Squad::getLiveObjects(void)
{
// first get all the objects.
// cheat, since we are a member function, and just use m_objectsCached
getAllObjects();
for (VecObjectPtrIt it = m_objectsCached.begin(); it != m_objectsCached.end(); ) {
if (!(*it)->isSelectable()) {
it = m_objectsCached.erase(it);
} else {
++it;
}
}
return m_objectsCached;
}
// getSizeOfGroup /////////////////////////////////////////////////////////////////////////////////
Int Squad::getSizeOfGroup(void) const
{
return m_objectIDs.size();
}
// isOnSquad //////////////////////////////////////////////////////////////////////////////////////
Bool Squad::isOnSquad(const Object *objToTest) const
{
// @todo need a faster way to do this. Perhaps a more efficient data structure?
ObjectID objID = objToTest->getID();
for (VecObjectID::const_iterator cit = m_objectIDs.begin(); cit != m_objectIDs.end(); ++cit) {
if (objID == (*cit)) {
return true;
}
}
return false;
}
/**
* There should never be a TeamFromSqaud as Teams are entirely a construct to work with the AI.
* Since things can only be on one Team at a time, creating a Team from an arbitrary Squad will
* cause weird, difficult to reproduce bugs. Please don't do it.
*/
// squadFromTeam //////////////////////////////////////////////////////////////////////////////////
void Squad::squadFromTeam(const Team* fromTeam, Bool clearSquadFirst)
{
if (!fromTeam) {
return;
}
if (clearSquadFirst) {
m_objectIDs.clear();
}
for (DLINK_ITERATOR