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