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