mirror of https://github.com/OpenTTD/OpenTTD
(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.
parent
b9aeb050e1
commit
5cd5aca98c
|
@ -144,6 +144,20 @@ public:
|
||||||
return &this->data[begin];
|
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.
|
* Search for the first occurrence of an item.
|
||||||
* The '!=' operator of T is used for comparison.
|
* The '!=' operator of T is used for comparison.
|
||||||
|
@ -212,6 +226,21 @@ public:
|
||||||
*item = this->data[--this->items];
|
*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.
|
* 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.
|
* The '!=' operator of T is used for comparison.
|
||||||
|
|
|
@ -395,6 +395,15 @@ struct RefitWindow : public Window {
|
||||||
continue;
|
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.
|
/* Check the vehicle's callback mask for cargo suffixes.
|
||||||
* This is not supported for ordered refits, since subtypes only have a meaning
|
* 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,
|
* for a specific vehicle at a specific point in time, which conflicts with shared orders,
|
||||||
|
@ -415,13 +424,40 @@ struct RefitWindow : public Window {
|
||||||
v->InvalidateNewGRFCache();
|
v->InvalidateNewGRFCache();
|
||||||
|
|
||||||
StringID subtype = GetCargoSubtypeText(v);
|
StringID subtype = GetCargoSubtypeText(v);
|
||||||
if (refit_cyc != 0 && subtype == STR_EMPTY) break;
|
|
||||||
|
if (first_vehicle) {
|
||||||
|
/* Append new subtype (don't add duplicates though) */
|
||||||
|
if (subtype == STR_EMPTY) break;
|
||||||
|
|
||||||
RefitOption option;
|
RefitOption option;
|
||||||
option.cargo = cid;
|
option.cargo = cid;
|
||||||
option.subtype = refit_cyc;
|
option.subtype = refit_cyc;
|
||||||
option.string = subtype;
|
option.string = subtype;
|
||||||
this->list[current_index].Include(option);
|
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 */
|
/* Reset the vehicle's cargo type */
|
||||||
|
@ -431,13 +467,6 @@ struct RefitWindow : public Window {
|
||||||
/* And make sure we haven't tainted the cache */
|
/* And make sure we haven't tainted the cache */
|
||||||
v->First()->InvalidateNewGRFCache();
|
v->First()->InvalidateNewGRFCache();
|
||||||
v->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++;
|
current_index++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue