src/gamelog.cpp
changeset 9704 54123af5f9a5
parent 9655 bab7f10b3130
child 10201 4c181fbe8f2a
--- a/src/gamelog.cpp	Thu Jul 24 08:46:34 2008 +0000
+++ b/src/gamelog.cpp	Thu Jul 24 15:19:26 2008 +0000
@@ -39,6 +39,7 @@
 	GLCT_GRFCOMPAT,   ///< Loading compatible GRF
 	GLCT_GRFPARAM,    ///< GRF parameter changed
 	GLCT_GRFMOVE,     ///< GRF order changed
+	GLCT_GRFBUG,      ///< GRF bug triggered
 	GLCT_END,         ///< So we know how many GLCTs are there
 	GLCT_NONE = 0xFF, ///< In savegames, end of list
 };
@@ -79,6 +80,11 @@
 			int32 oldval;    ///< old value
 			int32 newval;    ///< new value
 		} patch;
+		struct {
+			uint64 data;     ///< additional data
+			uint32 grfid;    ///< ID of problematic GRF
+			byte bug;        ///< type of bug, @see enum GRFBugs
+		} grfbug;
 	};
 };
 
@@ -198,7 +204,8 @@
 	"game loaded",
 	"GRF config changed",
 	"cheat was used",
-	"patch settings changed"
+	"patch settings changed",
+	"GRF bug triggered",
 };
 
 assert_compile(lengthof(la_text) == GLAT_END);
@@ -300,6 +307,15 @@
 						BSWAP32(lc->grfmove.grfid), abs(lc->grfmove.offset), lc->grfmove.offset >= 0 ? "down" : "up" );
 					PrintGrfFilename(buf, lc->grfmove.grfid);
 					break;
+
+				case GLCT_GRFBUG:
+					switch (lc->grfbug.bug) {
+						default: NOT_REACHED();
+						case GBUG_VEH_LENGTH:
+							AddDebugText(buf, "Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X", BSWAP32(lc->grfbug.grfid), (uint)lc->grfbug.data);
+							PrintGrfFilename(buf, lc->grfbug.grfid);
+							break;
+					}
 			}
 
 			proc(buf);
@@ -469,6 +485,51 @@
 }
 
 
+/** Logs triggered GRF bug.
+ * @param grfid ID of problematic GRF
+ * @param bug type of bug, @see enum GRFBugs
+ * @param data additional data
+ */
+static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data)
+{
+	assert(_gamelog_action_type == GLAT_GRFBUG);
+
+	LoggedChange *lc = GamelogChange(GLCT_GRFBUG);
+	if (lc == NULL) return;
+
+	lc->grfbug.data  = data;
+	lc->grfbug.grfid = grfid;
+	lc->grfbug.bug   = bug;
+}
+
+/** Logs GRF bug - rail vehicle has different length after reversing.
+ * Ensures this is logged only once for each GRF and engine type
+ * This check takes some time, but it is called pretty seldom, so it
+ * doesn't matter that much (ideally it shouldn't be called at all).
+ * @param engine engine to log
+ * @return true iff a unique record was done
+ */
+bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id)
+{
+	const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
+	for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
+		const LoggedChange *lcend = &la->change[la->changes];
+		for (const LoggedChange *lc = la->change; lc != lcend; lc++) {
+			if (lc->ct == GLCT_GRFBUG && lc->grfbug.grfid == grfid &&
+					lc->grfbug.bug == GBUG_VEH_LENGTH && lc->grfbug.data == internal_id) {
+				return false;
+			}
+		}
+	}
+
+	GamelogStartAction(GLAT_GRFBUG);
+	GamelogGRFBug(grfid, GBUG_VEH_LENGTH, internal_id);
+	GamelogStopAction();
+
+	return true;
+}
+
+
 /** Decides if GRF should be logged
  * @param g grf to determine
  * @return true iff GRF is not static and is loaded
@@ -724,8 +785,15 @@
 };
 
 static const SaveLoad _glog_grfmove_desc[] = {
-	SLE_VAR(LoggedChange, grfmove.grfid,    SLE_UINT32),
-	SLE_VAR(LoggedChange, grfmove.offset,   SLE_INT32),
+	SLE_VAR(LoggedChange, grfmove.grfid,     SLE_UINT32),
+	SLE_VAR(LoggedChange, grfmove.offset,    SLE_INT32),
+	SLE_END()
+};
+
+static const SaveLoad _glog_grfbug_desc[] = {
+	SLE_VAR(LoggedChange, grfbug.data,       SLE_UINT64),
+	SLE_VAR(LoggedChange, grfbug.grfid,      SLE_UINT32),
+	SLE_VAR(LoggedChange, grfbug.bug,        SLE_UINT8),
 	SLE_END()
 };
 
@@ -738,7 +806,8 @@
 	_glog_grfrem_desc,
 	_glog_grfcompat_desc,
 	_glog_grfparam_desc,
-	_glog_grfmove_desc
+	_glog_grfmove_desc,
+	_glog_grfbug_desc,
 };
 
 assert_compile(lengthof(_glog_desc) == GLCT_END);