mirror of https://github.com/OpenTTD/OpenTTD
(svn r19544) -Feature [FS#3496]: add an input box to the AI Debug window where you can input a break string (patch by Zuu)
parent
1cab553994
commit
8165737939
|
@ -65,6 +65,15 @@ public:
|
||||||
*/
|
*/
|
||||||
static void Stop(CompanyID company);
|
static void Stop(CompanyID company);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend an AI for the reminder of the current tick. If the AI is
|
||||||
|
* in a state when it cannot be suspended, it will continue to run
|
||||||
|
* until it can be suspended.
|
||||||
|
* @param company The company for which the AI should be suspended.
|
||||||
|
* @pre Company::IsValidAiID(company)
|
||||||
|
*/
|
||||||
|
static void Suspend(CompanyID company);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kill any and all AIs we manage.
|
* Kill any and all AIs we manage.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -108,6 +108,17 @@
|
||||||
DeleteWindowById(WC_AI_SETTINGS, company);
|
DeleteWindowById(WC_AI_SETTINGS, company);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void AI::Suspend(CompanyID company)
|
||||||
|
{
|
||||||
|
if (_networking && !_network_server) return;
|
||||||
|
|
||||||
|
CompanyID old_company = _current_company;
|
||||||
|
_current_company = company;
|
||||||
|
Company::Get(company)->ai_instance->Suspend();
|
||||||
|
|
||||||
|
_current_company = old_company;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ void AI::KillAll()
|
/* static */ void AI::KillAll()
|
||||||
{
|
{
|
||||||
/* It might happen there are no companies .. than we have nothing to loop */
|
/* It might happen there are no companies .. than we have nothing to loop */
|
||||||
|
|
|
@ -11,8 +11,10 @@
|
||||||
|
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
#include "../openttd.h"
|
#include "../openttd.h"
|
||||||
|
#include "../table/sprites.h"
|
||||||
#include "../gui.h"
|
#include "../gui.h"
|
||||||
#include "../window_gui.h"
|
#include "../window_gui.h"
|
||||||
|
#include "../querystring_gui.h"
|
||||||
#include "../company_func.h"
|
#include "../company_func.h"
|
||||||
#include "../company_base.h"
|
#include "../company_base.h"
|
||||||
#include "../company_gui.h"
|
#include "../company_gui.h"
|
||||||
|
@ -681,21 +683,31 @@ enum AIDebugWindowWidgets {
|
||||||
AID_WIDGET_SCROLLBAR,
|
AID_WIDGET_SCROLLBAR,
|
||||||
AID_WIDGET_COMPANY_BUTTON_START,
|
AID_WIDGET_COMPANY_BUTTON_START,
|
||||||
AID_WIDGET_COMPANY_BUTTON_END = AID_WIDGET_COMPANY_BUTTON_START + 14,
|
AID_WIDGET_COMPANY_BUTTON_END = AID_WIDGET_COMPANY_BUTTON_START + 14,
|
||||||
|
AID_WIDGET_BREAK_STR_ON_OFF_BTN,
|
||||||
|
AID_WIDGET_BREAK_STR_EDIT_BOX,
|
||||||
|
AID_WIDGET_MATCH_CASE_BTN,
|
||||||
|
AID_WIDGET_CONTINUE_BTN,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Window with everything an AI prints via AILog.
|
* Window with everything an AI prints via AILog.
|
||||||
*/
|
*/
|
||||||
struct AIDebugWindow : public Window {
|
struct AIDebugWindow : public QueryStringBaseWindow {
|
||||||
static const int top_offset; ///< Offset of the text at the top of the #AID_WIDGET_LOG_PANEL.
|
static const int top_offset; ///< Offset of the text at the top of the #AID_WIDGET_LOG_PANEL.
|
||||||
static const int bottom_offset; ///< Offset of the text at the bottom of the #AID_WIDGET_LOG_PANEL.
|
static const int bottom_offset; ///< Offset of the text at the bottom of the #AID_WIDGET_LOG_PANEL.
|
||||||
|
|
||||||
|
static const unsigned int MAX_BREAK_STR_STRING_LENGTH = 256;
|
||||||
|
|
||||||
static CompanyID ai_debug_company;
|
static CompanyID ai_debug_company;
|
||||||
int redraw_timer;
|
int redraw_timer;
|
||||||
int last_vscroll_pos;
|
int last_vscroll_pos;
|
||||||
bool autoscroll;
|
bool autoscroll;
|
||||||
|
static bool break_check_enabled; ///< Stop an AI when it prints a matching string
|
||||||
|
static char break_string[MAX_BREAK_STR_STRING_LENGTH]; ///< The string to match to the AI output
|
||||||
|
static bool case_sensitive_break_check; ///< Is the matchding done case-sensitive
|
||||||
|
int highlight_row; ///< The output row that matches the given string, or -1
|
||||||
|
|
||||||
AIDebugWindow(const WindowDesc *desc, WindowNumber number) : Window()
|
AIDebugWindow(const WindowDesc *desc, WindowNumber number) : QueryStringBaseWindow(MAX_BREAK_STR_STRING_LENGTH)
|
||||||
{
|
{
|
||||||
this->InitNested(desc, number);
|
this->InitNested(desc, number);
|
||||||
/* Disable the companies who are not active or not an AI */
|
/* Disable the companies who are not active or not an AI */
|
||||||
|
@ -704,11 +716,22 @@ struct AIDebugWindow : public Window {
|
||||||
}
|
}
|
||||||
this->DisableWidget(AID_WIDGET_RELOAD_TOGGLE);
|
this->DisableWidget(AID_WIDGET_RELOAD_TOGGLE);
|
||||||
this->DisableWidget(AID_WIDGET_SETTINGS);
|
this->DisableWidget(AID_WIDGET_SETTINGS);
|
||||||
|
this->DisableWidget(AID_WIDGET_CONTINUE_BTN);
|
||||||
|
|
||||||
this->last_vscroll_pos = 0;
|
this->last_vscroll_pos = 0;
|
||||||
this->autoscroll = true;
|
this->autoscroll = true;
|
||||||
|
this->highlight_row = -1;
|
||||||
|
InitializeTextBuffer(&this->text, this->edit_str_buf, this->edit_str_size, MAX_BREAK_STR_STRING_LENGTH);
|
||||||
|
|
||||||
|
/* Restore the break string value from static variable */
|
||||||
|
strecpy(this->edit_str_buf, this->break_string, this->edit_str_buf + MAX_BREAK_STR_STRING_LENGTH);
|
||||||
|
UpdateTextBufferSize(&this->text);
|
||||||
|
|
||||||
|
/* Restore button state from static class variables */
|
||||||
if (ai_debug_company != INVALID_COMPANY) this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
|
if (ai_debug_company != INVALID_COMPANY) this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START);
|
||||||
|
this->SetWidgetLoweredState(AID_WIDGET_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
|
||||||
|
this->SetWidgetLoweredState(AID_WIDGET_MATCH_CASE_BTN, this->case_sensitive_break_check);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||||
|
@ -754,6 +777,8 @@ struct AIDebugWindow : public Window {
|
||||||
|
|
||||||
if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
|
if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
|
||||||
|
|
||||||
|
this->DrawEditBox(AID_WIDGET_BREAK_STR_EDIT_BOX);
|
||||||
|
|
||||||
/* If there are no active companies, don't display anything else. */
|
/* If there are no active companies, don't display anything else. */
|
||||||
if (ai_debug_company == INVALID_COMPANY) return;
|
if (ai_debug_company == INVALID_COMPANY) return;
|
||||||
|
|
||||||
|
@ -851,7 +876,7 @@ struct AIDebugWindow : public Window {
|
||||||
|
|
||||||
int y = this->top_offset;
|
int y = this->top_offset;
|
||||||
for (int i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < log->used; i++) {
|
for (int i = this->vscroll.GetPosition(); this->vscroll.IsVisible(i) && i < log->used; i++) {
|
||||||
uint pos = (i + log->pos + 1 - log->used + log->count) % log->count;
|
int pos = (i + log->pos + 1 - log->used + log->count) % log->count;
|
||||||
if (log->lines[pos] == NULL) break;
|
if (log->lines[pos] == NULL) break;
|
||||||
|
|
||||||
TextColour colour;
|
TextColour colour;
|
||||||
|
@ -864,6 +889,12 @@ struct AIDebugWindow : public Window {
|
||||||
default: colour = TC_BLACK; break;
|
default: colour = TC_BLACK; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if the current line should be highlighted */
|
||||||
|
if (pos == this->highlight_row) {
|
||||||
|
GfxFillRect(r.left + 1, r.top + y, r.right - 1, r.top + y + this->resize.step_height - WD_PAR_VSEP_NORMAL, 0);
|
||||||
|
if (colour == TC_BLACK) colour = TC_WHITE; // Make black text readable by inverting it to white.
|
||||||
|
}
|
||||||
|
|
||||||
DrawString(r.left + 7, r.right - 7, r.top + y, log->lines[pos], colour, SA_LEFT | SA_FORCE);
|
DrawString(r.left + 7, r.right - 7, r.top + y, log->lines[pos], colour, SA_LEFT | SA_FORCE);
|
||||||
y += this->resize.step_height;
|
y += this->resize.step_height;
|
||||||
}
|
}
|
||||||
|
@ -911,6 +942,24 @@ struct AIDebugWindow : public Window {
|
||||||
case AID_WIDGET_SETTINGS:
|
case AID_WIDGET_SETTINGS:
|
||||||
ShowAISettingsWindow(ai_debug_company);
|
ShowAISettingsWindow(ai_debug_company);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AID_WIDGET_BREAK_STR_ON_OFF_BTN:
|
||||||
|
this->break_check_enabled = !this->break_check_enabled;
|
||||||
|
this->SetWidgetLoweredState(AID_WIDGET_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
|
||||||
|
this->SetWidgetDirty(AID_WIDGET_BREAK_STR_ON_OFF_BTN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AID_WIDGET_MATCH_CASE_BTN:
|
||||||
|
this->case_sensitive_break_check = !this->case_sensitive_break_check;
|
||||||
|
this->SetWidgetLoweredState(AID_WIDGET_MATCH_CASE_BTN, this->case_sensitive_break_check);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AID_WIDGET_CONTINUE_BTN:
|
||||||
|
/* Unpause */
|
||||||
|
DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE);
|
||||||
|
this->DisableWidget(AID_WIDGET_CONTINUE_BTN);
|
||||||
|
this->RaiseWidget(AID_WIDGET_CONTINUE_BTN); // Disabled widgets don't raise themself
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,9 +970,62 @@ struct AIDebugWindow : public Window {
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void OnMouseLoop()
|
||||||
|
{
|
||||||
|
this->HandleEditBox(AID_WIDGET_BREAK_STR_EDIT_BOX);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||||
|
{
|
||||||
|
EventState state;
|
||||||
|
if (this->HandleEditBoxKey(AID_WIDGET_BREAK_STR_EDIT_BOX, key, keycode, state) != HEBR_NOT_FOCUSED) {
|
||||||
|
/* Save the current string to static member so it can be restored next time the window is opened */
|
||||||
|
strecpy(this->break_string, this->edit_str_buf, lastof(this->break_string));
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnInvalidateData(int data = 0)
|
virtual void OnInvalidateData(int data = 0)
|
||||||
{
|
{
|
||||||
if (data == -1 || ai_debug_company == data) this->SetDirty();
|
if (data == -1 || ai_debug_company == data) this->SetDirty();
|
||||||
|
|
||||||
|
if (data == -2) {
|
||||||
|
/* The continue button should be disabled when the game is unpaused and
|
||||||
|
* it was previously paused by the break string ( = a line in the log
|
||||||
|
* was highlighted )*/
|
||||||
|
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED && this->highlight_row != -1) {
|
||||||
|
this->DisableWidget(AID_WIDGET_CONTINUE_BTN);
|
||||||
|
this->SetWidgetDirty(AID_WIDGET_CONTINUE_BTN);
|
||||||
|
this->SetWidgetDirty(AID_WIDGET_LOG_PANEL);
|
||||||
|
this->highlight_row = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the log message is related to the active company tab, check the break string */
|
||||||
|
if (data == ai_debug_company && this->break_check_enabled && !StrEmpty(this->edit_str_buf)) {
|
||||||
|
/* Get the log instance of the active company */
|
||||||
|
CompanyID old_company = _current_company;
|
||||||
|
_current_company = ai_debug_company;
|
||||||
|
AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer();
|
||||||
|
_current_company = old_company;
|
||||||
|
|
||||||
|
if (log != NULL && case_sensitive_break_check?
|
||||||
|
strstr(log->lines[log->pos], this->edit_str_buf) != 0 :
|
||||||
|
strcasestr(log->lines[log->pos], this->edit_str_buf) != 0) {
|
||||||
|
|
||||||
|
AI::Suspend(ai_debug_company);
|
||||||
|
if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) {
|
||||||
|
DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make it possible to click on the continue button */
|
||||||
|
this->EnableWidget(AID_WIDGET_CONTINUE_BTN);
|
||||||
|
this->SetWidgetDirty(AID_WIDGET_CONTINUE_BTN);
|
||||||
|
|
||||||
|
/* Highlight row that matched */
|
||||||
|
this->highlight_row = log->pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnResize()
|
virtual void OnResize()
|
||||||
|
@ -935,6 +1037,9 @@ struct AIDebugWindow : public Window {
|
||||||
const int AIDebugWindow::top_offset = WD_FRAMERECT_TOP + 2;
|
const int AIDebugWindow::top_offset = WD_FRAMERECT_TOP + 2;
|
||||||
const int AIDebugWindow::bottom_offset = WD_FRAMERECT_BOTTOM;
|
const int AIDebugWindow::bottom_offset = WD_FRAMERECT_BOTTOM;
|
||||||
CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY;
|
CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY;
|
||||||
|
char AIDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = "";
|
||||||
|
bool AIDebugWindow::break_check_enabled = true;
|
||||||
|
bool AIDebugWindow::case_sensitive_break_check = false;
|
||||||
|
|
||||||
static const NWidgetPart _nested_ai_debug_widgets[] = {
|
static const NWidgetPart _nested_ai_debug_widgets[] = {
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
@ -990,7 +1095,22 @@ static const NWidgetPart _nested_ai_debug_widgets[] = {
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, AID_WIDGET_RELOAD_TOGGLE), SetMinimalSize(100, 20), SetDataTip(STR_AI_DEBUG_RELOAD, STR_AI_DEBUG_RELOAD_TOOLTIP),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, AID_WIDGET_RELOAD_TOGGLE), SetMinimalSize(100, 20), SetDataTip(STR_AI_DEBUG_RELOAD, STR_AI_DEBUG_RELOAD_TOOLTIP),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
NWidget(WWT_PANEL, COLOUR_GREY, AID_WIDGET_LOG_PANEL), SetMinimalSize(287, 180), SetResize(1, 1),
|
NWidget(NWID_VERTICAL),
|
||||||
|
/* Log panel */
|
||||||
|
NWidget(WWT_PANEL, COLOUR_GREY, AID_WIDGET_LOG_PANEL), SetMinimalSize(287, 180), SetResize(1, 1),
|
||||||
|
EndContainer(),
|
||||||
|
/* Break string widgets */
|
||||||
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
NWidget(WWT_IMGBTN_2, COLOUR_GREY, AID_WIDGET_BREAK_STR_ON_OFF_BTN), SetFill(0, 1), SetDataTip(SPR_FLAG_VEH_STOPPED, STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP),
|
||||||
|
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||||
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
NWidget(WWT_LABEL, COLOUR_GREY), SetPadding(2, 2, 2, 4), SetDataTip(STR_AI_DEBUG_BREAK_ON_LABEL, 0x0),
|
||||||
|
NWidget(WWT_EDITBOX, COLOUR_WHITE, AID_WIDGET_BREAK_STR_EDIT_BOX), SetFill(1, 1), SetResize(1, 0), SetPadding(2, 2, 2, 2), SetDataTip(STR_AI_DEBUG_BREAK_STR_OSKTITLE, STR_AI_DEBUG_BREAK_STR_TOOLTIP),
|
||||||
|
EndContainer(),
|
||||||
|
EndContainer(),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, AID_WIDGET_MATCH_CASE_BTN), SetMinimalSize(100, 0), SetFill(0, 1), SetDataTip(STR_AI_DEBUG_MATCH_CASE, STR_AI_DEBUG_MATCH_CASE_TOOLTIP),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, AID_WIDGET_CONTINUE_BTN), SetMinimalSize(100, 0), SetFill(0, 1), SetDataTip(STR_AI_DEBUG_CONTINUE, STR_AI_DEBUG_CONTINUE_TOOLTIP),
|
||||||
|
EndContainer(),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(NWID_VERTICAL),
|
NWidget(NWID_VERTICAL),
|
||||||
NWidget(WWT_SCROLLBAR, COLOUR_GREY, AID_WIDGET_SCROLLBAR),
|
NWidget(WWT_SCROLLBAR, COLOUR_GREY, AID_WIDGET_SCROLLBAR),
|
||||||
|
|
|
@ -658,6 +658,12 @@ void AIInstance::Save()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AIInstance::Suspend()
|
||||||
|
{
|
||||||
|
HSQUIRRELVM vm = this->engine->GetVM();
|
||||||
|
Squirrel::DecreaseOps(vm, _settings_game.ai.ai_max_opcode_till_suspend);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ bool AIInstance::LoadObjects(HSQUIRRELVM vm)
|
/* static */ bool AIInstance::LoadObjects(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
SlObject(NULL, _ai_byte);
|
SlObject(NULL, _ai_byte);
|
||||||
|
|
|
@ -137,6 +137,13 @@ public:
|
||||||
*/
|
*/
|
||||||
static void LoadEmpty();
|
static void LoadEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces the number of opcodes the AI have left to zero. Unless
|
||||||
|
* the AI is in a state where it cannot suspend it will be suspended
|
||||||
|
* for the reminder of the current tick. This function is safe to
|
||||||
|
* call from within a function called by the AI.
|
||||||
|
*/
|
||||||
|
void Suspend();
|
||||||
private:
|
private:
|
||||||
class AIController *controller;
|
class AIController *controller;
|
||||||
class AIStorage *storage;
|
class AIStorage *storage;
|
||||||
|
|
|
@ -3228,6 +3228,14 @@ STR_AI_DEBUG_SETTINGS :{BLACK}AI Setti
|
||||||
STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Change the settings of the AI
|
STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Change the settings of the AI
|
||||||
STR_AI_DEBUG_RELOAD :{BLACK}Reload AI
|
STR_AI_DEBUG_RELOAD :{BLACK}Reload AI
|
||||||
STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Kill the AI, reload the script, and restart the AI
|
STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Kill the AI, reload the script, and restart the AI
|
||||||
|
STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Enable/disable breaking when an AI log message matches the break string
|
||||||
|
STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}Break on:
|
||||||
|
STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}Break on
|
||||||
|
STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}When an AI log message matches this string, the game is paused.
|
||||||
|
STR_AI_DEBUG_MATCH_CASE :{BLACK}Match case
|
||||||
|
STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Toggle matching case when comparing AI log messages against the break string
|
||||||
|
STR_AI_DEBUG_CONTINUE :{BLACK}Continue
|
||||||
|
STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Unpause and continue the AI
|
||||||
|
|
||||||
STR_ERROR_NO_AI :{WHITE}OpenTTD is built without AI support...
|
STR_ERROR_NO_AI :{WHITE}OpenTTD is built without AI support...
|
||||||
STR_ERROR_NO_AI_SUB :{WHITE}... no AIs are available!
|
STR_ERROR_NO_AI_SUB :{WHITE}... no AIs are available!
|
||||||
|
|
|
@ -173,6 +173,7 @@ CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2,
|
||||||
} else {
|
} else {
|
||||||
_pause_mode = _pause_mode | p1;
|
_pause_mode = _pause_mode | p1;
|
||||||
}
|
}
|
||||||
|
InvalidateWindowClassesData(WC_AI_DEBUG, -2);
|
||||||
|
|
||||||
#ifdef ENABLE_NETWORK
|
#ifdef ENABLE_NETWORK
|
||||||
NetworkHandlePauseChange(prev_mode, (PauseMode)p1);
|
NetworkHandlePauseChange(prev_mode, (PauseMode)p1);
|
||||||
|
|
Loading…
Reference in New Issue