summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aircraft_cmd.c4
-rw-r--r--news.h7
-rw-r--r--news_gui.c34
-rw-r--r--order_cmd.c30
-rw-r--r--roadveh_cmd.c4
-rw-r--r--ship_cmd.c4
-rw-r--r--train_cmd.c4
-rw-r--r--vehicle.c2
8 files changed, 86 insertions, 3 deletions
diff --git a/aircraft_cmd.c b/aircraft_cmd.c
index 5d2b32c2c..954667c64 100644
--- a/aircraft_cmd.c
+++ b/aircraft_cmd.c
@@ -382,6 +382,10 @@ int32 CmdStartStopAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2)
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);
diff --git a/news.h b/news.h
index 736542eae..d90cb4df2 100644
--- a/news.h
+++ b/news.h
@@ -73,4 +73,11 @@ enum {
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 */
diff --git a/news_gui.c b/news_gui.c
index 5d484436c..1354983ec 100644
--- a/news_gui.c
+++ b/news_gui.c
@@ -865,3 +865,37 @@ void ShowMessageOptions(void)
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;
+ }
+ }
+}
diff --git a/order_cmd.c b/order_cmd.c
index 22770eac4..c0b950952 100644
--- a/order_cmd.c
+++ b/order_cmd.c
@@ -143,6 +143,22 @@ void AssignOrder(Order *order, Order data)
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 @@ int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
}
}
- 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 @@ int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
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 @@ int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
{
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 @@ void DeleteVehicleOrders(Vehicle *v)
{
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)) {
diff --git a/roadveh_cmd.c b/roadveh_cmd.c
index a40801a97..b12debae4 100644
--- a/roadveh_cmd.c
+++ b/roadveh_cmd.c
@@ -216,6 +216,10 @@ int32 CmdStartStopRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
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);
diff --git a/ship_cmd.c b/ship_cmd.c
index 651239286..82bedb3f8 100644
--- a/ship_cmd.c
+++ b/ship_cmd.c
@@ -951,6 +951,10 @@ int32 CmdStartStopShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
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);
diff --git a/train_cmd.c b/train_cmd.c
index 4ab362821..cf2450bc2 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -1176,6 +1176,10 @@ int32 CmdStartStopTrain(int x, int y, uint32 flags, uint32 p1, uint32 p2)
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);
diff --git a/vehicle.c b/vehicle.c
index f6543c84a..a368c5d4b 100644
--- a/vehicle.c
+++ b/vehicle.c
@@ -536,6 +536,8 @@ void DeleteVehicle(Vehicle *v)
Vehicle *u;
bool has_artic_part = false;
+ DeleteVehicleNews(v->index, INVALID_STRING_ID);
+
do {
u = v->next;
has_artic_part = EngineHasArticPart(v);