From 36e31fa41fceb9044d1a4106e6775af7ab04fc8d Mon Sep 17 00:00:00 2001 From: tron Date: Sun, 4 Jun 2006 09:10:24 +0000 Subject: (svn r5092) -Fix: There was a gross race condition in the AI code which made it pretty random if the AI could give a new vehicle its orders --- ai/ai.c | 18 +++++++++++++----- ai/ai.h | 2 ++ ai/trolly/build.c | 21 ++++++++++++++++++++- ai/trolly/trolly.c | 15 ++------------- ai/trolly/trolly.h | 1 + callback_table.c | 3 +++ 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/ai/ai.c b/ai/ai.c index 6754dc82e..6725faaea 100644 --- a/ai/ai.c +++ b/ai/ai.c @@ -32,7 +32,7 @@ static void AI_DequeueCommands(PlayerID player) /* Copy the DP back in place */ _cmd_text = com->text; - DoCommandP(com->tile, com->p1, com->p2, NULL, com->procc); + DoCommandP(com->tile, com->p1, com->p2, com->callback, com->procc); /* Free item */ entry_com = com->next; @@ -45,7 +45,7 @@ static void AI_DequeueCommands(PlayerID player) * Needed for SP; we need to delay DoCommand with 1 tick, because else events * will make infinite loops (AIScript). */ -static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uint32 p2, uint procc) +static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCallback* callback) { AICommand *com; @@ -67,6 +67,7 @@ static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uin com->p1 = p1; com->p2 = p2; com->procc = procc; + com->callback = callback; com->next = NULL; com->text = NULL; @@ -80,7 +81,7 @@ static void AI_PutCommandInQueue(PlayerID player, TileIndex tile, uint32 p1, uin /** * Executes a raw DoCommand for the AI. */ -int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc) +int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback) { PlayerID old_lp; int32 res = 0; @@ -120,12 +121,12 @@ int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint proc /* Send the command */ if (_networking) /* Network is easy, send it to his handler */ - NetworkSend_Command(tile, p1, p2, procc, NULL); + NetworkSend_Command(tile, p1, p2, procc, callback); else #endif /* If we execute BuildCommands directly in SP, we have a big problem with events * so we need to delay is for 1 tick */ - AI_PutCommandInQueue(_current_player, tile, p1, p2, procc); + AI_PutCommandInQueue(_current_player, tile, p1, p2, procc, callback); /* Set _local_player back */ _local_player = old_lp; @@ -135,6 +136,13 @@ int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint proc return res; } + +int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc) +{ + return AI_DoCommandCc(tile, p1, p2, flags, procc, NULL); +} + + /** * Run 1 tick of the AI. Don't overdo it, keep it realistic. */ diff --git a/ai/ai.h b/ai/ai.h index 76e2dc035..ec06b302f 100644 --- a/ai/ai.h +++ b/ai/ai.h @@ -11,6 +11,7 @@ typedef struct AICommand { uint32 p1; uint32 p2; uint32 procc; + CommandCallback* callback; char *text; uint uid; @@ -46,6 +47,7 @@ void AI_RunGameLoop(void); void AI_Initialize(void); void AI_Uninitialize(void); int32 AI_DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc); +int32 AI_DoCommandCc(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc, CommandCallback* callback); /** Is it allowed to start a new AI. * This function checks some boundries to see if we should launch a new AI. diff --git a/ai/trolly/build.c b/ai/trolly/build.c index 2b6342604..1f4324355 100644 --- a/ai/trolly/build.c +++ b/ai/trolly/build.c @@ -7,6 +7,7 @@ #include "../../map.h" #include "../../road_map.h" #include "../../tile.h" +#include "../../vehicle.h" #include "../../command.h" #include "trolly.h" #include "../../engine.h" @@ -249,6 +250,20 @@ EngineID AiNew_PickVehicle(Player *p) } +void CcAI(bool success, TileIndex tile, uint32 p1, uint32 p2) +{ + Player* p = GetPlayer(_current_player); + + if (success) { + p->ainew.state = AI_STATE_GIVE_ORDERS; + p->ainew.veh_id = _new_vehicle_id; + } else { + /* XXX this should be handled more gracefully */ + p->ainew.state = AI_STATE_NOTHING; + } +} + + // Builds the best vehicle possible int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag) { @@ -257,7 +272,11 @@ int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag) if (i == INVALID_ENGINE) return CMD_ERROR; if (p->ainew.tbt == AI_TRAIN) return CMD_ERROR; - return AI_DoCommand(tile, i, 0, flag, CMD_BUILD_ROAD_VEH); + if (flag & DC_EXEC) { + return AI_DoCommandCc(tile, i, 0, flag, CMD_BUILD_ROAD_VEH, CcAI); + } else { + return AI_DoCommand(tile, i, 0, flag, CMD_BUILD_ROAD_VEH); + } } int AiNew_Build_Depot(Player* p, TileIndex tile, DiagDirection direction, byte flag) diff --git a/ai/trolly/trolly.c b/ai/trolly/trolly.c index 52cf573e3..b003c21df 100644 --- a/ai/trolly/trolly.c +++ b/ai/trolly/trolly.c @@ -1155,7 +1155,7 @@ static void AiNew_State_BuildVehicle(Player *p) // Decrease the total counter p->ainew.amount_veh--; // Go give some orders! - p->ainew.state = AI_STATE_GIVE_ORDERS; + p->ainew.state = AI_STATE_WAIT_FOR_BUILD; } @@ -1167,18 +1167,6 @@ static void AiNew_State_GiveOrders(Player *p) assert(p->ainew.state == AI_STATE_GIVE_ORDERS); - // Get the new ID - /* XXX -- Because this AI isn't using any event-system, this is VERY dangerous! - * There is no way telling if the vehicle is already bought (or delayed by the - * network), and if bought, if not an other vehicle is bought in between.. in - * other words, there is absolutely no way knowing if this id is the true - * id.. soon this will all change, but for now, we needed something to test - * on ;) -- TrueLight -- 21-11-2005 */ - if (p->ainew.tbt == AI_TRAIN) { - } else { - p->ainew.veh_id = _new_roadveh_id; - } - if (p->ainew.veh_main_id != INVALID_VEHICLE) { AI_DoCommand(0, p->ainew.veh_id + (p->ainew.veh_main_id << 16), 0, DC_EXEC, CMD_CLONE_ORDER); @@ -1323,6 +1311,7 @@ static AiNew_StateFunction* const _ainew_state[] = { AiNew_State_BuildPath, AiNew_State_BuildDepot, AiNew_State_BuildVehicle, + NULL, AiNew_State_GiveOrders, AiNew_State_StartVehicle, AiNew_State_RepayMoney, diff --git a/ai/trolly/trolly.h b/ai/trolly/trolly.h index 3e364a2b5..e0d70fbf6 100644 --- a/ai/trolly/trolly.h +++ b/ai/trolly/trolly.h @@ -187,6 +187,7 @@ enum { AI_STATE_BUILD_PATH, AI_STATE_BUILD_DEPOT, AI_STATE_BUILD_VEHICLE, + AI_STATE_WAIT_FOR_BUILD, AI_STATE_GIVE_ORDERS, AI_STATE_START_VEHICLE, AI_STATE_REPAY_MONEY, diff --git a/callback_table.c b/callback_table.c index 2c9ff3d84..14203a2c3 100644 --- a/callback_table.c +++ b/callback_table.c @@ -53,6 +53,8 @@ CommandCallback CcBuildWagon; CommandCallback CcBuildLoco; CommandCallback CcCloneTrain; +CommandCallback CcAI; + CommandCallback *_callback_table[] = { /* 0x00 */ NULL, /* 0x01 */ CcBuildAircraft, @@ -79,6 +81,7 @@ CommandCallback *_callback_table[] = { /* 0x16 */ CcCloneRoadVeh, /* 0x17 */ CcCloneShip, /* 0x18 */ CcCloneTrain, + /* 0x19 */ CcAI }; const int _callback_table_count = lengthof(_callback_table); -- cgit v1.2.3-70-g09d2