ai/ai.c
changeset 4000 4009d092b306
parent 3950 608973882f8a
child 4077 d4d440dd8925
equal deleted inserted replaced
3999:69dfaadb5c3c 4000:4009d092b306
    95 	tmp_cmdtext = _cmd_text;
    95 	tmp_cmdtext = _cmd_text;
    96 
    96 
    97 	/* First, do a test-run to see if we can do this */
    97 	/* First, do a test-run to see if we can do this */
    98 	res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
    98 	res = DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
    99 	/* The command failed, or you didn't want to execute, or you are quering, return */
    99 	/* The command failed, or you didn't want to execute, or you are quering, return */
   100 	if ((CmdFailed(res)) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
   100 	if (CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
   101 		return res;
   101 		return res;
   102 	}
   102 	}
   103 
   103 
   104 	/* Restore _cmd_text */
   104 	/* Restore _cmd_text */
   105 	_cmd_text = tmp_cmdtext;
   105 	_cmd_text = tmp_cmdtext;
   106 
   106 
   107 	/* If we did a DC_EXEC, and the command did not return an error, execute it
   107 	/* If we did a DC_EXEC, and the command did not return an error, execute it
   108 	    over the network */
   108 	 * over the network */
   109 	if (flags & DC_AUTO)                  procc |= CMD_AUTO;
   109 	if (flags & DC_AUTO)     procc |= CMD_AUTO;
   110 	if (flags & DC_NO_WATER)              procc |= CMD_NO_WATER;
   110 	if (flags & DC_NO_WATER) procc |= CMD_NO_WATER;
   111 
   111 
   112 	/* NetworkSend_Command needs _local_player to be set correctly, so
   112 	/* NetworkSend_Command needs _local_player to be set correctly, so
   113 	    adjust it, and put it back right after the function */
   113 	 * adjust it, and put it back right after the function */
   114 	old_lp = _local_player;
   114 	old_lp = _local_player;
   115 	_local_player = _current_player;
   115 	_local_player = _current_player;
   116 
   116 
   117 #ifdef ENABLE_NETWORK
   117 #ifdef ENABLE_NETWORK
   118 	/* Send the command */
   118 	/* Send the command */
   119 	if (_networking)
   119 	if (_networking) {
   120 		/* Network is easy, send it to his handler */
   120 		/* Network is easy, send it to his handler */
   121 		NetworkSend_Command(tile, p1, p2, procc, callback);
   121 		NetworkSend_Command(tile, p1, p2, procc, callback);
   122 	else
   122 	} else {
       
   123 #else
       
   124 	{
   123 #endif
   125 #endif
   124 		/* If we execute BuildCommands directly in SP, we have a big problem with events
   126 		/* If we execute BuildCommands directly in SP, we have a big problem with events
   125 		 *  so we need to delay is for 1 tick */
   127 		 *  so we need to delay is for 1 tick */
   126 		AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback);
   128 		AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback);
       
   129 	}
   127 
   130 
   128 	/* Set _local_player back */
   131 	/* Set _local_player back */
   129 	_local_player = old_lp;
   132 	_local_player = old_lp;
   130 
   133 
   131 	return res;
   134 	return res;
   171 	/* Don't do anything if we are a network-client
   174 	/* Don't do anything if we are a network-client
   172 	 *  (too bad when a client joins, he thinks the AIs are real, so it wants to control
   175 	 *  (too bad when a client joins, he thinks the AIs are real, so it wants to control
   173 	 *   them.. this avoids that, while loading a network game in singleplayer, does make
   176 	 *   them.. this avoids that, while loading a network game in singleplayer, does make
   174 	 *   the AIs to continue ;))
   177 	 *   the AIs to continue ;))
   175 	 */
   178 	 */
   176 	if (_networking && !_network_server && !_ai.network_client)
   179 	if (_networking && !_network_server && !_ai.network_client) return;
   177 		return;
       
   178 
   180 
   179 	/* New tick */
   181 	/* New tick */
   180 	_ai.tick++;
   182 	_ai.tick++;
   181 
   183 
   182 	/* Make sure the AI follows the difficulty rule.. */
   184 	/* Make sure the AI follows the difficulty rule.. */
   183 	assert(_opt.diff.competitor_speed <= 4);
   185 	assert(_opt.diff.competitor_speed <= 4);
   184 	if ((_ai.tick & ((1 << (4 - _opt.diff.competitor_speed)) - 1)) != 0)
   186 	if ((_ai.tick & ((1 << (4 - _opt.diff.competitor_speed)) - 1)) != 0) return;
   185 		return;
       
   186 
   187 
   187 	/* Check for AI-client (so joining a network with an AI) */
   188 	/* Check for AI-client (so joining a network with an AI) */
   188 	if (_ai.network_client && _ai_player[_ai.network_playas].active) {
   189 	if (_ai.network_client && _ai_player[_ai.network_playas].active) {
   189 		/* Run the script */
   190 		/* Run the script */
   190 		AI_DequeueCommands(_ai.network_playas);
   191 		AI_DequeueCommands(_ai.network_playas);
   191 		AI_RunTick(_ai.network_playas);
   192 		AI_RunTick(_ai.network_playas);
   192 	} else if (!_networking || _network_server) {
   193 	} else if (!_networking || _network_server) {
   193 		/* Check if we want to run AIs (server or SP only) */
   194 		/* Check if we want to run AIs (server or SP only) */
   194 		Player *p;
   195 		const Player* p;
   195 
   196 
   196 		FOR_ALL_PLAYERS(p) {
   197 		FOR_ALL_PLAYERS(p) {
   197 			if (p->is_active && p->is_ai) {
   198 			if (p->is_active && p->is_ai) {
   198 				/* This should always be true, else something went wrong... */
   199 				/* This should always be true, else something went wrong... */
   199 				assert(_ai_player[p->index].active);
   200 				assert(_ai_player[p->index].active);
   222 /**
   223 /**
   223  * This AI player died. Give it some chance to make a final puf.
   224  * This AI player died. Give it some chance to make a final puf.
   224  */
   225  */
   225 void AI_PlayerDied(PlayerID player)
   226 void AI_PlayerDied(PlayerID player)
   226 {
   227 {
   227 	if (_ai.network_client && _ai.network_playas == player)
   228 	if (_ai.network_client && _ai.network_playas == player) {
   228 		_ai.network_playas = OWNER_SPECTATOR;
   229 		_ai.network_playas = OWNER_SPECTATOR;
       
   230 	}
   229 
   231 
   230 	/* Called if this AI died */
   232 	/* Called if this AI died */
   231 	_ai_player[player].active = false;
   233 	_ai_player[player].active = false;
   232 }
   234 }
   233 
   235 
   252 /**
   254 /**
   253  * Deinitializer for AI-related stuff.
   255  * Deinitializer for AI-related stuff.
   254  */
   256  */
   255 void AI_Uninitialize(void)
   257 void AI_Uninitialize(void)
   256 {
   258 {
   257 	Player* p;
   259 	const Player* p;
   258 
   260 
   259 	FOR_ALL_PLAYERS(p) {
   261 	FOR_ALL_PLAYERS(p) {
   260 		if (p->is_active && p->is_ai) AI_PlayerDied(p->index);
   262 		if (p->is_active && p->is_ai) AI_PlayerDied(p->index);
   261 	}
   263 	}
   262 }
   264 }