diff -r 8b688e6517d0 -r d675836e865c src/ai/api/ai_object.cpp --- a/src/ai/api/ai_object.cpp Sun Mar 18 14:23:26 2007 +0000 +++ b/src/ai/api/ai_object.cpp Sun Mar 18 16:02:23 2007 +0000 @@ -8,6 +8,27 @@ #include "../ai.h" #include "../ai_threads.h" +void AIObject::SetDoCommandDelay(uint ticks) +{ + assert(ticks > 0); + AIObject::GetDoCommandStruct(_current_player)->delay = ticks; +} + +uint AIObject::GetDoCommandDelay() +{ + return AIObject::GetDoCommandStruct(_current_player)->delay; +} + +void AIObject::SetDoCommandMode(AIModeProc *proc) +{ + AIObject::GetDoCommandStruct(_current_player)->mode = proc; +} + +AIModeProc *AIObject::GetDoCommandMode() +{ + return AIObject::GetDoCommandStruct(_current_player)->mode; +} + bool AIObject::CmdFailed(int32 res) { return ::CmdFailed(res); @@ -18,6 +39,24 @@ return !::CmdFailed(res); } +AIObject::AIDoCommandStruct *AIObject::GetDoCommandStruct(PlayerID player) +{ + static bool initialized = false; + /* Storage for data on per-AI level */ + static AIObject::AIDoCommandStruct command_struct[MAX_PLAYERS]; + + if (!initialized) { + initialized = true; + /* Set default values */ + for (int i = 0; i < MAX_PLAYERS; i++) { + command_struct[i].mode = NULL; + command_struct[i].delay = 1; + } + } + + return &command_struct[player]; +} + int32 AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc) { PlayerID old_lp; @@ -29,8 +68,11 @@ /* First, do a test-run to see if we can do this */ res = ::DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc); - /* The command failed, or you didn't want to execute, or you are quering, return */ - if (this->CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) return res; + /* The command failed, so return */ + if (this->CmdFailed(res)) return res; + + /* Check what the callback wants us to do */ + if (this->GetDoCommandMode() != NULL && !this->GetDoCommandMode()(tile, p1, p2, flags, procc)) return res; /* Restore _cmd_text */ _cmd_text = tmp_cmdtext; @@ -51,7 +93,7 @@ _local_player = old_lp; /* Suspend the AI till the command is really executed */ - AI_SuspendPlayer(_current_player, -1); + AI_SuspendPlayer(_current_player, -this->GetDoCommandDelay()); /* Check if the callback still agrees with us, else return error */ if (!AI_GetCallbackResult(_current_player)) res = CMD_ERROR; } else { @@ -61,7 +103,7 @@ /* For SinglePlayer we execute the command immediatly */ ::DoCommandP(tile, p1, p2, NULL, procc); /* Suspend the AI player for 1 tick, so it simulates MultiPlayer */ - AI_SuspendPlayer(_current_player, 1); + AI_SuspendPlayer(_current_player, this->GetDoCommandDelay()); } return res;