1
0
Fork 0

(svn r5108) - Backport from trunk (r5092):

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
release/0.4
Darkvater 2006-06-04 22:02:51 +00:00
parent 4f27e53d17
commit 590cd1d07b
6 changed files with 42 additions and 20 deletions

18
ai/ai.c
View File

@ -32,7 +32,7 @@ static void AI_DequeueCommands(byte player)
/* Copy the DP back in place */ /* Copy the DP back in place */
_cmd_text = com->text; _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 */ /* Free item */
entry_com = com->next; entry_com = com->next;
@ -46,7 +46,7 @@ static void AI_DequeueCommands(byte player)
* Needed for SP; we need to delay DoCommand with 1 tick, because else events * Needed for SP; we need to delay DoCommand with 1 tick, because else events
* will make infinite loops (AIScript). * will make infinite loops (AIScript).
*/ */
static void AI_PutCommandInQueue(byte player, uint 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; AICommand *com;
@ -68,6 +68,7 @@ static void AI_PutCommandInQueue(byte player, uint tile, uint32 p1, uint32 p2, u
com->p1 = p1; com->p1 = p1;
com->p2 = p2; com->p2 = p2;
com->procc = procc; com->procc = procc;
com->callback = callback;
com->next = NULL; com->next = NULL;
com->text = NULL; com->text = NULL;
@ -81,7 +82,7 @@ static void AI_PutCommandInQueue(byte player, uint tile, uint32 p1, uint32 p2, u
/** /**
* Executes a raw DoCommand for the AI. * Executes a raw DoCommand for the AI.
*/ */
int32 AI_DoCommand(uint 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; PlayerID old_lp;
int32 res = 0; int32 res = 0;
@ -122,12 +123,12 @@ int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
/* Send the command */ /* Send the command */
if (_networking) if (_networking)
/* Network is easy, send it to his handler */ /* Network is easy, send it to his handler */
NetworkSend_Command(tile, p1, p2, procc, NULL); NetworkSend_Command(tile, p1, p2, procc, callback);
else else
#endif #endif
/* If we execute BuildCommands directly in SP, we have a big problem with events /* If we execute BuildCommands directly in SP, we have a big problem with events
* so we need to delay is for 1 tick */ * 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 */ /* Set _local_player back */
_local_player = old_lp; _local_player = old_lp;
@ -139,6 +140,13 @@ int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
return res; 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. * Run 1 tick of the AI. Don't overdo it, keep it realistic.
*/ */

View File

@ -11,6 +11,7 @@ typedef struct AICommand {
uint32 p1; uint32 p1;
uint32 p2; uint32 p2;
uint32 procc; uint32 procc;
CommandCallback* callback;
char *text; char *text;
uint uid; uint uid;
@ -45,7 +46,8 @@ void AI_PlayerDied(PlayerID player);
void AI_RunGameLoop(void); void AI_RunGameLoop(void);
void AI_Initialize(void); void AI_Initialize(void);
void AI_Uninitialize(void); void AI_Uninitialize(void);
int32 AI_DoCommand(uint tile, uint32 p1, uint32 p2, uint32 flags, uint procc); 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. /** Is it allowed to start a new AI.
* This function checks some boundries to see if we should launch a new AI. * This function checks some boundries to see if we should launch a new AI.

View File

@ -6,6 +6,7 @@
#include "../../functions.h" #include "../../functions.h"
#include "../../map.h" #include "../../map.h"
#include "../../tile.h" #include "../../tile.h"
#include "../../vehicle.h"
#include "../../command.h" #include "../../command.h"
#include "trolly.h" #include "trolly.h"
#include "../../engine.h" #include "../../engine.h"
@ -245,6 +246,20 @@ int 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 // Builds the best vehicle possible
int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag) int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
{ {
@ -253,7 +268,11 @@ int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
if (p->ainew.tbt == AI_TRAIN) 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, byte direction, byte flag) int AiNew_Build_Depot(Player *p, TileIndex tile, byte direction, byte flag)

View File

@ -1162,7 +1162,7 @@ static void AiNew_State_BuildVehicle(Player *p)
// Decrease the total counter // Decrease the total counter
p->ainew.amount_veh--; p->ainew.amount_veh--;
// Go give some orders! // Go give some orders!
p->ainew.state = AI_STATE_GIVE_ORDERS; p->ainew.state = AI_STATE_WAIT_FOR_BUILD;
} }
@ -1174,18 +1174,6 @@ static void AiNew_State_GiveOrders(Player *p)
assert(p->ainew.state == AI_STATE_GIVE_ORDERS); 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 != (VehicleID)-1) { if (p->ainew.veh_main_id != (VehicleID)-1) {
AI_DoCommand(0, p->ainew.veh_id + (p->ainew.veh_main_id << 16), 0, DC_EXEC, CMD_CLONE_ORDER); AI_DoCommand(0, p->ainew.veh_id + (p->ainew.veh_main_id << 16), 0, DC_EXEC, CMD_CLONE_ORDER);
@ -1330,6 +1318,7 @@ static AiNew_StateFunction* const _ainew_state[] = {
AiNew_State_BuildPath, AiNew_State_BuildPath,
AiNew_State_BuildDepot, AiNew_State_BuildDepot,
AiNew_State_BuildVehicle, AiNew_State_BuildVehicle,
NULL,
AiNew_State_GiveOrders, AiNew_State_GiveOrders,
AiNew_State_StartVehicle, AiNew_State_StartVehicle,
AiNew_State_RepayMoney, AiNew_State_RepayMoney,

View File

@ -187,6 +187,7 @@ enum {
AI_STATE_BUILD_PATH, AI_STATE_BUILD_PATH,
AI_STATE_BUILD_DEPOT, AI_STATE_BUILD_DEPOT,
AI_STATE_BUILD_VEHICLE, AI_STATE_BUILD_VEHICLE,
AI_STATE_WAIT_FOR_BUILD,
AI_STATE_GIVE_ORDERS, AI_STATE_GIVE_ORDERS,
AI_STATE_START_VEHICLE, AI_STATE_START_VEHICLE,
AI_STATE_REPAY_MONEY, AI_STATE_REPAY_MONEY,

View File

@ -53,6 +53,8 @@ CommandCallback CcBuildWagon;
CommandCallback CcBuildLoco; CommandCallback CcBuildLoco;
CommandCallback CcCloneTrain; CommandCallback CcCloneTrain;
CommandCallback CcAI;
CommandCallback *_callback_table[] = { CommandCallback *_callback_table[] = {
/* 0x00 */ NULL, /* 0x00 */ NULL,
/* 0x01 */ CcBuildAircraft, /* 0x01 */ CcBuildAircraft,
@ -79,6 +81,7 @@ CommandCallback *_callback_table[] = {
/* 0x16 */ CcCloneRoadVeh, /* 0x16 */ CcCloneRoadVeh,
/* 0x17 */ CcCloneShip, /* 0x17 */ CcCloneShip,
/* 0x18 */ CcCloneTrain, /* 0x18 */ CcCloneTrain,
/* 0x19 */ CcAI
}; };
const int _callback_table_count = lengthof(_callback_table); const int _callback_table_count = lengthof(_callback_table);