mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-01-22 23:26:34 +00:00
(svn r3304) -Add: allow AI-events to see the UID of the command
-Fix: improved the logic of the UID code for AIs
This commit is contained in:
parent
f6330faead
commit
f94da63a8d
28
ai/ai.c
28
ai/ai.c
@ -156,7 +156,7 @@ int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
|
||||
int32 AI_DoCommandChecked(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
|
||||
{
|
||||
AICommand *new;
|
||||
uint unique_id = uids[_current_player];
|
||||
uint unique_id = uids[_current_player] + 1; // + 1, because 0 is reserved
|
||||
int32 res;
|
||||
|
||||
res = DoCommandByTile(tile, p1, p2, flags & ~DC_EXEC, procc);
|
||||
@ -192,13 +192,16 @@ int32 AI_DoCommandChecked(uint tile, uint32 p1, uint32 p2, uint32 flags, uint pr
|
||||
}
|
||||
|
||||
/**
|
||||
* A command is executed for real, and is giving us his result (failed yes/no). Inform the AI with it via
|
||||
* an event.Z
|
||||
* Find the right UID for this command.
|
||||
*/
|
||||
void AI_CommandResult(uint32 cmd, uint32 p1, uint32 p2, TileIndex tile, bool succeeded)
|
||||
void AI_GetCommandUID(uint32 cmd, uint32 p1, uint32 p2, TileIndex tile)
|
||||
{
|
||||
AICommand *command = command_uid[_current_player];
|
||||
|
||||
/* Reset to 0, meaning no UID. Then we start detecting if we have an UID for this command */
|
||||
_ai_current_uid = 0;
|
||||
_ai_current_tile = INVALID_TILE;
|
||||
|
||||
if (command == NULL)
|
||||
return;
|
||||
|
||||
@ -217,14 +220,29 @@ void AI_CommandResult(uint32 cmd, uint32 p1, uint32 p2, TileIndex tile, bool suc
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove this command from the list */
|
||||
command_uid[_current_player] = command_uid[_current_player]->next;
|
||||
if (command_uid[_current_player] == NULL)
|
||||
command_uid_tail[_current_player] = NULL;
|
||||
|
||||
ai_event(_current_player, succeeded ? ottd_Event_CommandSucceeded : ottd_Event_CommandFailed, tile, command->uid);
|
||||
/* Broadcast our current UID and tile */
|
||||
_ai_current_uid = command->uid;
|
||||
_ai_current_tile = tile;
|
||||
free(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* A command is executed for real, and is giving us his result (failed yes/no). Inform the AI with it via
|
||||
* an event.
|
||||
*/
|
||||
void AI_CommandResult(bool succeeded)
|
||||
{
|
||||
if (_ai_current_uid == 0)
|
||||
return;
|
||||
|
||||
ai_event(_current_player, succeeded ? ottd_Event_CommandSucceeded : ottd_Event_CommandFailed, _ai_current_tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run 1 tick of the AI. Don't overdo it, keep it realistic.
|
||||
*/
|
||||
|
5
ai/ai.h
5
ai/ai.h
@ -51,6 +51,8 @@ typedef struct AIStruct {
|
||||
|
||||
VARDEF AIStruct _ai;
|
||||
VARDEF AIPlayer _ai_player[MAX_PLAYERS];
|
||||
VARDEF uint _ai_current_uid; //! Keeps track of the current UID, if any (0 means none)
|
||||
VARDEF TileIndex _ai_current_tile; //! Keeps track of the current Tile.
|
||||
|
||||
// ai.c
|
||||
void AI_StartNewAI(PlayerID player);
|
||||
@ -60,7 +62,8 @@ void AI_Initialize(void);
|
||||
void AI_Uninitialize(void);
|
||||
int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc);
|
||||
int32 AI_DoCommandChecked(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc);
|
||||
void AI_CommandResult(uint32 cmd, uint32 p1, uint32 p2, TileIndex tile, bool failed);
|
||||
void AI_GetCommandUID(uint32 cmd, uint32 p1, uint32 p2, TileIndex tile);
|
||||
void AI_CommandResult(bool failed);
|
||||
|
||||
/** Is it allowed to start a new AI.
|
||||
* This function checks some boundries to see if we should launch a new AI.
|
||||
|
@ -13,7 +13,7 @@
|
||||
* tell us ASAP! */
|
||||
# define ai_event(player, event, ...) \
|
||||
if ((player) < MAX_PLAYERS && _ai_player[(player)].module != NULL) \
|
||||
gpmi_event(_ai_player[(player)].module, (event), ##__VA_ARGS__)
|
||||
gpmi_event(_ai_player[(player)].module, (event), _ai_current_uid, ##__VA_ARGS__)
|
||||
|
||||
#else /* GPMI */
|
||||
|
||||
|
10
command.c
10
command.c
@ -403,6 +403,8 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
|
||||
int x = TileX(tile) * 16;
|
||||
int y = TileY(tile) * 16;
|
||||
|
||||
AI_GetCommandUID(cmd, p1, p2, tile);
|
||||
|
||||
/* Do not even think about executing out-of-bounds tile-commands */
|
||||
if (tile > MapSize()) {
|
||||
_cmd_text = NULL;
|
||||
@ -477,12 +479,12 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
|
||||
if (res & 0xFFFF) _error_message = res & 0xFFFF;
|
||||
/* Trigger an event special for the AI, so it knows the build has failed
|
||||
* Because the commands are always delayed, this is the only way. */
|
||||
AI_CommandResult(cmd, p1, p2, tile, false);
|
||||
AI_CommandResult(false);
|
||||
goto show_error;
|
||||
}
|
||||
// no money? Only check if notest is off
|
||||
if (!notest && res != 0 && !CheckPlayerHasMoney(res)) {
|
||||
AI_CommandResult(cmd, p1, p2, tile, false);
|
||||
AI_CommandResult(false);
|
||||
goto show_error;
|
||||
}
|
||||
}
|
||||
@ -519,12 +521,12 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
|
||||
} else {
|
||||
if (CmdFailed(res2)) {
|
||||
if (res2 & 0xFFFF) _error_message = res2 & 0xFFFF;
|
||||
AI_CommandResult(cmd, p1, p2, tile, false);
|
||||
AI_CommandResult(false);
|
||||
goto show_error;
|
||||
}
|
||||
}
|
||||
|
||||
AI_CommandResult(cmd, p1, p2, tile, true);
|
||||
AI_CommandResult(true);
|
||||
|
||||
SubtractMoneyFromPlayer(res2);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user