src/ai/api/ai_object.cpp
branchnoai
changeset 9450 d675836e865c
parent 9444 fd27df7ca2a0
child 9452 4c5eedbc3ba9
equal deleted inserted replaced
9449:8b688e6517d0 9450:d675836e865c
     6 #include "../../command.h"
     6 #include "../../command.h"
     7 #include "../../player.h"
     7 #include "../../player.h"
     8 #include "../ai.h"
     8 #include "../ai.h"
     9 #include "../ai_threads.h"
     9 #include "../ai_threads.h"
    10 
    10 
       
    11 void AIObject::SetDoCommandDelay(uint ticks)
       
    12 {
       
    13 	assert(ticks > 0);
       
    14 	AIObject::GetDoCommandStruct(_current_player)->delay = ticks;
       
    15 }
       
    16 
       
    17 uint AIObject::GetDoCommandDelay()
       
    18 {
       
    19 	return AIObject::GetDoCommandStruct(_current_player)->delay;
       
    20 }
       
    21 
       
    22 void AIObject::SetDoCommandMode(AIModeProc *proc)
       
    23 {
       
    24 	AIObject::GetDoCommandStruct(_current_player)->mode = proc;
       
    25 }
       
    26 
       
    27 AIModeProc *AIObject::GetDoCommandMode()
       
    28 {
       
    29 	return AIObject::GetDoCommandStruct(_current_player)->mode;
       
    30 }
       
    31 
    11 bool AIObject::CmdFailed(int32 res)
    32 bool AIObject::CmdFailed(int32 res)
    12 {
    33 {
    13 	return ::CmdFailed(res);
    34 	return ::CmdFailed(res);
    14 }
    35 }
    15 
    36 
    16 bool AIObject::CmdSucceeded(int32 res)
    37 bool AIObject::CmdSucceeded(int32 res)
    17 {
    38 {
    18 	return !::CmdFailed(res);
    39 	return !::CmdFailed(res);
       
    40 }
       
    41 
       
    42 AIObject::AIDoCommandStruct *AIObject::GetDoCommandStruct(PlayerID player)
       
    43 {
       
    44 	static bool initialized = false;
       
    45 	/* Storage for data on per-AI level */
       
    46 	static AIObject::AIDoCommandStruct command_struct[MAX_PLAYERS];
       
    47 
       
    48 	if (!initialized) {
       
    49 		initialized = true;
       
    50 		/* Set default values */
       
    51 		for (int i = 0; i < MAX_PLAYERS; i++) {
       
    52 			command_struct[i].mode = NULL;
       
    53 			command_struct[i].delay = 1;
       
    54 		}
       
    55 	}
       
    56 
       
    57 	return &command_struct[player];
    19 }
    58 }
    20 
    59 
    21 int32 AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
    60 int32 AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
    22 {
    61 {
    23 	PlayerID old_lp;
    62 	PlayerID old_lp;
    27 	/* The test already resets _cmd_text, so backup the pointer */
    66 	/* The test already resets _cmd_text, so backup the pointer */
    28 	tmp_cmdtext = _cmd_text;
    67 	tmp_cmdtext = _cmd_text;
    29 
    68 
    30 	/* First, do a test-run to see if we can do this */
    69 	/* First, do a test-run to see if we can do this */
    31 	res = ::DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
    70 	res = ::DoCommand(tile, p1, p2, flags & ~DC_EXEC, procc);
    32 	/* The command failed, or you didn't want to execute, or you are quering, return */
    71 	/* The command failed, so return */
    33 	if (this->CmdFailed(res) || !(flags & DC_EXEC) || (flags & DC_QUERY_COST)) return res;
    72 	if (this->CmdFailed(res)) return res;
       
    73 
       
    74 	/* Check what the callback wants us to do */
       
    75 	if (this->GetDoCommandMode() != NULL && !this->GetDoCommandMode()(tile, p1, p2, flags, procc)) return res;
    34 
    76 
    35 	/* Restore _cmd_text */
    77 	/* Restore _cmd_text */
    36 	_cmd_text = tmp_cmdtext;
    78 	_cmd_text = tmp_cmdtext;
    37 
    79 
    38 	/* If we did a DC_EXEC, and the command did not return an error, execute it
    80 	/* If we did a DC_EXEC, and the command did not return an error, execute it
    49 		_local_player = _current_player;
    91 		_local_player = _current_player;
    50 		::NetworkSend_Command(tile, p1, p2, procc, CcAI);
    92 		::NetworkSend_Command(tile, p1, p2, procc, CcAI);
    51 		_local_player = old_lp;
    93 		_local_player = old_lp;
    52 
    94 
    53 		/* Suspend the AI till the command is really executed */
    95 		/* Suspend the AI till the command is really executed */
    54 		AI_SuspendPlayer(_current_player, -1);
    96 		AI_SuspendPlayer(_current_player, -this->GetDoCommandDelay());
    55 		/* Check if the callback still agrees with us, else return error */
    97 		/* Check if the callback still agrees with us, else return error */
    56 		if (!AI_GetCallbackResult(_current_player)) res = CMD_ERROR;
    98 		if (!AI_GetCallbackResult(_current_player)) res = CMD_ERROR;
    57 	} else {
    99 	} else {
    58 #else
   100 #else
    59 	{
   101 	{
    60 #endif
   102 #endif
    61 		/* For SinglePlayer we execute the command immediatly */
   103 		/* For SinglePlayer we execute the command immediatly */
    62 		::DoCommandP(tile, p1, p2, NULL, procc);
   104 		::DoCommandP(tile, p1, p2, NULL, procc);
    63 		/* Suspend the AI player for 1 tick, so it simulates MultiPlayer */
   105 		/* Suspend the AI player for 1 tick, so it simulates MultiPlayer */
    64 		AI_SuspendPlayer(_current_player, 1);
   106 		AI_SuspendPlayer(_current_player, this->GetDoCommandDelay());
    65 	}
   107 	}
    66 
   108 
    67 	return res;
   109 	return res;
    68 }
   110 }