mirror of https://github.com/OpenTTD/OpenTTD
(svn r27432) [1.5] -Backport from trunk:
- Fix: When selecting a refit cargo for orders, do not check whether the vehicle is in a depot or station, and do not ask whether the vehicle currently allows station-refitting. Also hide the refit cost for orders, it is not predictable (r27428) - Fix: Use the NewGRF railtype sorting order in the infrastructure window (r27427) - Fix: Crash when switching to or taking over companies, when an order window of a vehicle of the new company was opened. Now close those windows [FS#5842] (r27425) - Fix: Towns did not connect roads to existing roads, unless they had only a single roadbit. Otoh, towns also tried to connect to single roadbit tiles such as tunnels and depots, even though they were not connectable in the direction of interest [FS#6374] (r27424) - Fix: When towns expanded single-bit roadtiles using a grid-layout, they used the layout position of the neighbouring tile (r27423) - Fix: Aircraft picked the wrong airport entry point, if airports were rotated by 180 degree [FS#6341] (r27422)release/1.5
parent
4575e50a69
commit
6351f4dc28
|
@ -809,7 +809,7 @@ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc,
|
|||
/* We are northwest or southeast of the airport */
|
||||
dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE;
|
||||
}
|
||||
dir = ChangeDiagDir(dir, (DiagDirDiff)ReverseDiagDir(DirToDiagDir(rotation)));
|
||||
dir = ChangeDiagDir(dir, DiagDirDifference(DIAGDIR_NE, DirToDiagDir(rotation)));
|
||||
return apc->entry_points[dir];
|
||||
}
|
||||
|
||||
|
|
|
@ -1764,7 +1764,8 @@ struct CompanyInfrastructureWindow : Window
|
|||
|
||||
if (this->railtypes != RAILTYPES_NONE) {
|
||||
/* Draw name of each valid railtype. */
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
RailType rt;
|
||||
FOR_ALL_SORTED_RAILTYPES(rt) {
|
||||
if (HasBit(this->railtypes, rt)) {
|
||||
SetDParam(0, GetRailTypeInfo(rt)->strings.name);
|
||||
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
|
||||
|
@ -1781,7 +1782,8 @@ struct CompanyInfrastructureWindow : Window
|
|||
case WID_CI_RAIL_COUNT: {
|
||||
/* Draw infrastructure count for each valid railtype. */
|
||||
uint32 rail_total = c->infrastructure.GetRailTotal();
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
RailType rt;
|
||||
FOR_ALL_SORTED_RAILTYPES(rt) {
|
||||
if (HasBit(this->railtypes, rt)) {
|
||||
this->DrawCountLine(r, y, c->infrastructure.rail[rt], RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
|
||||
}
|
||||
|
|
|
@ -61,11 +61,11 @@ static inline Direction ReverseDir(Direction d)
|
|||
|
||||
|
||||
/**
|
||||
* Calculate the difference between to directions
|
||||
* Calculate the difference between two directions
|
||||
*
|
||||
* @param d0 The first direction as the base
|
||||
* @param d1 The second direction as the offset from the base
|
||||
* @return The difference how the second directions drifts of the first one.
|
||||
* @return The difference how the second direction drifts of the first one.
|
||||
*/
|
||||
static inline DirDiff DirDifference(Direction d0, Direction d1)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ static inline DirDiff DirDifference(Direction d0, Direction d1)
|
|||
/**
|
||||
* Applies two differences together
|
||||
*
|
||||
* This function adds two differences together and return the resulting
|
||||
* This function adds two differences together and returns the resulting
|
||||
* difference. So adding two DIRDIFF_REVERSE together results in the
|
||||
* DIRDIFF_SAME difference.
|
||||
*
|
||||
|
@ -123,6 +123,20 @@ static inline DiagDirection ReverseDiagDir(DiagDirection d)
|
|||
return (DiagDirection)(2 ^ d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the difference between two DiagDirection values
|
||||
*
|
||||
* @param d0 The first direction as the base
|
||||
* @param d1 The second direction as the offset from the base
|
||||
* @return The difference how the second direction drifts of the first one.
|
||||
*/
|
||||
static inline DiagDirDiff DiagDirDifference(DiagDirection d0, DiagDirection d1)
|
||||
{
|
||||
assert(IsValidDiagDirection(d0));
|
||||
assert(IsValidDiagDirection(d1));
|
||||
/* Cast to uint so compiler can use bitmask. Result can never be negative. */
|
||||
return (DiagDirDiff)((uint)(d0 - d1) % 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a difference on a DiagDirection
|
||||
|
|
|
@ -1713,6 +1713,12 @@ void ShowOrdersWindow(const Vehicle *v)
|
|||
DeleteWindowById(WC_VEHICLE_TIMETABLE, v->index, false);
|
||||
if (BringWindowToFrontById(WC_VEHICLE_ORDERS, v->index) != NULL) return;
|
||||
|
||||
/* Using a different WindowDescs for _local_company causes problems.
|
||||
* Due to this we have to close order windows in ChangeWindowOwner/DeleteCompanyWindows,
|
||||
* because we cannot change switch the WindowDescs and keeping the old WindowDesc results
|
||||
* in crashed due to missing widges.
|
||||
* TODO Rewrite the order GUI to not use different WindowDescs.
|
||||
*/
|
||||
if (v->owner != _local_company) {
|
||||
new OrdersWindow(&_other_orders_desc, v);
|
||||
} else {
|
||||
|
|
|
@ -423,4 +423,13 @@ void ResetRailTypes();
|
|||
void InitRailTypes();
|
||||
RailType AllocateRailType(RailTypeLabel label);
|
||||
|
||||
extern RailType _sorted_railtypes[RAILTYPE_END];
|
||||
extern uint8 _sorted_railtypes_size;
|
||||
|
||||
/**
|
||||
* Loop header for iterating over railtypes, sorted by sortorder.
|
||||
* @param var Railtype.
|
||||
*/
|
||||
#define FOR_ALL_SORTED_RAILTYPES(var) for (uint8 index = 0; index < _sorted_railtypes_size && (var = _sorted_railtypes[index], true) ; index++)
|
||||
|
||||
#endif /* RAIL_H */
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
typedef SmallVector<Train *, 16> TrainList;
|
||||
|
||||
RailtypeInfo _railtypes[RAILTYPE_END];
|
||||
RailType _sorted_railtypes[RAILTYPE_END];
|
||||
uint8 _sorted_railtypes_size;
|
||||
|
||||
assert_compile(sizeof(_original_railtypes) <= sizeof(_railtypes));
|
||||
|
||||
|
@ -109,6 +111,17 @@ void ResolveRailTypeGUISprites(RailtypeInfo *rti)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare railtypes based on their sorting order.
|
||||
* @param first The railtype to compare to.
|
||||
* @param second The railtype to compare.
|
||||
* @return True iff the first should be sorted before the second.
|
||||
*/
|
||||
static int CDECL CompareRailTypes(const RailType *first, const RailType *second)
|
||||
{
|
||||
return GetRailTypeInfo(*first)->sorting_order - GetRailTypeInfo(*second)->sorting_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve sprites of custom rail types
|
||||
*/
|
||||
|
@ -118,6 +131,14 @@ void InitRailTypes()
|
|||
RailtypeInfo *rti = &_railtypes[rt];
|
||||
ResolveRailTypeGUISprites(rti);
|
||||
}
|
||||
|
||||
_sorted_railtypes_size = 0;
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
if (_railtypes[rt].label != 0) {
|
||||
_sorted_railtypes[_sorted_railtypes_size++] = rt;
|
||||
}
|
||||
}
|
||||
QSortT(_sorted_railtypes, _sorted_railtypes_size, CompareRailTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1978,17 +1978,6 @@ void InitializeRailGUI()
|
|||
ResetSignalVariant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare railtypes based on their sorting order.
|
||||
* @param first The railtype to compare to.
|
||||
* @param second The railtype to compare.
|
||||
* @return True iff the first should be sorted before the second.
|
||||
*/
|
||||
static int CDECL CompareRailTypes(const DropDownListItem * const *first, const DropDownListItem * const *second)
|
||||
{
|
||||
return GetRailTypeInfo((RailType)(*first)->result)->sorting_order - GetRailTypeInfo((RailType)(*second)->result)->sorting_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a drop down list for all the rail types of the local company.
|
||||
* @param for_replacement Whether this list is for the replacement window.
|
||||
|
@ -2011,13 +2000,12 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement)
|
|||
|
||||
const Company *c = Company::Get(_local_company);
|
||||
DropDownList *list = new DropDownList();
|
||||
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||
RailType rt;
|
||||
FOR_ALL_SORTED_RAILTYPES(rt) {
|
||||
/* If it's not used ever, don't show it to the user. */
|
||||
if (!HasBit(used_railtypes, rt)) continue;
|
||||
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(rt);
|
||||
/* Skip rail type if it has no label */
|
||||
if (rti->label == 0) continue;
|
||||
|
||||
StringID str = for_replacement ? rti->strings.replace_text : (rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING);
|
||||
DropDownListParamStringItem *item = new DropDownListParamStringItem(str, rt, !HasBit(c->avail_railtypes, rt));
|
||||
|
@ -2025,6 +2013,5 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement)
|
|||
item->SetParam(1, rti->max_speed);
|
||||
*list->Append() = item;
|
||||
}
|
||||
QSortT(list->Begin(), list->Length(), CompareRailTypes);
|
||||
return list;
|
||||
}
|
||||
|
|
57
src/road.cpp
57
src/road.cpp
|
@ -57,41 +57,44 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
|
|||
bool connective = false;
|
||||
const RoadBits mirrored_rb = MirrorRoadBits(target_rb);
|
||||
|
||||
switch (GetTileType(neighbor_tile)) {
|
||||
/* Always connective ones */
|
||||
case MP_CLEAR: case MP_TREES:
|
||||
connective = true;
|
||||
break;
|
||||
if (IsValidTile(neighbor_tile)) {
|
||||
switch (GetTileType(neighbor_tile)) {
|
||||
/* Always connective ones */
|
||||
case MP_CLEAR: case MP_TREES:
|
||||
connective = true;
|
||||
break;
|
||||
|
||||
/* The conditionally connective ones */
|
||||
case MP_TUNNELBRIDGE:
|
||||
case MP_STATION:
|
||||
case MP_ROAD: {
|
||||
const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM);
|
||||
/* The conditionally connective ones */
|
||||
case MP_TUNNELBRIDGE:
|
||||
case MP_STATION:
|
||||
case MP_ROAD:
|
||||
if (IsNormalRoadTile(neighbor_tile)) {
|
||||
/* Always connective */
|
||||
connective = true;
|
||||
} else {
|
||||
const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM);
|
||||
|
||||
/* Accept only connective tiles */
|
||||
connective = (neighbor_rb & mirrored_rb) || // Neighbor has got the fitting RoadBit
|
||||
HasExactlyOneBit(neighbor_rb); // Neighbor has got only one Roadbit
|
||||
/* Accept only connective tiles */
|
||||
connective = (neighbor_rb & mirrored_rb) != ROAD_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case MP_RAILWAY:
|
||||
connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir));
|
||||
break;
|
||||
|
||||
case MP_WATER:
|
||||
/* Check for real water tile */
|
||||
connective = !IsWater(neighbor_tile);
|
||||
break;
|
||||
|
||||
/* The definitely not connective ones */
|
||||
default: break;
|
||||
}
|
||||
|
||||
case MP_RAILWAY:
|
||||
connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir));
|
||||
break;
|
||||
|
||||
case MP_WATER:
|
||||
/* Check for real water tile */
|
||||
connective = !IsWater(neighbor_tile);
|
||||
break;
|
||||
|
||||
/* The definitely not connective ones */
|
||||
default: break;
|
||||
}
|
||||
|
||||
/* If the neighbor tile is inconnective, remove the planed road connection to it */
|
||||
if (!connective) org_rb ^= target_rb;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1247,8 +1247,8 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
|||
/* FALL THROUGH */
|
||||
|
||||
case TL_2X2_GRID:
|
||||
rcmd = GetTownRoadGridElement(t1, house_tile, target_dir);
|
||||
allow_house = (rcmd == ROAD_NONE);
|
||||
rcmd = GetTownRoadGridElement(t1, tile, target_dir);
|
||||
allow_house = (rcmd & DiagDirToRoadBits(target_dir)) == ROAD_NONE;
|
||||
break;
|
||||
|
||||
case TL_BETTER_ROADS: // Use original afterwards!
|
||||
|
|
|
@ -358,8 +358,10 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
|
|||
|
||||
bool auto_refit_allowed;
|
||||
CommandCost refit_cost = GetRefitCost(v, v->engine_type, new_cid, actual_subtype, &auto_refit_allowed);
|
||||
if (auto_refit && !auto_refit_allowed) {
|
||||
/* Sorry, auto-refitting not allowed, subtract the cargo amount again from the total. */
|
||||
if (auto_refit && (flags & DC_QUERY_COST) == 0 && !auto_refit_allowed) {
|
||||
/* Sorry, auto-refitting not allowed, subtract the cargo amount again from the total.
|
||||
* When querrying cost/capacity (for example in order refit GUI), we always assume 'allowed'.
|
||||
* It is not predictable. */
|
||||
total_capacity -= amount;
|
||||
total_mail_capacity -= mail_capacity;
|
||||
|
||||
|
@ -446,8 +448,15 @@ CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
|||
|
||||
/* Don't allow shadows and such to be refitted. */
|
||||
if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
|
||||
|
||||
/* Allow auto-refitting only during loading and normal refitting only in a depot. */
|
||||
if (!free_wagon && (!auto_refit || !front->current_order.IsType(OT_LOADING)) && !front->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type);
|
||||
if ((flags & DC_QUERY_COST) == 0 && // used by the refit GUI, including the order refit GUI.
|
||||
!free_wagon && // used by autoreplace/renew
|
||||
(!auto_refit || !front->current_order.IsType(OT_LOADING)) && // refit inside stations
|
||||
!front->IsStoppedInDepot()) { // refit inside depots
|
||||
return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type);
|
||||
}
|
||||
|
||||
if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED);
|
||||
|
||||
/* Check cargo */
|
||||
|
|
|
@ -701,7 +701,10 @@ struct RefitWindow : public Window {
|
|||
if (_returned_mail_refit_capacity > 0) {
|
||||
SetDParam(2, CT_MAIL);
|
||||
SetDParam(3, _returned_mail_refit_capacity);
|
||||
if (money <= 0) {
|
||||
if (this->order != INVALID_VEH_ORDER_ID) {
|
||||
/* No predictable cost */
|
||||
return STR_PURCHASE_INFO_AIRCRAFT_CAPACITY;
|
||||
} else if (money <= 0) {
|
||||
SetDParam(4, -money);
|
||||
return STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT;
|
||||
} else {
|
||||
|
@ -709,7 +712,11 @@ struct RefitWindow : public Window {
|
|||
return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT;
|
||||
}
|
||||
} else {
|
||||
if (money <= 0) {
|
||||
if (this->order != INVALID_VEH_ORDER_ID) {
|
||||
/* No predictable cost */
|
||||
SetDParam(2, STR_EMPTY);
|
||||
return STR_PURCHASE_INFO_CAPACITY;
|
||||
} else if (money <= 0) {
|
||||
SetDParam(2, -money);
|
||||
return STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT;
|
||||
} else {
|
||||
|
|
|
@ -1207,6 +1207,7 @@ void ChangeWindowOwner(Owner old_owner, Owner new_owner)
|
|||
case WC_BUY_COMPANY:
|
||||
case WC_COMPANY:
|
||||
case WC_COMPANY_INFRASTRUCTURE:
|
||||
case WC_VEHICLE_ORDERS: // Changing owner would also require changing WindowDesc, which is not possible; however keeping the old one crashes because of missing widgets etc.. See ShowOrdersWindow().
|
||||
continue;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue