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