Author Topic: Ai Player Index  (Read 1480 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4911
Ai Player Index
« on: July 14, 2008, 12:10:33 AM »
This seems to be a common problem. Getting the AI player index. There are two main cases. Single player games, and multiplayer games.

In single player, the TethysGame::NoPlayers is set to DescBlock.numPlayers. In multiplayer, it is set to the number of players that join (from 2 to DescBlock.numPlayers) plus the number of AI players set in DescBlockEx.

Code: [Select]
singleNumPlayers = DescBlock.numPlayers
multiNumPlayers = gameStartupFlags.numPlayers + DescBlockEx.numAIPlayers

When the game starts, that many Player classes are initialized (depending on single or multi games), as well as Player[6] (i.e., the 7th player). This last Player is the owner of weapons fire, beacons, fumaroles, etc. It's what a lot of games would call the Gaia player.

Note that DescBlockEx is only used for multiplayer games.

When there is no AI, you can just use TethysGame::NoPlayers, to initialize all the human players. When there is an AI present, you have to modify the returned value.

Code: [Select]
numHumanPlayers = TethysGame::NoPlayers() - numAIPlayers;

Most people just hardcode a 1 in place of numAIPlayers. If you make a multi mission and include a DescBlockEx, as you should if it has an AI, then you can use the corresponding field of the DescBlockEx structure. (You'll have to make sure the field is named first). As in:
Code: [Select]
numHumanPlayers = TethysGame::NoPlayers() - DescBlockEx.numAIPlayers;

I also took a look at ml4_21.dll to see how the people from Sierra did it. Seems they have code that works something like this:

Code: [Select]
	/* Determine number of Human Players
   Note: Code based on ml4_21.dll */
for (numHumanPlayers = 2; Player[numHumanPlayers].IsHuman(); numHumanPlayers++)
; /* No loop body needed */

I would like to point out that numHumanPlayers is initialized to 2, since this is from a multiplayer level that must have at least 2 players to start. Also, the loop is technically unbounded. If you don't include an AI player, then this might not terminate, or it might access unitialized Player records. The loop is also less efficient then simply reading a value with the NoPlayers() function. It does adapt well to changing the number of AI players though (without adjusting variable values, or hardcoded constants), and the code seems to work for either the single or the multi case. Note that you should change that 2 to a 1 to make sure it works for single player too though. (A slight loss of efficiency for multiplayer, but still correct).

The first index available for AI players, would then be the value of numHumanPlayers.

Code: [Select]
aiPlayerIndex = numHumanPlayers;

As for the initializing DescBlock and DescBlockEx, remember these rules. In single player, initialize DescBlock to the number of players total (human + AI). In multiplayer, initialize DescBlock to the max possible number of human players (the actual number of human players will vary from 2 up to this number), and DescBlockEx contains the number of AI players. Note that DescBlock is initialized in two different ways depending on whether it's a single or multi game.
« Last Edit: December 16, 2016, 09:12:01 AM by leeor_net »