Changeset - r20080:370491fa9c80
[Not reviewed]
master
0 2 0
frosch - 12 years ago 2013-02-24 16:43:24
frosch@openttd.org
(svn r25043) -Change [FS#3764]: Only display subtypes in the refit GUI which are available for all selected vehicles. Also add a generic list item to refit while keeping the subtypes of individual vehicles.
2 files changed with 72 insertions and 14 deletions:
0 comments (0 inline, 0 general)
src/core/smallvec_type.hpp
Show inline comments
 
@@ -142,12 +142,26 @@ public:
 
		}
 

	
 
		return &this->data[begin];
 
	}
 

	
 
	/**
 
	 * Set the size of the vector, effectively truncating items from the end or appending uninitialised ones.
 
	 * @param num_items Target size.
 
	 */
 
	inline void Resize(uint num_items)
 
	{
 
		this->items = num_items;
 

	
 
		if (this->items > this->capacity) {
 
			this->capacity = Align(this->items, S);
 
			this->data = ReallocT(this->data, this->capacity);
 
		}
 
	}
 

	
 
	/**
 
	 * Search for the first occurrence of an item.
 
	 * The '!=' operator of T is used for comparison.
 
	 * @param item Item to search for
 
	 * @return The position of the item, or End() when not present
 
	 */
 
	inline const T *Find(const T &item) const
 
@@ -210,12 +224,27 @@ public:
 
	{
 
		assert(item >= this->Begin() && item < this->End());
 
		*item = this->data[--this->items];
 
	}
 

	
 
	/**
 
	 * Remove items from the vector while preserving the order of other items.
 
	 * @param pos First item to remove.
 
	 * @param count Number of consecutive items to remove.
 
	 */
 
	void ErasePreservingOrder(uint pos, uint count = 1)
 
	{
 
		if (count == 0) return;
 
		assert(pos < this->items);
 
		assert(pos + count <= this->items);
 
		this->items -= count;
 
		uint to_move = this->items - pos;
 
		if (to_move > 0) MemMoveT(this->data + pos, this->data + pos + count, to_move);
 
	}
 

	
 
	/**
 
	 * Tests whether a item is present in the vector, and appends it to the end if not.
 
	 * The '!=' operator of T is used for comparison.
 
	 * @param item Item to test for
 
	 * @return true iff the item is was already present
 
	 */
 
	inline bool Include(const T &item)
src/vehicle_gui.cpp
Show inline comments
 
@@ -392,12 +392,21 @@ struct RefitWindow : public Window {
 
				/* Skip cargo type if it's not listed */
 
				if (!HasBit(cmask, cid)) {
 
					current_index++;
 
					continue;
 
				}
 

	
 
				bool first_vehicle = this->list[current_index].Length() == 0;
 
				if (first_vehicle) {
 
					/* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */
 
					RefitOption *option = this->list[current_index].Append();
 
					option->cargo   = cid;
 
					option->subtype = 0xFF;
 
					option->string  = STR_EMPTY;
 
				}
 

	
 
				/* Check the vehicle's callback mask for cargo suffixes.
 
				 * This is not supported for ordered refits, since subtypes only have a meaning
 
				 * for a specific vehicle at a specific point in time, which conflicts with shared orders,
 
				 * autoreplace, autorenew, clone, order restoration, ... */
 
				if (this->order == INVALID_VEH_ORDER_ID && HasBit(callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) {
 
					/* Make a note of the original cargo type. It has to be
 
@@ -412,35 +421,55 @@ struct RefitWindow : public Window {
 

	
 
						/* Make sure we don't pick up anything cached. */
 
						v->First()->InvalidateNewGRFCache();
 
						v->InvalidateNewGRFCache();
 

	
 
						StringID subtype = GetCargoSubtypeText(v);
 
						if (refit_cyc != 0 && subtype == STR_EMPTY) break;
 

	
 
						RefitOption option;
 
						option.cargo   = cid;
 
						option.subtype = refit_cyc;
 
						option.string  = subtype;
 
						this->list[current_index].Include(option);
 

	
 
						if (first_vehicle) {
 
							/* Append new subtype (don't add duplicates though) */
 
							if (subtype == STR_EMPTY) break;
 

	
 
							RefitOption option;
 
							option.cargo   = cid;
 
							option.subtype = refit_cyc;
 
							option.string  = subtype;
 
							this->list[current_index].Include(option);
 
						} else {
 
							/* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */
 
							if (subtype == STR_EMPTY) {
 
								/* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */
 
								SubtypeList &l = this->list[current_index];
 
								/* 0xFF item is in front, other subtypes are sorted. So just truncate the list in the right spot */
 
								for (uint i = 1; i < l.Length(); i++) {
 
									if (l[i].subtype >= refit_cyc) {
 
										l.Resize(i);
 
										break;
 
									}
 
								}
 
								break;
 
							} else {
 
								/* Check whether the subtype matches with the subtype of earlier vehicles. */
 
								uint pos = 1;
 
								SubtypeList &l = this->list[current_index];
 
								while (pos < l.Length() && l[pos].subtype != refit_cyc) pos++;
 
								if (pos < l.Length() && l[pos].string != subtype) {
 
									/* String mismatch, remove item keeping the order */
 
									l.ErasePreservingOrder(pos);
 
								}
 
							}
 
						}
 
					}
 

	
 
					/* Reset the vehicle's cargo type */
 
					v->cargo_type    = temp_cargo;
 
					v->cargo_subtype = temp_subtype;
 

	
 
					/* And make sure we haven't tainted the cache */
 
					v->First()->InvalidateNewGRFCache();
 
					v->InvalidateNewGRFCache();
 
				} else {
 
					/* No cargo suffix callback -- use no subtype */
 
					RefitOption option;
 
					option.cargo   = cid;
 
					option.subtype = 0;
 
					option.string  = STR_EMPTY;
 
					this->list[current_index].Include(option);
 
				}
 
				current_index++;
 
			}
 
		} while (v->IsGroundVehicle() && (v = v->Next()) != NULL);
 

	
 
		int scroll_size = 0;
0 comments (0 inline, 0 general)