(svn r3757) -Feature: Delete news items about vehicles, when they get stale
authortron
Sat, 04 Mar 2006 11:01:35 +0000
changeset 3139 4c950c7ec5c9
parent 3138 2bd76fda80c1
child 3140 69cb681c6d86
(svn r3757) -Feature: Delete news items about vehicles, when they get stale
This is used to delete
- all news about a vehicle, when it gets deleted
- "vehicle has stopped in depot" news, when it gets started
- "vehicle has invalid orders" news, when the orders get changed
aircraft_cmd.c
news.h
news_gui.c
order_cmd.c
roadveh_cmd.c
ship_cmd.c
train_cmd.c
vehicle.c
--- a/aircraft_cmd.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/aircraft_cmd.c	Sat Mar 04 11:01:35 2006 +0000
@@ -382,6 +382,10 @@
 		return_cmd_error(STR_A017_AIRCRAFT_IS_IN_FLIGHT);
 
 	if (flags & DC_EXEC) {
+		if (v->vehstatus & VS_STOPPED && IsAircraftHangarTile(v->tile)) {
+			DeleteVehicleNews(p1, STR_A014_AIRCRAFT_IS_WAITING_IN);
+		}
+
 		v->vehstatus ^= VS_STOPPED;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
--- a/news.h	Fri Mar 03 22:21:29 2006 +0000
+++ b/news.h	Sat Mar 04 11:01:35 2006 +0000
@@ -73,4 +73,11 @@
 	DNC_BANKRUPCY = 4,
 };
 
+/**
+ * Delete a news item type about a vehicle
+ * if the news item type is INVALID_STRING_ID all news about the vehicle get
+ * deleted
+ */
+void DeleteVehicleNews(VehicleID, StringID news);
+
 #endif /* NEWS_H */
--- a/news_gui.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/news_gui.c	Sat Mar 04 11:01:35 2006 +0000
@@ -865,3 +865,37 @@
 	DeleteWindowById(WC_GAME_OPTIONS, 0);
 	AllocateWindowDesc(&_message_options_desc);
 }
+
+
+void DeleteVehicleNews(VehicleID vid, StringID news)
+{
+	byte n;
+
+	for (n = _oldest_news; _latest_news != INVALID_NEWS && n != _latest_news + 1; n = (n + 1) % MAX_NEWS) {
+		const NewsItem* ni = &_news_items[n];
+
+		if (ni->flags & NF_VEHICLE &&
+				ni->data_a == vid &&
+				(news == INVALID_STRING_ID || ni->string_id == news)) {
+			Window* w;
+			byte i;
+
+			if (_forced_news  == n) MoveToNexItem();
+			if (_current_news == n) MoveToNexItem();
+
+			// If this is the last news item, invalidate _latest_news
+			if (_latest_news == _oldest_news) _latest_news = INVALID_NEWS;
+
+			for (i = n; i != _oldest_news; i = (i + MAX_NEWS - 1) % MAX_NEWS) {
+				_news_items[i] = _news_items[(i + MAX_NEWS - 1) % MAX_NEWS];
+			}
+			_oldest_news = (_oldest_news + 1) % MAX_NEWS;
+			_total_news--;
+
+			w = FindWindowById(WC_MESSAGE_HISTORY, 0);
+			if (w == NULL) return;
+			SetWindowDirty(w);
+			w->vscroll.count = _total_news;
+		}
+	}
+}
--- a/order_cmd.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/order_cmd.c	Sat Mar 04 11:01:35 2006 +0000
@@ -143,6 +143,22 @@
 	order->station = data.station;
 }
 
+
+/**
+ * Delete all news items regarding defective orders about a vehicle
+ * This could kill still valid warnings (for example about void order when just
+ * another order gets added), but assume the player will notice the problems,
+ * when (s)he's changing the orders.
+ */
+static void DeleteOrderWarnings(const Vehicle* v)
+{
+	DeleteVehicleNews(v->index, STR_TRAIN_HAS_TOO_FEW_ORDERS  + (v->type - VEH_Train) * 4);
+	DeleteVehicleNews(v->index, STR_TRAIN_HAS_VOID_ORDER      + (v->type - VEH_Train) * 4);
+	DeleteVehicleNews(v->index, STR_TRAIN_HAS_DUPLICATE_ENTRY + (v->type - VEH_Train) * 4);
+	DeleteVehicleNews(v->index, STR_TRAIN_HAS_INVALID_ENTRY   + (v->type - VEH_Train) * 4);
+}
+
+
 /** Add an order to the orderlist of a vehicle.
  * @param x,y unused
  * @param p1 various bitstuffed elements
@@ -366,7 +382,9 @@
 			}
 		}
 
-		for (u = GetFirstVehicleFromSharedList(v); u != NULL; u = u->next_shared) {
+		u = GetFirstVehicleFromSharedList(v);
+		DeleteOrderWarnings(u);
+		for (; u != NULL; u = u->next_shared) {
 			/* Increase amount of orders */
 			u->num_orders++;
 
@@ -451,7 +469,9 @@
 		order->type = OT_NOTHING;
 		order->next = NULL;
 
-		for (u = GetFirstVehicleFromSharedList(v); u != NULL; u = u->next_shared) {
+		u = GetFirstVehicleFromSharedList(v);
+		DeleteOrderWarnings(u);
+		for (; u != NULL; u = u->next_shared) {
 			u->num_orders--;
 
 			if (sel_ord < u->cur_order_index)
@@ -575,7 +595,9 @@
 		{
 			Vehicle* u;
 
-			for (u = GetFirstVehicleFromSharedList(v); u != NULL; u = u->next_shared) {
+			u = GetFirstVehicleFromSharedList(v);
+			DeleteOrderWarnings(u);
+			for (; u != NULL; u = u->next_shared) {
 				/* toggle u->current_order "Full load" flag if it changed */
 				if (sel_ord == u->cur_order_index &&
 						HASBIT(u->current_order.flags, OFB_FULL_LOAD) != HASBIT(order->flags, OFB_FULL_LOAD)) {
@@ -1006,6 +1028,8 @@
 {
 	Order *order, *cur;
 
+	DeleteOrderWarnings(v);
+
 	/* If we have a shared order-list, don't delete the list, but just
 	    remove our pointer */
 	if (IsOrderListShared(v)) {
--- a/roadveh_cmd.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/roadveh_cmd.c	Sat Mar 04 11:01:35 2006 +0000
@@ -216,6 +216,10 @@
 	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
+		if (v->vehstatus & VS_STOPPED && v->u.road.state == 254) {
+			DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
+		}
+
 		v->vehstatus ^= VS_STOPPED;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
--- a/ship_cmd.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/ship_cmd.c	Sat Mar 04 11:01:35 2006 +0000
@@ -951,6 +951,10 @@
 	if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
+		if (v->vehstatus & VS_STOPPED && v->u.ship.state == 0x80) {
+			DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT);
+		}
+
 		v->vehstatus ^= VS_STOPPED;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
--- a/train_cmd.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/train_cmd.c	Sat Mar 04 11:01:35 2006 +0000
@@ -1176,6 +1176,10 @@
 	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
+		if (v->vehstatus & VS_STOPPED && v->u.rail.track == 0x80) {
+			DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);
+		}
+
 		v->u.rail.days_since_order_progr = 0;
 		v->vehstatus ^= VS_STOPPED;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
--- a/vehicle.c	Fri Mar 03 22:21:29 2006 +0000
+++ b/vehicle.c	Sat Mar 04 11:01:35 2006 +0000
@@ -536,6 +536,8 @@
 	Vehicle *u;
 	bool has_artic_part = false;
 
+	DeleteVehicleNews(v->index, INVALID_STRING_ID);
+
 	do {
 		u = v->next;
 		has_artic_part = EngineHasArticPart(v);