ai_object.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../../stdafx.h"
00013 #include <squirrel.h>
00014 #include "../../script/squirrel.hpp"
00015 #include "../../company_base.h"
00016
00017 #include "table/strings.h"
00018 #include "../ai.hpp"
00019 #include "../ai_storage.hpp"
00020 #include "../ai_instance.hpp"
00021 #include "ai_error.hpp"
00022
00023 static AIStorage *GetStorage()
00024 {
00025 return AIInstance::GetStorage();
00026 }
00027
00028 void AIObject::SetDoCommandDelay(uint ticks)
00029 {
00030 assert(ticks > 0);
00031 GetStorage()->delay = ticks;
00032 }
00033
00034 uint AIObject::GetDoCommandDelay()
00035 {
00036 return GetStorage()->delay;
00037 }
00038
00039 void AIObject::SetDoCommandMode(AIModeProc *proc, AIObject *instance)
00040 {
00041 GetStorage()->mode = proc;
00042 GetStorage()->mode_instance = instance;
00043 }
00044
00045 AIModeProc *AIObject::GetDoCommandMode()
00046 {
00047 return GetStorage()->mode;
00048 }
00049
00050 AIObject *AIObject::GetDoCommandModeInstance()
00051 {
00052 return GetStorage()->mode_instance;
00053 }
00054
00055 void AIObject::SetDoCommandCosts(Money value)
00056 {
00057 GetStorage()->costs = CommandCost(value);
00058 }
00059
00060 void AIObject::IncreaseDoCommandCosts(Money value)
00061 {
00062 GetStorage()->costs.AddCost(value);
00063 }
00064
00065 Money AIObject::GetDoCommandCosts()
00066 {
00067 return GetStorage()->costs.GetCost();
00068 }
00069
00070 void AIObject::SetLastError(AIErrorType last_error)
00071 {
00072 GetStorage()->last_error = last_error;
00073 }
00074
00075 AIErrorType AIObject::GetLastError()
00076 {
00077 return GetStorage()->last_error;
00078 }
00079
00080 void AIObject::SetLastCost(Money last_cost)
00081 {
00082 GetStorage()->last_cost = last_cost;
00083 }
00084
00085 Money AIObject::GetLastCost()
00086 {
00087 return GetStorage()->last_cost;
00088 }
00089
00090 void AIObject::SetRoadType(RoadType road_type)
00091 {
00092 GetStorage()->road_type = road_type;
00093 }
00094
00095 RoadType AIObject::GetRoadType()
00096 {
00097 return GetStorage()->road_type;
00098 }
00099
00100 void AIObject::SetRailType(RailType rail_type)
00101 {
00102 GetStorage()->rail_type = rail_type;
00103 }
00104
00105 RailType AIObject::GetRailType()
00106 {
00107 return GetStorage()->rail_type;
00108 }
00109
00110 void AIObject::SetLastCommandRes(bool res)
00111 {
00112 GetStorage()->last_command_res = res;
00113
00114 SetNewVehicleID(_new_vehicle_id);
00115 SetNewSignID(_new_sign_id);
00116 SetNewTunnelEndtile(_build_tunnel_endtile);
00117 SetNewGroupID(_new_group_id);
00118 }
00119
00120 bool AIObject::GetLastCommandRes()
00121 {
00122 return GetStorage()->last_command_res;
00123 }
00124
00125 void AIObject::SetNewVehicleID(VehicleID vehicle_id)
00126 {
00127 GetStorage()->new_vehicle_id = vehicle_id;
00128 }
00129
00130 VehicleID AIObject::GetNewVehicleID()
00131 {
00132 return GetStorage()->new_vehicle_id;
00133 }
00134
00135 void AIObject::SetNewSignID(SignID sign_id)
00136 {
00137 GetStorage()->new_sign_id = sign_id;
00138 }
00139
00140 SignID AIObject::GetNewSignID()
00141 {
00142 return GetStorage()->new_sign_id;
00143 }
00144
00145 void AIObject::SetNewTunnelEndtile(TileIndex tile)
00146 {
00147 GetStorage()->new_tunnel_endtile = tile;
00148 }
00149
00150 TileIndex AIObject::GetNewTunnelEndtile()
00151 {
00152 return GetStorage()->new_tunnel_endtile;
00153 }
00154
00155 void AIObject::SetNewGroupID(GroupID group_id)
00156 {
00157 GetStorage()->new_group_id = group_id;
00158 }
00159
00160 GroupID AIObject::GetNewGroupID()
00161 {
00162 return GetStorage()->new_group_id;
00163 }
00164
00165 void AIObject::SetAllowDoCommand(bool allow)
00166 {
00167 GetStorage()->allow_do_command = allow;
00168 }
00169
00170 bool AIObject::GetAllowDoCommand()
00171 {
00172 return GetStorage()->allow_do_command;
00173 }
00174
00175 bool AIObject::CanSuspend()
00176 {
00177 Squirrel *squirrel = Company::Get(_current_company)->ai_instance->engine;
00178 return GetStorage()->allow_do_command && squirrel->CanSuspend();
00179 }
00180
00181 void *&AIObject::GetEventPointer()
00182 {
00183 return GetStorage()->event_data;
00184 }
00185
00186 void *&AIObject::GetLogPointer()
00187 {
00188 return GetStorage()->log_data;
00189 }
00190
00191 void AIObject::SetCallbackVariable(int index, int value)
00192 {
00193 if ((size_t)index >= GetStorage()->callback_value.size()) GetStorage()->callback_value.resize(index + 1);
00194 GetStorage()->callback_value[index] = value;
00195 }
00196
00197 int AIObject::GetCallbackVariable(int index)
00198 {
00199 return GetStorage()->callback_value[index];
00200 }
00201
00202 bool AIObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text, AISuspendCallbackProc *callback)
00203 {
00204 if (!AIObject::CanSuspend()) {
00205 throw AI_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator.");
00206 }
00207
00208 CommandCost res;
00209
00210
00211 if (callback == NULL) callback = &AIInstance::DoCommandReturn;
00212
00213
00214 SetLastError(AIError::ERR_NONE);
00215
00216
00217 res = ::DoCommand(tile, p1, p2, CommandFlagsToDCFlags(GetCommandFlags(cmd)), cmd, text);
00218
00219 if (::CmdFailed(res)) {
00220 SetLastError(AIError::StringToError(_error_message));
00221 return false;
00222 }
00223
00224
00225 if (GetDoCommandMode() != NULL && !GetDoCommandMode()(tile, p1, p2, cmd, res)) {
00226 IncreaseDoCommandCosts(res.GetCost());
00227 return true;
00228 }
00229
00230 #ifdef ENABLE_NETWORK
00231
00232 if (_networking) {
00233
00234
00235 CompanyID old_company = _local_company;
00236 _local_company = _current_company;
00237 ::NetworkSend_Command(tile, p1, p2, cmd, CcAI, text);
00238 _local_company = old_company;
00239 SetLastCost(res.GetCost());
00240
00241
00242 throw AI_VMSuspend(-(int)GetDoCommandDelay(), callback);
00243 } else {
00244 #else
00245 {
00246 #endif
00247
00248 if (!::DoCommandP(tile, p1, p2, cmd, NULL, text)) res = CMD_ERROR;
00249 SetLastCommandRes(!::CmdFailed(res));
00250
00251 if (::CmdFailed(res)) {
00252 SetLastError(AIError::StringToError(_error_message));
00253 return false;
00254 }
00255 SetLastCost(res.GetCost());
00256 IncreaseDoCommandCosts(res.GetCost());
00257
00258
00259
00260
00261
00262 throw AI_VMSuspend(GetDoCommandDelay(), callback);
00263 }
00264
00265 NOT_REACHED();
00266 }