Page 1 of 1
Save game editing?
Posted: Sat Dec 02, 2006 7:43 pm
by bountyhunter
What format are the save games in? or what do you need to edit them? Let's face sometimes you you just can't resist doing some tinkering!
RE: Save game editing?
Posted: Mon Dec 04, 2006 2:31 am
by ericbabe
They are in text format, though the format can only charitably be described as technical.
I can provide the source code for the save files if people are really interested in knowing the details, though I have to warn that the code for this is quite extensive.
RE: Save game editing?
Posted: Mon Dec 04, 2006 5:07 am
by jchastain
ORIGINAL: ericbabe
They are in text format, though the format can only charitably be described as technical.
I can provide the source code for the save files if people are really interested in knowing the details, though I have to warn that the code for this is quite extensive.
The most obvious use of such code would be for an editor - which we be a doable project with such a headstart for those who actually know what they are doing.
RE: Save game editing?
Posted: Thu Dec 14, 2006 2:57 pm
by Sonny
ORIGINAL: ericbabe
They are in text format, though the format can only charitably be described as technical.
I can provide the source code for the save files if people are really interested in knowing the details, though I have to warn that the code for this is quite extensive.
Would be handy (if I can get the time to do something with it).
RE: Save game editing?
Posted: Thu Dec 14, 2006 3:43 pm
by ericbabe
Alright, will post here. This should be all the code you need to program a loader for the .sve file. It is thorough, but I'm not sure the adjective "handy" applies since that generally connotes something that's easy with which to work.
SaveGame_Stream takes a standard iostream on the .sve file opened in text mode (I use fstream, but any iostream properly initialized will be OK). It also takes a pointer to a CHexWar object, which contains the data for detailed combat; I'll include the data members of CHexWar and its base classes as well. This method also uses stream overrides for various classes of data, such as TPlayer. I will include the code for the classes (or for the base classes, it gets tricky) after this method. It should be obvious in most cases which class instantiations go with which classes (i.e. Player obviously goes with TPlayer) but in some cases it may not be obvious... I can help sort these out if you're still interested and can't puzzle-out particular instantiations. Similarly, the names of the actual data members should on the whole be self-explanatory... the data that is not self explanatory you probably don't care about anyway.
I follow some Hungarian-style naming conventions, so fVariable is usually a variable of type "float" and pVariable is a pointer, ppVariable a pointer to a pointer; I also use code that uses PT and PTPT as the Hungarian-style prefixes, but this shouldn't be too confusing... when MSFT switched from PT to p, so did I, albeit a few years later. In some cases I don't use a Hungarian style prefix for string variables... I've gotten better about this, but older code doesn't use it, though often the name of the variable should tell you whether it's of type char[] or char*: e.g., variables called "Name" are a good indication that they are strings.
Finally, I'm including code for all Save(iostream) methods within my code... some of these may not be relevant to the save game code, some may be old COG stuff that the current engine doesn't even compile.
All the calls to base class methods are explicit in the code: e.g., TPiece has TMover as a base class, and the so the save method for TPiece makes an explicit call to the save method in TMover.) You should be able to reconstruct all the class hierarchy from this.
Good luck!
bool TGame::SaveGame_Stream(iostream &stream, CHexWar* pHexWar)
{
// save version
stream << MajorVersion << " ";
stream << MajorVersion2 << " ";
stream << MinorVersion << " ";
// save scenario
if (ScenarioPath)
{
stream << ScenarioPath << "\n";
}
else
{
stream << "Data\\" << "\n";
}
// game options
for (int g=0; g<eo_gameopt; g++)
stream << GameOptions[g] << " ";
PTProvMap->Save(stream);
for (int p=1; p<NoPlayers; p++)
Players[p].Save(stream);
for (p=1; p<NoPlayersWithTreaties; p++)
stream << (int) HaveReceivedOrders[p] << " ";
stream << 101001 << " ";
for (p=1; p<NoPlayers; p++)
PlayerOrders[p].Save(stream);
stream << 202002 << " ";
for (p=1; p<NoPlayers; p++)
for (int p2=1; p2<NoPlayers; p2++)
Relations[p][p2].Save(stream);
for (p=1; p<NoPlayers; p++)
for (int p2=1; p2<NoPlayers; p2++)
Remember_Relations[p][p2].Save(stream);
// TTreaty::Save_TreatyList(stream);
// TTreaty::Save_Proposals(stream);
stream << Phase << "\n"
<< ActivePlayer << "\n"
<< Turn << "\n"
<< NextOrderOfArrival << "\n"
;
/*
for (p=1; p<NoPlayersWithTreaties; p++)
for (int p2=1; p2<NoPlayersWithTreaties; p2++)
{
stream << SurrenderPoints[p][p2] << " ";
stream << CarnageTotal[p][p2] << " ";
stream << PeaceTurns[p][p2] << " ";
}
*/
for (p=1; p<NoPlayersWithTreaties; p++)
{
for (int r=1; r<NoTradeRoutes; r++)
Routes[p][r].Save(stream);
GetGovs(p).Save(stream);
SelectGovs[p].Save(stream);
Remember_Govs[p].Save(stream);
//stream << Glory[p] << " ";
//stream << fTreatyMakingPoints[p] << " ";
stream << NationalMorale[p] << " ";
}
for (int d=0; d<3; d++)
{
stream << Europe_TradeLevel[d] << " ";
stream << Europe_MilitaryLevel[d] << " ";
}
for (d=0; d<3; d++)
stream << NationWonLastBattles[d] << " ";
for (int c=1; c<NoCities; c++)
Cities[c].Save(stream);
for (int r=1; r<NoProvinces; r++)
{
stream << ProvWeather[r] << " ";
}
/* for (p=1; p<NoPlayersWithTreaties; p++)
for (int p2=1; p2<NoPlayers; p2++)
stream << HotList[p][p2] << " ";
for (int p1=1; p<NoNations; p++)
for (int p2=1; p2<NoNations; p2++)
{
stream << RejectAlliance[p1][p2] << " ";
stream << RejectLimSur[p1][p2] << " ";
stream << RejectCeaseFire[p1][p2] << " ";
for (int g1=1; g1<NoMasterGoods; g1++)
stream << RejectTrade[p1][p2][g1] << " ";
}
*/
// check
stream << 112233 << " ";
// save governor variable info
for (r=1; r<NoRulers; r++)
Rulers[r].Save(stream);
// save history
for (p=1; p<NoPlayers; p++)
for (int t=0; t<MaxTurnsOfHistory; t++)
{
stream << History_TotalStrength[p][t] << " ";
stream << History_Casualties[p][t] << " ";
stream << History_Victory[p][t] << " ";
stream << History_NationalWill[p][t] << " ";
stream << History_Quality[p][t] << " ";
stream << History_Weapons[p][t] << " ";
}
// save number key
for (p=1; p<NoNations; p++)
for (int t=0; t<10; t++)
stream << hPieceStore[p][t] << " ";
pbem.Save(stream);
stream << DifficultyLevel << " ";
stream << GameLength << " ";
stream << GloryVictoryCondition << " ";
stream << StartOfGame << " ";
stream << EndOfGame << " ";
if (pHexWar)
{
stream << "HEXWAR" << " ";
pHexWar->SaveGame_Stream(stream);
stream << CurrentSubphase << " ";
stream << hSaveBattlePlayer << " ";
saveDummyCFight.Save(stream);
// save TGameFightBattle data
for (int p=1; p<NoPlayers; p++)
{
stream << dead[p] << " ";
stream << fresh[p] << " ";
stream << PlayerBattleStrength[p] << " ";
stream << StrengthByPlayer[0][p] << " ";
stream << StrengthByPlayer[1][p] << " ";
stream << PlayerStrength[p] << " ";
}
for (int g=0; g<MaxGarList; g++)
stream << hGarrisonList[g] << " ";
//char description[2048];
for (int i=0; i<2; i++)
{
stream << teamCount << " ";
stream << strength << " ";
stream << isTeamComputer << " ";
stream << frontSize << " ";
stream << TotalTeamStrength << " ";
}
stream << GarrisonIndex << " ";
stream << hGarrisonControllerPlayer << " ";
stream << hStrongestHumanInBattle << " ";
stream << TotalMenInBattle << " ";
stream << hVictor << " ";
stream << hSiegeUnitCombat << " ";
int scratch;
scratch = bResults; stream << scratch << " ";
scratch = bRallyGarrison; stream << scratch << " ";
}
else
{
stream << "NOHEX" << " ";
}
stream << ends;
return true;
}
void CFight::Save(iostream &stream)
{
for (int u=0; u<szFightUnits; u++)
{
stream << Units.hPiece << " ";
stream << Units.team << " ";
stream << Units.x << " ";
stream << Units.y << " ";
stream << Units.movex << " ";
stream << Units.movey << " ";
stream << Units.reinforce << " ";
}
// DONT NEED TO SAVE THIS....int Map[FightWidth][FightHeight];
for (int i=0; i<2; i++)
{
stream << hTeamLeader << " ";
stream << Supply << " ";
stream << CarnageTakenByTeam << " ";
stream << CarnageCausedByTeamThisRound << " ";
}
for (int p=1; p<NoPlayers; p++)
stream << CarnageTakenByPlayer[p] << " ";
GCOfBattle.Save(stream);
GCOfPortAttack.Save(stream);
for (int g=0; g<szFightGenerals; g++)
for (int i=0; i<2; i++)
{
stream << hGenerals[g] << " ";
}
stream << Weather << " ";
stream << DefenderPortDefenses << " ";
stream << WeatherGauge << " ";
stream << VictoriousTeam << " ";
stream << DefenderTerrainBonus << " ";
stream << DefenderFortBonus << " ";
int scratch;
scratch = bIsNavalBattle; stream << scratch << " ";
scratch = bSilentRun; stream << scratch << " ";
}
void TCity::Save(iostream &stream)
{
for (int d=1; d<eoDev; d++)
stream << Development[d] << " ";
stream << DevelopmentArea << " ";
stream << TurnsToNextDevelopment << " ";
}
void THexAi::Save(iostream &stream)
{
stream << ourTeam << " ";
stream << Stance << " ";
stream << Opx << " ";
stream << Opy << " ";
stream << hDesignatedVictim << " ";
stream << ourPower << " ";
stream << theirPower << " ";
// PERIMETER STUFF
for (int x=0; x<HexMapSize; x++)
for (int y=0; y<HexMapSize; y++)
stream << EnemyPower[x][y] << " ";
for (int per=0; per<szPerList; per++)
{
stream << PerList[per].x << " ";
stream << PerList[per].y << " ";
stream << PerList[per].hAssignedBat << " ";
}
stream << PerListIndex << " ";
for (int b=0; b<szBat; b++)
stream << BatIndex2AssignedPerListIndex << " ";
}
void TPbem::Save(iostream &stream)
{
stream << 123456 << "\n"; // check
stream << IsPbemGame << "\n";
if (PbemName[0])
stream << PbemName << "\n";
else
stream << "noname" << "\n";
for (PLAYER_HANDLE a=1; a<NoNations; a++)
{
for (PLAYER_HANDLE b=1; b<NoNations; b++)
{
stream << OpportunityAlliance[a] << " ";
stream << OpportunityWar[a] << " ";
stream << OpportunityTradeWithPlayer[a] << " ";
}
for (int g=1; g<TMasterGoods::eoGoods; g++)
{
stream << OpportunityTradeFor[a][g] << " ";
stream << OpportunityTradeAway[a][g] << " ";
}
}
for (a=1; a<NoNations; a++)
{
if (Passwords[a][0])
stream << Passwords[a] << "\n";
else
stream << "default" << "\n";
}
}
void TRuler::Save(iostream &stream)
{
stream << IsGovernor << " ";
stream << State << " ";
stream << Player << " ";
stream << Mugshot << " ";
stream << WantDev << " ";
stream << WantDevLevel << " ";
stream << WantBrigades << " ";
stream << WantBrigadesLevel << " ";
stream << Action << " ";
stream << Support << " ";
stream << Party << " ";
stream << Power << " ";
stream << Temper << " ";
}
void TGov::Save(iostream &stream)
{
stream << FeudalDues << " ";
stream << MilitaryReadiness << " ";
stream << MilitaryIndustry << " ";
stream << Tax << " ";
stream << Dole << " ";
stream << WantDole << " ";
stream << FoodRation << " ";
stream << Loan << " ";
stream << LoanRate << " ";
stream << DraftYoung << " ";
stream << DraftOld << " ";
stream << DraftTime << " ";
stream << DraftSize << " ";
stream << DraftPool << " ";
stream << DraftPoolMorale << " ";
stream << DraftTraining << " ";
for (int u=0; u<eo_Upg; u++)
stream << Upgrades << " ";
}
void TVisible::Save(iostream &stream)
{
stream << Visible_Bits << " ";
}
void TNapPiece::Save(iostream &stream)
{
stream << Forage << " ";
stream << ForcedMarch << " ";
stream << (int) Blockade << " ";
stream << LookingForBattle << " ";
stream << Supplied << " ";
stream << hProduction_AutoJoin << " ";
stream << DivisionNumber << " ";
stream << CityIndex << " ";
stream << Diplomat_Espionage << " ";
stream << Diplomat_Influence << " ";
stream << Diplomat_Legal << " ";
stream << DetailedOrderNumber << " ";
TPiece::Save(stream);
}
void TPieceInterface::Save(iostream &stream)
{
PTPieceList->Save(stream);
}
void TContainer::Save(iostream &stream)
{
stream << HContainer << " "
<< hContainerAtBeginningOfTurn << " "
<< CanCarry << " "
<< CarryType
<< "\n";
}
void TGameCoord::Save(iostream &stream)
{
//ZoomCoord.Save(stream);
stream << Province << "\n";
}
void TGeneralAttrib::Save(iostream &stream)
{
stream << Initiative_Modifier << " "
<< Rank << " "
<< TacticalSkill << " "
<< MoraleBonus << " "
<< CavalryRating << " "
<< CommandRating << " "
<< SpecTactic[0] << " "
<< SpecTactic[1] << " "
<< SpecTactic[2] << " "
<< SpecTactic[3] << " "
<< SpecTactic[4] << " "
//<< MugshotNo << " "
<< FoughtThisTurn << " "
<< WestPoint << " "
<< VMI << " "
<< GraduationRank << " "
<< ForeignService << " "
<< RelievedOfCommand << " "
<< ResignedCommand << " "
<< MedalOfHonor << " "
<< hState << " "
;
for (int k=0; k<eo_gk; k++)
stream << Know[k] << " ";
stream << 57455475 << "\n";
if (!pNotes)
stream << "NoNotes" << " ";
else
{
if (!strlen(pNotes))
stream << "NoNotes" << " ";
else
stream << pNotes << " ";
}
stream << "\n";
}
void TOwned::Save(iostream &stream)
{
stream << PlayerID << "\n";
stream << OriginalPlayerID << "\n";
stream << Surrendered << "\n";
}
void TCoord::Save(iostream &stream)
{
stream << location[0] << " " << location[1] << "\n";
}
void TCoordf::Save(iostream &stream)
{
stream << location[0] << " " << location[1] << "\n";
}
ostream& operator << (ostream& os, TGoods& g)
{
int n;
for (int i=1; i<NoMasterGoods; i++)
{
n = g.GetNumber(i);
os << n << " ";
}
return os;
}
// NOTE FROM ERIC: This method uses the above stream override
void TGoods::Save(iostream &stream)
{
/* for (int i=1; i<NoMasterGoods; i++)
{
stream << GetNumber(i) << " ";
}
*/
stream << *this;
}
void TLoc::Save(iostream &stream)
{
TOwned::Save(stream);
stream << MasterLocID << " ";
Coord.Save(stream);
}
void TMover::Save(iostream &stream)
{
stream << MovesLeft << " ";
MoveTimer.Save(stream);
GameCoord.Save(stream);
AssociatedEdge.Save(stream);
BegGameCoord.Save(stream);
Destination.Save(stream);
TOrderThing::Save(stream);
for (int m=0; m<MaxMovePath; m++)
MovePath[m].Save(stream);
}
void TOrders::Save(iostream &stream)
{
if (string[0]==0)
strcpy(string, "NoString");
stream << (int) Order << " "
<< hOwner << " "
<< hPiece << " "
<< When << " "
<< data.arg1 << " "
<< data.arg2 << " "
<< data.argf1 << " "
<< data.argf2 << " "
<< string << "\n"
;
gcHere.Save(stream);
gcThere.Save(stream);
}
void TOrderThing::Save(iostream &stream)
{
int count = 0;
for (int i=0; i<MaxNoOrders; i++)
{
if (Orders[i].GetOrder())
{
Orders[i].Save(stream);
count++;
}
//Orders[i].Save(stream);
//if (!Orders[i].GetOrder())
// break;
}
// save blank order to mark end of orders
TOrders blank;
blank.Save(stream);
}
void TPiece::Save(iostream &stream)
{
//stream << "Piece\n";
if (!UniqueName)
stream << "noname" << " ";
else
stream << UniqueName << " ";
stream
<< Handle << " "
<< Selected << " "
<< MasterPieceIndex << " "
<< Strength << " "
<< Morale << " "
<< Experience << " "
<< Disposition << " "
<< Firearm << " "
<< StratSupply << " "
<< LogisticStaff << " "
<< CommandStaff << " "
<< EngineeringJob << " "
<< SupplyPriority << " "
<< hGunBuy << " "
<< GunBuyNumbers << " "
<< hSiegeTarget << " "
<< FlagNumber << " "
<< AIGroup << " "
<< hFleetInvasionProvince << " "
<< Remember_Strength << " "
<< Remember_Morale << " "
<< Temporary_Piece << " "
<< Temporary_Deleted << " "
<< Port << " "
<< Province_CoordList_Index << "\n"
;
for (int i=0; i<NoPieceAttributes; i++)
stream << Attributes[i] << " ";
for (i=0; i<NoPieceSpecialAbilities; i++)
stream << SpecialAbility[i] << " ";
TMover::Save(stream);
TOwned::Save(stream);
TContainer::Save(stream);
TGeneralAttrib::Save(stream);
TVisible::Save(stream);
//LifeTimer.Save(stream);
// save reports
for (int no=0; no<NoPieceReports; no++)
{
for (int r=0; r<NoPieceReportEntries; r++)
{
if (Reports[no][r] && strlen(Reports[no][r])>0)
{
NonGraphLetters_To_Underscores(Reports[no][r]);
stream << no << " " << r << " " << Reports[no][r] << "\n";
}
else
{
break;
}
}
}
stream << -1 << " " << -1 << " " << "end" << "\n";
stream << 31 << "\n";
}
void TPieceList::Save(iostream &stream)
{
for (int i=0; i<List.GetIndex(); i++)
{
List[i]->Save(stream);
}
// SAVE END OF LIST PIECE
GAMEPIECE_OBJECT blank;
blank.Save(stream);
// save handle list
for (i=0; i<MaxPieceHandle; i++)
stream << HandleToListIndex[i] << " ";
}
void TPcMap::Save(iostream &stream)
{
TPieceInterface::Save(stream);
TMap::Save(stream);
}
void TPcProvMap::Save(iostream &stream)
{
TPcMap::Save(stream);
stream << 20052006 << " ";
TProvMap::Save(stream);
}
void TPlayer::Save(iostream &stream)
{
stream << 13117 << " ";
stream << id << " ";
//char* Name;
if (!LeaderName)
stream << "noname" << " ";
else
stream << LeaderName << " ";
stream << ComputerPlayer << " ";
Goods.Save(stream);
stream << BaseMorale << " ";
stream << Expert << " ";
stream << Empire << " ";
stream << Handicap << " ";
stream << gcHome.Province << " ";
stream << hRallyLocation << "\n";
for (int d=0; d<3; d++)
{
stream << DiploSpending[d] << " ";
stream << DiploLevels[d] << " ";
}
stream << Emancipated << " ";
stream << POWs << " ";
stream << Will << " ";
stream << LastBattle << " ";
stream << 13113 << "\n ";
}
void TRelation::Save(iostream &stream)
{
stream << Declaration << " " <<
Attitude << " " <<
ViolateNeutrality << " " <<
Slaughter << "\n";
}
void TProvince::Save(iostream &stream)
{
stream << 18611864 << " "; // test
TLoc::Save(stream);
Production.Save(stream);
for (int lab = 0; lab<eoLabor; lab++)
stream << LaborAllocation[lab] << " ";
stream << hVeryOriginalPlayer << " ";
stream << hVeryOriginalNation << " ";
stream << FOWVisible << " ";
// stream << 717273 << " "; // test
stream << SpecialCharacteristic << " ";
stream << Unrest << " ";
stream << ImpressGood << " ";
stream << ImpressAmount << " ";
stream << ImpressSuccess << " ";
stream << ImpressDanger << " ";
Production.Save(stream);
for (int dx=0; dx<DevelopmentMapWidth; dx++)
for (int dy=0; dy<DevelopmentMapHeight; dy++)
stream << DevelopmentXY[dx][dy] << " ";
for (dx=0; dx<DevelopmentMapWidth; dx++)
for (int dy=0; dy<DevelopmentMapHeight; dy++)
stream << DevelopmentXY_TimeLeft[dx][dy] << " ";
// stream << 554433 << " "; // test
for (int r=0; r<5; r++)
stream << ResourcesUsed[r] << " ";
stream << SustainablePopulation << " ";
// stream << 999888 << " "; // test
}
void TProvMap::Save(iostream &stream)
{
for (int i=0; i<NoProvinces; i++)
{
pProvinces[i].Save(stream);
}
}
void CHexWar::SaveGame_Stream(iostream &stream)
{
int scratch;
stream << 10001 << " ";
for (int x=0; x<HexMapSize; x++)
for (int y=0; y<HexMapSize; y++)
{
stream << Map[x][y] << " ";
// prop
stream << Prop[x][y].road << " ";
stream << Prop[x][y].river << " ";
stream << Prop[x][y].trench << " ";
stream << Prop[x][y].height << " ";
stream << Prop[x][y].coast << " ";
// stream << Prop[x][y].tree << " ";
stream << Prop[x][y].swamp << " ";
stream << Prop[x][y].mud << " ";
stream << Prop[x][y].village << " ";
stream << Prop[x][y].smoke << " ";
stream << Prop[x][y].fow << " ";
stream << Prop[x][y].variety << " ";
stream << Prop[x][y].corpses << " ";
stream << Prop[x][y].crater << " ";
stream << Prop[x][y].forested << " ";
stream << Prop[x][y].ford << " ";
stream << Prop[x][y].trench << " ";
stream << Prop[x][y].urban << " ";
stream << Prop[x][y].impass << " ";
stream << Prop[x][y].rock << " ";
stream << Prop[x][y].GrassType0 << " ";
stream << Prop[x][y].GrassType1 << " ";
stream << Prop[x][y].GrassTile << " ";
for (int c=0; c<MaxCorpsesPerHex; c++)
{
stream << Prop[x][y].CorpseUgxPlus1[c] << " ";
stream << Prop[x][y].CorpseFace[c] << " ";
stream << Prop[x][y].CorpsePlayer[c] << " ";
stream << Prop[x][y].CorpseCell[c] << " ";
stream << Prop[x][y].CorpseDxDy[c][2] << " ";
}
stream << hBat[x][y] << " ";
stream << HiMap[x][y] << " ";
stream << Move[x][y] << " ";
stream << ScratchMove[x][y] << " ";
stream << Face[x][y] << " ";
scratch = AlreadyMoved[x][y]; stream << scratch << " ";
scratch = Zoc[x][y]; stream << scratch << " ";
scratch = FortWallZoc[x][y]; stream << scratch << " ";
scratch = Sight[x][y]; stream << scratch << " ";
scratch = LocalSight[x][y]; stream << scratch << " ";
scratch = Threat[x][y]; stream << scratch << " ";
}
stream << 10002 << " ";
// save units
for (int b=0; b<szBat; b++)
{
if (Bat.Name[0]==0)
strcpy(Bat.Name, "Unit");
NonLetters_NonPeriodsAndAsterisks_To_Underscores(Bat.Name);
stream << Bat.Name << " ";
stream << Bat.type << " ";
stream << Bat.form << " ";
stream << Bat[b].strength << " ";
stream << Bat[b].morale << " ";
stream << Bat[b].maxMorale << " ";
stream << Bat[b].supply << " ";
stream << Bat[b].x << " ";
stream << Bat[b].y << " ";
stream << Bat[b].hPlayer << " ";
stream << Bat[b].team << " ";
stream << Bat[b].hOriginalPlayer << " ";
stream << Bat[b].initiative << " ";
stream << Bat[b].hPiece << " ";
stream << Bat[b].hCorps << " ";
stream << Bat[b].Moves << " ";
stream << Bat[b].face << " ";
stream << Bat[b].hGeneral << " ";
stream << Bat[b].Gun << " ";
stream << Bat[b].CanBePlaced << " ";
stream << Bat[b].Attributes[0] << " ";
stream << Bat[b].Attributes[1] << " ";
stream << Bat[b].Special[0] << " ";
stream << Bat[b].Special[1] << " ";
stream << Bat[b].AutoThisTurn << " ";
stream << Bat[b].TelegraphBonus << " ";
stream << Bat[b].RailBonus << " ";
stream << Bat[b].RangingX << " ";
stream << Bat[b].RangingY << " ";
scratch = Bat[b].bSkirmishers; stream << scratch << " ";
scratch = Bat[b].bSurrendered; stream << scratch << " ";
scratch = Bat[b].bSentry; stream << scratch << " ";
scratch = Bat[b].bFortified; stream << scratch << " ";
scratch = Bat[b].bFresh; stream << scratch << " ";
scratch = Bat[b].bForceMarch; stream << scratch << " ";
scratch = Bat[b].bFatigue; stream << scratch << " ";
scratch = Bat[b].bEagle; stream << scratch << " ";
scratch = Bat[b].bShaken; stream << scratch << " ";
scratch = Bat[b].bInCommand; stream << scratch << " ";
}
stream << 10003 << " ";
for (b=0; b<szReinforcementList; b++)
{
if (ReinforcementList[b].Name[0]==0)
strcpy(ReinforcementList[b].Name, "Unit");
NonLetters_NonPeriodsAndAsterisks_To_Underscores(ReinforcementList[b].Name);
stream << ReinforcementList[b].Name << " ";
stream << ReinforcementList[b].type << " ";
stream << ReinforcementList[b].form << " ";
stream << ReinforcementList[b].strength << " ";
stream << ReinforcementList[b].morale << " ";
stream << ReinforcementList[b].maxMorale << " ";
stream << ReinforcementList[b].supply << " ";
stream << ReinforcementList[b].x << " ";
stream << ReinforcementList[b].y << " ";
stream << ReinforcementList[b].hPlayer << " ";
stream << ReinforcementList[b].team << " ";
stream << ReinforcementList[b].hOriginalPlayer << " ";
stream << ReinforcementList[b].initiative << " ";
stream << ReinforcementList[b].hPiece << " ";
stream << ReinforcementList[b].hCorps << " ";
stream << ReinforcementList[b].Moves << " ";
stream << ReinforcementList[b].face << " ";
stream << ReinforcementList[b].hGeneral << " ";
stream << ReinforcementList[b].Gun << " ";
stream << ReinforcementList[b].CanBePlaced << " ";
stream << ReinforcementList[b].Attributes[0] << " ";
stream << ReinforcementList[b].Attributes[1] << " ";
stream << ReinforcementList[b].Special[0] << " ";
stream << ReinforcementList[b].Special[1] << " ";
stream << ReinforcementList[b].AutoThisTurn << " ";
stream << ReinforcementList[b].TelegraphBonus << " ";
stream << ReinforcementList[b].RailBonus << " ";
stream << ReinforcementList[b].RangingX << " ";
stream << ReinforcementList[b].RangingY << " ";
scratch = ReinforcementList[b].bSkirmishers; stream << scratch << " ";
scratch = ReinforcementList[b].bSurrendered; stream << scratch << " ";
scratch = ReinforcementList[b].bSentry; stream << scratch << " ";
scratch = ReinforcementList[b].bFortified; stream << scratch << " ";
scratch = ReinforcementList[b].bFresh; stream << scratch << " ";
scratch = ReinforcementList[b].bForceMarch; stream << scratch << " ";
scratch = ReinforcementList[b].bFatigue; stream << scratch << " ";
scratch = ReinforcementList[b].bEagle; stream << scratch << " ";
scratch = ReinforcementList[b].bShaken; stream << scratch << " ";
scratch = ReinforcementList[b].bInCommand; stream << scratch << " ";
}
// save title of battle
if (TitleOfBattle[0]==0)
strcpy(TitleOfBattle, "Battle");
NonLetters_NonPeriodsAndAsterisks_To_Underscores(TitleOfBattle);
stream << TitleOfBattle << " ";
for (int p=1; p<NoPlayers; p++)
{
stream << CarnageTakenByPlayer[p] << " ";
stream << RetreatRounds[p] << " ";
stream << ReinforcementDelay[p] << " ";
scratch = bCallReinforce[p]; stream << scratch << " ";
scratch = bTotalMopup[p]; stream << scratch << " ";
scratch = bSkipAll[p]; stream << scratch << " ";
}
stream << 10004 << " ";
GCOfBattle.Save(stream);
stream << AdvisorBkgNumber << " ";
for (int i=0; i<2; i++)
{
stream << BattlefieldIsFull[i] << " ";
stream << BattlefieldSizeLimit[i] << " ";
stream << CarnageTakenByTeam[i] << " ";
}
ai[0].Save(stream);
ai[1].Save(stream);
stream << MapSeed << " ";
stream << ScoutCheck << " ";
stream << ScoutingTeam << " ";
stream << ScoutSuccess << " ";
stream << CommandCounter[0] << " ";
stream << CommandCounter[1] << " ";
for (i=0; i<NoVictoryLocations; i++)
{
stream << VictoryLocations[i][0] << " ";
stream << VictoryLocations[i][1] << " ";
}
for (i=0; i<NoRallyLocations; i++)
{
stream << RallyLocations[i][0] << " ";
stream << RallyLocations[i][1] << " ";
stream << RallyLocations[i][2] << " ";
}
for (int g=0; g<3; g++)
stream << GrassTypeNumbers[g] << " ";
for (int t=0; t<2; t++)
for (int m=0; m<eo_gm; m++)
stream << GlobalMorale[t][m] << " ";
stream << 10005 << " ";
for (b=0; b<szBat; b++)
{
scratch = bCanSupply[b]; stream << scratch << " ";
}
stream << iWeather << " ";
stream << hVictoriousPlayer << " ";
stream << iServerBaseWeather << " ";
stream << xPos << " ";
stream << yPos << " ";
stream << Init << " ";
stream << hSelect << " ";
stream << DrawCount << " ";
stream << Minutes << " ";
stream << TurnNumber << " ";
stream << mountainous << " ";
stream << forested << " ";
stream << swampy << " ";
stream << desert << " ";
stream << rivers << " ";
stream << RetreatingSide << " ";
for (int r=0; r<szReinforcementList; r++)
{
stream << hReinforceAtStart[r] << " ";
stream << hReinforceAtStart_team[r] << " ";
}
for (r=0; r<szhPieceRetreated; r++)
{
stream << hPieceRetreated[r] << " ";
stream << hStrengthRetreated[r] << " ";
stream << hTeamRetreated[r] << " ";
}
stream << 10006 << " ";
scratch = bDontEnterUnitControl; stream << scratch << " ";
scratch = bPleaseDeleteMe; stream << scratch << " ";
scratch = bIsWinter; stream << scratch << " ";
scratch = bIsDesert; stream << scratch << " ";
scratch = bConiferous; stream << scratch << " ";
scratch = bMixedConiferous; stream << scratch << " ";
scratch = bScrubtrees; stream << scratch << " ";
scratch = bAlreadyPlayedVictoryMusic; stream << scratch << " ";
scratch = bIsFirstTurn; stream << scratch << " ";
for (int n=0; n<NoNamedLocations; n++)
{
stream << Name[n][0] << " ";
stream << NameXY[n][0] << " ";
stream << Name[n][1] << " ";
stream << NameXY[n][1] << " ";
}
// ****************
stream << pProvince->GetProvinceIndex() << " ";
// CONVERT THIS TO -> TProvince* pProvince;
// ****************
stream << 10007 << " ";
}