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 { |
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. |