ai/ai.c
changeset 2738 d8de2d4bee17
parent 2734 a2b52101be1c
child 2739 73bbb2b02554
equal deleted inserted replaced
2737:f16e0a808897 2738:d8de2d4bee17
    43 	/* Dequeue all commands */
    43 	/* Dequeue all commands */
    44 	while ((com = entry_com) != NULL) {
    44 	while ((com = entry_com) != NULL) {
    45 		_current_player = player;
    45 		_current_player = player;
    46 
    46 
    47 		/* Copy the DP back in place */
    47 		/* Copy the DP back in place */
    48 		memcpy(_decode_parameters, com->dp, sizeof(com->dp));
    48 		_cmd_text = com->text;
    49 		DoCommandP(com->tile, com->p1, com->p2, NULL, com->procc);
    49 		DoCommandP(com->tile, com->p1, com->p2, NULL, com->procc);
       
    50 		_cmd_text = NULL;
    50 
    51 
    51 		/* Free item */
    52 		/* Free item */
    52 		entry_com = com->next;
    53 		entry_com = com->next;
       
    54 		if (com->text != NULL)
       
    55 			free(com->text);
    53 		free(com);
    56 		free(com);
    54 	}
    57 	}
    55 }
    58 }
    56 
    59 
    57 /**
    60 /**
    79 	com->tile  = tile;
    82 	com->tile  = tile;
    80 	com->p1    = p1;
    83 	com->p1    = p1;
    81 	com->p2    = p2;
    84 	com->p2    = p2;
    82 	com->procc = procc;
    85 	com->procc = procc;
    83 	com->next  = NULL;
    86 	com->next  = NULL;
    84 
    87 	com->text  = NULL;
    85 	/* Copy the decode_parameters */
    88 
    86 	memcpy(com->dp, _decode_parameters, sizeof(com->dp));
    89 	/* Copy the cmd_text, if needed */
       
    90 	if (_cmd_text != NULL) {
       
    91 		com->text = strdup(_cmd_text);
       
    92 		_cmd_text = NULL;
       
    93 	}
    87 }
    94 }
    88 
    95 
    89 /**
    96 /**
    90  * Executes a raw DoCommand for the AI.
    97  * Executes a raw DoCommand for the AI.
    91  */
    98  */
    92 int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
    99 int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
    93 {
   100 {
    94 	PlayerID old_lp;
   101 	PlayerID old_lp;
    95 	int32 res = 0;
   102 	int32 res = 0;
       
   103 	char *cmdtext = NULL;
    96 
   104 
    97 	/* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
   105 	/* If you enable DC_EXEC with DC_QUERY_COST you are a really strange
    98 	 *   person.. should we check for those funny jokes?
   106 	 *   person.. should we check for those funny jokes?
    99 	 */
   107 	 */
   100 
   108 
       
   109 	/* The test already free _cmd_text in most cases, so let's backup the string, else we have a problem ;) */
       
   110 	if (_cmd_text != NULL)
       
   111 		cmdtext = strdup(_cmd_text);
       
   112 
   101 	/* First, do a test-run to see if we can do this */
   113 	/* First, do a test-run to see if we can do this */
   102 	res = DoCommandByTile(tile, p1, p2, flags & ~DC_EXEC, procc);
   114 	res = DoCommandByTile(tile, p1, p2, flags & ~DC_EXEC, procc);
   103 	/* The command failed, or you didn't want to execute, or you are quering, return */
   115 	/* The command failed, or you didn't want to execute, or you are quering, return */
   104 	if ((CmdFailed(res)) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST))
   116 	if ((CmdFailed(res)) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) {
       
   117 		if (cmdtext != NULL)
       
   118 			free(cmdtext);
   105 		return res;
   119 		return res;
       
   120 	}
       
   121 
       
   122 	/* Recover _cmd_text */
       
   123 	if (cmdtext != NULL)
       
   124 		_cmd_text = cmdtext;
   106 
   125 
   107 	/* If we did a DC_EXEC, and the command did not return an error, execute it
   126 	/* If we did a DC_EXEC, and the command did not return an error, execute it
   108 	    over the network */
   127 	    over the network */
   109 	if (flags & DC_AUTO)                  procc |= CMD_AUTO;
   128 	if (flags & DC_AUTO)                  procc |= CMD_AUTO;
   110 	if (flags & DC_NO_WATER)              procc |= CMD_NO_WATER;
   129 	if (flags & DC_NO_WATER)              procc |= CMD_NO_WATER;
   126 		AI_PutCommandInQueue(_current_player, tile, p1, p2, procc);
   145 		AI_PutCommandInQueue(_current_player, tile, p1, p2, procc);
   127 
   146 
   128 	/* Set _local_player back */
   147 	/* Set _local_player back */
   129 	_local_player = old_lp;
   148 	_local_player = old_lp;
   130 
   149 
       
   150 	/* Free the temp _cmd_text var */
       
   151 	if (cmdtext != NULL)
       
   152 		free(cmdtext);
       
   153 
   131 	return res;
   154 	return res;
   132 }
   155 }
   133 
   156 
   134 int32 AI_DoCommandChecked(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
   157 int32 AI_DoCommandChecked(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
   135 {
   158 {
   150 	new->tile  = tile;
   173 	new->tile  = tile;
   151 	new->p1    = p1;
   174 	new->p1    = p1;
   152 	new->p2    = p2;
   175 	new->p2    = p2;
   153 	new->procc = procc;
   176 	new->procc = procc;
   154 	new->next  = NULL;
   177 	new->next  = NULL;
   155 	new->dp[0] = unique_id;
   178 	new->uid   = unique_id;
   156 
   179 
   157 	/* Add it to the back of the list */
   180 	/* Add it to the back of the list */
   158 	if (command_uid_tail[_current_player] == NULL)
   181 	if (command_uid_tail[_current_player] == NULL)
   159 		command_uid_tail[_current_player] = new;
   182 		command_uid_tail[_current_player] = new;
   160 	else {
   183 	else {
   197 
   220 
   198 	command_uid[_current_player] = command_uid[_current_player]->next;
   221 	command_uid[_current_player] = command_uid[_current_player]->next;
   199 	if (command_uid[_current_player] == NULL)
   222 	if (command_uid[_current_player] == NULL)
   200 		command_uid_tail[_current_player] = NULL;
   223 		command_uid_tail[_current_player] = NULL;
   201 
   224 
   202 	ai_event(_current_player, succeeded ? ottd_Event_CommandSucceeded : ottd_Event_CommandFailed, tile, command->dp[0]);
   225 	ai_event(_current_player, succeeded ? ottd_Event_CommandSucceeded : ottd_Event_CommandFailed, tile, command->uid);
   203 	free(command);
   226 	free(command);
   204 }
   227 }
   205 
   228 
   206 /**
   229 /**
   207  * Run 1 tick of the AI. Don't overdo it, keep it realistic.
   230  * Run 1 tick of the AI. Don't overdo it, keep it realistic.