changeset 17247:5221777879f1 draft

(svn r21987) -Fix: Make news items, engine previews and AI preview events deal with no longer existing Engine items after resetting the pool.
author frosch <frosch@openttd.org>
date Sat, 05 Feb 2011 20:41:13 +0000
parents f98b40bd4ccb
children 114fbdb11b40
files src/ai/api/ai_event_types.cpp src/ai/api/ai_event_types.hpp src/engine.cpp src/news_func.h src/news_gui.cpp src/saveload/afterload.cpp
diffstat 6 files changed, 41 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/api/ai_event_types.cpp
+++ b/src/ai/api/ai_event_types.cpp
@@ -19,8 +19,15 @@
 #include "../../articulated_vehicles.h"
 #include "table/strings.h"
 
+bool AIEventEnginePreview::IsEngineValid() const
+{
+	const Engine *e = ::Engine::GetIfValid(this->engine);
+	return e != NULL && e->IsEnabled();
+}
+
 char *AIEventEnginePreview::GetName()
 {
+	if (!this->IsEngineValid()) return NULL;
 	static const int len = 64;
 	char *engine_name = MallocT<char>(len);
 
@@ -31,6 +38,7 @@
 
 CargoID AIEventEnginePreview::GetCargoType()
 {
+	if (!this->IsEngineValid()) return CT_INVALID;
 	CargoArray cap = ::GetCapacityOfArticulatedParts(this->engine);
 
 	CargoID most_cargo = CT_INVALID;
@@ -47,6 +55,7 @@
 
 int32 AIEventEnginePreview::GetCapacity()
 {
+	if (!this->IsEngineValid()) return -1;
 	const Engine *e = ::Engine::Get(this->engine);
 	switch (e->type) {
 		case VEH_ROAD:
@@ -69,6 +78,7 @@
 
 int32 AIEventEnginePreview::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;
@@ -77,16 +87,19 @@
 
 Money AIEventEnginePreview::GetPrice()
 {
+	if (!this->IsEngineValid()) return -1;
 	return ::Engine::Get(this->engine)->GetCost();
 }
 
 Money AIEventEnginePreview::GetRunningCost()
 {
+	if (!this->IsEngineValid()) return -1;
 	return ::Engine::Get(this->engine)->GetRunningCost();
 }
 
 int32 AIEventEnginePreview::GetVehicleType()
 {
+	if (!this->IsEngineValid()) return AIVehicle::VT_INVALID;
 	switch (::Engine::Get(this->engine)->type) {
 		case VEH_ROAD:     return AIVehicle::VT_ROAD;
 		case VEH_TRAIN:    return AIVehicle::VT_RAIL;
@@ -98,6 +111,7 @@
 
 bool AIEventEnginePreview::AcceptPreview()
 {
+	if (!this->IsEngineValid()) return false;
 	return AIObject::DoCommand(0, this->engine, 0, CMD_WANT_ENGINE_PREVIEW);
 }
 
--- a/src/ai/api/ai_event_types.hpp
+++ b/src/ai/api/ai_event_types.hpp
@@ -296,6 +296,7 @@
 
 private:
 	EngineID engine;
+	bool IsEngineValid() const;
 };
 
 /**
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -499,6 +499,7 @@
 
 void SetupEngines()
 {
+	DeleteWindowByClass(WC_ENGINE_PREVIEW);
 	_engine_pool.CleanPool();
 
 	assert(_engine_mngr.Length() >= _engine_mngr.NUM_DEFAULT_ENGINES);
@@ -859,6 +860,9 @@
 				CalcEngineReliability(e);
 			}
 
+			/* Do not introduce invalid engines */
+			if (!e->IsEnabled()) continue;
+
 			if (!(e->flags & ENGINE_AVAILABLE) && _date >= (e->intro_date + DAYS_IN_YEAR)) {
 				/* Introduce it to all companies */
 				NewVehicleAvailable(e);
--- a/src/news_func.h
+++ b/src/news_func.h
@@ -51,6 +51,7 @@
 
 extern NewsTypeData _news_type_data[];
 
+void DeleteInvalidEngineNews();
 void DeleteVehicleNews(VehicleID vid, StringID news);
 void DeleteStationNews(StationID sid);
 void DeleteIndustryNews(IndustryID iid);
--- a/src/news_gui.cpp
+++ b/src/news_gui.cpp
@@ -28,6 +28,7 @@
 #include "statusbar_gui.h"
 #include "company_manager_face.h"
 #include "company_func.h"
+#include "engine_base.h"
 #include "engine_gui.h"
 #include "core/geometry_func.hpp"
 
@@ -809,6 +810,23 @@
 	}
 }
 
+/**
+ * Remove engine announcements for invalid engines.
+ */
+void DeleteInvalidEngineNews()
+{
+	NewsItem *ni = _oldest_news;
+
+	while (ni != NULL) {
+		NewsItem *next = ni->next;
+		if ((ni->reftype1 == NR_ENGINE && (!Engine::IsValidID(ni->ref1) || !Engine::Get(ni->ref1)->IsEnabled())) ||
+				(ni->reftype2 == NR_ENGINE && (!Engine::IsValidID(ni->ref2) || !Engine::Get(ni->ref2)->IsEnabled()))) {
+			DeleteNewsItem(ni);
+		}
+		ni = next;
+	}
+}
+
 static void RemoveOldNewsItems()
 {
 	NewsItem *next;
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -51,6 +51,7 @@
 #include "../rail_gui.h"
 #include "../core/backup_type.hpp"
 #include "../smallmap_gui.h"
+#include "../news_func.h"
 
 #include "table/strings.h"
 
@@ -2604,6 +2605,8 @@
 	AfterLoadStations();
 	/* Check and update house and town values */
 	UpdateHousesAndTowns();
+	/* Delete news referring to no longer existing entities */
+	DeleteInvalidEngineNews();
 	/* Update livery selection windows */
 	for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) InvalidateWindowData(WC_COMPANY_COLOUR, i);
 	/* redraw the whole screen */