summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2019-09-07 19:16:31 +0200
committerNiels Martin Hansen <nielsm@indvikleren.dk>2019-09-07 19:38:13 +0200
commit0549a81c30be09529ab8a1f9acb4e435100c7c26 (patch)
treef1eb30d8d6f392ce6432432c86317ff90f47654e
parentb3fd7879596defeb6af78acb4ea45e4418821bdf (diff)
downloadopenttd-0549a81c30be09529ab8a1f9acb4e435100c7c26.tar.xz
Fix b3fd7879: Ignore command flags when verifying script commands
Multiplayer games has the server add some flags to the cmd value during the handling. These flags should not be included in the verification, mask them out. Without this masking out, scripts tend to die when executing their first command in multiplayer.
-rw-r--r--src/script/api/script_object.cpp21
-rw-r--r--src/script/script_instance.cpp5
2 files changed, 17 insertions, 9 deletions
diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp
index ac06c4c2d..6714782e1 100644
--- a/src/script/api/script_object.cpp
+++ b/src/script/api/script_object.cpp
@@ -23,6 +23,7 @@
#include "../script_instance.hpp"
#include "../script_fatalerror.hpp"
#include "script_error.hpp"
+#include "../../debug.h"
#include "../../safeguards.h"
@@ -85,18 +86,22 @@ ScriptObject::ActiveInstance::~ActiveInstance()
/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
{
- GetStorage()->last_tile = tile;
- GetStorage()->last_p1 = p1;
- GetStorage()->last_p2 = p2;
- GetStorage()->last_cmd = cmd;
+ ScriptStorage *s = GetStorage();
+ DEBUG(script, 6, "SetLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd);
+ s->last_tile = tile;
+ s->last_p1 = p1;
+ s->last_p2 = p2;
+ s->last_cmd = cmd & CMD_ID_MASK;
}
/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd)
{
- if (GetStorage()->last_tile != tile) return false;
- if (GetStorage()->last_p1 != p1) return false;
- if (GetStorage()->last_p2 != p2) return false;
- if (GetStorage()->last_cmd != cmd) return false;
+ ScriptStorage *s = GetStorage();
+ DEBUG(script, 6, "CheckLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd);
+ if (s->last_tile != tile) return false;
+ if (s->last_p1 != p1) return false;
+ if (s->last_p2 != p2) return false;
+ if (s->last_cmd != (cmd & CMD_ID_MASK)) return false;
return true;
}
diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp
index 64ae51cf3..3468bff44 100644
--- a/src/script/script_instance.cpp
+++ b/src/script/script_instance.cpp
@@ -684,7 +684,10 @@ bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile
{
ScriptObject::ActiveInstance active(this);
- if (!ScriptObject::CheckLastCommand(tile, p1, p2, cmd)) return false;
+ if (!ScriptObject::CheckLastCommand(tile, p1, p2, cmd)) {
+ DEBUG(script, 1, "DoCommandCallback terminating a script, last command does not match expected command");
+ return false;
+ }
ScriptObject::SetLastCommandRes(result.Succeeded());