Files @ r25958:603d75b53498
Branch filter:

Location: cpp/openttd-patchpack/source/src/script/api/script_event_types.cpp - annotation

Patric Stout
Doc: update multiplayer documentation with latest changes (#9552)

Although several places were fixed during the PR making the change,
not all made it in this document.

While at it, removed all kinds of Markdown warnings by an excessive
usage of spacebar in this document.
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18765:0c8917c89d77
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r21410:ae5961f02724
r18500:14a481bc4437
r18500:14a481bc4437
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r23607:36c15679007d
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r23607:36c15679007d
r18500:14a481bc4437
r18500:14a481bc4437
r18917:144687613228
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18501:8e3d905ea4bc
r18501:8e3d905ea4bc
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18501:8e3d905ea4bc
r18500:14a481bc4437
r18765:0c8917c89d77
r25575:634f384ae528
r21410:ae5961f02724
r25575:634f384ae528
r21410:ae5961f02724
r21410:ae5961f02724
r21410:ae5961f02724
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r25575:634f384ae528
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r25574:6c110f88f880
r18765:0c8917c89d77
r25574:6c110f88f880
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r25575:634f384ae528
r25575:634f384ae528
r25574:6c110f88f880
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r25574:6c110f88f880
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r25574:6c110f88f880
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r20765:a98457a97dde
r25574:6c110f88f880
r20765:a98457a97dde
r20765:a98457a97dde
r21868:9829c8af7712
r20765:a98457a97dde
r20765:a98457a97dde
r20765:a98457a97dde
r18765:0c8917c89d77
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r23607:36c15679007d
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
r18765:0c8917c89d77
/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file script_event_types.cpp Implementation of all EventTypes. */

#include "../../stdafx.h"
#include "script_event_types.hpp"
#include "script_vehicle.hpp"
#include "script_log.hpp"
#include "../../strings_func.h"
#include "../../settings_type.h"
#include "../../engine_base.h"
#include "../../articulated_vehicles.h"
#include "../../string_func.h"
#include "table/strings.h"

#include "../../safeguards.h"

bool ScriptEventEnginePreview::IsEngineValid() const
{
	const Engine *e = ::Engine::GetIfValid(this->engine);
	return e != nullptr && e->IsEnabled();
}

char *ScriptEventEnginePreview::GetName()
{
	if (!this->IsEngineValid()) return nullptr;

	::SetDParam(0, this->engine);
	return GetString(STR_ENGINE_NAME);
}

CargoID ScriptEventEnginePreview::GetCargoType()
{
	if (!this->IsEngineValid()) return CT_INVALID;
	CargoArray cap = ::GetCapacityOfArticulatedParts(this->engine);

	CargoID most_cargo = CT_INVALID;
	uint amount = 0;
	for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
		if (cap[cid] > amount) {
			amount = cap[cid];
			most_cargo = cid;
		}
	}

	return most_cargo;
}

int32 ScriptEventEnginePreview::GetCapacity()
{
	if (!this->IsEngineValid()) return -1;
	const Engine *e = ::Engine::Get(this->engine);
	switch (e->type) {
		case VEH_ROAD:
		case VEH_TRAIN: {
			CargoArray capacities = GetCapacityOfArticulatedParts(this->engine);
			for (CargoID c = 0; c < NUM_CARGO; c++) {
				if (capacities[c] == 0) continue;
				return capacities[c];
			}
			return -1;
		}

		case VEH_SHIP:
		case VEH_AIRCRAFT:
			return e->GetDisplayDefaultCapacity();

		default: NOT_REACHED();
	}
}

int32 ScriptEventEnginePreview::GetMaxSpeed()
{
	if (!this->IsEngineValid()) return -1;
	const Engine *e = ::Engine::Get(this->engine);
	int32 max_speed = e->GetDisplayMaxSpeed(); // km-ish/h
	if (e->type == VEH_AIRCRAFT) max_speed /= _settings_game.vehicle.plane_speed;
	return max_speed;
}

Money ScriptEventEnginePreview::GetPrice()
{
	if (!this->IsEngineValid()) return -1;
	return ::Engine::Get(this->engine)->GetCost();
}

Money ScriptEventEnginePreview::GetRunningCost()
{
	if (!this->IsEngineValid()) return -1;
	return ::Engine::Get(this->engine)->GetRunningCost();
}

int32 ScriptEventEnginePreview::GetVehicleType()
{
	if (!this->IsEngineValid()) return ScriptVehicle::VT_INVALID;
	switch (::Engine::Get(this->engine)->type) {
		case VEH_ROAD:     return ScriptVehicle::VT_ROAD;
		case VEH_TRAIN:    return ScriptVehicle::VT_RAIL;
		case VEH_SHIP:     return ScriptVehicle::VT_WATER;
		case VEH_AIRCRAFT: return ScriptVehicle::VT_AIR;
		default: NOT_REACHED();
	}
}

bool ScriptEventEnginePreview::AcceptPreview()
{
	if (!this->IsEngineValid()) return false;
	return ScriptObject::DoCommand(0, this->engine, 0, CMD_WANT_ENGINE_PREVIEW);
}

bool ScriptEventCompanyAskMerger::AcceptMerger()
{
	return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
}

ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) :
		ScriptEvent(ET_ADMIN_PORT),
		json(json)
{
}

#define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++;
#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; }

SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm)
{
	const char *p = this->json.c_str();

	if (this->ReadTable(vm, p) == nullptr) {
		sq_pushnull(vm);
		return 1;
	}

	return 1;
}

const char *ScriptEventAdminPort::ReadString(HSQUIRRELVM vm, const char *p)
{
	const char *value = p;

	bool escape = false;
	for (;;) {
		if (*p == '\\') {
			escape = true;
			p++;
			continue;
		}
		if (*p == '"' && escape) {
			escape = false;
			p++;
			continue;
		}
		escape = false;

		if (*p == '"') break;
		if (*p == '\0') RETURN_ERROR(0);

		p++;
	}

	size_t len = p - value;
	sq_pushstring(vm, value, len);
	p++; // Step past the end-of-string marker (")

	return p;
}

const char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, const char *p)
{
	sq_newtable(vm);

	SKIP_EMPTY(p);
	if (*p++ != '{') RETURN_ERROR(1);

	for (;;) {
		SKIP_EMPTY(p);
		if (*p++ != '"') RETURN_ERROR(1);

		p = ReadString(vm, p);
		if (p == nullptr) {
			sq_pop(vm, 1);
			return nullptr;
		}

		SKIP_EMPTY(p);
		if (*p++ != ':') RETURN_ERROR(2);

		p = this->ReadValue(vm, p);
		if (p == nullptr) {
			sq_pop(vm, 2);
			return nullptr;
		}

		sq_rawset(vm, -3);
		/* The key (-2) and value (-1) are popped from the stack by squirrel. */

		SKIP_EMPTY(p);
		if (*p == ',') {
			p++;
			continue;
		}
		break;
	}

	SKIP_EMPTY(p);
	if (*p++ != '}') RETURN_ERROR(1);

	return p;
}

const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p)
{
	SKIP_EMPTY(p);

	if (strncmp(p, "false", 5) == 0) {
		sq_pushinteger(vm, 0);
		return p + 5;
	}
	if (strncmp(p, "true", 4) == 0) {
		sq_pushinteger(vm, 1);
		return p + 4;
	}
	if (strncmp(p, "null", 4) == 0) {
		sq_pushnull(vm);
		return p + 4;
	}

	switch (*p) {
		case '"': {
			/* String */
			p = ReadString(vm, ++p);
			if (p == nullptr) return nullptr;

			break;
		}

		case '{': {
			/* Table */
			p = this->ReadTable(vm, p);
			if (p == nullptr) return nullptr;

			break;
		}

		case '[': {
			/* Array */
			sq_newarray(vm, 0);

			/* Empty array? */
			const char *p2 = p + 1;
			SKIP_EMPTY(p2);
			if (*p2 == ']') {
				p = p2 + 1;
				break;
			}

			while (*p++ != ']') {
				p = this->ReadValue(vm, p);
				if (p == nullptr) {
					sq_pop(vm, 1);
					return nullptr;
				}
				sq_arrayappend(vm, -2);

				SKIP_EMPTY(p);
				if (*p == ',') continue;
				if (*p == ']') break;
				RETURN_ERROR(1);
			}

			p++;

			break;
		}

		case '1': case '2': case '3': case '4': case '5':
		case '6': case '7': case '8': case '9': case '0':
		case '-': {
			/* Integer */

			const char *value = p++;
			for (;;) {
				switch (*p++) {
					case '1': case '2': case '3': case '4': case '5':
					case '6': case '7': case '8': case '9': case '0':
						continue;

					default:
						break;
				}

				p--;
				break;
			}

			int res = atoi(value);
			sq_pushinteger(vm, (SQInteger)res);

			break;
		}

		default:
			RETURN_ERROR(0);
	}

	return p;
}

#undef SKIP_EMPTY
#undef RETURN_ERROR