/*
** Command & Conquer Generals(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: CaveSystem.cpp /////////////////////////////////////////////////////////////////////////////////
// Author: Graham Smallwood July 2002
// Desc: System responsible for keeping track of all cave systems on the map
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
#include "Common/GameState.h"
#include "Common/TunnelTracker.h"
#include "Common/Xfer.h"
#include "GameLogic/CaveSystem.h"
CaveSystem *TheCaveSystem = NULL;
CaveSystem::CaveSystem()
{
}
CaveSystem::~CaveSystem()
{
}
void CaveSystem::init()
{
}
void CaveSystem::reset()
{
for( std::vector::iterator iter = m_tunnelTrackerVector.begin(); iter != m_tunnelTrackerVector.end(); iter++ )
{
TunnelTracker *currentTracker = *iter;
if( currentTracker )// could be NULL, since we don't slide back to fill deleted entries so offsets don't shift
{
currentTracker->deleteInstance();
}
}
m_tunnelTrackerVector.clear();
}
void CaveSystem::update()
{
}
Bool CaveSystem::canSwitchIndexToIndex( Int oldIndex, Int newIndex )
{
// When I grant permission, you need to do it. ie call Unregister and then re-register with the new number
TunnelTracker *oldTracker = NULL;
TunnelTracker *newTracker = NULL;
if( m_tunnelTrackerVector.size() > oldIndex )
{
oldTracker = m_tunnelTrackerVector[oldIndex];
if( oldTracker && oldTracker->getContainCount() > 0 )
return FALSE;// You can't switch a connection if one of the two is non empty
}
if( m_tunnelTrackerVector.size() > newIndex )
{
newTracker = m_tunnelTrackerVector[newIndex];
if( newTracker && newTracker->getContainCount() > 0 )
return FALSE;// You can't switch a connection if one of the two is non empty
}
// Both are either empty or non-existent, so go ahead.
// (Remember non-exist is only a valid case because you are going to do the switch now.)
return TRUE;
}
void CaveSystem::registerNewCave( Int theIndex )
{
Bool needToCreate = FALSE;
if( theIndex >= m_tunnelTrackerVector.size() )
{
// You are new and off the edge, so I will fill NULLs up to you and then make a newTracker at that spot
while( theIndex >= m_tunnelTrackerVector.size() )
m_tunnelTrackerVector.push_back( NULL );
needToCreate = TRUE;
}
else
{
// else you either exist or have existed, so I will either let things be or re-create that slot
if( m_tunnelTrackerVector[theIndex] == NULL )
needToCreate = TRUE;
}
if( needToCreate )// if true, we new theIndex is the index of a NULL to be filled
m_tunnelTrackerVector[theIndex] = newInstance(TunnelTracker);
}
void CaveSystem::unregisterCave( Int theIndex )
{
// Doesn't need to do a thing. ContainModule logic knows how to say goodbye, and a TunnelTracker
// knows how to exist while having no entry points.
theIndex;
}
TunnelTracker *CaveSystem::getTunnelTrackerForCaveIndex( Int theIndex )
{
TunnelTracker *theTracker = NULL;
if( theIndex < m_tunnelTrackerVector.size() )
{
theTracker = m_tunnelTrackerVector[theIndex];
}
DEBUG_ASSERTCRASH( theTracker != NULL, ("No one should be interested in a sub-cave that doesn't exist.") );
return theTracker;
}
// ------------------------------------------------------------------------------------------------
/** Xfer Method
* Version Info
* 1: Initial version */
// ------------------------------------------------------------------------------------------------
void CaveSystem::xfer( Xfer *xfer )
{
// version
XferVersion currentVersion = 1;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
// tunnel tracker size and data
UnsignedShort count = m_tunnelTrackerVector.size();
xfer->xferUnsignedShort( &count );
TunnelTracker *tracker;
if( xfer->getXferMode() == XFER_SAVE )
{
std::vector< TunnelTracker* >::iterator it;
for( it = m_tunnelTrackerVector.begin(); it != m_tunnelTrackerVector.end(); ++it )
{
// xfer data
tracker = *it;
xfer->xferSnapshot( tracker );
} // end
} // end if, save
else
{
// the list must be empty now
if( m_tunnelTrackerVector.empty() == FALSE )
{
DEBUG_CRASH(( "CaveSystem::xfer - m_tunnelTrackerVector should be empty but is not\n" ));
throw SC_INVALID_DATA;
} // end if
// read each item
for( UnsignedShort i = 0; i < count; ++i )
{
// allocate new tracker
tracker = newInstance( TunnelTracker );
// read data
xfer->xferSnapshot( tracker );
// put in vector
m_tunnelTrackerVector.push_back( tracker );
} // end for, i
} // end else, laod
} // end xfer