(svn r3226) -Fix: GPMI implementation had minor glitches
-Fix: the AI speed control is done by the AI-core, individual AIs don't have to do it (so, AIs were delayed twice ;) -Add: Support for AI-network-clients (an AI, connecting to a remote server) -Fix: minor AI-core problems
This commit is contained in:
		
							
								
								
									
										15
									
								
								ai/ai.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								ai/ai.c
									
									
									
									
									
								
							@@ -87,7 +87,7 @@ int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
 | 
			
		||||
	/* First, do a test-run to see if we can do this */
 | 
			
		||||
	res = DoCommandByTile(tile, p1, p2, flags & ~DC_EXEC, procc);
 | 
			
		||||
	/* The command failed, or you didn't want to execute, or you are quering, return */
 | 
			
		||||
	if ((res & CMD_ERROR) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST))
 | 
			
		||||
	if ((CmdFailed(res)) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST))
 | 
			
		||||
		return res;
 | 
			
		||||
 | 
			
		||||
	/* If we did a DC_EXEC, and the command did not return an error, execute it
 | 
			
		||||
@@ -162,10 +162,10 @@ void AI_RunGameLoop(void)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Check for AI-client (so joining a network with an AI) */
 | 
			
		||||
	if (_ai.network_client) {
 | 
			
		||||
	if (_ai.network_client && _ai_player[_ai.network_playas].active) {
 | 
			
		||||
		/* Run the script */
 | 
			
		||||
		AI_DequeueCommands(_ai.network_player);
 | 
			
		||||
		AI_RunTick(_ai.network_player);
 | 
			
		||||
		AI_DequeueCommands(_ai.network_playas);
 | 
			
		||||
		AI_RunTick(_ai.network_playas);
 | 
			
		||||
	} else if (!_networking || _network_server) {
 | 
			
		||||
		/* Check if we want to run AIs (server or SP only) */
 | 
			
		||||
		Player *p;
 | 
			
		||||
@@ -199,6 +199,9 @@ void AI_StartNewAI(PlayerID player)
 | 
			
		||||
 */
 | 
			
		||||
void AI_PlayerDied(PlayerID player)
 | 
			
		||||
{
 | 
			
		||||
	if (_ai.network_client && _ai.network_playas == player)
 | 
			
		||||
		_ai.network_playas = OWNER_SPECTATOR;
 | 
			
		||||
 | 
			
		||||
	/* Called if this AI died */
 | 
			
		||||
	_ai_player[player].active = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -208,9 +211,13 @@ void AI_PlayerDied(PlayerID player)
 | 
			
		||||
 */
 | 
			
		||||
void AI_Initialize(void)
 | 
			
		||||
{
 | 
			
		||||
	bool ai_network_client = _ai.network_client;
 | 
			
		||||
 | 
			
		||||
	memset(&_ai, 0, sizeof(_ai));
 | 
			
		||||
	memset(&_ai_player, 0, sizeof(_ai_player));
 | 
			
		||||
 | 
			
		||||
	_ai.network_client = ai_network_client;
 | 
			
		||||
	_ai.network_playas = OWNER_SPECTATOR;
 | 
			
		||||
	_ai.enabled = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								ai/ai.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								ai/ai.h
									
									
									
									
									
								
							@@ -31,7 +31,7 @@ typedef struct AIStruct {
 | 
			
		||||
 | 
			
		||||
	/* For network-clients (a OpenTTD client who acts as an AI connected to a server) */
 | 
			
		||||
	bool network_client;    //! Are we a network_client?
 | 
			
		||||
	uint8 network_player;   //! The current network player we are connected as
 | 
			
		||||
	uint8 network_playas;   //! The current network player we are connected as
 | 
			
		||||
} AIStruct;
 | 
			
		||||
 | 
			
		||||
VARDEF AIStruct _ai;
 | 
			
		||||
 
 | 
			
		||||
@@ -3938,24 +3938,6 @@ void AiDoGameLoop(Player *p)
 | 
			
		||||
	AiAdjustLoan(p);
 | 
			
		||||
	AiBuildCompanyHQ(p);
 | 
			
		||||
 | 
			
		||||
	if (_opt.diff.competitor_speed == 4) {
 | 
			
		||||
		/* ultraspeed */
 | 
			
		||||
		_ai_actions[p->ai.state](p);
 | 
			
		||||
		if (p->bankrupt_asked != 0)
 | 
			
		||||
			return;
 | 
			
		||||
	} else if (_opt.diff.competitor_speed != 3) {
 | 
			
		||||
		p->ai.tick++;
 | 
			
		||||
		if (!(p->ai.tick&1))
 | 
			
		||||
			return;
 | 
			
		||||
		if (_opt.diff.competitor_speed != 2) {
 | 
			
		||||
			if (!(p->ai.tick&2))
 | 
			
		||||
				return;
 | 
			
		||||
			if (_opt.diff.competitor_speed == 0) {
 | 
			
		||||
				if (!(p->ai.tick&4))
 | 
			
		||||
					return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#if 0
 | 
			
		||||
	{
 | 
			
		||||
		static byte old_state = 99;
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ static void AiNew_State_FirstTime(Player *p)
 | 
			
		||||
	assert(p->ainew.state == AI_STATE_FIRST_TIME);
 | 
			
		||||
	// We first have to init some things
 | 
			
		||||
 | 
			
		||||
	if (_current_player == 1) {
 | 
			
		||||
	if (_current_player == 1 || _ai.network_client) {
 | 
			
		||||
		ShowErrorMessage(-1, TEMP_AI_IN_PROGRESS, 0, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1347,9 +1347,6 @@ static void AiNew_OnTick(Player *p)
 | 
			
		||||
 | 
			
		||||
void AiNewDoGameLoop(Player *p)
 | 
			
		||||
{
 | 
			
		||||
	// If it is a human player, it is not an AI, so bubye!
 | 
			
		||||
	if (IS_HUMAN_PLAYER(_current_player)) return;
 | 
			
		||||
 | 
			
		||||
	if (p->ainew.state == AI_STATE_STARTUP) {
 | 
			
		||||
		// The AI just got alive!
 | 
			
		||||
		p->ainew.state = AI_STATE_FIRST_TIME;
 | 
			
		||||
@@ -1362,29 +1359,6 @@ void AiNewDoGameLoop(Player *p)
 | 
			
		||||
	// We keep a ticker. We use it for competitor_speed
 | 
			
		||||
	p->ainew.tick++;
 | 
			
		||||
 | 
			
		||||
	// See what the speed is
 | 
			
		||||
	switch (_opt.diff.competitor_speed) {
 | 
			
		||||
		case 0: // Very slow
 | 
			
		||||
			if (!(p->ainew.tick&8)) return;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case 1: // Slow
 | 
			
		||||
			if (!(p->ainew.tick&4)) return;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case 2:
 | 
			
		||||
			if (!(p->ainew.tick&2)) return;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case 3:
 | 
			
		||||
			if (!(p->ainew.tick&1)) return;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case 4: // Very fast
 | 
			
		||||
		default: // Cool, a new speed setting.. ;) VERY fast ;)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If we come here, we can do a tick.. do so!
 | 
			
		||||
	AiNew_OnTick(p);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user