#include "pch.h"
#include "mapmakerIGC.h"
const char * CMapData::smszClusterName[c_NumClusterNames] =
{
"Aegis", "Aeroflex", "Ahto", "Aredne",
"Blenhem", "Borsonis", "Bragi", "Caladonia", "Cirt",
"Claytow", "Denom", "Dunatis", "Eleesh",
"Enlil", "Fejfar", "Fenris", "Fierro",
"Freya", "Gala", "Gery",
"Gobo", "Goron", "Holokine", "Jol",
"Karlo", "Kassano", "Kassimier", "Kik",
"Kilvero", "Kishoten", "Kuat", "L'Sau",
"Larchis", "Lemminakean", "Leighton", "Louhi",
"Loviatar", "Luerentia", "Meesh", "Mercor",
"Miekko", "Mielikki", "Monmar",
"Nadir", "Night", "Oblivion",
"Okanagon", "Oxyl", "Pohjola",
"Raiko", "Resnik", "Rib'zki", "Rimin", "Sleipener",
"Solitaire", "Soron", "Sri Metsa", "Surma",
"Tathlum", "Tierankeen", "Tjeerd", "Torc",
"Touni", "Tauceti", "Titty Baby" ,"Turakeen", "Udar", "Virkinow",
"Xuping"
} ;
const char * CmapMakerIGC::smszPlanetName[c_NumberOfPlanetPosters] =
{
"nebplnt36bmp",
"nebplnt35bmp",
"nebplnt02bmp",
"nebplnt23bmp",
"nebplnt19bmp",
"nebplnt01bmp",
"nebplnt03bmp",
"nebplnt04bmp",
"nebplnt05bmp",
"nebplnt06bmp",
"nebplnt07bmp",
"nebplnt08bmp",
"nebplnt09bmp",
"nebplnt10bmp",
"nebplnt11bmp",
"nebplnt12bmp",
"nebplnt16bmp",
"nebplnt19bmp",
"nebplnt24bmp",
"nebplnt25bmp",
"nebplnt29bmp",
"nebplnt30bmp",
"nebplnt31bmp",
"nebplnt33bmp",
"nebplnt37bmp"
} ;
CMapData::CMapData()
{
SectorID sID;
mpMission = NULL;
mpMissionParams = NULL;
ZeroMemory(mpCluster, sizeof(mpCluster));
for(sID = 0; sID < c_NumClusterNames; sID++)
mClusterNamesLeft[sID] = sID;
mcClusterNamesLeft = c_NumClusterNames;
mcTeamClustersPerTeam = 0;
mcNeutralClustersPerTeam = 0;
mcOtherClusters = 0;
mIDNextWarp = 0;
}
CMapData::~CMapData()
{
SectorID sID;
for(sID = 0; sID < c_MaxClustersPerMap; sID++)
{
if (NULL != mpCluster[sID])
mpCluster[sID]->Release();
}
}
VOID CMapData::SetCluster(SectorID sID, IclusterIGC * pCluster, SideID sideID)
{
if (NULL != pCluster)
pCluster->AddRef();
if (NULL != mpCluster[sID])
mpCluster[sID]->Release();
mpCluster[sID] = pCluster;
msideIDCluster[sID] = sideID;
}
VOID CMapData::GetNewClusterName(CHAR * szClusterName)
{
INT n = randomInt(0, mcClusterNamesLeft - 1);
strcpy(szClusterName, smszClusterName[mClusterNamesLeft[n]]);
mcClusterNamesLeft--;
mClusterNamesLeft[n] = mClusterNamesLeft[mcClusterNamesLeft];
}
const char* ImapMakerIGC::IsValid(const MissionParams* pmp)
{
switch (pmp->mmMapType)
{
case c_mmSingleRing:
return CmapMakerSingleRingIGC::IsValid(pmp);
case c_mmDoubleRing:
return CmapMakerDoubleRingIGC::IsValid(pmp);
case c_mmPinWheel:
return CmapMakerPinWheelIGC::IsValid(pmp);
case c_mmDiamondRing:
return CmapMakerDiamondRingIGC::IsValid(pmp);
case c_mmSnowFlake:
return CmapMakerSnowFlakeIGC::IsValid(pmp);
case c_mmSplitBase:
return CmapMakerSplitBaseIGC::IsValid(pmp);
case c_mmLargeSplit:
return CmapMakerLargeSplitIGC::IsValid(pmp);
case c_mmBrawl:
return CmapMakerBrawlIGC::IsValid(pmp);
case c_mmBigRing:
return CmapMakerBigRingIGC::IsValid(pmp);
case c_mmHiLo:
return CmapMakerHiLoIGC::IsValid(pmp);
case c_mmHiHigher:
return CmapMakerHiHigherIGC::IsValid(pmp);
case c_mmStar:
return CmapMakerStarIGC::IsValid(pmp);
case c_mmInsideOut:
return CmapMakerInsideOutIGC::IsValid(pmp);
case c_mmGrid:
return CmapMakerGridIGC::IsValid(pmp);
case c_mmEastWest:
return CmapMakerEastWestIGC::IsValid(pmp);
}
return "Invalid map type";
}
void ImapMakerIGC::Create(Time now,
const MissionParams* pmp,
ImissionIGC* pmission)
{
assert (pmp->nTeams >= 2);
assert (pmp->nTeams <= c_cSidesMax);
#define MakeMap(x) case c_mm##x: \
{ \
CmapMaker##x##IGC mm; \
mm.GenerateMission(now, pmp, pmission); \
} \
break; \
switch(pmp->mmMapType)
{
MakeMap(SingleRing)
MakeMap(DoubleRing)
MakeMap(PinWheel)
MakeMap(DiamondRing)
MakeMap(SnowFlake)
MakeMap(SplitBase)
MakeMap(Brawl)
MakeMap(BigRing)
MakeMap(HiLo)
MakeMap(HiHigher)
MakeMap(Star)
MakeMap(InsideOut)
MakeMap(Grid)
MakeMap(EastWest)
MakeMap(LargeSplit)
default:
assert (false);
}
#undef MakeMap
}
CmapMakerIGC::CmapMakerIGC()
{
mMMID = c_mmSingleRing;
this->SetName("Single Ring");
}
CmapMakerIGC::~CmapMakerIGC()
{
}
static bool FindPath(IclusterIGC* p2,
int* pStart,
int* pStop,
IclusterIGC** pclustersAdjacent,
IclusterIGC** pclusterBackTrack,
bool* bVisited)
{
if (*pStart == *pStop)
return false;
IclusterIGC* p1 = pclustersAdjacent[*pStart];
assert (p1);
if (p1 == p2)
return true;
(*pStart)++;
for (WarpLinkIGC* pwl = p1->GetWarps()->first(); (pwl != NULL); pwl = pwl->next())
{
IclusterIGC* p = pwl->data()->GetDestination()->GetCluster();
SectorID id = p->GetObjectID();
if ((pclusterBackTrack[id] == NULL) && !bVisited[id])
{
pclusterBackTrack[id] = p1;
pclustersAdjacent[*pStop] = p;
(*pStop)++;
}
}
return FindPath(p2, pStart, pStop,
pclustersAdjacent,
pclusterBackTrack,
bVisited);
}
static bool EnoughPaths(IclusterIGC** pclusterBackTrack,
bool* bVisited,
const ClusterListIGC* pclusters,
IwarpIGC* pwarp,
int count)
{
IclusterIGC* pcluster1 = pwarp->GetCluster();
IclusterIGC* pcluster2 = pwarp->GetDestination()->GetCluster();
for (int i = pclusters->n() - 1; (i >= 0); i--)
{
pclusterBackTrack[i] = NULL;
}
IclusterIGC** pclustersAdjacent = (IclusterIGC**)alloca(pclusters->n() * pclusters->n() * sizeof(IclusterIGC*));
int nStart = 0;
int nStop = 0;
for (WarpLinkIGC* pwl = pcluster1->GetWarps()->first(); (pwl != NULL); pwl = pwl->next())
{
IwarpIGC* pw = pwl->data();
if (pw != pwarp)
{
IclusterIGC* pcluster = pw->GetDestination()->GetCluster();
SectorID id = pcluster->GetObjectID();
if (!bVisited[id])
{
pclustersAdjacent[nStop++] = pcluster;
pclusterBackTrack[id] = pcluster1;
}
}
}
if (!FindPath(pcluster2, &nStart, &nStop, pclustersAdjacent, pclusterBackTrack, bVisited))
{
return false;
}
else if (count == 1)
{
return true;
}
else
{
IclusterIGC* pcluster = pcluster2;
SectorID id = pcluster->GetObjectID();
do
{
assert (pclusterBackTrack[id] != NULL);
pcluster = pclusterBackTrack[id];
id = pcluster->GetObjectID();
bVisited[id] = true;
}
while (pcluster != pcluster1);
return EnoughPaths(pclusterBackTrack,
bVisited,
pclusters,
pwarp,
--count);
}
}
static bool OkToRemove(const ClusterListIGC* pclusters, IwarpIGC* pwarp)
{
IclusterIGC** pclusterBackTrack = (IclusterIGC**)alloca(pclusters->n() * sizeof(IclusterIGC*));
bool* bVisited = (bool*)alloca(pclusters->n() * sizeof(bool));
{
for (int i = pclusters->n() - 1; (i >= 0); i--)
bVisited[i] = false;
}
bVisited[pwarp->GetCluster()->GetObjectID()] = true;
return EnoughPaths(pclusterBackTrack, bVisited, pclusters, pwarp, 2);
}
VOID CmapMakerIGC::GenerateMission(Time now,
const MissionParams * pmp,
ImissionIGC * pMission)
{
CMapData MapData;
assert(NULL == ImapMakerIGC::IsValid(pmp));
MapData.SetTime(now);
MapData.SetMissionParams(pmp);
MapData.SetMission(pMission);
this->GenerateLayout(&MapData);
{
float majorRadius = pMission->GetFloatConstant(c_fcidRadiusUniverse);
for (ClusterLinkIGC* pcl = pMission->GetClusters()->first(); (pcl != NULL); pcl = pcl->next())
{
IclusterIGC* pcluster = pcl->data();
const WarpListIGC* pwarps = pcluster->GetWarps();
if (pwarps->n() != 0)
{
float nWarps = (float)(pwarps->n());
const int c_maxWarps = 10;
assert (pwarps->n() <= c_maxWarps);
float offset[c_maxWarps] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
float displacement;
if (pwarps->n() > 1)
{
displacement = sin(pi/nWarps) * 2.0f / 3.0f;
for (int index = 0; (index < pwarps->n()); index++)
{
int swap = randomInt(0, pwarps->n() - 1);
if (swap != index)
{
float t = offset[index];
offset[index] = offset[swap];
offset[swap] = t;
}
}
}
else
displacement = 2.0f / 3.0f;
{
float bias = random(0.0f, 2.0f * pi);
int index = 0;
for (WarpLinkIGC* pwl = pwarps->first(); (pwl != NULL); pwl = pwl->next())
{
IwarpIGC* pwarp = pwl->data();
float r = pwarp->GetPosition().z * majorRadius;
float angle = bias + offset[index++] * (2.0f * pi) / nWarps;
Vector position;
position = Vector::RandomPosition(r * displacement);
position.x += cos(angle) * r;
position.y += sin(angle) * r;
position.z *= 1.2f;
pwarp->SetPosition(position);
Orientation o(-position);
pwarp->SetOrientation(o);
pwarp->GetHitTest()->UpdateStaticBB();
}
}
}
}
}
if (pmp->iRandomEncounters > 1)
{
const WarpListIGC* pwarpList = pMission->GetWarps();
IwarpIGC** pwarps = (IwarpIGC**)(alloca(pwarpList->n() * sizeof(IwarpIGC*)));
int nWarps = 0;
{
for (WarpLinkIGC* pwl = pwarpList->first(); (pwl != NULL); pwl = pwl->next())
{
IwarpIGC* pwarp = pwl->data();
if ((pwarp->GetObjectID() < pwarp->GetDestination()->GetObjectID()) &&
(randomInt(0, pmp->iRandomEncounters) > 1))
{
assert (nWarps < pwarpList->n());
pwarps[nWarps++] = pwarp;
}
}
}
const ClusterListIGC* pclusters = pMission->GetClusters();
while (nWarps > 0)
{
int index = randomInt(0, nWarps - 1);
IwarpIGC* pwarp = pwarps[index];
if (OkToRemove(pclusters, pwarp))
{
pwarp->GetDestination()->Terminate();
pwarp->Terminate();
}
pwarps[index] = pwarps[--nWarps];
}
}
this->PopulateClusters(&MapData);
if (TRUE == pmp->bShowHomeSector)
this->RevealHomeClusters(pMission);
if (TRUE == pmp->bShowMap)
this->RevealMap(pMission);
this->ActivateSides(pMission);
}
VOID CmapMakerIGC::GenerateTeamClusterScreenPosition(CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta;
flTheta = (float) (2.0 * pi * sID / pMapData->GetTotalClusters());
pdc->screenX = cos(flTheta) * 0.8f;
pdc->screenY = sin(flTheta) * 0.8f;
}
IclusterIGC * CmapMakerIGC::GenerateTeamCluster(CMapData * pMapData,
SectorID sID)
{
DataClusterIGC dc;
INT n;
dc.bHomeSector = true;
dc.clusterID = sID;
dc.activeF = true;
dc.lightColor = 0xffffffff;
dc.lightDirection = Vector::RandomDirection();
pMapData->GetNewClusterName(dc.name);
strcpy(dc.posterName, "globe");
dc.posterName[5] = '0' + randomInt(1, 8);
dc.posterName[6] = '\0';
n = randomInt(0, c_NumberOfPlanetPosters - 1);
strcpy(dc.planetName, smszPlanetName[n]);
dc.planetSinLatitude = random(0.0f, 1.0f);
dc.planetLongitude = random(0.0f, 1.0f);
dc.planetRadius = (unsigned char)randomInt(50, 100);
dc.starSeed = rand();
dc.nDebris = randomInt(250, 750);
dc.nStars = randomInt(250, 750);
this->GenerateTeamClusterScreenPosition(pMapData, &dc, sID);
IclusterIGC * o = (IclusterIGC *) pMapData->GetMission()->CreateObject(
pMapData->GetTime(),
OT_cluster,
&dc,
sizeof(dc));
assert(o);
return(o);
}
VOID CmapMakerIGC::GenerateNeutralClusterScreenPosition(CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta;
flTheta = (float) (2.0 * pi * sID / pMapData->GetTotalClusters());
pdc->screenX = cos(flTheta) * 0.4f;
pdc->screenY = sin(flTheta) * 0.4f;
}
IclusterIGC * CmapMakerIGC::GenerateNeutralCluster(CMapData * pMapData,
SectorID sID)
{
DataClusterIGC dc;
dc.bHomeSector = false;
dc.clusterID = sID;
dc.activeF = true;
dc.lightColor = 0xffffffff;
dc.lightDirection = Vector::RandomDirection();
pMapData->GetNewClusterName(dc.name);
strcpy(dc.posterName, "globe");
dc.posterName[5] = '0' + randomInt(1, 8);
dc.posterName[6] = '\0';
dc.planetName[0] = '\0';
dc.starSeed = rand();
dc.nDebris = randomInt(250, 750);
dc.nStars = randomInt(250, 750);
this->GenerateNeutralClusterScreenPosition(pMapData, &dc, sID);
IclusterIGC * o = (IclusterIGC *) pMapData->GetMission()->CreateObject(
pMapData->GetTime(),
OT_cluster,
&dc,
sizeof(dc));
assert(o);
return(o);
}
VOID CmapMakerIGC::GenerateRingClusters(CMapData * pMapData)
{
SectorID sID, cTotalRingClusters;
IclusterIGC * pCluster;
cTotalRingClusters = pMapData->GetTotalClusters() -
pMapData->GetOtherClusters();
for(sID = 0; sID < cTotalRingClusters; sID++)
{
if (sID % pMapData->GetClustersPerTeam() <
pMapData->GetTeamClustersPerTeam())
{
pCluster = this->GenerateTeamCluster(pMapData, sID);
pMapData->SetCluster(sID,
pCluster,
sID / pMapData->GetClustersPerTeam());
} else
{
pCluster = this->GenerateNeutralCluster(pMapData, sID);
pMapData->SetCluster(sID, pCluster, NA);
}
pCluster->Release();
}
while(sID < pMapData->GetTotalClusters())
{
pCluster = this->GenerateNeutralCluster(pMapData, sID);
pMapData->SetCluster(sID, pCluster, NA);
sID++;
}
}
VOID CmapMakerIGC::GenerateWarp(CMapData * pMapData,
IclusterIGC * pCluster,
DataWarpIGC * pdw)
{
pdw->forward.x = pdw->forward.y = 0.0f;
pdw->forward.z = 1.0f;
pdw->rotation.axis(pdw->forward);
pdw->rotation.angle(0.0f);
pdw->warpDef.radius = 100;
IObject * o = pMapData->GetMission()->CreateObject(pMapData->GetTime(),
OT_warp,
pdw,
sizeof(*pdw));
assert(o);
o->Release();
}
VOID CmapMakerIGC::LinkClusters(CMapData* pMapData,
SectorID sID1,
SectorID sID2,
int alephType)
{
DataWarpIGC dw;
static const char* c_pszIconNeutral = "neutralaleph";
static const char* c_pszIconPlayer = "homealeph";
static const char* c_pszTextureNeutral = "plnt19";
static const char* c_pszTexturePlayer = "plnt42";
float signature1 = 1.0f;
float signature2 = 1.0f;
float radius1 = 0.6f;
float radius2 = 0.6f;
if (alephType == NA)
{
SideID side1 = pMapData->GetClusterSide(sID1);
SideID side2 = pMapData->GetClusterSide(sID2);
if (NA == side1)
{
if (NA == side2)
{
alephType = c_NeutralAleph;
}
else
{
alephType = c_NeutralToPlayerAleph;
}
}
else if (side1 == side2)
{
alephType = c_FriendlyAleph;
}
else if (NA != side2)
{
alephType = c_EnemyAleph;
}
else
{
alephType = c_PlayerToNeutralAleph;
}
}
const char* pszTexture1;
const char* pszTexture2;
const char* pszIcon1;
const char* pszIcon2;
switch (alephType)
{
case c_FriendlyAleph:
pszIcon1 = pszIcon2 = c_pszIconPlayer;
pszTexture1 = pszTexture2 = c_pszTexturePlayer;
break;
case c_EnemyAleph:
pszIcon1 = pszIcon2 = c_pszIconPlayer;
pszTexture1 = pszTexture2 = c_pszTexturePlayer;
signature1 = signature2 = 0.33f;
radius1 = radius2 = 0.85f;
break;
case c_NeutralToPlayerAleph:
pszIcon1 = c_pszIconPlayer;
pszTexture1 = c_pszTexturePlayer;
signature1 = 0.67f;
pszIcon2 = c_pszIconNeutral;
pszTexture2 = c_pszTextureNeutral;
break;
case c_PlayerToNeutralAleph:
pszIcon2 = c_pszIconPlayer;
pszTexture2 = c_pszTexturePlayer;
signature2 = 0.67f;
pszIcon1 = c_pszIconNeutral;
pszTexture1 = c_pszTextureNeutral;
break;
case c_NeutralAleph:
pszIcon1 = pszIcon2 = c_pszIconNeutral;
pszTexture1 = pszTexture2 = c_pszTextureNeutral;
break;
case c_HiddenToPlayerAleph:
pszIcon2 = c_pszIconPlayer;
pszTexture2 = c_pszTexturePlayer;
signature2 = 0.33f;
radius2 = 0.85f;
pszIcon1 = c_pszIconNeutral;
pszTexture1 = c_pszTextureNeutral;
break;
default:
assert (false);
}
dw.warpDef.warpID = pMapData->GetNextWarpID();
dw.clusterID = sID1;
strcpy(dw.warpDef.textureName, pszTexture1);
strcpy(dw.warpDef.iconName, pszIcon1);
strcpy(dw.name, pMapData->GetCluster(sID2)->GetName());
dw.signature = signature1;
dw.position.x = dw.position.y = 0.0f;
dw.position.z = radius1;
dw.warpDef.destinationID = dw.warpDef.warpID + 1;
this->GenerateWarp(pMapData, pMapData->GetCluster(sID1), &dw);
dw.warpDef.warpID = pMapData->GetNextWarpID();
dw.clusterID = sID2;
strcpy(dw.warpDef.textureName, pszTexture2);
strcpy(dw.warpDef.iconName, pszIcon2);
strcpy(dw.name, pMapData->GetCluster(sID1)->GetName());
dw.signature = signature2;
dw.position.x = dw.position.y = 0.0f;
dw.position.z = radius2;
dw.warpDef.destinationID = dw.warpDef.warpID - 1;
this->GenerateWarp(pMapData, pMapData->GetCluster(sID2), &dw);
}
VOID CmapMakerIGC::CrossLinkClusters(CMapData * pMapData, SectorID sFirstID)
{
SectorID sMax, sWrap;
sMax = pMapData->GetTotalClusters();
if (pMapData->GetTeams() < 4)
sMax = 0;
else if (pMapData->GetTeams() == 4)
sMax /= 2;
while(sFirstID < sMax)
{
sWrap = (sFirstID + 2 * pMapData->GetClustersPerTeam()) %
pMapData->GetTotalClusters();
LinkClusters(pMapData, sFirstID, sWrap);
sFirstID += pMapData->GetClustersPerTeam();
}
}
VOID CmapMakerIGC::LinkClusters(CMapData * pMapData)
{
SectorID sID, cTotalSectors;
cTotalSectors = pMapData->GetTotalClusters();
for(sID = 0; sID < cTotalSectors - 1; sID++)
this->LinkClusters(pMapData, sID, sID + 1);
this->LinkClusters(pMapData, sID, 0);
this->CrossLinkClusters(pMapData, pMapData->GetTeamClustersPerTeam());
}
VOID CmapMakerIGC::GenerateLayout(CMapData * pMapData)
{
SectorID s = pMapData->GetMapSize() != 0 ? 2 : 1;
pMapData->SetTeamClustersPerTeam(s);
pMapData->SetNeutralClustersPerTeam(1);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerIGC::GenerateStarbase(CMapData* pMapData,
IclusterIGC* pcluster)
{
DataStationIGC ds;
SideID sideID = pMapData->GetClusterSide(pcluster->GetObjectID());
IsideIGC* pSide = pMapData->GetMission()->GetSide(sideID);
assert(pSide);
ds.clusterID = pcluster->GetObjectID();
ds.position = Vector::GetZero();
ds.forward.x = ds.forward.y = 0.0f;
ds.forward.z = 1.0f;
ds.up.x = 1.0f;
ds.up.y = ds.up.z = 0.0f;
ds.rotation.axis(ds.forward);
ds.rotation.angle(0.0f);
ds.bpHull = 1.0f;
ds.bpShield = 1.0f;
ds.sideID = sideID;
ds.stationID = pMapData->GetMission()->GenerateNewStationID();
IstationTypeIGC* pst = pSide->GetCivilization()->GetInitialStationType();
assert (pst);
pst = pst->GetSuccessorStationType(pSide);
ds.stationTypeID = pst->GetObjectID();
strcpy(ds.name, pst->GetName());
IObject * o = pMapData->GetMission()->CreateObject(
pMapData->GetTime(),
OT_station,
&ds,
sizeof(ds));
assert(o);
o->Release();
}
VOID CmapMakerIGC::PopulateCluster(CMapData* pMapData,
IclusterIGC* pcluster,
float amountHe3)
{
::PopulateCluster(pMapData->GetMission(), pMapData->GetMissionParams(), pcluster, amountHe3);
}
VOID CmapMakerIGC::PopulateClusters(CMapData* pMapData)
{
float amountHe3 = pMapData->GetMission()->GetFloatConstant(c_fcidAmountHe3) *
pMapData->GetMissionParams()->fHe3Density *
float(pMapData->GetTeams()) / float(pMapData->GetMinableAsteroids());
for (ClusterLinkIGC* pcl = pMapData->GetMission()->GetClusters()->first(); (pcl != NULL); pcl = pcl->next())
{
IclusterIGC* pcluster = pcl->data();
if (pcluster->GetHomeSector())
GenerateStarbase(pMapData, pcluster);
PopulateCluster(pMapData, pcluster, amountHe3);
}
}
VOID CmapMakerIGC::RevealHomeClusters(ImissionIGC * pMission)
{
for (SideLinkIGC * psl = pMission->GetSides()->first();
(psl != NULL);
psl = psl->next())
{
IsideIGC* pside = psl->data();
for (StationLinkIGC * pstnl = pside->GetStations()->first();
(pstnl != NULL);
pstnl = pstnl->next())
{
for (ModelLinkIGC * pml =
pstnl->data()->GetCluster()->GetModels()->first();
(pml != NULL);
pml = pml->next())
{
pml->data()->SetSideVisibility(pside, true);
}
}
}
}
VOID CmapMakerIGC::RevealMap(ImissionIGC * pMission)
{
for (WarpLinkIGC * pwl = pMission->GetWarps()->first();
(pwl != NULL);
pwl = pwl->next())
{
IwarpIGC* pwarp = pwl->data();
for (SideLinkIGC * psl = pMission->GetSides()->first();
(psl != NULL);
psl = psl->next())
{
pwarp->SetSideVisibility(psl->data(), true);
}
}
}
VOID CmapMakerIGC::ActivateSides(ImissionIGC * pMission)
{
const SideListIGC * psideList = pMission->GetSides();
for (SideLinkIGC * psidelink = psideList->first();
NULL != psidelink;
psidelink = psidelink->next())
{
psidelink->data()->SetActiveF(true);
}
}
CmapMakerDoubleRingIGC::CmapMakerDoubleRingIGC()
{
mMMID = c_mmDoubleRing;
this->SetName("Double Ring");
}
VOID CmapMakerDoubleRingIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta = (float) (2.0 * pi * sID / pMapData->GetTotalClusters());
pdc->screenX = cos(flTheta) * 0.9f;
pdc->screenY = sin(flTheta) * 0.9f;
}
VOID CmapMakerDoubleRingIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta = (float) (2.0 * pi * sID / pMapData->GetTotalClusters());
float flRadius = (pMapData->GetTeams() == 2) && (pMapData->GetTeamClustersPerTeam() == 2)
? 0.2f
: 0.3f;
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerDoubleRingIGC::LinkClusters(CMapData * pMapData)
{
SectorID sID, cTotalSectors, sWrapID, sIndex;
cTotalSectors = pMapData->GetTotalClusters();
for(sID = 0; sID < cTotalSectors; sID += pMapData->GetClustersPerTeam())
{
sWrapID = (sID + cTotalSectors - 1) % cTotalSectors;
for(sIndex = 0; sIndex < pMapData->GetTeamClustersPerTeam(); sIndex++)
{
CmapMakerIGC::LinkClusters(pMapData,
sID + sIndex,
sID + pMapData->GetTeamClustersPerTeam());
CmapMakerIGC::LinkClusters(pMapData,
sID + sIndex,
sWrapID);
}
}
sWrapID = cTotalSectors - 1 - pMapData->GetNeutralClustersPerTeam();
for(sID = 0; sID < cTotalSectors; sID++)
{
if (NA != pMapData->GetClusterSide(sID))
{
CmapMakerIGC::LinkClusters(pMapData, sID, sWrapID);
sWrapID = sID;
}
}
sWrapID = cTotalSectors - 1;
for(sID = 0; sID < cTotalSectors; sID++)
{
if (NA == pMapData->GetClusterSide(sID))
{
CmapMakerIGC::LinkClusters(pMapData, sID, sWrapID);
sWrapID = sID;
}
}
}
CmapMakerBigRingIGC::CmapMakerBigRingIGC()
{
mMMID = c_mmBigRing;
this->SetName("Big Ring");
}
VOID CmapMakerBigRingIGC::GenerateLayout(CMapData * pMapData)
{
SectorID s = pMapData->GetMapSize() != 0 ? 2 : 1;
pMapData->SetTeamClustersPerTeam(s);
pMapData->SetNeutralClustersPerTeam(2);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerBigRingIGC::GenerateTeamClusterScreenPosition(CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID s = (pMapData->GetTeamClustersPerTeam() == 1) ? (sID / 3) : ((sID + 1) / 2);
SectorID n = pMapData->GetTeamClusters();
float flTheta = (float) (2.0 * pi * s / n);
pdc->screenX = cos(flTheta) * 0.9f;
pdc->screenY = sin(flTheta) * 0.9f;
}
VOID CmapMakerBigRingIGC::GenerateNeutralClusterScreenPosition(CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta;
SectorID n = pMapData->GetNeutralClusters();
if (pMapData->GetTeamClustersPerTeam() == 1)
{
SectorID s = (sID - 1 - sID/3);
flTheta = (float) (2.0 * pi * (s + 0.5f) / n);
}
else
{
SectorID s = ((sID + 1) / 2);
flTheta = (float) (2.0 * pi * s / n);
}
pdc->screenX = cos(flTheta) * 0.6f;
pdc->screenY = sin(flTheta) * 0.6f;
}
VOID CmapMakerBigRingIGC::LinkClusters(CMapData * pMapData)
{
SectorID cTotalSectors = pMapData->GetTotalClusters();
{
SectorID sWrapID = cTotalSectors - 1;
for(SectorID sID = 0; sID < cTotalSectors; sID++)
{
CmapMakerIGC::LinkClusters(pMapData, sID, sWrapID);
sWrapID = sID;
}
}
if (pMapData->GetTeams() > 2)
{
SectorID n = pMapData->GetTeamClustersPerTeam();
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID + n, (sID + 3 + 2*n) % cTotalSectors);
if (pMapData->GetTeams() > 3)
CmapMakerIGC::LinkClusters(pMapData, sID + n + 1, (cTotalSectors + (sID - 2)) % cTotalSectors);
}
}
}
CmapMakerHiLoIGC::CmapMakerHiLoIGC()
{
mMMID = c_mmHiLo;
this->SetName("HiLo");
}
VOID CmapMakerHiLoIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(pMapData->GetMapSize() != 0 ? 2 : 1);
pMapData->SetNeutralClustersPerTeam(3);
pMapData->SetOtherClusters(1);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerHiLoIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta, flRadius;
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = sID % pMapData->GetClustersPerTeam();
flTheta = (float) (2.0f * pi * float(sTeam) / float(pMapData->GetTeams()));
flRadius = 0.5f + 0.4f * sID;
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerHiLoIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
if (sTeam < pMapData->GetTeams())
{
sID = (sID % pMapData->GetClustersPerTeam()) - pMapData->GetTeamClustersPerTeam();
float flTheta1 = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
float flTheta2 = (float) (2.0 * pi * (sTeam + 1) / pMapData->GetTeams());
float flTheta;
float flRadius;
switch (sID)
{
case 0:
flTheta = (flTheta1 + flTheta2) / 2.0f;
flRadius = 0.4f;
break;
case 1:
flTheta = (2.0f * flTheta1 + flTheta2) / 3.0f;
flRadius = 0.8f;
break;
case 2:
flTheta = (flTheta1 + 2.0f * flTheta2) / 3.0f;
flRadius = 0.8f;
break;
}
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
else
pdc->screenX = pdc->screenY = 0.0f;
}
VOID CmapMakerHiLoIGC::LinkClusters(CMapData * pMapData)
{
if (pMapData->GetTeamClustersPerTeam() != 1)
{
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID, sID + 1);
}
}
{
SectorID sidCenter = pMapData->GetTotalClusters() - 1;
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam() +
pMapData->GetTeamClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID, sidCenter);
SectorID sidPrevious = i * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID, sidPrevious);
SectorID sidNext = ((i+1)%pMapData->GetTeams()) * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID, sidNext);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sID + 2);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sidPrevious + pMapData->GetTeamClustersPerTeam() - 1);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, sidNext + pMapData->GetTeamClustersPerTeam() - 1);
}
}
}
CmapMakerHiHigherIGC::CmapMakerHiHigherIGC()
{
mMMID = c_mmHiHigher;
this->SetName("HiHigher");
}
VOID CmapMakerHiHigherIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam((mMMID == c_mmHiHigher)
? (pMapData->GetMapSize() != 0 ? 2 : 1)
: ((mMMID == c_mmLargeSplit)
? 2
: 1));
pMapData->SetNeutralClustersPerTeam(5);
pMapData->SetOtherClusters(1);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerHiHigherIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam());
float flTheta;
float flRadius;
if (mMMID == c_mmInsideOut)
{
flTheta = (float) (2.0 * pi * (sTeam + 0.5f) / pMapData->GetTeams());
flRadius = 0.3f;
}
else
{
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
flRadius = (pMapData->GetTeamClustersPerTeam() == 1) ? 1.0f : (0.75f + 0.25f * sID);
}
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerHiHigherIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
if (sTeam < pMapData->GetTeams())
{
sID = (sID % pMapData->GetClustersPerTeam()) - pMapData->GetTeamClustersPerTeam();
float flTheta1 = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
float flTheta2 = (float) (2.0 * pi * (sTeam + 1) / pMapData->GetTeams());
float flTheta;
float flRadius;
switch (sID)
{
case 0:
flTheta = (3.0f * flTheta1 + flTheta2) / 4.0f;
flRadius = 0.6f;
break;
case 1:
if (mMMID == c_mmInsideOut)
{
flTheta = flTheta1;
flRadius = 1.0f;
}
else
{
flTheta = (flTheta1 + flTheta2) / 2.0f;
flRadius = 0.3f;
}
break;
case 2:
flTheta = (flTheta1 + 3.0f * flTheta2) / 4.0f;
flRadius = 0.6f;
break;
case 3:
flTheta = (2.0f * flTheta1 + flTheta2) / 3.0f;
flRadius = 1.0f;
break;
case 4:
flTheta = (flTheta1 + 2.0f * flTheta2) / 3.0f;
flRadius = 1.0f;
break;
}
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
else
pdc->screenX = pdc->screenY = 0.0f;
}
VOID CmapMakerHiHigherIGC::LinkClusters(CMapData * pMapData)
{
if ((pMapData->GetTeamClustersPerTeam() != 1) && (mMMID != c_mmLargeSplit))
{
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID, sID + 1);
}
}
{
SectorID sidCenter = pMapData->GetTotalClusters() - 1;
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sIDp = i * pMapData->GetClustersPerTeam();
SectorID sID0 = sIDp +
pMapData->GetTeamClustersPerTeam();
SectorID sID1 = sID0 + 1;
SectorID sID2 = sID0 + 2;
SectorID sID3 = sID0 + 3;
SectorID sID4 = sID0 + 4;
SectorID sIDn = ((i+1)%pMapData->GetTeams()) * pMapData->GetClustersPerTeam();
if (mMMID == c_mmInsideOut)
{
assert (pMapData->GetTeamClustersPerTeam() == 1);
sID1 = sIDp;
sIDp = sID0 + 1;
sIDn = ((i+1)%pMapData->GetTeams()) * pMapData->GetClustersPerTeam() + 1 + 1;
}
CmapMakerIGC::LinkClusters(pMapData, sID1, sidCenter,
(mMMID == c_mmInsideOut) ? c_HiddenToPlayerAleph : NA);
CmapMakerIGC::LinkClusters(pMapData, sID0, sID1);
CmapMakerIGC::LinkClusters(pMapData, sID1, sID2);
CmapMakerIGC::LinkClusters(pMapData, sID0, sID3);
CmapMakerIGC::LinkClusters(pMapData, sID2, sID4);
CmapMakerIGC::LinkClusters(pMapData, sID3, sID4);
CmapMakerIGC::LinkClusters(pMapData, sID0, sIDp);
CmapMakerIGC::LinkClusters(pMapData, sID2, sIDn);
CmapMakerIGC::LinkClusters(pMapData, sID3, sIDp + pMapData->GetTeamClustersPerTeam() - 1);
CmapMakerIGC::LinkClusters(pMapData, sID4, sIDn + pMapData->GetTeamClustersPerTeam() - 1);
if (pMapData->GetMissionParams()->iRandomEncounters != 0)
CmapMakerIGC::LinkClusters(pMapData, sID2,
(mMMID == c_mmInsideOut)
? (sIDn - 1)
: (sIDn + pMapData->GetTeamClustersPerTeam()));
}
}
}
CmapMakerStarIGC::CmapMakerStarIGC()
{
mMMID = c_mmStar;
this->SetName("Star");
}
VOID CmapMakerStarIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(pMapData->GetMapSize() != 0 ? 2 : 1);
pMapData->SetNeutralClustersPerTeam(5);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerStarIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam = sID / pMapData->GetClustersPerTeam();
sID = sID % pMapData->GetClustersPerTeam();
float flDelta = (2.0f * pi / float(pMapData->GetTeams()));
float flTheta = flDelta * float(sTeam);
if (pMapData->GetTeamClustersPerTeam() == 2)
flTheta += flDelta * (float(sID) - 0.5f) * 0.5f;
pdc->screenX = cos(flTheta);
pdc->screenY = sin(flTheta);
}
VOID CmapMakerStarIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam = sID / pMapData->GetClustersPerTeam();
sID = sID % pMapData->GetClustersPerTeam() - pMapData->GetTeamClustersPerTeam();
float flRadius;
float flDelta = (2.0f * pi / float(pMapData->GetTeams()));
float flTheta = flDelta * float(sTeam);
switch (sID)
{
case 0:
case 1:
{
flRadius = 0.7f;
flTheta += flDelta * (float(sID) - 0.5f) * 0.5f;
}
break;
case 3:
{
flTheta += flDelta * 0.5f;
}
case 2:
{
flRadius = 0.5f;
}
break;
case 4:
{
flRadius = 0.2f;
}
break;
}
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerStarIGC::LinkClusters(CMapData * pMapData)
{
{
SectorID sidCenter = pMapData->GetTotalClusters() - 1;
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam() +
pMapData->GetTeamClustersPerTeam();
if (pMapData->GetTeamClustersPerTeam() == 1)
{
CmapMakerIGC::LinkClusters(pMapData, sID, sID - 1);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sID - 1);
}
else
{
CmapMakerIGC::LinkClusters(pMapData, sID - 1, sID - 2);
CmapMakerIGC::LinkClusters(pMapData, sID, sID - 2);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sID - 1);
}
CmapMakerIGC::LinkClusters(pMapData, sID, sID + 2);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sID + 2);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sID + 3);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, sID + 3);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, sID + 4);
{
SectorID s = (sID + pMapData->GetTotalClusters() - pMapData->GetClustersPerTeam()) % pMapData->GetTotalClusters();
CmapMakerIGC::LinkClusters(pMapData, s + 3, sID);
CmapMakerIGC::LinkClusters(pMapData, s + 3, sID + 2);
}
{
SideID j = (i + pMapData->GetTeams()/2) % pMapData->GetTeams();
SectorID s = j * pMapData->GetClustersPerTeam() +
pMapData->GetTeamClustersPerTeam();
if (pMapData->GetTeams() % 2 == 0)
{
CmapMakerIGC::LinkClusters(pMapData, sID + 4, s + 4);
}
else
{
CmapMakerIGC::LinkClusters(pMapData, sID + 4, s + 4);
CmapMakerIGC::LinkClusters(pMapData, sID + 4, (s + 4 + pMapData->GetClustersPerTeam()) % pMapData->GetTotalClusters());
}
}
}
}
}
CmapMakerBrawlIGC::CmapMakerBrawlIGC()
{
mMMID = c_mmBrawl;
this->SetName("Brawl");
}
const char* CmapMakerBrawlIGC::IsValid(const MissionParams * pmp)
{
return(NULL);
}
VOID CmapMakerBrawlIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(0);
pMapData->SetOtherClusters(1);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerBrawlIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
pdc->screenX = 0.0f;
pdc->screenY = 0.0f;
}
VOID CmapMakerBrawlIGC::LinkClusters(CMapData * pMapData)
{
}
VOID CmapMakerBrawlIGC::PopulateCluster(CMapData* pMapData,
IclusterIGC* pcluster,
float amountHe3)
{
SectorID sID = pcluster->GetObjectID();
for (SideID sideID = 0; (sideID < pMapData->GetTeams()); sideID++)
{
DataStationIGC ds;
IsideIGC* pSide = pMapData->GetMission()->GetSide(sideID);
assert(pSide);
ds.clusterID = sID;
{
const float c_startRadius = 2500.0f;
float angle = 2.0f * pi * float(sideID) / float(pMapData->GetTeams());
ds.position.x = c_startRadius * cos(angle);
ds.position.y = c_startRadius * sin(angle);
ds.position.z = 0.0f;
}
ds.forward.x = ds.forward.y = 0.0f;
ds.forward.z = 1.0f;
ds.up.x = 1.0f;
ds.up.y = ds.up.z = 0.0f;
ds.rotation.axis(ds.forward);
ds.rotation.angle(0.0f);
ds.bpHull = 1.0f;
ds.bpShield = 1.0f;
ds.sideID = sideID;
ds.stationID = pMapData->GetMission()->GenerateNewStationID();
IstationTypeIGC* pst = pSide->GetCivilization()->GetInitialStationType();
assert (pst);
ds.stationTypeID = pst->GetObjectID();
strcpy(ds.name, pst->GetName());
IstationIGC* pstation = (IstationIGC*)pMapData->GetMission()->CreateObject(pMapData->GetTime(),
OT_station,
&ds,
sizeof(ds));
assert(pstation);
pstation->Release();
}
for (int i = randomInt(3, 5); (i >= 0); i--)
{
CreateAsteroid(pMapData->GetMission(), pcluster, IasteroidIGC::GetRandomType(0), 0.0f);
}
::PopulateCluster(pMapData->GetMission(), pMapData->GetMissionParams(), pcluster, amountHe3,
true, true,
1, -3 * (pMapData->GetTeams()/2));
}
CmapMakerPinWheelIGC::CmapMakerPinWheelIGC()
{
mMMID = c_mmPinWheel;
this->SetName("PinWheel");
}
const char* CmapMakerPinWheelIGC::IsValid(const MissionParams * pmp)
{
return(NULL);
}
VOID CmapMakerPinWheelIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(1);
if (pMapData->GetMapSize() == 0)
pMapData->SetOtherClusters(1);
else
pMapData->SetNeutralClustersPerTeam(1);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerPinWheelIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta;
if (0 != pMapData->GetNeutralClustersPerTeam())
{
sID = sID / pMapData->GetClustersPerTeam();
flTheta = (float) (2.0 * pi * sID / pMapData->GetNeutralClusters());
pdc->screenX = cos(flTheta) * 0.4f;
pdc->screenY = sin(flTheta) * 0.4f;
} else
pdc->screenX = pdc->screenY = 0.0f;
}
VOID CmapMakerPinWheelIGC::LinkClusters(CMapData * pMapData)
{
SectorID sID, cTotalClusters, sWrapID, sFirstNA;
cTotalClusters = pMapData->GetTotalClusters();
if (0 != pMapData->GetNeutralClustersPerTeam())
{
sWrapID = NA;
for(sID = 0; sID < cTotalClusters; sID++)
{
if (NA != pMapData->GetClusterSide(sID))
CmapMakerIGC::LinkClusters(pMapData, sID, sID + 1);
else
{
if (NA != sWrapID)
CmapMakerIGC::LinkClusters(pMapData, sID, sWrapID);
else
sFirstNA = sID;
sWrapID = sID;
}
}
if (pMapData->GetTeams() > 2)
CmapMakerIGC::LinkClusters(pMapData, sWrapID, sFirstNA);
this->CrossLinkClusters(pMapData, pMapData->GetTeamClustersPerTeam());
}
else
{
for(sID = 0; sID < cTotalClusters; sID++)
{
if (NA != pMapData->GetClusterSide(sID))
CmapMakerIGC::LinkClusters(pMapData, sID, cTotalClusters - 1);
}
}
}
VOID CmapMakerPinWheelIGC::PopulateCluster(CMapData* pMapData,
IclusterIGC* pcluster,
float amountHe3)
{
short k;
if (pcluster->GetHomeSector() ||
(pMapData->GetNeutralClustersPerTeam() != 0))
{
k = 1;
}
else
k = 2;
::PopulateCluster(pMapData->GetMission(), pMapData->GetMissionParams(), pcluster, amountHe3,
true, true,
k, k, k);
}
CmapMakerDiamondRingIGC::CmapMakerDiamondRingIGC()
{
mMMID = c_mmDiamondRing;
this->SetName("Diamond Ring");
}
const char* CmapMakerDiamondRingIGC::IsValid(const MissionParams * pmp)
{
if (pmp->nTeams < 3)
return("Diamond ring maps must have more than 2 teams; "
"please change the map type, or number of teams.");
return(NULL);
}
VOID CmapMakerDiamondRingIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(pMapData->GetMapSize() != 0 ? 2 : 1);
pMapData->SetNeutralClustersPerTeam(2);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerDiamondRingIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta, flAdjust, flRadius;
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = sID % pMapData->GetTeamClustersPerTeam();
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
switch(pMapData->GetTeamClustersPerTeam())
{
case 2:
flAdjust = (float) (pi / 8.0f);
if (1 == sID)
flAdjust = -flAdjust;
break;
case 3:
flAdjust = (sID - 1) * (float) (pi / 6.0f);
break;
default:
flAdjust = 0.0f;
break;
}
flTheta += flAdjust;
flRadius = 0.55f;
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerDiamondRingIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flTheta, flRadius;
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam()) -
pMapData->GetTeamClustersPerTeam();
if (0 == (sID & 0x01))
{
flRadius = 0.3f;
} else
flRadius = 0.8f;
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerDiamondRingIGC::LinkClusters(CMapData * pMapData)
{
SectorID sID, cTotalSectors, sNeutralID, sIndex;
cTotalSectors = pMapData->GetTotalClusters();
for(sID = 0; sID < cTotalSectors; sID += pMapData->GetClustersPerTeam())
{
sNeutralID = sID + pMapData->GetTeamClustersPerTeam();
for(sIndex = 0; sIndex < pMapData->GetTeamClustersPerTeam(); sIndex++)
{
CmapMakerIGC::LinkClusters(pMapData,
sID + sIndex,
sNeutralID);
CmapMakerIGC::LinkClusters(pMapData,
sID + sIndex,
sNeutralID + 1);
}
}
for(sID = 0; sID < cTotalSectors; sID++)
{
if (NA == pMapData->GetClusterSide(sID))
{
sNeutralID = (sID + pMapData->GetClustersPerTeam()) % cTotalSectors;
CmapMakerIGC::LinkClusters(pMapData, sID, sNeutralID);
}
}
this->CrossLinkClusters(pMapData, pMapData->GetTeamClustersPerTeam());
}
CmapMakerSnowFlakeIGC::CmapMakerSnowFlakeIGC()
{
mMMID = c_mmSnowFlake;
this->SetName("SnowFlake");
}
VOID CmapMakerSnowFlakeIGC::GenerateLayout(CMapData * pMapData)
{
SectorID s = pMapData->GetMapSize() != 0 ? 2 : 1;
pMapData->SetTeamClustersPerTeam(s);
pMapData->SetNeutralClustersPerTeam(3);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerSnowFlakeIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flRadius, flTheta, flAdjust;
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = sID % pMapData->GetClustersPerTeam();
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
flAdjust = pMapData->GetTeamClustersPerTeam() == 1 ? 0.0f : (float) (pi / (2.0f * pMapData->GetTeams()));
flRadius = 0.9f;
if (pMapData->GetTeamClustersPerTeam() == sID + 1)
flAdjust = -flAdjust;
flTheta += flAdjust;
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerSnowFlakeIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
float flRadius, flTheta, flAdjust;
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam()) -
pMapData->GetTeamClustersPerTeam();
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
if (sID % 3 < 2)
{
flRadius = 0.65f;
flAdjust = (float) (pi / (2.0f * pMapData->GetTeams()));
if (0 == sID)
flAdjust = -flAdjust;
}
else
{
flRadius = 0.3f;
flAdjust = 0.0f;
}
flTheta += flAdjust;
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerSnowFlakeIGC::LinkClusters(CMapData * pMapData)
{
SectorID sID, cTotalClusters, cTeamClustersPerTeam, sIndex;
SectorID cClustersPerTeam;
cTotalClusters = pMapData->GetTotalClusters();
cTeamClustersPerTeam = pMapData->GetTeamClustersPerTeam();
cClustersPerTeam = pMapData->GetClustersPerTeam();
for(sID = 0; sID < cTotalClusters; sID += cClustersPerTeam)
{
if (cTeamClustersPerTeam > 1)
{
for(sIndex = 0; sIndex < cTeamClustersPerTeam - 1; sIndex++)
{
CmapMakerIGC::LinkClusters(pMapData,
sID + sIndex,
sID + sIndex + 1);
}
CmapMakerIGC::LinkClusters(pMapData, sID + sIndex, sID);
}
sIndex = sID + cTeamClustersPerTeam;
CmapMakerIGC::LinkClusters(pMapData, sIndex, sIndex + 2);
CmapMakerIGC::LinkClusters(pMapData, sIndex + 1, sIndex + 2);
switch(cTeamClustersPerTeam)
{
case 3:
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sIndex);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sIndex + 1);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, sIndex);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, sIndex + 1);
break;
case 2:
CmapMakerIGC::LinkClusters(pMapData, sID, sIndex);
CmapMakerIGC::LinkClusters(pMapData, sID, sIndex + 1);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sIndex);
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sIndex + 1);
break;
default:
CmapMakerIGC::LinkClusters(pMapData, sID, sIndex);
CmapMakerIGC::LinkClusters(pMapData, sID, sIndex + 1);
break;
}
}
sIndex = NA;
for(sID = cTeamClustersPerTeam;
sID < cTotalClusters;
sID += cClustersPerTeam)
{
CmapMakerIGC::LinkClusters(pMapData, sID, sID + 1);
if (NA != sIndex)
CmapMakerIGC::LinkClusters(pMapData, sIndex, sID);
sIndex = sID + 1;
}
CmapMakerIGC::LinkClusters(pMapData, sIndex, cTeamClustersPerTeam);
CmapMakerIGC::CrossLinkClusters(pMapData, cTeamClustersPerTeam + 2);
if (pMapData->GetTeams() < 4)
{
sIndex = NA;
for(sID = cTeamClustersPerTeam + 2;
sID < cTotalClusters;
sID += cClustersPerTeam)
{
if (NA != sIndex)
CmapMakerIGC::LinkClusters(pMapData, sID, sIndex);
sIndex = sID;
}
if (pMapData->GetTeams() > 2)
{
CmapMakerIGC::LinkClusters(pMapData,
sIndex,
cTeamClustersPerTeam + 2);
}
}
}
const char* CmapMakerLargeSplitIGC::IsValid(const MissionParams * pmp)
{
return(NULL);
}
CmapMakerLargeSplitIGC::CmapMakerLargeSplitIGC()
{
mMMID = c_mmLargeSplit;
this->SetName("LargeSplit");
}
CmapMakerInsideOutIGC::CmapMakerInsideOutIGC()
{
mMMID = c_mmInsideOut;
this->SetName("Inside out");
}
CmapMakerGridIGC::CmapMakerGridIGC()
{
mMMID = c_mmGrid;
this->SetName("Grid");
}
VOID CmapMakerGridIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(pMapData->GetMapSize() != 0 ? 2 : 1);
pMapData->SetNeutralClustersPerTeam(4);
pMapData->SetOtherClusters(0);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerGridIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam());
float flTheta;
float flRadius;
if (pMapData->GetTeamClustersPerTeam() == 1)
{
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
static const float radii[c_cSidesMax + 1] = {0.0f, 0.0f, 0.55f, 0.6f, 0.65f, 0.70f, 0.75f};
assert (pMapData->GetTeams() <= c_cSidesMax);
flRadius = radii[pMapData->GetTeams()];
}
else
{
flTheta = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
static const float radii0[c_cSidesMax + 1] = {0.0f, 0.0f, 0.475f, 0.525f, 0.575f, 0.625f, 0.675f};
static const float radii1[c_cSidesMax + 1] = {0.0f, 0.0f, 0.625f, 0.675f, 0.725f, 0.775f, 0.825f};
assert (pMapData->GetTeams() <= c_cSidesMax);
flRadius = (sID == 0)
? radii0[pMapData->GetTeams()]
: radii1[pMapData->GetTeams()];
}
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerGridIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam()) - pMapData->GetTeamClustersPerTeam();
float flTheta1 = (float) (2.0 * pi * sTeam / pMapData->GetTeams());
float flTheta2 = (float) (2.0 * pi * (sTeam + 1) / pMapData->GetTeams());
float flTheta;
float flRadius;
switch (sID)
{
case 0:
flTheta = (5.0f * flTheta1 + flTheta2) / 6.0f;
flRadius = 1.0f;
break;
case 1:
flTheta = (3.0f * flTheta1 + flTheta2) / 4.0f;
flRadius = 0.5f;
break;
case 2:
flTheta = (3.0f * flTheta2 + flTheta1) / 4.0f;
flRadius = 0.5f;
break;
case 3:
flTheta = (5.0f * flTheta2 + flTheta1) / 6.0f;
flRadius = 1.0f;
break;
}
pdc->screenX = cos(flTheta) * flRadius;
pdc->screenY = sin(flTheta) * flRadius;
}
VOID CmapMakerGridIGC::LinkClusters(CMapData * pMapData)
{
if (pMapData->GetTeamClustersPerTeam() != 1)
{
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID, sID + 1);
}
}
{
SectorID sidCenter = pMapData->GetTotalClusters() - 1;
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sIDh = i * pMapData->GetClustersPerTeam();
SectorID sID0 = sIDh +
pMapData->GetTeamClustersPerTeam();
SectorID sID1 = sID0 + 1;
SectorID sID2 = sID0 + 2;
SectorID sID3 = sID0 + 3;
SectorID sIDn = ((i+1)%pMapData->GetTeams()) * pMapData->GetClustersPerTeam();
SectorID sIDn0 = sIDn +
pMapData->GetTeamClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID0, sID1);
CmapMakerIGC::LinkClusters(pMapData, sID1, sID2);
CmapMakerIGC::LinkClusters(pMapData, sID2, sID3);
CmapMakerIGC::LinkClusters(pMapData, sID3, sID0);
CmapMakerIGC::LinkClusters(pMapData, sID2, sIDn0 + 1);
CmapMakerIGC::LinkClusters(pMapData, sID3, sIDn0 + 0);
CmapMakerIGC::LinkClusters(pMapData, sID0, sIDh + pMapData->GetTeamClustersPerTeam() - 1);
CmapMakerIGC::LinkClusters(pMapData, sID1, sIDh);
CmapMakerIGC::LinkClusters(pMapData, sID2, sIDn);
CmapMakerIGC::LinkClusters(pMapData, sID3, sIDn + pMapData->GetTeamClustersPerTeam() - 1);
if (pMapData->GetMissionParams()->iRandomEncounters != 0)
{
if (pMapData->GetTeams() == 2)
CmapMakerIGC::LinkClusters(pMapData, sID1 + i, sIDn0 + 1 + i);
}
}
}
}
const char* CmapMakerEastWestIGC::IsValid(const MissionParams * pmp)
{
if (pmp->nTeams != 2)
return("East West maps must have exactly two teams; "
"please change the map type, or the number of teams.");
return(NULL);
}
CmapMakerEastWestIGC::CmapMakerEastWestIGC()
{
mMMID = c_mmEastWest;
this->SetName("EastWest");
}
VOID CmapMakerEastWestIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(2);
pMapData->SetNeutralClustersPerTeam(11);
pMapData->SetOtherClusters(0);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerEastWestIGC::GenerateTeamClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam());
pdc->screenX = sTeam == 0 ? 0.70f : -0.70f;
pdc->screenY = (sID == sTeam) ? -0.55f : 0.55f;
}
VOID CmapMakerEastWestIGC::GenerateNeutralClusterScreenPosition(
CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID sTeam;
sTeam = sID / pMapData->GetClustersPerTeam();
sID = (sID % pMapData->GetClustersPerTeam()) - pMapData->GetTeamClustersPerTeam();
static const float x[11] = { 1.0f, 1.0f, 0.4f, 0.4f, 1.0f, 1.0f, 0.4f, 0.4f, 0.15f, 0.15f, 0.15f };
static const float y[11] = {-0.9f, -0.2f, -0.9f, -0.2f, 0.2f, 0.9f, 0.2f, 0.9f, -0.55f, 0.00f, 0.55f };
if (sTeam == 0)
{
pdc->screenX = x[sID];
pdc->screenY = y[sID];
}
else
{
pdc->screenX = -x[sID];
pdc->screenY = -y[sID];
}
}
VOID CmapMakerEastWestIGC::LinkClusters(CMapData * pMapData)
{
assert (pMapData->GetTeams() == 2);
assert (pMapData->GetClustersPerTeam() == 13);
assert (pMapData->GetTeamClustersPerTeam() == 2);
for (SideID i = 0; (i < 2); i++)
{
SectorID sIDf0 = i * 13;
SectorID sIDf1 = sIDf0 + 1;
SectorID sID0 = sIDf1 + 1;
CmapMakerIGC::LinkClusters(pMapData, sIDf0, sID0 + 0);
CmapMakerIGC::LinkClusters(pMapData, sIDf0, sID0 + 1);
CmapMakerIGC::LinkClusters(pMapData, sIDf0, sID0 + 2);
CmapMakerIGC::LinkClusters(pMapData, sIDf0, sID0 + 3);
CmapMakerIGC::LinkClusters(pMapData, sIDf1, sID0 + 4);
CmapMakerIGC::LinkClusters(pMapData, sIDf1, sID0 + 5);
CmapMakerIGC::LinkClusters(pMapData, sIDf1, sID0 + 6);
CmapMakerIGC::LinkClusters(pMapData, sIDf1, sID0 + 7);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 0, sID0 + 1);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 1, sID0 + 3);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 3, sID0 + 2);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 2, sID0 + 0);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 4, sID0 + 5);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 5, sID0 + 7);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 7, sID0 + 6);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 6, sID0 + 4);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 4, sID0 + 1);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 8, sID0 + 2);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 8, sID0 + 3);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 9, sID0 + 3);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 9, sID0 + 6);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 10, sID0 + 6);
CmapMakerIGC::LinkClusters(pMapData, sID0 + 10, sID0 + 7);
}
CmapMakerIGC::LinkClusters(pMapData, 10, 25);
CmapMakerIGC::LinkClusters(pMapData, 11, 24);
CmapMakerIGC::LinkClusters(pMapData, 12, 23);
}
VOID CmapMakerEastWestIGC::PopulateCluster(CMapData* pMapData,
IclusterIGC* pcluster,
float amountHe3)
{
SectorID localID = (pcluster->GetObjectID() % pMapData->GetClustersPerTeam());
static const short cMineable[13] = {2, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1};
static const short cSpecial[13] = {0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0};
::PopulateCluster(pMapData->GetMission(), pMapData->GetMissionParams(), pcluster, amountHe3,
true, true,
cMineable[localID], cSpecial[localID]);
}
const char* CmapMakerSplitBaseIGC::IsValid(const MissionParams * pmp)
{
return(NULL);
}
CmapMakerSplitBaseIGC::CmapMakerSplitBaseIGC()
{
mMMID = c_mmSplitBase;
this->SetName("Split Base");
}
VOID CmapMakerSplitBaseIGC::GenerateLayout(CMapData * pMapData)
{
pMapData->SetTeamClustersPerTeam(2);
pMapData->SetNeutralClustersPerTeam(2);
this->GenerateRingClusters(pMapData);
this->LinkClusters(pMapData);
}
VOID CmapMakerSplitBaseIGC::GenerateTeamClusterScreenPosition(CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID n = pMapData->GetTeamClusters();
SectorID s = (sID + 1) / 2;
float flTheta = (float) (2.0 * pi * s / n);
pdc->screenX = cos(flTheta) * 0.9f;
pdc->screenY = sin(flTheta) * 0.9f;
}
VOID CmapMakerSplitBaseIGC::GenerateNeutralClusterScreenPosition(CMapData * pMapData,
DataClusterIGC * pdc,
SectorID sID)
{
SectorID n = pMapData->GetTeamClusters();
SectorID s = (sID + 1) / 2;
float flTheta = (float) (2.0 * pi * s / n);
pdc->screenX = cos(flTheta) * 0.6f;
pdc->screenY = sin(flTheta) * 0.6f;
}
VOID CmapMakerSplitBaseIGC::LinkClusters(CMapData * pMapData)
{
SectorID cTotalSectors = pMapData->GetTotalClusters();
for (SideID i = 0; (i < pMapData->GetTeams()); i++)
{
SectorID sID = i * pMapData->GetClustersPerTeam();
CmapMakerIGC::LinkClusters(pMapData, sID + 1, sID + 2);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, sID + 3);
CmapMakerIGC::LinkClusters(pMapData, sID + 3, (sID + 4) % cTotalSectors);
CmapMakerIGC::LinkClusters(pMapData, sID + 2, (cTotalSectors + (sID - 1)) % cTotalSectors);
if (pMapData->GetTeams() > 2)
{
CmapMakerIGC::LinkClusters(pMapData, sID + 2, (sID + 7) % cTotalSectors);
if (pMapData->GetTeams() > 3)
CmapMakerIGC::LinkClusters(pMapData, sID + 3, (cTotalSectors + (sID - 2)) % cTotalSectors);
}
}
}