ai_object.cpp

Go to the documentation of this file.
00001 /* $Id: ai_object.cpp 18866 2010-01-18 22:57:21Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "../../stdafx.h"
00013 #include <squirrel.h>
00014 #include "../../script/squirrel.hpp"
00015 #include "../../company_base.h"
00016 
00017 #include "../ai_storage.hpp"
00018 #include "../ai_instance.hpp"
00019 #include "ai_error.hpp"
00020 
00021 static AIStorage *GetStorage()
00022 {
00023   return AIInstance::GetStorage();
00024 }
00025 
00026 void AIObject::SetDoCommandDelay(uint ticks)
00027 {
00028   assert(ticks > 0);
00029   GetStorage()->delay = ticks;
00030 }
00031 
00032 uint AIObject::GetDoCommandDelay()
00033 {
00034   return GetStorage()->delay;
00035 }
00036 
00037 void AIObject::SetDoCommandMode(AIModeProc *proc, AIObject *instance)
00038 {
00039   GetStorage()->mode = proc;
00040   GetStorage()->mode_instance = instance;
00041 }
00042 
00043 AIModeProc *AIObject::GetDoCommandMode()
00044 {
00045   return GetStorage()->mode;
00046 }
00047 
00048 AIObject *AIObject::GetDoCommandModeInstance()
00049 {
00050   return GetStorage()->mode_instance;
00051 }
00052 
00053 void AIObject::SetDoCommandCosts(Money value)
00054 {
00055   GetStorage()->costs = CommandCost(value);
00056 }
00057 
00058 void AIObject::IncreaseDoCommandCosts(Money value)
00059 {
00060   GetStorage()->costs.AddCost(value);
00061 }
00062 
00063 Money AIObject::GetDoCommandCosts()
00064 {
00065   return GetStorage()->costs.GetCost();
00066 }
00067 
00068 void AIObject::SetLastError(AIErrorType last_error)
00069 {
00070   GetStorage()->last_error = last_error;
00071 }
00072 
00073 AIErrorType AIObject::GetLastError()
00074 {
00075   return GetStorage()->last_error;
00076 }
00077 
00078 void AIObject::SetLastCost(Money last_cost)
00079 {
00080   GetStorage()->last_cost = last_cost;
00081 }
00082 
00083 Money AIObject::GetLastCost()
00084 {
00085   return GetStorage()->last_cost;
00086 }
00087 
00088 void AIObject::SetRoadType(RoadType road_type)
00089 {
00090   GetStorage()->road_type = road_type;
00091 }
00092 
00093 RoadType AIObject::GetRoadType()
00094 {
00095   return GetStorage()->road_type;
00096 }
00097 
00098 void AIObject::SetRailType(RailType rail_type)
00099 {
00100   GetStorage()->rail_type = rail_type;
00101 }
00102 
00103 RailType AIObject::GetRailType()
00104 {
00105   return GetStorage()->rail_type;
00106 }
00107 
00108 void AIObject::SetLastCommandRes(bool res)
00109 {
00110   GetStorage()->last_command_res = res;
00111   /* Also store the results of various global variables */
00112   SetNewVehicleID(_new_vehicle_id);
00113   SetNewSignID(_new_sign_id);
00114   SetNewTunnelEndtile(_build_tunnel_endtile);
00115   SetNewGroupID(_new_group_id);
00116 }
00117 
00118 bool AIObject::GetLastCommandRes()
00119 {
00120   return GetStorage()->last_command_res;
00121 }
00122 
00123 void AIObject::SetNewVehicleID(VehicleID vehicle_id)
00124 {
00125   GetStorage()->new_vehicle_id = vehicle_id;
00126 }
00127 
00128 VehicleID AIObject::GetNewVehicleID()
00129 {
00130   return GetStorage()->new_vehicle_id;
00131 }
00132 
00133 void AIObject::SetNewSignID(SignID sign_id)
00134 {
00135   GetStorage()->new_sign_id = sign_id;
00136 }
00137 
00138 SignID AIObject::GetNewSignID()
00139 {
00140   return GetStorage()->new_sign_id;
00141 }
00142 
00143 void AIObject::SetNewTunnelEndtile(TileIndex tile)
00144 {
00145   GetStorage()->new_tunnel_endtile = tile;
00146 }
00147 
00148 TileIndex AIObject::GetNewTunnelEndtile()
00149 {
00150   return GetStorage()->new_tunnel_endtile;
00151 }
00152 
00153 void AIObject::SetNewGroupID(GroupID group_id)
00154 {
00155   GetStorage()->new_group_id = group_id;
00156 }
00157 
00158 GroupID AIObject::GetNewGroupID()
00159 {
00160   return GetStorage()->new_group_id;
00161 }
00162 
00163 void AIObject::SetAllowDoCommand(bool allow)
00164 {
00165   GetStorage()->allow_do_command = allow;
00166 }
00167 
00168 bool AIObject::GetAllowDoCommand()
00169 {
00170   return GetStorage()->allow_do_command;
00171 }
00172 
00173 bool AIObject::CanSuspend()
00174 {
00175   Squirrel *squirrel = Company::Get(_current_company)->ai_instance->engine;
00176   return GetStorage()->allow_do_command && squirrel->CanSuspend();
00177 }
00178 
00179 void *&AIObject::GetEventPointer()
00180 {
00181   return GetStorage()->event_data;
00182 }
00183 
00184 void *&AIObject::GetLogPointer()
00185 {
00186   return GetStorage()->log_data;
00187 }
00188 
00189 void AIObject::SetCallbackVariable(int index, int value)
00190 {
00191   if ((size_t)index >= GetStorage()->callback_value.size()) GetStorage()->callback_value.resize(index + 1);
00192   GetStorage()->callback_value[index] = value;
00193 }
00194 
00195 int AIObject::GetCallbackVariable(int index)
00196 {
00197   return GetStorage()->callback_value[index];
00198 }
00199 
00200 bool AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text, AISuspendCallbackProc *callback)
00201 {
00202   if (!AIObject::CanSuspend()) {
00203     throw AI_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
00204   }
00205 
00206   /* Set the default callback to return a true/false result of the DoCommand */
00207   if (callback == NULL) callback = &AIInstance::DoCommandReturn;
00208 
00209   /* Are we only interested in the estimate costs? */
00210   bool estimate_only = GetDoCommandMode() != NULL && !GetDoCommandMode()();
00211 
00212   /* Try to perform the command. */
00213   CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, _networking ? CcAI : NULL, text, false, estimate_only);
00214 
00215   /* We failed; set the error and bail out */
00216   if (res.Failed()) {
00217     res.SetGlobalErrorMessage();
00218     SetLastError(AIError::StringToError(_error_message));
00219     return false;
00220   }
00221 
00222   /* No error, then clear it. */
00223   SetLastError(AIError::ERR_NONE);
00224 
00225   /* Estimates, update the cost for the estimate and be done */
00226   if (estimate_only) {
00227     IncreaseDoCommandCosts(res.GetCost());
00228     return true;
00229   }
00230 
00231   /* Costs of this operation. */
00232   SetLastCost(res.GetCost());
00233   SetLastCommandRes(true);
00234 
00235   if (_networking) {
00236     /* Suspend the AI till the command is really executed. */
00237     throw AI_VMSuspend(-(int)GetDoCommandDelay(), callback);
00238   } else {
00239     IncreaseDoCommandCosts(res.GetCost());
00240 
00241     /* Suspend the AI player for 1+ ticks, so it simulates multiplayer. This
00242      *  both avoids confusion when a developer launched his AI in a
00243      *  multiplayer game, but also gives time for the GUI and human player
00244      *  to interact with the game. */
00245     throw AI_VMSuspend(GetDoCommandDelay(), callback);
00246   }
00247 
00248   NOT_REACHED();
00249 }

Generated on Sat Jul 31 21:37:44 2010 for OpenTTD by  doxygen 1.6.1