From 29762140bf928ea201dd1fa9ff0fb8ee013aeeb0 Mon Sep 17 00:00:00 2001
From: jsalmon3 <>
Date: Fri, 26 Sep 2003 17:52:19 +0000
Subject: [PATCH] More work to make number of races configurable

---
 src/include/player.h     |  2 +-
 src/stratagus/player.cpp |  6 +--
 src/stratagus/pud.cpp    |  8 +---
 src/ui/botpanel.cpp      |  3 --
 src/ui/menus.cpp         | 82 ++++++++++++++++++++++++++++++++++------
 src/unit/unit_draw.cpp   |  4 +-
 6 files changed, 77 insertions(+), 28 deletions(-)

diff --git a/src/include/player.h b/src/include/player.h
index f3ed10a94..65f81018e 100644
--- a/src/include/player.h
+++ b/src/include/player.h
@@ -373,8 +373,8 @@ typedef struct _player_race_ {
 enum PlayerRacesOld {
     PlayerRaceHuman	=0,		/// belongs to human
     PlayerRaceOrc	=1,		/// belongs to orc
-    PlayerRaceNeutral	=2,		/// belongs to none
 };
+#define PlayerRaceNeutral (PlayerRaces.Count-1)
 
 /**
 **	Types for the player (must fit to PUD!)
diff --git a/src/stratagus/player.cpp b/src/stratagus/player.cpp
index 57685a769..7958629a2 100644
--- a/src/stratagus/player.cpp
+++ b/src/stratagus/player.cpp
@@ -127,7 +127,8 @@ global int PlayerRacesIndex(int race)
 	}
     }
     fprintf(stderr,"Invalid race: %d\n", race);
-    return -1;
+    DebugCheck(1);
+    return PlayerRaceNeutral;
 }
 
 /**
@@ -1082,9 +1083,6 @@ global void DebugPlayers(void)
 	    case 7: DebugLevel0("rescue akt.  ");	break;
 	}
 	k=PlayerRacesIndex(Players[i].Race);
-	if( k==-1 ) {
-	    k=PlayerRaces.Race[PlayerRaces.Count-1];
-	}
 	DebugLevel0("%9s" _C_ PlayerRaces.Name[k]);
 	DebugLevel0("%2d " _C_ Players[i].AiNum);
 	switch( Players[i].AiNum ) {
diff --git a/src/stratagus/pud.cpp b/src/stratagus/pud.cpp
index 5613e1354..d2f915241 100644
--- a/src/stratagus/pud.cpp
+++ b/src/stratagus/pud.cpp
@@ -578,9 +578,7 @@ global MapInfo* GetPudInfo(const char* pud)
 		    v=PudReadByte(input);
 		    buf[0] = v & 0xFF;
 		    info->MapUID += ChksumArea(buf, 1);
-		    if( PlayerRacesIndex(v)==-1 ) {
-			v=PlayerRaces.Race[PlayerRaces.Count-1];
-		    }
+		    v=PlayerRaces.Race[PlayerRacesIndex(v)];
 		    info->PlayerSide[i]=v;
 		}
 		continue;
@@ -1055,9 +1053,7 @@ global void LoadPud(const char* pud,WorldMap* map)
 
 		for( i=0; i<16; ++i ) {
 		    v=PudReadByte(input);
-		    if( PlayerRacesIndex(v)==-1 ) {
-			v=PlayerRaces.Race[PlayerRaces.Count-1];
-		    }
+		    v=PlayerRaces.Race[PlayerRacesIndex(v)];
 		    if (GameSettings.Presets[i].Race == SettingsPresetMapDefault) {
 			PlayerSetSide(&Players[i],v);
 		    } else {
diff --git a/src/ui/botpanel.cpp b/src/ui/botpanel.cpp
index 167efaa26..d22fdf9b7 100644
--- a/src/ui/botpanel.cpp
+++ b/src/ui/botpanel.cpp
@@ -728,9 +728,6 @@ local void UpdateButtonPanelMultipleUnits(void)
     }
 
     i=PlayerRacesIndex(ThisPlayer->Race);
-    if( i==-1 ) {
-	i=PlayerRaces.Race[PlayerRaces.Count-1];
-    }
     sprintf(unit_ident,",%s-group,",PlayerRaces.Name[i]);
 
     for( z = 0; z < NumUnitButtons; z++ ) {
diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp
index a5c8a7046..82f5449ee 100644
--- a/src/ui/menus.cpp
+++ b/src/ui/menus.cpp
@@ -4228,11 +4228,24 @@ local void GameDrawFunc(Menuitem *mi __attribute__((unused)))
 */
 local void GameRCSAction(Menuitem *mi, int i)
 {
-    int v[] = { PlayerRaceHuman, PlayerRaceOrc, SettingsPresetMapDefault };
+    int n;
+    int x;
 
     if (mi->d.pulldown.curopt == i) {
-	GameSettings.Presets[0].Race = v[i];
-	ServerSetupState.Race[0] = 2 - i;
+	for (n = 0, x = 0; n < PlayerRaces.Count; ++n) {
+	    if (PlayerRaces.Visible[n]) {
+		if (x == i) {
+		    break;
+		}
+		++x;
+	    }
+	}
+	if (n != PlayerRaces.Count) {
+	    GameSettings.Presets[0].Race = PlayerRaces.Race[x];
+	} else {
+	    GameSettings.Presets[0].Race = SettingsPresetMapDefault;
+	}
+	ServerSetupState.Race[0] = mi->d.pulldown.noptions - 1 - i;
 	NetworkServerResyncClients();
     }
 }
@@ -4403,6 +4416,9 @@ local void NetworkGamePrepareGameSettings(void)
     int i;
     int num[PlayerMax];
     int comp[PlayerMax];
+    int n;
+    int x;
+    int v;
 
     DebugCheck(!MenuMapInfo);
 
@@ -4437,14 +4453,22 @@ local void NetworkGamePrepareGameSettings(void)
 	    case 0:
 		GameSettings.Presets[num[i]].Type = PlayerPerson;
 		DebugLevel3Fn("Settings[%d].Type == Person\n" _C_ num[i]);
-		switch (ServerSetupState.Race[num[i]]) {
-		    case 1:
-			GameSettings.Presets[num[i]].Race = PlayerRaceOrc;
-			break;
-		    case 2:
-			GameSettings.Presets[num[i]].Race = PlayerRaceHuman;
-		    default:
-			break;
+		for (n = 0, v = 0; n < PlayerRaces.Count; ++n) {
+		    if (PlayerRaces.Visible[n]) {
+			++v;
+		    }
+		}
+		v -= ServerSetupState.Race[num[i]];
+		for (n = 0, x = 0; n < PlayerRaces.Count; ++n) {
+		    if (PlayerRaces.Visible[n]) {
+			if (x == v) {
+			    break;
+			}
+			++x;
+		    }
+		}
+		if (n != PlayerRaces.Count) {
+		    GameSettings.Presets[num[i]].Race = PlayerRaces.Race[x];
 		}
 		break;
 	    case 1:
@@ -4898,7 +4922,7 @@ local void MultiClientGemAction(Menuitem *mi)
 local void MultiClientRCSAction(Menuitem *mi, int i)
 {
     if (mi->d.pulldown.curopt == i) {
-	LocalSetupState.Race[NetLocalHostsSlot] = 2 - i;
+	LocalSetupState.Race[NetLocalHostsSlot] = mi->d.pulldown.noptions - 1 - i;
 	MultiClientUpdate(0);
     }
 }
@@ -7092,12 +7116,46 @@ global void ErrorMenu(char *error)
 --	Init functions
 ----------------------------------------------------------------------------*/
 
+/**
+**	Initialize player races for a menu item
+*/
+local void InitPlayerRaces(Menuitem *mi)
+{
+    int i;
+    int n;
+
+    for (i = 0, n = 0; i < PlayerRaces.Count; ++i) {
+	if (PlayerRaces.Visible[i]) {
+	    ++n;
+	}
+    }
+    ++n;
+    mi->d.pulldown.options = (char **)malloc(n * sizeof(char *));
+    for (i = 0, n = 0; i < PlayerRaces.Count; ++i) {
+	if (PlayerRaces.Visible[i]) {
+	    mi->d.pulldown.options[n++] = strdup(PlayerRaces.Display[i]);
+	}
+    }
+    mi->d.pulldown.options[n++] = strdup("Map Default");
+    mi->d.pulldown.noptions = n;
+    mi->d.pulldown.defopt = n - 1;
+}
+
 /**
 **	Initialize the loaded menu data
 */
 global void InitMenuData(void)
 {
+    Menu *menu;
+
     InitNetMultiButtonStorage();
+
+    menu = FindMenu("menu-custom-game");
+    InitPlayerRaces(&menu->Items[6]);
+    menu = FindMenu("menu-multi-setup");
+    InitPlayerRaces(&menu->Items[21]);
+    menu = FindMenu("menu-net-multi-client");
+    InitPlayerRaces(&menu->Items[21]);
 }
 
 /**
diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp
index b272d7f08..9881074ce 100644
--- a/src/unit/unit_draw.cpp
+++ b/src/unit/unit_draw.cpp
@@ -800,7 +800,7 @@ local void DrawDecoration(const Unit* unit,const UnitType* type,int x,int y)
     //
     stats=unit->Stats;
     //  Why remove the neutral race?
-    if( (unit->Player->Type!=PlayerRaceNeutral)
+    if( (unit->Player->Type!=PlayerNeutral)
 		&& ShowHealthBar ) {
 	if( stats->HitPoints
 		&& !(ShowNoFull && unit->HP==stats->HitPoints) ) {
@@ -881,7 +881,7 @@ local void DrawDecoration(const Unit* unit,const UnitType* type,int x,int y)
     //	Health dot on left side of unit.
     //  Why skip the neutral units?
     //
-    if( (unit->Player->Type!=PlayerRaceNeutral)
+    if( (unit->Player->Type!=PlayerNeutral)
 		&& ShowHealthDot ) {
 	if( stats->HitPoints
 		&& !(ShowNoFull && unit->HP==stats->HitPoints) ) {