mirror of https://github.com/OpenTTD/OpenTTD
(svn r16121) [0.7] -Backport from trunk:
- Add: [NoAI] UseAsRandomAI as function in info.nut. When an AI returns false, it will never be chosen as random AI (r16113) - Fix: [NoAI] Make sure AIOrder::GetDestination always returns a tile belonging to the station (16109) - Fix: [NoAI] When giving an aircraft a goto-hangar order do not let it be a normal goto-station order (r16108) - Add: [NoAI] AIOF_STOP_IN_DEPOT to the orderflags in AIOrder to allow stop-in-depot orders (r16107) - Fix: [NoAI] AIOrder::SetOrderFlags always removed "Service if needed" from goto-depot orders (r16106) - Add: [NoAI] GetURL() as possible function to info.nut. If AIs implement it, that url is shown when the AI crashes and also in the AI selection window [FS#2808] (r16093) - Change: [NoAI] Reverse the order of the lines in the AI debug window [FS#2778] (r16091) - Fix: [NoAI] AIDebug window profiled the blitters by invalidating itself unconditionally on repaint. OTOH it was not invalidated in other cases when needed (r16094) - Fix: [NoAI] MOF_COND_DESTINATION was not accepted by CmdModifyOrder() (r16063)release/0.7
parent
f7cc97fe5c
commit
28e7981a5b
|
@ -103,6 +103,11 @@ struct AIListWindow : public Window {
|
|||
sprintf(buf, "%d", selected_info->GetVersion());
|
||||
DoDrawStringTruncated(buf, x + 5, y, TC_BLACK, this->width - x - 8);
|
||||
y += 13;
|
||||
if (selected_info->GetURL() != NULL) {
|
||||
SetDParamStr(0, selected_info->GetURL());
|
||||
DrawString(4, y, STR_AI_URL, TC_BLACK);
|
||||
y += 13;
|
||||
}
|
||||
SetDParamStr(0, selected_info->GetDescription());
|
||||
DrawStringMultiLine(4, y, STR_JUST_RAW_STRING, this->width - 8, this->widget[AIL_WIDGET_INFO_BG].bottom - y);
|
||||
}
|
||||
|
@ -575,6 +580,8 @@ struct AIDebugWindow : public Window {
|
|||
|
||||
static CompanyID ai_debug_company;
|
||||
int redraw_timer;
|
||||
int last_vscroll_pos;
|
||||
bool autoscroll;
|
||||
|
||||
AIDebugWindow(const WindowDesc *desc, WindowNumber number) : Window(desc, number)
|
||||
{
|
||||
|
@ -587,6 +594,8 @@ struct AIDebugWindow : public Window {
|
|||
this->vscroll.cap = 14;
|
||||
this->vscroll.pos = 0;
|
||||
this->resize.step_height = 12;
|
||||
this->last_vscroll_pos = 0;
|
||||
this->autoscroll = true;
|
||||
|
||||
if (ai_debug_company != INVALID_COMPANY) this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
|
||||
|
||||
|
@ -664,13 +673,35 @@ struct AIDebugWindow : public Window {
|
|||
AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
|
||||
_current_company = old_company;
|
||||
|
||||
SetVScrollCount(this, (log == NULL) ? 0 : log->used);
|
||||
this->InvalidateWidget(AID_WIDGET_SCROLLBAR);
|
||||
int scroll_count = (log == NULL) ? 0 : log->used;
|
||||
if (this->vscroll.count != scroll_count) {
|
||||
SetVScrollCount(this, scroll_count);
|
||||
|
||||
/* We need a repaint */
|
||||
this->InvalidateWidget(AID_WIDGET_SCROLLBAR);
|
||||
}
|
||||
|
||||
if (log == NULL) return;
|
||||
|
||||
/* Detect when the user scrolls the window. Enable autoscroll when the
|
||||
* bottom-most line becomes visible. */
|
||||
if (this->last_vscroll_pos != this->vscroll.pos) {
|
||||
this->autoscroll = this->vscroll.pos >= log->used - this->vscroll.cap;
|
||||
}
|
||||
if (this->autoscroll) {
|
||||
int scroll_pos = max(0, log->used - this->vscroll.cap);
|
||||
if (scroll_pos != this->vscroll.pos) {
|
||||
this->vscroll.pos = scroll_pos;
|
||||
|
||||
/* We need a repaint */
|
||||
this->InvalidateWidget(AID_WIDGET_SCROLLBAR);
|
||||
}
|
||||
}
|
||||
last_vscroll_pos = this->vscroll.pos;
|
||||
|
||||
int y = 6;
|
||||
for (int i = this->vscroll.pos; i < (this->vscroll.cap + this->vscroll.pos); i++) {
|
||||
uint pos = (log->count + log->pos - i) % log->count;
|
||||
for (int i = this->vscroll.pos; i < (this->vscroll.cap + this->vscroll.pos) && i < log->used; i++) {
|
||||
uint pos = (i + log->pos + 1 - log->used + log->count) % log->count;
|
||||
if (log->lines[pos] == NULL) break;
|
||||
|
||||
TextColour colour;
|
||||
|
@ -693,6 +724,8 @@ struct AIDebugWindow : public Window {
|
|||
this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
|
||||
ai_debug_company = show_ai;
|
||||
this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
|
||||
this->autoscroll = true;
|
||||
this->last_vscroll_pos = this->vscroll.pos;
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
|
@ -726,6 +759,7 @@ struct AIDebugWindow : public Window {
|
|||
virtual void OnResize(Point new_size, Point delta)
|
||||
{
|
||||
this->vscroll.cap += delta.y / (int)this->resize.step_height;
|
||||
SetVScrollCount(this, this->vscroll.count); // vscroll.pos should be in a valid range
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ AIFileInfo::~AIFileInfo()
|
|||
free((void *)this->description);
|
||||
free((void *)this->date);
|
||||
free((void *)this->instance_name);
|
||||
free((void *)this->url);
|
||||
free(this->main_script);
|
||||
free(this->SQ_instance);
|
||||
}
|
||||
|
@ -98,6 +99,11 @@ bool AIFileInfo::CheckMethod(const char *name) const
|
|||
if (!info->engine->CallIntegerMethod(*info->SQ_instance, "GetVersion", &info->version)) return SQ_ERROR;
|
||||
if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "CreateInstance", &info->instance_name)) return SQ_ERROR;
|
||||
|
||||
/* The GetURL function is optional. */
|
||||
if (info->engine->MethodExists(*info->SQ_instance, "GetURL")) {
|
||||
if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetURL", &info->url)) return SQ_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -125,6 +131,12 @@ bool AIFileInfo::CheckMethod(const char *name) const
|
|||
} else {
|
||||
info->min_loadable_version = info->GetVersion();
|
||||
}
|
||||
/* When there is an UseAsRandomAI function, call it. */
|
||||
if (info->engine->MethodExists(*info->SQ_instance, "UseAsRandomAI")) {
|
||||
if (!info->engine->CallBoolMethod(*info->SQ_instance, "UseAsRandomAI", &info->use_as_random)) return SQ_ERROR;
|
||||
} else {
|
||||
info->use_as_random = true;
|
||||
}
|
||||
|
||||
/* Remove the link to the real instance, else it might get deleted by RegisterAI() */
|
||||
sq_setinstanceup(vm, 2, NULL);
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
friend class AIInfo;
|
||||
friend class AILibrary;
|
||||
|
||||
AIFileInfo() : SQ_instance(NULL), main_script(NULL), author(NULL), name(NULL), short_name(NULL), description(NULL), date(NULL), instance_name(NULL) {};
|
||||
AIFileInfo() : SQ_instance(NULL), main_script(NULL), author(NULL), name(NULL), short_name(NULL), description(NULL), date(NULL), instance_name(NULL), url(NULL) {};
|
||||
~AIFileInfo();
|
||||
|
||||
/**
|
||||
|
@ -84,6 +84,11 @@ public:
|
|||
*/
|
||||
const char *GetInstanceName() const { return this->instance_name; }
|
||||
|
||||
/**
|
||||
* Get the website for this script.
|
||||
*/
|
||||
const char *GetURL() const { return this->url; }
|
||||
|
||||
/**
|
||||
* Get the filename of the main.nut script.
|
||||
*/
|
||||
|
@ -111,6 +116,7 @@ private:
|
|||
const char *date;
|
||||
const char *instance_name;
|
||||
int version;
|
||||
const char *url;
|
||||
};
|
||||
|
||||
class AIInfo : public AIFileInfo {
|
||||
|
@ -155,9 +161,15 @@ public:
|
|||
*/
|
||||
int GetSettingDefaultValue(const char *name) const;
|
||||
|
||||
/**
|
||||
* Use this AI as a random AI.
|
||||
*/
|
||||
bool UseAsRandomAI() const { return this->use_as_random; }
|
||||
|
||||
private:
|
||||
AIConfigItemList config_list;
|
||||
int min_loadable_version;
|
||||
bool use_as_random;
|
||||
};
|
||||
|
||||
class AILibrary : public AIFileInfo {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define DEFINE_SCRIPT_FILES
|
||||
|
||||
#include "ai_info.hpp"
|
||||
#include "ai_config.hpp"
|
||||
#include "ai_storage.hpp"
|
||||
#include "ai_instance.hpp"
|
||||
#include "ai_gui.hpp"
|
||||
|
@ -258,6 +259,12 @@ void AIInstance::Died()
|
|||
if (strcmp(GetCompany(_current_company)->ai_info->GetMainScript(), "%_dummy") != 0) {
|
||||
ShowErrorMessage(INVALID_STRING_ID, STR_AI_PLEASE_REPORT_CRASH, 0, 0);
|
||||
}
|
||||
|
||||
const AIInfo *info = AIConfig::GetConfig(_current_company)->GetInfo();
|
||||
if (info->GetURL() != NULL) {
|
||||
AILog::Info("Please report the error to the following URL:");
|
||||
AILog::Info(info->GetURL());
|
||||
}
|
||||
}
|
||||
|
||||
void AIInstance::GameLoop()
|
||||
|
|
|
@ -345,20 +345,31 @@ void AIScanner::RegisterAI(AIInfo *info)
|
|||
|
||||
AIInfo *AIScanner::SelectRandomAI()
|
||||
{
|
||||
if (this->info_single_list.size() == 0) {
|
||||
uint num_random_ais = 0;
|
||||
for (AIInfoList::iterator it = this->info_single_list.begin(); it != this->info_single_list.end(); it++) {
|
||||
if (it->second->UseAsRandomAI()) num_random_ais++;
|
||||
}
|
||||
|
||||
if (num_random_ais == 0) {
|
||||
DEBUG(ai, 0, "No suitable AI found, loading 'dummy' AI.");
|
||||
return this->info_dummy;
|
||||
}
|
||||
|
||||
/* Find a random AI */
|
||||
uint pos;
|
||||
if (_networking) pos = InteractiveRandomRange((uint16)this->info_single_list.size());
|
||||
else pos = RandomRange((uint16)this->info_single_list.size());
|
||||
if (_networking) {
|
||||
pos = InteractiveRandomRange(num_random_ais);
|
||||
} else {
|
||||
pos = RandomRange(num_random_ais);
|
||||
}
|
||||
|
||||
/* Find the Nth item from the array */
|
||||
AIInfoList::iterator it = this->info_single_list.begin();
|
||||
for (; pos > 0; pos--) it++;
|
||||
AIInfoList::iterator first_it = it;
|
||||
while (!it->second->UseAsRandomAI()) it++;
|
||||
for (; pos > 0; pos--) {
|
||||
it++;
|
||||
while (!it->second->UseAsRandomAI()) it++;
|
||||
}
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
log->lines = CallocT<char *>(80);
|
||||
log->type = CallocT<AILog::AILogType>(80);
|
||||
log->count = 80;
|
||||
log->pos = log->count;
|
||||
log->pos = log->count - 1;
|
||||
log->used = 0;
|
||||
}
|
||||
LogData *log = (LogData *)AIObject::GetLogPointer();
|
||||
|
|
|
@ -23,7 +23,10 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
|||
|
||||
switch (::GetTileType(t)) {
|
||||
default: break;
|
||||
case MP_STATION: return OT_GOTO_STATION; break;
|
||||
case MP_STATION:
|
||||
if (IsHangar(t)) return OT_GOTO_DEPOT;
|
||||
return OT_GOTO_STATION;
|
||||
break;
|
||||
case MP_WATER: if (::IsShipDepot(t)) return OT_GOTO_DEPOT; break;
|
||||
case MP_ROAD: if (::GetRoadTileType(t) == ROAD_TILE_DEPOT) return OT_GOTO_DEPOT; break;
|
||||
case MP_RAILWAY:
|
||||
|
@ -74,7 +77,10 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
|||
(((order_flags & AIOF_NO_UNLOAD) == 0) || ((order_flags & AIOF_NO_LOAD) == 0)) &&
|
||||
(((order_flags & AIOF_FULL_LOAD_ANY) == 0) || ((order_flags & AIOF_NO_LOAD) == 0));
|
||||
|
||||
case OT_GOTO_DEPOT: return (order_flags & ~(AIOF_NON_STOP_FLAGS | AIOF_SERVICE_IF_NEEDED)) == 0;
|
||||
case OT_GOTO_DEPOT:
|
||||
return ((order_flags & ~(AIOF_NON_STOP_FLAGS | AIOF_DEPOT_FLAGS)) == 0) &&
|
||||
(((order_flags & AIOF_SERVICE_IF_NEEDED) == 0) || ((order_flags & AIOF_STOP_IN_DEPOT) == 0));
|
||||
|
||||
case OT_GOTO_WAYPOINT: return (order_flags & ~(AIOF_NON_STOP_FLAGS)) == 0;
|
||||
default: return false;
|
||||
}
|
||||
|
@ -118,11 +124,36 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
|||
}
|
||||
|
||||
switch (order->GetType()) {
|
||||
case OT_GOTO_DEPOT:
|
||||
case OT_GOTO_DEPOT: {
|
||||
if (v->type != VEH_AIRCRAFT) return ::GetDepot(order->GetDestination())->xy;
|
||||
/* FALL THROUGH: aircraft's hangars are referenced by StationID, not DepotID */
|
||||
/* Aircraft's hangars are referenced by StationID, not DepotID */
|
||||
const Station *st = ::GetStation(order->GetDestination());
|
||||
const AirportFTAClass *airport = st->Airport();
|
||||
if (airport == NULL || airport->nof_depots == 0) return INVALID_TILE;
|
||||
return st->airport_tile + ::ToTileIndexDiff(st->Airport()->airport_depots[0]);
|
||||
}
|
||||
|
||||
case OT_GOTO_STATION: return ::GetStation(order->GetDestination())->xy;
|
||||
case OT_GOTO_STATION: {
|
||||
const Station *st = ::GetStation(order->GetDestination());
|
||||
if (st->train_tile != INVALID_TILE) {
|
||||
for (uint i = 0; i < st->trainst_w; i++) {
|
||||
TileIndex t = st->train_tile + TileDiffXY(i, 0);
|
||||
if (st->TileBelongsToRailStation(t)) return t;
|
||||
}
|
||||
} else if (st->dock_tile != INVALID_TILE) {
|
||||
return st->dock_tile;
|
||||
} else if (st->bus_stops != NULL) {
|
||||
return st->bus_stops->xy;
|
||||
} else if (st->truck_stops != NULL) {
|
||||
return st->truck_stops->xy;
|
||||
} else if (st->airport_tile != INVALID_TILE) {
|
||||
const AirportFTAClass *fta = st->Airport();
|
||||
BEGIN_TILE_LOOP(tile, fta->size_x, fta->size_y, st->airport_tile) {
|
||||
if (!::IsHangar(tile)) return tile;
|
||||
} END_TILE_LOOP(tile, fta->size_x, fta->size_y, st->airport_tile)
|
||||
}
|
||||
return INVALID_TILE;
|
||||
}
|
||||
case OT_GOTO_WAYPOINT: return ::GetWaypoint(order->GetDestination())->xy;
|
||||
default: return INVALID_TILE;
|
||||
}
|
||||
|
@ -145,6 +176,7 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
|||
switch (order->GetType()) {
|
||||
case OT_GOTO_DEPOT:
|
||||
if (order->GetDepotOrderType() & ODTFB_SERVICE) order_flags |= AIOF_SERVICE_IF_NEEDED;
|
||||
if (order->GetDepotActionType() & ODATFB_HALT) order_flags |= AIOF_STOP_IN_DEPOT;
|
||||
break;
|
||||
|
||||
case OT_GOTO_STATION:
|
||||
|
@ -260,9 +292,20 @@ static OrderType GetOrderTypeByTile(TileIndex t)
|
|||
|
||||
Order order;
|
||||
switch (::GetOrderTypeByTile(destination)) {
|
||||
case OT_GOTO_DEPOT:
|
||||
order.MakeGoToDepot(::GetDepotByTile(destination)->index, (OrderDepotTypeFlags)(ODTFB_PART_OF_ORDERS | ((order_flags & AIOF_SERVICE_IF_NEEDED) ? ODTFB_SERVICE : 0)));
|
||||
case OT_GOTO_DEPOT: {
|
||||
OrderDepotTypeFlags odtf = (OrderDepotTypeFlags)(ODTFB_PART_OF_ORDERS | ((order_flags & AIOF_SERVICE_IF_NEEDED) ? ODTFB_SERVICE : 0));
|
||||
OrderDepotActionFlags odaf = (OrderDepotActionFlags)(ODATF_SERVICE_ONLY | ((order_flags & AIOF_STOP_IN_DEPOT) ? ODATFB_HALT : 0));
|
||||
/* Check explicitly if the order is to a station (for aircraft) or
|
||||
* to a depot (other vehicle types). */
|
||||
if (::GetVehicle(vehicle_id)->type == VEH_AIRCRAFT) {
|
||||
if (!::IsTileType(destination, MP_STATION)) return false;
|
||||
order.MakeGoToDepot(::GetStationIndex(destination), odtf, odaf);
|
||||
} else {
|
||||
if (::IsTileType(destination, MP_STATION)) return false;
|
||||
order.MakeGoToDepot(::GetDepotByTile(destination)->index, odtf, odaf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OT_GOTO_STATION:
|
||||
order.MakeGoToStation(::GetStationIndex(destination));
|
||||
|
@ -356,8 +399,11 @@ static void _DoCommandReturnSetOrderFlags(class AIInstance *instance)
|
|||
|
||||
switch (order->GetType()) {
|
||||
case OT_GOTO_DEPOT:
|
||||
if ((current & AIOF_SERVICE_IF_NEEDED) != (order_flags & AIOF_SERVICE_IF_NEEDED)) {
|
||||
return AIObject::DoCommand(0, vehicle_id | (order_position << 16), MOF_DEPOT_ACTION, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnSetOrderFlags);
|
||||
if ((current & AIOF_DEPOT_FLAGS) != (order_flags & AIOF_DEPOT_FLAGS)) {
|
||||
uint data = DA_ALWAYS_GO;
|
||||
if (order_flags & AIOF_SERVICE_IF_NEEDED) data = DA_SERVICE;
|
||||
if (order_flags & AIOF_STOP_IN_DEPOT) data = DA_STOP;
|
||||
return AIObject::DoCommand(0, vehicle_id | (order_position << 16), (data << 4) | MOF_DEPOT_ACTION, CMD_MODIFY_ORDER, NULL, &_DoCommandReturnSetOrderFlags);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
/** Service the vehicle when needed, otherwise skip this order; only for depots. */
|
||||
AIOF_SERVICE_IF_NEEDED = 1 << 2,
|
||||
/** Stop in the depot instead of only go there for servicing; only for depots. */
|
||||
AIOF_STOP_IN_DEPOT = 1 << 3,
|
||||
|
||||
/** All flags related to non-stop settings. */
|
||||
AIOF_NON_STOP_FLAGS = AIOF_NON_STOP_INTERMEDIATE | AIOF_NON_STOP_DESTINATION,
|
||||
|
@ -64,6 +66,8 @@ public:
|
|||
AIOF_UNLOAD_FLAGS = AIOF_TRANSFER | AIOF_UNLOAD | AIOF_NO_UNLOAD,
|
||||
/** All flags related to loading. */
|
||||
AIOF_LOAD_FLAGS = AIOF_FULL_LOAD | AIOF_FULL_LOAD_ANY | AIOF_NO_LOAD,
|
||||
/** All flags related to depots. */
|
||||
AIOF_DEPOT_FLAGS = AIOF_SERVICE_IF_NEEDED | AIOF_STOP_IN_DEPOT,
|
||||
|
||||
/** For marking invalid order flags */
|
||||
AIOF_INVALID = 0xFFFF,
|
||||
|
|
|
@ -42,9 +42,11 @@ void SQAIOrder_Register(Squirrel *engine) {
|
|||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_FULL_LOAD_ANY, "AIOF_FULL_LOAD_ANY");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NO_LOAD, "AIOF_NO_LOAD");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_SERVICE_IF_NEEDED, "AIOF_SERVICE_IF_NEEDED");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_STOP_IN_DEPOT, "AIOF_STOP_IN_DEPOT");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_FLAGS, "AIOF_NON_STOP_FLAGS");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_UNLOAD_FLAGS, "AIOF_UNLOAD_FLAGS");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_LOAD_FLAGS, "AIOF_LOAD_FLAGS");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_DEPOT_FLAGS, "AIOF_DEPOT_FLAGS");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::AIOF_INVALID, "AIOF_INVALID");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::OC_LOAD_PERCENTAGE, "OC_LOAD_PERCENTAGE");
|
||||
SQAIOrder.DefSQConst(engine, AIOrder::OC_RELIABILITY, "OC_RELIABILITY");
|
||||
|
|
|
@ -3585,6 +3585,7 @@ STR_AI_RANDOM_AI :Random AI
|
|||
STR_AI_SETTINGS_CAPTION :{WHITE}AI Parameters
|
||||
STR_AI_AUTHOR :Author:
|
||||
STR_AI_VERSION :Version:
|
||||
STR_AI_URL :URL: {RAW_STRING}
|
||||
STR_AI_PLEASE_REPORT_CRASH :{WHITE}One of the running AIs crashed. Please report this to the AI author with a screenshot of the AI Debug Window.
|
||||
########
|
||||
|
||||
|
|
|
@ -498,7 +498,8 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||
|
||||
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
|
||||
if (new_order.GetDepotOrderType() & ~(ODTFB_PART_OF_ORDERS | ((new_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) != 0 ? ODTFB_SERVICE : 0))) return CMD_ERROR;
|
||||
if (new_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT) return CMD_ERROR;
|
||||
if (new_order.GetDepotActionType() & ~(ODATFB_HALT | ODATFB_NEAREST_DEPOT)) return CMD_ERROR;
|
||||
if ((new_order.GetDepotOrderType() & ODTFB_SERVICE) && (new_order.GetDepotActionType() & ODATFB_HALT)) return CMD_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -862,7 +863,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||
break;
|
||||
|
||||
case OT_CONDITIONAL:
|
||||
if (mof != MOF_COND_VARIABLE && mof != MOF_COND_COMPARATOR && mof != MOF_COND_VALUE) return CMD_ERROR;
|
||||
if (mof != MOF_COND_VARIABLE && mof != MOF_COND_COMPARATOR && mof != MOF_COND_VALUE && mof != MOF_COND_DESTINATION) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -234,6 +234,15 @@ bool Squirrel::CallIntegerMethod(HSQOBJECT instance, const char *method_name, in
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Squirrel::CallBoolMethod(HSQOBJECT instance, const char *method_name, bool *res, int suspend)
|
||||
{
|
||||
HSQOBJECT ret;
|
||||
if (!this->CallMethod(instance, method_name, &ret, suspend)) return false;
|
||||
if (ret._type != OT_BOOL) return false;
|
||||
*res = ObjectToBool(&ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool Squirrel::CreateClassInstanceVM(HSQUIRRELVM vm, const char *class_name, void *real_instance, HSQOBJECT *instance, SQRELEASEHOOK release_hook)
|
||||
{
|
||||
int oldtop = sq_gettop(vm);
|
||||
|
|
|
@ -116,6 +116,7 @@ public:
|
|||
bool CallMethod(HSQOBJECT instance, const char *method_name, int suspend = -1) { return this->CallMethod(instance, method_name, NULL, suspend); }
|
||||
bool CallStringMethodStrdup(HSQOBJECT instance, const char *method_name, const char **res, int suspend = -1);
|
||||
bool CallIntegerMethod(HSQOBJECT instance, const char *method_name, int *res, int suspend = -1);
|
||||
bool CallBoolMethod(HSQOBJECT instance, const char *method_name, bool *res, int suspend = -1);
|
||||
|
||||
/**
|
||||
* Check if a method exists in an instance.
|
||||
|
@ -161,6 +162,11 @@ public:
|
|||
*/
|
||||
static int ObjectToInteger(HSQOBJECT *ptr) { return sq_objtointeger(ptr); }
|
||||
|
||||
/**
|
||||
* Convert a Squirrel-object to a bool.
|
||||
*/
|
||||
static bool ObjectToBool(HSQOBJECT *ptr) { return sq_objtobool(ptr) == 1; }
|
||||
|
||||
/**
|
||||
* Sets a pointer in the VM that is reachable from where ever you are in SQ.
|
||||
* Useful to keep track of the main instance.
|
||||
|
|
Loading…
Reference in New Issue