Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../../stdafx.h"
00013 #include "script_event_types.hpp"
00014 #include "script_vehicle.hpp"
00015 #include "script_log.hpp"
00016 #include "../../command_type.h"
00017 #include "../../strings_func.h"
00018 #include "../../settings_type.h"
00019 #include "../../engine_base.h"
00020 #include "../../articulated_vehicles.h"
00021 #include "table/strings.h"
00022
00023 bool ScriptEventEnginePreview::IsEngineValid() const
00024 {
00025 const Engine *e = ::Engine::GetIfValid(this->engine);
00026 return e != NULL && e->IsEnabled();
00027 }
00028
00029 char *ScriptEventEnginePreview::GetName()
00030 {
00031 if (!this->IsEngineValid()) return NULL;
00032 static const int len = 64;
00033 char *engine_name = MallocT<char>(len);
00034
00035 ::SetDParam(0, this->engine);
00036 ::GetString(engine_name, STR_ENGINE_NAME, &engine_name[len - 1]);
00037 return engine_name;
00038 }
00039
00040 CargoID ScriptEventEnginePreview::GetCargoType()
00041 {
00042 if (!this->IsEngineValid()) return CT_INVALID;
00043 CargoArray cap = ::GetCapacityOfArticulatedParts(this->engine);
00044
00045 CargoID most_cargo = CT_INVALID;
00046 uint amount = 0;
00047 for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
00048 if (cap[cid] > amount) {
00049 amount = cap[cid];
00050 most_cargo = cid;
00051 }
00052 }
00053
00054 return most_cargo;
00055 }
00056
00057 int32 ScriptEventEnginePreview::GetCapacity()
00058 {
00059 if (!this->IsEngineValid()) return -1;
00060 const Engine *e = ::Engine::Get(this->engine);
00061 switch (e->type) {
00062 case VEH_ROAD:
00063 case VEH_TRAIN: {
00064 CargoArray capacities = GetCapacityOfArticulatedParts(this->engine);
00065 for (CargoID c = 0; c < NUM_CARGO; c++) {
00066 if (capacities[c] == 0) continue;
00067 return capacities[c];
00068 }
00069 return -1;
00070 }
00071
00072 case VEH_SHIP:
00073 case VEH_AIRCRAFT:
00074 return e->GetDisplayDefaultCapacity();
00075
00076 default: NOT_REACHED();
00077 }
00078 }
00079
00080 int32 ScriptEventEnginePreview::GetMaxSpeed()
00081 {
00082 if (!this->IsEngineValid()) return -1;
00083 const Engine *e = ::Engine::Get(this->engine);
00084 int32 max_speed = e->GetDisplayMaxSpeed();
00085 if (e->type == VEH_AIRCRAFT) max_speed /= _settings_game.vehicle.plane_speed;
00086 return max_speed;
00087 }
00088
00089 Money ScriptEventEnginePreview::GetPrice()
00090 {
00091 if (!this->IsEngineValid()) return -1;
00092 return ::Engine::Get(this->engine)->GetCost();
00093 }
00094
00095 Money ScriptEventEnginePreview::GetRunningCost()
00096 {
00097 if (!this->IsEngineValid()) return -1;
00098 return ::Engine::Get(this->engine)->GetRunningCost();
00099 }
00100
00101 int32 ScriptEventEnginePreview::GetVehicleType()
00102 {
00103 if (!this->IsEngineValid()) return ScriptVehicle::VT_INVALID;
00104 switch (::Engine::Get(this->engine)->type) {
00105 case VEH_ROAD: return ScriptVehicle::VT_ROAD;
00106 case VEH_TRAIN: return ScriptVehicle::VT_RAIL;
00107 case VEH_SHIP: return ScriptVehicle::VT_WATER;
00108 case VEH_AIRCRAFT: return ScriptVehicle::VT_AIR;
00109 default: NOT_REACHED();
00110 }
00111 }
00112
00113 bool ScriptEventEnginePreview::AcceptPreview()
00114 {
00115 if (!this->IsEngineValid()) return false;
00116 return ScriptObject::DoCommand(0, this->engine, 0, CMD_WANT_ENGINE_PREVIEW);
00117 }
00118
00119 bool ScriptEventCompanyAskMerger::AcceptMerger()
00120 {
00121 return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
00122 }
00123
00124 #define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
00125 #define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return NULL; }
00126
00127 SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
00128 {
00129 char *p = this->json;
00130
00131 if (this->ReadTable(vm, p) == NULL) {
00132 sq_pushnull(vm);
00133 return 1;
00134 }
00135
00136 return 1;
00137 }
00138
00139 char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, char *p)
00140 {
00141 char *value = p;
00142
00143 bool escape = false;
00144 for (;;) {
00145 if (*p == '\\') {
00146 escape = true;
00147 p++;
00148 continue;
00149 }
00150 if (*p == '"' && escape) {
00151 escape = false;
00152 p++;
00153 continue;
00154 }
00155 escape = false;
00156
00157 if (*p == '"') break;
00158 if (*p == '\0') RETURN_ERROR(0);
00159
00160 p++;
00161 }
00162
00163 *p = '\0';
00164 sq_pushstring(vm, OTTD2SQ(value), -1);
00165 *p++ = '"';
00166
00167 return p;
00168 }
00169
00170 char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p)
00171 {
00172 sq_newtable(vm);
00173
00174 SKIP_EMPTY(p);
00175 if (*p++ != '{') RETURN_ERROR(1);
00176
00177 for (;;) {
00178 SKIP_EMPTY(p);
00179 if (*p++ != '"') RETURN_ERROR(1);
00180
00181 p = ReadString(vm, p);
00182 if (p == NULL) {
00183 sq_pop(vm, 1);
00184 return NULL;
00185 }
00186
00187 SKIP_EMPTY(p);
00188 if (*p++ != ':') RETURN_ERROR(2);
00189
00190 p = this->ReadValue(vm, p);
00191 if (p == NULL) {
00192 sq_pop(vm, 2);
00193 return NULL;
00194 }
00195
00196 sq_rawset(vm, -3);
00197
00198
00199 SKIP_EMPTY(p);
00200 if (*p == ',') {
00201 p++;
00202 continue;
00203 }
00204 break;
00205 }
00206
00207 SKIP_EMPTY(p);
00208 if (*p++ != '}') RETURN_ERROR(1);
00209
00210 return p;
00211 }
00212
00213 char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p)
00214 {
00215 SKIP_EMPTY(p);
00216
00217 if (strncmp(p, "false", 5) == 0) {
00218 sq_pushinteger(vm, 0);
00219 return p + 5;
00220 }
00221 if (strncmp(p, "true", 4) == 0) {
00222 sq_pushinteger(vm, 1);
00223 return p + 4;
00224 }
00225 if (strncmp(p, "null", 4) == 0) {
00226 sq_pushnull(vm);
00227 return p + 4;
00228 }
00229
00230 switch (*p) {
00231 case '"': {
00232
00233 p = ReadString(vm, ++p);
00234 if (p == NULL) return NULL;
00235
00236 break;
00237 }
00238
00239 case '{': {
00240
00241 p = this->ReadTable(vm, p);
00242 if (p == NULL) return NULL;
00243
00244 break;
00245 }
00246
00247 case '[': {
00248
00249 sq_newarray(vm, 0);
00250
00251 while (*p++ != ']') {
00252 p = this->ReadValue(vm, p);
00253 if (p == NULL) {
00254 sq_pop(vm, 1);
00255 return NULL;
00256 }
00257 sq_arrayappend(vm, -2);
00258
00259 SKIP_EMPTY(p);
00260 if (*p == ',') continue;
00261 if (*p == ']') break;
00262 RETURN_ERROR(1);
00263 }
00264
00265 p++;
00266
00267 break;
00268 }
00269
00270 case '1': case '2': case '3': case '4': case '5':
00271 case '6': case '7': case '8': case '9': case '0':
00272 case '-': {
00273
00274
00275 const char *value = p++;
00276 for (;;) {
00277 switch (*p++) {
00278 case '1': case '2': case '3': case '4': case '5':
00279 case '6': case '7': case '8': case '9': case '0':
00280 continue;
00281
00282 default:
00283 break;
00284 }
00285
00286 p--;
00287 break;
00288 }
00289
00290 int res = atoi(value);
00291 sq_pushinteger(vm, (SQInteger)res);
00292
00293 break;
00294 }
00295
00296 default:
00297 RETURN_ERROR(0);
00298 }
00299
00300 return p;
00301 }
00302
00303 #undef SKIP_EMPTY
00304 #undef RETURN_ERROR