00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../../stdafx.h"
00013 #include "../../string_func.h"
00014 #include "../../script/squirrel.hpp"
00015 #include "../../rev.h"
00016
00017 #include "script_controller.hpp"
00018 #include "../script_fatalerror.hpp"
00019 #include "../script_info.hpp"
00020 #include "../script_instance.hpp"
00021 #include "../script_suspend.hpp"
00022 #include "script_log.hpp"
00023
00024 void ScriptController::SetCommandDelay(int ticks)
00025 {
00026 if (ticks <= 0) return;
00027 ScriptObject::SetDoCommandDelay(ticks);
00028 }
00029
00030 void ScriptController::Sleep(int ticks)
00031 {
00032 if (!ScriptObject::CanSuspend()) {
00033 throw Script_FatalError("You are not allowed to call Sleep in your constructor, Save(), Load(), and any valuator.");
00034 }
00035
00036 if (ticks <= 0) {
00037 ScriptLog::Warning("Sleep() value should be > 0. Assuming value 1.");
00038 ticks = 1;
00039 }
00040
00041 throw Script_Suspend(ticks, NULL);
00042 }
00043
00044 void ScriptController::Print(bool error_msg, const char *message)
00045 {
00046 ScriptLog::Log(error_msg ? ScriptLog::LOG_SQ_ERROR : ScriptLog::LOG_SQ_INFO, message);
00047 }
00048
00049 ScriptController::ScriptController(CompanyID company) :
00050 ticks(0),
00051 loaded_library_count(0)
00052 {
00053 ScriptObject::SetCompany(company);
00054 }
00055
00056 ScriptController::~ScriptController()
00057 {
00058 for (LoadedLibraryList::iterator iter = this->loaded_library.begin(); iter != this->loaded_library.end(); iter++) {
00059 free((*iter).second);
00060 free((*iter).first);
00061 }
00062
00063 this->loaded_library.clear();
00064 }
00065
00066 uint ScriptController::GetTick()
00067 {
00068 return ScriptObject::GetActiveInstance()->GetController()->ticks;
00069 }
00070
00071 int ScriptController::GetOpsTillSuspend()
00072 {
00073 return ScriptObject::GetActiveInstance()->GetOpsTillSuspend();
00074 }
00075
00076 int ScriptController::GetSetting(const char *name)
00077 {
00078 return ScriptObject::GetActiveInstance()->GetSetting(name);
00079 }
00080
00081 uint ScriptController::GetVersion()
00082 {
00083 return _openttd_newgrf_version;
00084 }
00085
00086 HSQOBJECT ScriptController::Import(const char *library, const char *class_name, int version)
00087 {
00088 ScriptController *controller = ScriptObject::GetActiveInstance()->GetController();
00089 Squirrel *engine = ScriptObject::GetActiveInstance()->engine;
00090 HSQUIRRELVM vm = engine->GetVM();
00091
00092
00093 char library_name[1024];
00094 snprintf(library_name, sizeof(library_name), "%s.%d", library, version);
00095 strtolower(library_name);
00096
00097 ScriptInfo *lib = ScriptObject::GetActiveInstance()->FindLibrary(library, version);
00098 if (lib == NULL) {
00099 char error[1024];
00100 snprintf(error, sizeof(error), "couldn't find library '%s' with version %d", library, version);
00101 throw sq_throwerror(vm, OTTD2SQ(error));
00102 }
00103
00104
00105 HSQOBJECT parent;
00106 sq_getstackobj(vm, 1, &parent);
00107
00108 char fake_class[1024];
00109
00110 LoadedLibraryList::iterator iter = controller->loaded_library.find(library_name);
00111 if (iter != controller->loaded_library.end()) {
00112 ttd_strlcpy(fake_class, (*iter).second, sizeof(fake_class));
00113 } else {
00114 int next_number = ++controller->loaded_library_count;
00115
00116
00117 snprintf(fake_class, sizeof(fake_class), "_internalNA%d", next_number);
00118
00119
00120 sq_pushroottable(vm);
00121 sq_pushstring(vm, OTTD2SQ(fake_class), -1);
00122 sq_newclass(vm, SQFalse);
00123
00124 if (!engine->LoadScript(vm, lib->GetMainScript(), false)) {
00125 char error[1024];
00126 snprintf(error, sizeof(error), "there was a compile error when importing '%s' version %d", library, version);
00127 throw sq_throwerror(vm, OTTD2SQ(error));
00128 }
00129
00130 sq_newslot(vm, -3, SQFalse);
00131 sq_pop(vm, 1);
00132
00133 controller->loaded_library[strdup(library_name)] = strdup(fake_class);
00134 }
00135
00136
00137 sq_pushroottable(vm);
00138 sq_pushstring(vm, OTTD2SQ(fake_class), -1);
00139 if (SQ_FAILED(sq_get(vm, -2))) {
00140 throw sq_throwerror(vm, _SC("internal error assigning library class"));
00141 }
00142 sq_pushstring(vm, OTTD2SQ(lib->GetInstanceName()), -1);
00143 if (SQ_FAILED(sq_get(vm, -2))) {
00144 char error[1024];
00145 snprintf(error, sizeof(error), "unable to find class '%s' in the library '%s' version %d", lib->GetInstanceName(), library, version);
00146 throw sq_throwerror(vm, OTTD2SQ(error));
00147 }
00148 HSQOBJECT obj;
00149 sq_getstackobj(vm, -1, &obj);
00150 sq_pop(vm, 3);
00151
00152 if (StrEmpty(class_name)) return obj;
00153
00154
00155 sq_pushobject(vm, parent);
00156 sq_pushstring(vm, OTTD2SQ(class_name), -1);
00157 sq_pushobject(vm, obj);
00158 sq_newclass(vm, SQTrue);
00159 sq_newslot(vm, -3, SQFalse);
00160 sq_pop(vm, 1);
00161
00162 return obj;
00163 }