mirror of https://github.com/OpenTTD/OpenTTD
(svn r19300) [1.0] -Backport from trunk:
- Fix: [NewGRF] Return the TTD airport type in station var 0xF1 (r19299) - Fix: [NewGRF] Segfault when station vars 0xF2/0xF3 is accessed when there is no truck/bus stop (r19298) - Fix: [NoAI] Some methods of AIAbstractList left invalid iterators [FS#3566] (r19293) - Fix: [YAPP] If reversing at path signals was disabled, a train would not reverse when hitting the back of an one-way signal (r19286) [1.0] -Update: Intro gamerelease/1.0
parent
ccf52c64e9
commit
fa9867879f
|
@ -785,6 +785,36 @@ function Regression::List()
|
|||
|
||||
list.Clear();
|
||||
print(" IsEmpty(): " + list.IsEmpty());
|
||||
|
||||
for (local i = 0; i < 10; i++) {
|
||||
list.AddItem(i, 5 + i / 2);
|
||||
}
|
||||
|
||||
local it = list.Begin();
|
||||
print(" " + it + " => " + list.GetValue(it) + " (" + list.HasNext() + ")");
|
||||
list.Sort(list.SORT_BY_VALUE, list.SORT_ASCENDING);
|
||||
it = list.Next();
|
||||
print(" " + it + " => " + list.GetValue(it) + " (" + list.HasNext() + ")");
|
||||
|
||||
it = list.Begin();
|
||||
print(" " + it + " => " + list.GetValue(it) + " (" + list.HasNext() + ")");
|
||||
|
||||
list.SetValue(it + 1, -5);
|
||||
it = list.Next();
|
||||
print(" " + it + " => " + list.GetValue(it) + " (" + list.HasNext() + ")");
|
||||
|
||||
list.RemoveValue(list.GetValue(it) + 1);
|
||||
it = list.Next();
|
||||
print(" " + it + " => " + list.GetValue(it) + " (" + list.HasNext() + ")");
|
||||
|
||||
list.RemoveAboveValue(list.GetValue(it));
|
||||
it = list.Next();
|
||||
print(" " + it + " => " + list.GetValue(it) + " (" + list.HasNext() + ")");
|
||||
|
||||
while (list.HasNext()) {
|
||||
it = list.Next();
|
||||
print(" " + it + " => " + list.GetValue(it));
|
||||
}
|
||||
}
|
||||
|
||||
function Regression::Map()
|
||||
|
|
|
@ -569,6 +569,14 @@
|
|||
[]:
|
||||
4000 => 50
|
||||
IsEmpty(): true
|
||||
0 => 5 (true)
|
||||
ERROR: Next() is invalid as Begin() is never called
|
||||
ERROR: HasNext() is invalid as Begin() is never called
|
||||
0 => 5 (false)
|
||||
0 => 5 (true)
|
||||
2 => 6 (true)
|
||||
3 => 6 (true)
|
||||
9 => 0 (false)
|
||||
|
||||
--Company--
|
||||
SetName(): true
|
||||
|
|
Binary file not shown.
|
@ -437,8 +437,8 @@ int32 AIAbstractList::Begin()
|
|||
int32 AIAbstractList::Next()
|
||||
{
|
||||
if (this->initialized == false) {
|
||||
DEBUG(ai, 0, "ERROR: Next() is invalid as Begin() is never called");
|
||||
return false;
|
||||
DEBUG(ai, 0, "Next() is invalid as Begin() is never called");
|
||||
return 0;
|
||||
}
|
||||
return this->sorter->Next();
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ bool AIAbstractList::IsEmpty()
|
|||
bool AIAbstractList::HasNext()
|
||||
{
|
||||
if (this->initialized == false) {
|
||||
DEBUG(ai, 0, "ERROR: HasNext() is invalid as Begin() is never called");
|
||||
DEBUG(ai, 0, "HasNext() is invalid as Begin() is never called");
|
||||
return false;
|
||||
}
|
||||
return this->sorter->HasNext();
|
||||
|
@ -517,6 +517,7 @@ void AIAbstractList::Sort(SorterType sorter, bool ascending)
|
|||
}
|
||||
this->sorter_type = sorter;
|
||||
this->sort_ascending = ascending;
|
||||
this->initialized = false;
|
||||
}
|
||||
|
||||
void AIAbstractList::AddList(AIAbstractList *list)
|
||||
|
@ -534,12 +535,7 @@ void AIAbstractList::RemoveAboveValue(int32 value)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second > value) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first > value) this->buckets.erase(iter);
|
||||
if ((*iter).second > value) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,12 +545,7 @@ void AIAbstractList::RemoveBelowValue(int32 value)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second < value) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first < value) this->buckets.erase(iter);
|
||||
if ((*iter).second < value) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,12 +555,7 @@ void AIAbstractList::RemoveBetweenValue(int32 start, int32 end)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second > start && (*iter).second < end) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first > start && (*iter).first < end) this->buckets.erase(iter);
|
||||
if ((*iter).second > start && (*iter).second < end) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,12 +565,7 @@ void AIAbstractList::RemoveValue(int32 value)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second == value) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first == value) this->buckets.erase(iter);
|
||||
if ((*iter).second == value) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,12 +658,7 @@ void AIAbstractList::KeepAboveValue(int32 value)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second <= value) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first <= value) this->buckets.erase(iter);
|
||||
if ((*iter).second <= value) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,12 +668,7 @@ void AIAbstractList::KeepBelowValue(int32 value)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second >= value) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first >= value) this->buckets.erase(iter);
|
||||
if ((*iter).second >= value) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -707,12 +678,7 @@ void AIAbstractList::KeepBetweenValue(int32 start, int32 end)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second <= start || (*iter).second >= end) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first <= start || (*iter).first >= end) this->buckets.erase(iter);
|
||||
if ((*iter).second <= start || (*iter).second >= end) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -722,12 +688,7 @@ void AIAbstractList::KeepValue(int32 value)
|
|||
|
||||
for (AIAbstractListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).second != value) this->items.erase(iter);
|
||||
}
|
||||
|
||||
for (AIAbstractListBucket::iterator next_iter, iter = this->buckets.begin(); iter != this->buckets.end(); iter = next_iter) {
|
||||
next_iter = iter; next_iter++;
|
||||
if ((*iter).first != value) this->buckets.erase(iter);
|
||||
if ((*iter).second != value) this->RemoveItem((*iter).first);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ protected:
|
|||
/**
|
||||
* Remove a single item from the list.
|
||||
* @param item the item to remove. If not existing, it is ignored.
|
||||
* @note Always use this function for removing items. It keeps the iterator valid!
|
||||
*/
|
||||
void RemoveItem(int32 item);
|
||||
|
||||
|
|
|
@ -486,6 +486,25 @@ static uint32 PositionHelper(const Vehicle *v, bool consecutive)
|
|||
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
|
||||
}
|
||||
|
||||
byte MapAirportTypeToTTDType(byte ottd_type)
|
||||
{
|
||||
switch (ottd_type) {
|
||||
/* Note, Helidepot and Helistation are treated as small airports
|
||||
* as they are at ground level. */
|
||||
case AT_HELIDEPOT:
|
||||
case AT_HELISTATION:
|
||||
case AT_COMMUTER:
|
||||
case AT_SMALL: return ATP_TTDP_SMALL;
|
||||
case AT_METROPOLITAN:
|
||||
case AT_INTERNATIONAL:
|
||||
case AT_INTERCON:
|
||||
case AT_LARGE: return ATP_TTDP_LARGE;
|
||||
case AT_HELIPORT: return ATP_TTDP_HELIPORT;
|
||||
case AT_OILRIG: return ATP_TTDP_OILRIG;
|
||||
default: return ATP_TTDP_LARGE;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
||||
{
|
||||
Vehicle *v = const_cast<Vehicle*>(GRV(object));
|
||||
|
@ -609,21 +628,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
|
|||
const Station *st = GetTargetAirportIfValid(Aircraft::From(v));
|
||||
|
||||
if (st != NULL) {
|
||||
switch (st->airport_type) {
|
||||
/* Note, Helidepot and Helistation are treated as small airports
|
||||
* as they are at ground level. */
|
||||
case AT_HELIDEPOT:
|
||||
case AT_HELISTATION:
|
||||
case AT_COMMUTER:
|
||||
case AT_SMALL: airporttype = ATP_TTDP_SMALL; break;
|
||||
case AT_METROPOLITAN:
|
||||
case AT_INTERNATIONAL:
|
||||
case AT_INTERCON:
|
||||
case AT_LARGE: airporttype = ATP_TTDP_LARGE; break;
|
||||
case AT_HELIPORT: airporttype = ATP_TTDP_HELIPORT; break;
|
||||
case AT_OILRIG: airporttype = ATP_TTDP_OILRIG; break;
|
||||
default: airporttype = ATP_TTDP_LARGE; break;
|
||||
}
|
||||
airporttype = MapAirportTypeToTTDType(st->airport_type);
|
||||
}
|
||||
|
||||
return (altitude << 8) | airporttype;
|
||||
|
|
|
@ -510,6 +510,8 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
|
|||
return st->GetNewGRFVariable(object, variable, parameter, available);
|
||||
}
|
||||
|
||||
byte MapAirportTypeToTTDType(byte ottd_type);
|
||||
|
||||
uint32 Station::GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const
|
||||
{
|
||||
switch (variable) {
|
||||
|
@ -524,9 +526,9 @@ uint32 Station::GetNewGRFVariable(const ResolverObject *object, byte variable, b
|
|||
}
|
||||
|
||||
case 0x8A: return this->had_vehicle_of_type;
|
||||
case 0xF1: return this->airport_type;
|
||||
case 0xF2: return this->truck_stops->status;
|
||||
case 0xF3: return this->bus_stops->status;
|
||||
case 0xF1: return MapAirportTypeToTTDType(this->airport_type);
|
||||
case 0xF2: return (this->truck_stops != NULL) ? this->truck_stops->status : 0;
|
||||
case 0xF3: return (this->bus_stops != NULL) ? this->bus_stops->status : 0;
|
||||
case 0xF6: return this->airport_flags;
|
||||
case 0xF7: return GB(this->airport_flags, 8, 8);
|
||||
}
|
||||
|
|
|
@ -3367,8 +3367,11 @@ static void TrainController(Train *v, Vehicle *nomove)
|
|||
}
|
||||
|
||||
/* If we would reverse but are currently in a PBS block and
|
||||
* reversing of stuck trains is disabled, don't reverse. */
|
||||
if (_settings_game.pf.wait_for_pbs_path == 255 && UpdateSignalsOnSegment(v->tile, enterdir, v->owner) == SIGSEG_PBS) {
|
||||
* reversing of stuck trains is disabled, don't reverse.
|
||||
* This does not apply if the reason for reversing is a one-way
|
||||
* signal blocking us, because a train would then be stuck forever. */
|
||||
if (_settings_game.pf.wait_for_pbs_path == 255 && !HasOnewaySignalBlockingTrackdir(gp.new_tile, i) &&
|
||||
UpdateSignalsOnSegment(v->tile, enterdir, v->owner) == SIGSEG_PBS) {
|
||||
v->wait_counter = 0;
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue