00001
00002
00005 #include "../stdafx.h"
00006 #include "../debug.h"
00007 #include "../settings_type.h"
00008 #include "../vehicle_base.h"
00009 #include "../saveload/saveload.h"
00010 #include "../gui.h"
00011 #include "table/strings.h"
00012
00013 #include <squirrel.h>
00014 #include "../script/squirrel.hpp"
00015 #include "../script/squirrel_helper.hpp"
00016 #include "../script/squirrel_class.hpp"
00017 #include "../script/squirrel_std.hpp"
00018
00019 #define DEFINE_SCRIPT_FILES
00020
00021 #include "ai_info.hpp"
00022 #include "ai_config.hpp"
00023 #include "ai_storage.hpp"
00024 #include "ai_instance.hpp"
00025 #include "ai_gui.hpp"
00026
00027
00028
00029 #include "api/ai_abstractlist.hpp.sq"
00030 #include "api/ai_accounting.hpp.sq"
00031 #include "api/ai_airport.hpp.sq"
00032 #include "api/ai_base.hpp.sq"
00033 #include "api/ai_bridge.hpp.sq"
00034 #include "api/ai_bridgelist.hpp.sq"
00035 #include "api/ai_cargo.hpp.sq"
00036 #include "api/ai_cargolist.hpp.sq"
00037 #include "api/ai_company.hpp.sq"
00038 #include "api/ai_controller.hpp.sq"
00039 #include "api/ai_date.hpp.sq"
00040 #include "api/ai_depotlist.hpp.sq"
00041 #include "api/ai_engine.hpp.sq"
00042 #include "api/ai_enginelist.hpp.sq"
00043 #include "api/ai_error.hpp.sq"
00044 #include "api/ai_event.hpp.sq"
00045 #include "api/ai_event_types.hpp.sq"
00046 #include "api/ai_execmode.hpp.sq"
00047 #include "api/ai_gamesettings.hpp.sq"
00048 #include "api/ai_group.hpp.sq"
00049 #include "api/ai_grouplist.hpp.sq"
00050 #include "api/ai_industry.hpp.sq"
00051 #include "api/ai_industrylist.hpp.sq"
00052 #include "api/ai_industrytype.hpp.sq"
00053 #include "api/ai_industrytypelist.hpp.sq"
00054 #include "api/ai_list.hpp.sq"
00055 #include "api/ai_log.hpp.sq"
00056 #include "api/ai_map.hpp.sq"
00057 #include "api/ai_marine.hpp.sq"
00058 #include "api/ai_order.hpp.sq"
00059 #include "api/ai_rail.hpp.sq"
00060 #include "api/ai_railtypelist.hpp.sq"
00061 #include "api/ai_road.hpp.sq"
00062 #include "api/ai_sign.hpp.sq"
00063 #include "api/ai_signlist.hpp.sq"
00064 #include "api/ai_station.hpp.sq"
00065 #include "api/ai_stationlist.hpp.sq"
00066 #include "api/ai_subsidy.hpp.sq"
00067 #include "api/ai_subsidylist.hpp.sq"
00068 #include "api/ai_testmode.hpp.sq"
00069 #include "api/ai_tile.hpp.sq"
00070 #include "api/ai_tilelist.hpp.sq"
00071 #include "api/ai_town.hpp.sq"
00072 #include "api/ai_townlist.hpp.sq"
00073 #include "api/ai_tunnel.hpp.sq"
00074 #include "api/ai_vehicle.hpp.sq"
00075 #include "api/ai_vehiclelist.hpp.sq"
00076 #include "api/ai_waypoint.hpp.sq"
00077 #include "api/ai_waypointlist.hpp.sq"
00078
00079 #undef DEFINE_SCRIPT_FILES
00080
00081 AIInstance *AIInstance::current_instance = NULL;
00082
00083 AIStorage::~AIStorage()
00084 {
00085
00086 if (event_data != NULL) AIEventController::FreeEventPointer();
00087 if (log_data != NULL) AILog::FreeLogPointer();
00088 }
00089
00090 static void PrintFunc(bool error_msg, const SQChar *message)
00091 {
00092
00093 AIController::Print(error_msg, FS2OTTD(message));
00094 }
00095
00096 AIInstance::AIInstance(AIInfo *info) :
00097 controller(NULL),
00098 storage(NULL),
00099 engine(NULL),
00100 instance(NULL),
00101 is_started(false),
00102 is_dead(false),
00103 is_save_data_on_stack(false),
00104 suspend(0),
00105 callback(NULL)
00106 {
00107
00108 GetCompany(_current_company)->ai_instance = this;
00109 AIInstance::current_instance = this;
00110
00111 this->controller = new AIController();
00112 this->storage = new AIStorage();
00113 this->engine = new Squirrel();
00114 this->engine->SetPrintFunction(&PrintFunc);
00115
00116
00117 this->engine->AddMethod("import", &AILibrary::Import, 4, ".ssi");
00118
00119
00120 SQAIController_Register(this->engine);
00121
00122
00123 this->RegisterAPI();
00124
00125
00126 const char *main_script = info->GetMainScript();
00127 if (strcmp(main_script, "%_dummy") == 0) {
00128 extern void AI_CreateAIDummy(HSQUIRRELVM vm);
00129 AI_CreateAIDummy(this->engine->GetVM());
00130 } else if (!this->engine->LoadScript(main_script)) {
00131 this->Died();
00132 return;
00133 }
00134
00135
00136 this->instance = MallocT<SQObject>(1);
00137 if (!this->engine->CreateClassInstance(info->GetInstanceName(), this->controller, this->instance)) {
00138 this->Died();
00139 return;
00140 }
00141 }
00142
00143 AIInstance::~AIInstance()
00144 {
00145 if (instance != NULL) this->engine->ReleaseObject(this->instance);
00146 if (engine != NULL) delete this->engine;
00147 delete this->storage;
00148 delete this->controller;
00149 free(this->instance);
00150 }
00151
00152 void AIInstance::RegisterAPI()
00153 {
00154
00155 squirrel_register_std(this->engine);
00156 SQAIAbstractList_Register(this->engine);
00157 SQAIAccounting_Register(this->engine);
00158 SQAIAirport_Register(this->engine);
00159 SQAIBase_Register(this->engine);
00160 SQAIBridge_Register(this->engine);
00161 SQAIBridgeList_Register(this->engine);
00162 SQAIBridgeList_Length_Register(this->engine);
00163 SQAICargo_Register(this->engine);
00164 SQAICargoList_Register(this->engine);
00165 SQAICargoList_IndustryAccepting_Register(this->engine);
00166 SQAICargoList_IndustryProducing_Register(this->engine);
00167 SQAICompany_Register(this->engine);
00168 SQAIDate_Register(this->engine);
00169 SQAIDepotList_Register(this->engine);
00170 SQAIEngine_Register(this->engine);
00171 SQAIEngineList_Register(this->engine);
00172 SQAIError_Register(this->engine);
00173 SQAIEvent_Register(this->engine);
00174 SQAIEventCompanyBankrupt_Register(this->engine);
00175 SQAIEventCompanyInTrouble_Register(this->engine);
00176 SQAIEventCompanyMerger_Register(this->engine);
00177 SQAIEventCompanyNew_Register(this->engine);
00178 SQAIEventController_Register(this->engine);
00179 SQAIEventDisasterZeppelinerCleared_Register(this->engine);
00180 SQAIEventDisasterZeppelinerCrashed_Register(this->engine);
00181 SQAIEventEngineAvailable_Register(this->engine);
00182 SQAIEventEnginePreview_Register(this->engine);
00183 SQAIEventIndustryClose_Register(this->engine);
00184 SQAIEventIndustryOpen_Register(this->engine);
00185 SQAIEventStationFirstVehicle_Register(this->engine);
00186 SQAIEventSubsidyAwarded_Register(this->engine);
00187 SQAIEventSubsidyExpired_Register(this->engine);
00188 SQAIEventSubsidyOffer_Register(this->engine);
00189 SQAIEventSubsidyOfferExpired_Register(this->engine);
00190 SQAIEventVehicleCrashed_Register(this->engine);
00191 SQAIEventVehicleLost_Register(this->engine);
00192 SQAIEventVehicleUnprofitable_Register(this->engine);
00193 SQAIEventVehicleWaitingInDepot_Register(this->engine);
00194 SQAIExecMode_Register(this->engine);
00195 SQAIGameSettings_Register(this->engine);
00196 SQAIGroup_Register(this->engine);
00197 SQAIGroupList_Register(this->engine);
00198 SQAIIndustry_Register(this->engine);
00199 SQAIIndustryList_Register(this->engine);
00200 SQAIIndustryList_CargoAccepting_Register(this->engine);
00201 SQAIIndustryList_CargoProducing_Register(this->engine);
00202 SQAIIndustryType_Register(this->engine);
00203 SQAIIndustryTypeList_Register(this->engine);
00204 SQAIList_Register(this->engine);
00205 SQAILog_Register(this->engine);
00206 SQAIMap_Register(this->engine);
00207 SQAIMarine_Register(this->engine);
00208 SQAIOrder_Register(this->engine);
00209 SQAIRail_Register(this->engine);
00210 SQAIRailTypeList_Register(this->engine);
00211 SQAIRoad_Register(this->engine);
00212 SQAISign_Register(this->engine);
00213 SQAISignList_Register(this->engine);
00214 SQAIStation_Register(this->engine);
00215 SQAIStationList_Register(this->engine);
00216 SQAIStationList_Vehicle_Register(this->engine);
00217 SQAISubsidy_Register(this->engine);
00218 SQAISubsidyList_Register(this->engine);
00219 SQAITestMode_Register(this->engine);
00220 SQAITile_Register(this->engine);
00221 SQAITileList_Register(this->engine);
00222 SQAITileList_IndustryAccepting_Register(this->engine);
00223 SQAITileList_IndustryProducing_Register(this->engine);
00224 SQAITileList_StationType_Register(this->engine);
00225 SQAITown_Register(this->engine);
00226 SQAITownList_Register(this->engine);
00227 SQAITunnel_Register(this->engine);
00228 SQAIVehicle_Register(this->engine);
00229 SQAIVehicleList_Register(this->engine);
00230 SQAIVehicleList_DefaultGroup_Register(this->engine);
00231 SQAIVehicleList_Group_Register(this->engine);
00232 SQAIVehicleList_SharedOrders_Register(this->engine);
00233 SQAIVehicleList_Station_Register(this->engine);
00234 SQAIWaypoint_Register(this->engine);
00235 SQAIWaypointList_Register(this->engine);
00236 SQAIWaypointList_Vehicle_Register(this->engine);
00237
00238 this->engine->SetGlobalPointer(this->engine);
00239 }
00240
00241 void AIInstance::Continue()
00242 {
00243 assert(this->suspend < 0);
00244 this->suspend = -this->suspend - 1;
00245 }
00246
00247 void AIInstance::Died()
00248 {
00249 DEBUG(ai, 0, "The AI died unexpectedly.");
00250 this->is_dead = true;
00251
00252 if (this->instance != NULL) this->engine->ReleaseObject(this->instance);
00253 delete this->engine;
00254 this->instance = NULL;
00255 this->engine = NULL;
00256
00257 ShowAIDebugWindow(_current_company);
00258
00259 const AIInfo *info = AIConfig::GetConfig(_current_company)->GetInfo();
00260 if (info != NULL) {
00261 ShowErrorMessage(INVALID_STRING_ID, STR_AI_PLEASE_REPORT_CRASH, 0, 0);
00262
00263 if (info->GetURL() != NULL) {
00264 AILog::Info("Please report the error to the following URL:");
00265 AILog::Info(info->GetURL());
00266 }
00267 }
00268 }
00269
00270 void AIInstance::GameLoop()
00271 {
00272 if (this->IsDead()) return;
00273 if (this->engine->HasScriptCrashed()) {
00274
00275 this->Died();
00276 return;
00277 }
00278 this->controller->ticks++;
00279
00280 if (this->suspend < -1) this->suspend++;
00281 if (this->suspend < 0) return;
00282 if (--this->suspend > 0) return;
00283
00284
00285 if (this->callback != NULL) {
00286 if (this->is_save_data_on_stack) {
00287 sq_poptop(this->engine->GetVM());
00288 this->is_save_data_on_stack = false;
00289 }
00290 try {
00291 this->callback(this);
00292 } catch (AI_VMSuspend e) {
00293 this->suspend = e.GetSuspendTime();
00294 this->callback = e.GetSuspendCallback();
00295
00296 return;
00297 }
00298 }
00299
00300 this->suspend = 0;
00301 this->callback = NULL;
00302
00303 if (!this->is_started) {
00304 try {
00305 AIObject::SetAllowDoCommand(false);
00306
00307 if (this->engine->MethodExists(*this->instance, "constructor")) {
00308 if (!this->engine->CallMethod(*this->instance, "constructor", 100000) || this->engine->IsSuspended()) {
00309 if (this->engine->IsSuspended()) AILog::Error("This AI took too long to initialize. AI is not started.");
00310 this->Died();
00311 return;
00312 }
00313 }
00314 if (!this->CallLoad() || this->engine->IsSuspended()) {
00315 if (this->engine->IsSuspended()) AILog::Error("This AI took too long in the Load function. AI is not started.");
00316 this->Died();
00317 return;
00318 }
00319 AIObject::SetAllowDoCommand(true);
00320
00321 if (!this->engine->CallMethod(*this->instance, "Start", _settings_game.ai.ai_max_opcode_till_suspend) || !this->engine->IsSuspended()) this->Died();
00322 } catch (AI_VMSuspend e) {
00323 this->suspend = e.GetSuspendTime();
00324 this->callback = e.GetSuspendCallback();
00325 } catch (AI_FatalError e) {
00326 this->is_dead = true;
00327 this->engine->ThrowError(e.GetErrorMessage());
00328 this->engine->ResumeError();
00329 this->Died();
00330 }
00331
00332 this->is_started = true;
00333 return;
00334 }
00335 if (this->is_save_data_on_stack) {
00336 sq_poptop(this->engine->GetVM());
00337 this->is_save_data_on_stack = false;
00338 }
00339
00340
00341 try {
00342 if (!this->engine->Resume(_settings_game.ai.ai_max_opcode_till_suspend)) this->Died();
00343 } catch (AI_VMSuspend e) {
00344 this->suspend = e.GetSuspendTime();
00345 this->callback = e.GetSuspendCallback();
00346 } catch (AI_FatalError e) {
00347 this->is_dead = true;
00348 this->engine->ThrowError(e.GetErrorMessage());
00349 this->engine->ResumeError();
00350 this->Died();
00351 }
00352 }
00353
00354 void AIInstance::CollectGarbage()
00355 {
00356 if (this->is_started && !this->IsDead()) this->engine->CollectGarbage();
00357 }
00358
00359 void AIInstance::DoCommandReturn(AIInstance *instance)
00360 {
00361 instance->engine->InsertResult(AIObject::GetLastCommandRes());
00362 }
00363
00364 void AIInstance::DoCommandReturnVehicleID(AIInstance *instance)
00365 {
00366 instance->engine->InsertResult(AIObject::GetNewVehicleID());
00367 }
00368
00369 void AIInstance::DoCommandReturnSignID(AIInstance *instance)
00370 {
00371 instance->engine->InsertResult(AIObject::GetNewSignID());
00372 }
00373
00374 void AIInstance::DoCommandReturnGroupID(AIInstance *instance)
00375 {
00376 instance->engine->InsertResult(AIObject::GetNewGroupID());
00377 }
00378
00379 AIStorage *AIInstance::GetStorage()
00380 {
00381 assert(IsValidCompanyID(_current_company) && !IsHumanCompany(_current_company));
00382 return GetCompany(_current_company)->ai_instance->storage;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00407 enum SQSaveLoadType {
00408 SQSL_INT = 0x00,
00409 SQSL_STRING = 0x01,
00410 SQSL_ARRAY = 0x02,
00411 SQSL_TABLE = 0x03,
00412 SQSL_BOOL = 0x04,
00413 SQSL_NULL = 0x05,
00414 SQSL_ARRAY_TABLE_END = 0xFF,
00415 };
00416
00417 static byte _ai_sl_byte;
00418
00419 static const SaveLoad _ai_byte[] = {
00420 SLEG_VAR(_ai_sl_byte, SLE_UINT8),
00421 SLE_END()
00422 };
00423
00424 enum {
00425 AISAVE_MAX_DEPTH = 25,
00426 };
00427
00428 bool AIInstance::SaveObject(HSQUIRRELVM vm, SQInteger index, int max_depth, bool test)
00429 {
00430 if (max_depth == 0) {
00431 AILog::Error("Savedata can only be nested to 25 deep. No data saved.");
00432 return false;
00433 }
00434
00435 switch (sq_gettype(vm, index)) {
00436 case OT_INTEGER: {
00437 if (!test) {
00438 _ai_sl_byte = SQSL_INT;
00439 SlObject(NULL, _ai_byte);
00440 }
00441 SQInteger res;
00442 sq_getinteger(vm, index, &res);
00443 if (!test) {
00444 int value = (int)res;
00445 SlArray(&value, 1, SLE_INT32);
00446 }
00447 return true;
00448 }
00449
00450 case OT_STRING: {
00451 if (!test) {
00452 _ai_sl_byte = SQSL_STRING;
00453 SlObject(NULL, _ai_byte);
00454 }
00455 const SQChar *res;
00456 sq_getstring(vm, index, &res);
00457
00458
00459 const char *buf = FS2OTTD(res);
00460 size_t len = strlen(buf) + 1;
00461 if (len >= 255) {
00462 AILog::Error("Maximum string length is 254 chars. No data saved.");
00463 return false;
00464 }
00465 if (!test) {
00466 _ai_sl_byte = (byte)len;
00467 SlObject(NULL, _ai_byte);
00468 SlArray((void*)buf, len, SLE_CHAR);
00469 }
00470 return true;
00471 }
00472
00473 case OT_ARRAY: {
00474 if (!test) {
00475 _ai_sl_byte = SQSL_ARRAY;
00476 SlObject(NULL, _ai_byte);
00477 }
00478 sq_pushnull(vm);
00479 while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
00480
00481 bool res = SaveObject(vm, -1, max_depth - 1, test);
00482 sq_pop(vm, 2);
00483 if (!res) {
00484 sq_pop(vm, 1);
00485 return false;
00486 }
00487 }
00488 sq_pop(vm, 1);
00489 if (!test) {
00490 _ai_sl_byte = SQSL_ARRAY_TABLE_END;
00491 SlObject(NULL, _ai_byte);
00492 }
00493 return true;
00494 }
00495
00496 case OT_TABLE: {
00497 if (!test) {
00498 _ai_sl_byte = SQSL_TABLE;
00499 SlObject(NULL, _ai_byte);
00500 }
00501 sq_pushnull(vm);
00502 while (SQ_SUCCEEDED(sq_next(vm, index - 1))) {
00503
00504 bool res = SaveObject(vm, -2, max_depth - 1, test) && SaveObject(vm, -1, max_depth - 1, test);
00505 sq_pop(vm, 2);
00506 if (!res) {
00507 sq_pop(vm, 1);
00508 return false;
00509 }
00510 }
00511 sq_pop(vm, 1);
00512 if (!test) {
00513 _ai_sl_byte = SQSL_ARRAY_TABLE_END;
00514 SlObject(NULL, _ai_byte);
00515 }
00516 return true;
00517 }
00518
00519 case OT_BOOL: {
00520 if (!test) {
00521 _ai_sl_byte = SQSL_BOOL;
00522 SlObject(NULL, _ai_byte);
00523 }
00524 SQBool res;
00525 sq_getbool(vm, index, &res);
00526 if (!test) {
00527 _ai_sl_byte = res ? 1 : 0;
00528 SlObject(NULL, _ai_byte);
00529 }
00530 return true;
00531 }
00532
00533 case OT_NULL: {
00534 if (!test) {
00535 _ai_sl_byte = SQSL_NULL;
00536 SlObject(NULL, _ai_byte);
00537 }
00538 return true;
00539 }
00540
00541 default:
00542 AILog::Error("You tried to save an unsupported type. No data saved.");
00543 return false;
00544 }
00545 }
00546
00547 void AIInstance::SaveEmpty()
00548 {
00549 _ai_sl_byte = 0;
00550 SlObject(NULL, _ai_byte);
00551 }
00552
00553 void AIInstance::Save()
00554 {
00555
00556 if (this->engine == NULL || this->engine->HasScriptCrashed()) {
00557 SaveEmpty();
00558 return;
00559 }
00560
00561 HSQUIRRELVM vm = this->engine->GetVM();
00562 if (this->is_save_data_on_stack) {
00563 _ai_sl_byte = 1;
00564 SlObject(NULL, _ai_byte);
00565
00566 SaveObject(vm, -1, AISAVE_MAX_DEPTH, false);
00567 } else if (!this->is_started) {
00568 SaveEmpty();
00569 return;
00570 } else if (this->engine->MethodExists(*this->instance, "Save")) {
00571 HSQOBJECT savedata;
00572
00573 bool backup_allow = AIObject::GetAllowDoCommand();
00574 AIObject::SetAllowDoCommand(false);
00575 try {
00576 if (!this->engine->CallMethod(*this->instance, "Save", &savedata)) {
00577
00578
00579 SaveEmpty();
00580 this->engine->CrashOccurred();
00581 return;
00582 }
00583 } catch (AI_FatalError e) {
00584
00585
00586 this->is_dead = true;
00587 this->engine->ThrowError(e.GetErrorMessage());
00588 this->engine->ResumeError();
00589 SaveEmpty();
00590
00591
00592 this->is_dead = false;
00593 this->engine->CrashOccurred();
00594 return;
00595 }
00596 AIObject::SetAllowDoCommand(backup_allow);
00597
00598 if (!sq_istable(savedata)) {
00599 AILog::Error("Save function should return a table.");
00600 SaveEmpty();
00601 this->engine->CrashOccurred();
00602 return;
00603 }
00604 sq_pushobject(vm, savedata);
00605 if (SaveObject(vm, -1, AISAVE_MAX_DEPTH, true)) {
00606 _ai_sl_byte = 1;
00607 SlObject(NULL, _ai_byte);
00608 SaveObject(vm, -1, AISAVE_MAX_DEPTH, false);
00609 this->is_save_data_on_stack = true;
00610 } else {
00611 SaveEmpty();
00612 this->engine->CrashOccurred();
00613 }
00614 } else {
00615 AILog::Warning("Save function is not implemented");
00616 _ai_sl_byte = 0;
00617 SlObject(NULL, _ai_byte);
00618 }
00619
00620 }
00621
00622 bool AIInstance::LoadObjects(HSQUIRRELVM vm)
00623 {
00624 SlObject(NULL, _ai_byte);
00625 switch (_ai_sl_byte) {
00626 case SQSL_INT: {
00627 int value;
00628 SlArray(&value, 1, SLE_INT32);
00629 if (vm != NULL) sq_pushinteger(vm, (SQInteger)value);
00630 return true;
00631 }
00632
00633 case SQSL_STRING: {
00634 SlObject(NULL, _ai_byte);
00635 static char buf[256];
00636 SlArray(buf, _ai_sl_byte, SLE_CHAR);
00637 if (vm != NULL) sq_pushstring(vm, OTTD2FS(buf), -1);
00638 return true;
00639 }
00640
00641 case SQSL_ARRAY: {
00642 if (vm != NULL) sq_newarray(vm, 0);
00643 while (LoadObjects(vm)) {
00644 if (vm != NULL) sq_arrayappend(vm, -2);
00645
00646 }
00647 return true;
00648 }
00649
00650 case SQSL_TABLE: {
00651 if (vm != NULL) sq_newtable(vm);
00652 while (LoadObjects(vm)) {
00653 LoadObjects(vm);
00654 if (vm != NULL) sq_rawset(vm, -3);
00655
00656 }
00657 return true;
00658 }
00659
00660 case SQSL_BOOL: {
00661 SlObject(NULL, _ai_byte);
00662 if (vm != NULL) sq_pushinteger(vm, (SQBool)(_ai_sl_byte != 0));
00663 return true;
00664 }
00665
00666 case SQSL_NULL: {
00667 if (vm != NULL) sq_pushnull(vm);
00668 return true;
00669 }
00670
00671 case SQSL_ARRAY_TABLE_END: {
00672 return false;
00673 }
00674
00675 default: NOT_REACHED();
00676 }
00677 }
00678
00679 void AIInstance::LoadEmpty()
00680 {
00681 SlObject(NULL, _ai_byte);
00682
00683 if (_ai_sl_byte == 0) return;
00684
00685 LoadObjects(NULL);
00686 }
00687
00688 void AIInstance::Load(int version)
00689 {
00690 if (this->engine == NULL || version == -1) {
00691 LoadEmpty();
00692 return;
00693 }
00694 HSQUIRRELVM vm = this->engine->GetVM();
00695
00696 SlObject(NULL, _ai_byte);
00697
00698 if (_ai_sl_byte == 0) return;
00699
00700 sq_pushinteger(vm, version);
00701 LoadObjects(vm);
00702 this->is_save_data_on_stack = true;
00703 }
00704
00705 bool AIInstance::CallLoad()
00706 {
00707 HSQUIRRELVM vm = this->engine->GetVM();
00708
00709 if (!this->is_save_data_on_stack) return true;
00710
00711 this->is_save_data_on_stack = false;
00712
00713 if (!this->engine->MethodExists(*this->instance, "Load")) {
00714 AILog::Warning("Loading failed: there was data for the AI to load, but the AI does not have a Load() function.");
00715
00716
00717 sq_pop(vm, 2);
00718 return true;
00719 }
00720
00721
00722 sq_pushobject(vm, *this->instance);
00723
00724 sq_pushstring(vm, OTTD2FS("Load"), -1);
00725
00726 sq_get(vm, -2);
00727
00728 sq_pushobject(vm, *this->instance);
00729
00730 sq_push(vm, -5);
00731 sq_push(vm, -5);
00732
00733
00734
00735 if (SQ_FAILED(sq_call(vm, 3, SQFalse, SQFalse, 100000))) return false;
00736
00737
00738 sq_pop(vm, 4);
00739 return true;
00740 }