1
0
Fork 0

(svn r19554) [1.0] -Backport from trunk:

- Fix: Improperly scaled cargo payment graph when having lots of cargo (r19550, 19543)
- Fix: [NewGRF] Properties set before property 08 (house, industry, industry tiles) should be ignored, not trigger the NewGRF to be disabled [FS#3725] (r19547)
- Fix: Vehicle details window did not resize correctly after refitting a road vehicle to a longer variant [FS#3720] (r19533)
release/1.0
rubidium 2010-04-03 20:09:19 +00:00
parent a9163d0503
commit fcff99da75
4 changed files with 226 additions and 35 deletions

View File

@ -199,12 +199,17 @@ protected:
byte colours[GRAPH_MAX_DATASETS];
OverflowSafeInt64 cost[GRAPH_MAX_DATASETS][GRAPH_NUM_MONTHS]; ///< Stored costs for the last #GRAPH_NUM_MONTHS months
int64 GetHighestValue(int initial_highest_value) const
/**
* Get the highest value of the graph's data. Excluded data is ignored to allow showing smaller values in
* better detail when disabling higher ones.
* @return Highest value of the graph (ignoring disabled data).
*/
int64 GetHighestValue() const
{
OverflowSafeInt64 highest_value = initial_highest_value;
OverflowSafeInt64 highest_value = 0;
for (int i = 0; i < this->num_dataset; i++) {
if (!HasBit(this->excluded_data, i)) {
if (HasBit(this->excluded_data, i)) continue;
for (int j = 0; j < this->num_on_x_axis; j++) {
OverflowSafeInt64 datapoint = this->cost[i][j];
@ -216,8 +221,11 @@ protected:
}
}
}
}
/* Prevent showing the highest value too close to the graph upper limit. */
highest_value = (11 * highest_value) / 10;
/* Avoid using zero as the highest value. */
if (highest_value == 0) highest_value = GRAPH_NUM_LINES_Y - 1;
/* Round up highest_value so that it will divide cleanly into the number of
* axis labels used. */
int round_val = highest_value % (GRAPH_NUM_LINES_Y - 1);
@ -274,13 +282,7 @@ protected:
r.left += 9;
r.right -= 5;
/* Start of with a highest_value of twice the height of the graph in pixels.
* It's a bit arbitrary, but it makes the cargo payment graph look a little
* nicer, and prevents division by zero when calculating where the datapoint
* should be drawn. */
highest_value = r.bottom - r.top + 1;
if (!this->has_negative_values) highest_value *= 2;
highest_value = GetHighestValue(highest_value);
highest_value = GetHighestValue();
/* Get width for Y labels */
int label_width = GetYLabelWidth(highest_value);

View File

@ -1454,6 +1454,61 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR
return ret;
}
static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
{
ChangeInfoResult ret = CIR_SUCCESS;
switch (prop) {
case 0x09:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
case 0x11:
case 0x14:
case 0x15:
case 0x16:
case 0x18:
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x1F:
buf->ReadByte();
break;
case 0x0A:
case 0x10:
case 0x12:
case 0x13:
case 0x21:
case 0x22:
buf->ReadWord();
break;
case 0x1E:
buf->ReadDWord();
break;
case 0x17:
for (uint j = 0; j < 4; j++) buf->ReadByte();
break;
case 0x20: {
byte count = buf->ReadByte();
for (byte j = 0; j < count; j++) buf->ReadByte();
ret = CIR_UNHANDLED;
} break;
default:
ret = CIR_UNKNOWN;
break;
}
return ret;
}
static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
{
ChangeInfoResult ret = CIR_SUCCESS;
@ -1472,8 +1527,10 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt
HouseSpec *housespec = _cur_grffile->housespec[hid + i];
if (prop != 0x08 && housespec == NULL) {
grfmsg(2, "TownHouseChangeInfo: Attempt to modify undefined house %u. Ignoring.", hid + i);
return CIR_INVALID_ID;
/* If the house property 08 is not yet set, ignore this property */
ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
if (cir > ret) ret = cir;
continue;
}
switch (prop) {
@ -2060,6 +2117,34 @@ static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, B
return ret;
}
static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
{
ChangeInfoResult ret = CIR_SUCCESS;
switch (prop) {
case 0x09:
case 0x0D:
case 0x0E:
case 0x10:
case 0x11:
case 0x12:
buf->ReadByte();
break;
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0F:
buf->ReadWord();
break;
default:
ret = CIR_UNKNOWN;
break;
}
return ret;
}
static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
{
ChangeInfoResult ret = CIR_SUCCESS;
@ -2078,8 +2163,9 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr
IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i];
if (prop != 0x08 && tsp == NULL) {
grfmsg(2, "IndustryTilesChangeInfo: Attempt to modify undefined industry tile %u. Ignoring.", indtid + i);
return CIR_INVALID_ID;
ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
if (cir > ret) ret = cir;
continue;
}
switch (prop) {
@ -2168,6 +2254,83 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr
return ret;
}
static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
{
ChangeInfoResult ret = CIR_SUCCESS;
switch (prop) {
case 0x09:
case 0x0B:
case 0x0F:
case 0x12:
case 0x13:
case 0x14:
case 0x17:
case 0x18:
case 0x19:
case 0x21:
case 0x22:
buf->ReadByte();
break;
case 0x0C:
case 0x0D:
case 0x0E:
case 0x10:
case 0x1B:
case 0x1F:
case 0x24:
buf->ReadWord();
break;
case 0x1A:
case 0x1C:
case 0x1D:
case 0x1E:
case 0x20:
case 0x23:
buf->ReadDWord();
break;
case 0x0A: {
byte num_table = buf->ReadByte();
for (byte j = 0; j < num_table; j++) {
for (uint k = 0;; k++) {
byte x = buf->ReadByte();
if (x == 0xFE && k == 0) {
buf->ReadByte();
buf->ReadByte();
break;
}
byte y = buf->ReadByte();
if (x == 0 && y == 0x80) break;
byte gfx = buf->ReadByte();
if (gfx == 0xFE) buf->ReadWord();
}
}
} break;
case 0x11:
case 0x16:
for (byte j = 0; j < 3; j++) buf->ReadByte();
break;
case 0x15: {
byte number_of_sounds = buf->ReadByte();
for (uint8 j = 0; j < number_of_sounds; j++) {
buf->ReadByte();
}
} break;
default:
ret = CIR_UNKNOWN;
break;
}
return ret;
}
/**
* Validate the industry layout; e.g. to prevent duplicate tiles.
* @param layout the layout to check
@ -2207,8 +2370,9 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop,
IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
if (prop != 0x08 && indsp == NULL) {
grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i);
return CIR_INVALID_ID;
ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
if (cir > ret) ret = cir;
continue;
}
switch (prop) {

View File

@ -1737,7 +1737,7 @@ CommandCost CmdRefitRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
if (flags & DC_EXEC) {
RoadVehicle *front = v->First();
RoadVehUpdateCache(front);
SetWindowDirty(WC_VEHICLE_DETAILS, front->index);
InvalidateWindowData(WC_VEHICLE_DETAILS, front->index);
SetWindowDirty(WC_VEHICLE_DEPOT, front->tile);
InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
} else {

View File

@ -1398,6 +1398,40 @@ struct VehicleDetailsWindow : Window {
this->tab = TDW_TAB_CARGO;
}
virtual void OnInvalidateData(int data)
{
const Vehicle *v = Vehicle::Get(this->window_number);
if (v->type == VEH_ROAD) {
const NWidgetBase *nwid_info = this->GetWidget<NWidgetBase>(VLD_WIDGET_MIDDLE_DETAILS);
uint aimed_height = this->GetRoadVehDetailsHeight(v);
/* If the number of articulated parts changes, the size of the window must change too. */
if (aimed_height != nwid_info->current_y) {
this->ReInit();
}
}
}
/**
* Gets the desired height for the road vehicle details panel.
* @param v Road vehicle being shown.
* @return Desired height in pixels.
*/
uint GetRoadVehDetailsHeight(const Vehicle *v)
{
uint desired_height;
if (RoadVehicle::From(v)->HasArticulatedPart()) {
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
desired_height = WD_FRAMERECT_TOP + 15 + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM;
/* Add space for the cargo amount for each part. */
for (const Vehicle *u = v; u != NULL; u = u->Next()) {
if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1;
}
} else {
desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
}
return desired_height;
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
switch (widget) {
@ -1425,16 +1459,7 @@ struct VehicleDetailsWindow : Window {
const Vehicle *v = Vehicle::Get(this->window_number);
switch (v->type) {
case VEH_ROAD:
if (RoadVehicle::From(v)->HasArticulatedPart()) {
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
size->height = WD_FRAMERECT_TOP + 15 + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM;
/* Add space for the cargo amount for each part. */
for (const Vehicle *u = v; u != NULL; u = u->Next()) {
if (u->cargo_cap != 0) size->height += FONT_HEIGHT_NORMAL + 1;
}
} else {
size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
}
size->height = this->GetRoadVehDetailsHeight(v);
break;
case VEH_SHIP: