mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-04 06:00:15 +00:00
(svn r11862) -Fix [FS#1559]: when two NewGRFs 'fight' to define the same cargo it could happen that the strings are defined by one cargo and the 'action2' by another and when one assumes that both come from the same NewGRF... So store the GRF ID with the strings. To be extra sure add the same protection mechanism to industries and towns too.
This commit is contained in:
parent
e0c61a8921
commit
fcee6dad93
@ -7,7 +7,7 @@
|
||||
|
||||
#include "cargo_type.h"
|
||||
#include "gfx_type.h"
|
||||
#include "strings_type.h"
|
||||
#include "newgrf_string_type.h"
|
||||
|
||||
typedef uint32 CargoLabel;
|
||||
|
||||
@ -36,11 +36,11 @@ struct CargoSpec {
|
||||
uint16 multipliertowngrowth;
|
||||
uint8 callback_mask;
|
||||
|
||||
StringID name;
|
||||
StringID name_single;
|
||||
StringID units_volume;
|
||||
StringID quantifier;
|
||||
StringID abbrev;
|
||||
GRFMappedStringID name;
|
||||
GRFMappedStringID name_single;
|
||||
GRFMappedStringID units_volume;
|
||||
GRFMappedStringID quantifier;
|
||||
GRFMappedStringID abbrev;
|
||||
|
||||
SpriteID sprite;
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "date_type.h"
|
||||
#include "town_type.h"
|
||||
#include "industry_type.h"
|
||||
#include "strings_type.h"
|
||||
#include "newgrf_string_type.h"
|
||||
|
||||
enum {
|
||||
INVALID_INDUSTRY = 0xFFFF,
|
||||
@ -174,11 +174,11 @@ struct IndustrySpec {
|
||||
byte climate_availability; ///< Bitmask, giving landscape enums as bit position
|
||||
IndustryBehaviour behaviour; ///< How this industry will behave, and how others entities can use it
|
||||
byte map_colour; ///< colour used for the small map
|
||||
StringID name; ///< Displayed name of the industry
|
||||
StringID new_industry_text; ///< Message appearing when the industry is built
|
||||
StringID closure_text; ///< Message appearing when the industry closes
|
||||
StringID production_up_text; ///< Message appearing when the industry's production is increasing
|
||||
StringID production_down_text; ///< Message appearing when the industry's production is decreasing
|
||||
GRFMappedStringID name; ///< Displayed name of the industry
|
||||
GRFMappedStringID new_industry_text; ///< Message appearing when the industry is built
|
||||
GRFMappedStringID closure_text; ///< Message appearing when the industry closes
|
||||
GRFMappedStringID production_up_text; ///< Message appearing when the industry's production is increasing
|
||||
GRFMappedStringID production_down_text; ///< Message appearing when the industry's production is decreasing
|
||||
byte appear_ingame[NUM_LANDSCAPE]; ///< Probability of appearance in game
|
||||
byte appear_creation[NUM_LANDSCAPE]; ///< Probability of appearance during map creation
|
||||
uint8 number_of_sounds; ///< Number of sounds available in the sounds array
|
||||
|
@ -1343,7 +1343,7 @@ static bool TownHouseChangeInfo(uint hid, int numinfo, int prop, byte **bufp, in
|
||||
break;
|
||||
|
||||
case 0x12: // Building name ID
|
||||
housespec->building_name = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
housespec->building_name = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x13: // Building availability mask
|
||||
@ -1596,25 +1596,25 @@ static bool CargoChangeInfo(uint cid, int numinfo, int prop, byte **bufp, int le
|
||||
break;
|
||||
|
||||
case 0x09: /* String ID for cargo type name */
|
||||
cs->name = grf_load_word(&buf);
|
||||
cs->name = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0A: /* String for 1 unit of cargo */
|
||||
cs->name_single = grf_load_word(&buf);
|
||||
cs->name_single = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0B:
|
||||
/* String for units of cargo. This is different in OpenTTD to TTDPatch
|
||||
* (e.g. 10 tonnes of coal) */
|
||||
cs->units_volume = grf_load_word(&buf);
|
||||
cs->units_volume = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0C: /* String for quantity of cargo (e.g. 10 tonnes of coal) */
|
||||
cs->quantifier = grf_load_word(&buf);
|
||||
cs->quantifier = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0D: /* String for two letter cargo abbreviation */
|
||||
cs->abbrev = grf_load_word(&buf);
|
||||
cs->abbrev = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0E: /* Sprite ID for cargo icon */
|
||||
@ -1998,15 +1998,15 @@ static bool IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp,
|
||||
break;
|
||||
|
||||
case 0x0C: // Industry closure message
|
||||
indsp->closure_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
indsp->closure_text = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0D: // Production increase message
|
||||
indsp->production_up_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
indsp->production_up_text = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0E: // Production decrease message
|
||||
indsp->production_down_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
indsp->production_down_text = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x0F: // Fund cost multiplier
|
||||
@ -2065,7 +2065,7 @@ static bool IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp,
|
||||
break;
|
||||
|
||||
case 0x1B: // New industry text ID
|
||||
indsp->new_industry_text = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
indsp->new_industry_text = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x1C: // Input cargo multipliers for the three input cargo types
|
||||
@ -2077,7 +2077,7 @@ static bool IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp,
|
||||
} break;
|
||||
|
||||
case 0x1F: // Industry name
|
||||
indsp->name = MapGRFStringID(_cur_grffile->grfid, grf_load_word(&buf));
|
||||
indsp->name = GRFMappedStringID(grf_load_word(&buf), _cur_grffile->grfid);
|
||||
break;
|
||||
|
||||
case 0x20: // Prospecting success chance
|
||||
@ -3208,7 +3208,7 @@ static void FeatureNewName(byte *buf, int len)
|
||||
if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
|
||||
grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
|
||||
} else {
|
||||
_cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
|
||||
_cur_grffile->housespec[GB(id, 0, 8)]->building_name = GRFMappedStringID(AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED), 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5284,6 +5284,7 @@ static void FinaliseHouseArray()
|
||||
for (int i = 0; i < HOUSE_MAX; i++) {
|
||||
HouseSpec *hs = file->housespec[i];
|
||||
if (hs != NULL) {
|
||||
hs->building_name.MapString();
|
||||
_house_mngr.SetEntitySpec(hs);
|
||||
if (hs->min_date < min_date) min_date = hs->min_date;
|
||||
}
|
||||
@ -5314,18 +5315,23 @@ static void FinaliseIndustriesArray()
|
||||
/* process the conversion of text at the end, so to be sure everything will be fine
|
||||
* and available. Check if it does not return undefind marker, which is a very good sign of a
|
||||
* substitute industry who has not changed the string been examined, thus using it as such */
|
||||
indsp->name.MapString();
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
|
||||
if (strid != STR_UNDEFINED) indsp->name = strid;
|
||||
|
||||
indsp->closure_text.MapString();
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
|
||||
if (strid != STR_UNDEFINED) indsp->closure_text = strid;
|
||||
|
||||
indsp->production_up_text.MapString();
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
|
||||
if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
|
||||
|
||||
indsp->production_down_text.MapString();
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
|
||||
if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
|
||||
|
||||
indsp->new_industry_text.MapString();
|
||||
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
|
||||
if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
|
||||
|
||||
@ -5365,11 +5371,11 @@ static void MapNewCargoStrings()
|
||||
/* Don't map if the cargo is unavailable or not from NewGRF */
|
||||
if (cs->grfid == 0) continue;
|
||||
|
||||
cs->name = MapGRFStringID(cs->grfid, cs->name);
|
||||
cs->name_single = MapGRFStringID(cs->grfid, cs->name_single);
|
||||
cs->units_volume = MapGRFStringID(cs->grfid, cs->units_volume);
|
||||
cs->quantifier = MapGRFStringID(cs->grfid, cs->quantifier);
|
||||
cs->abbrev = MapGRFStringID(cs->grfid, cs->abbrev);
|
||||
cs->name.MapString();
|
||||
cs->name_single.MapString();
|
||||
cs->units_volume.MapString();
|
||||
cs->quantifier.MapString();
|
||||
cs->abbrev.MapString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -5636,3 +5642,11 @@ bool HasGrfMiscBit(GrfMiscBit bit)
|
||||
{
|
||||
return HasBit(_misc_grf_features, bit);
|
||||
}
|
||||
|
||||
void GRFMappedStringID::MapString()
|
||||
{
|
||||
if (this->grfid == 0) return;
|
||||
|
||||
this->string = MapGRFStringID(this->grfid, this->string);
|
||||
this->grfid = 0;
|
||||
}
|
||||
|
54
src/newgrf_string_type.h
Normal file
54
src/newgrf_string_type.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file newgrf_string_type.h */
|
||||
|
||||
#ifndef NEWGRF_STRING_TYPE_H
|
||||
#define NEWGRF_STRING_TYPE_H
|
||||
|
||||
#include "strings_type.h"
|
||||
|
||||
/**
|
||||
* A string with the required information to perform a GRF string remapping.
|
||||
*/
|
||||
struct GRFMappedStringID
|
||||
{
|
||||
private:
|
||||
/** The GRF ID associated to the to-be-remapped string */
|
||||
uint32 grfid;
|
||||
/** The string; when grfid != 0 it should be remapped */
|
||||
StringID string;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create the struct.
|
||||
* @param str the string to store (or remap)
|
||||
* @param grf_id the GRF to remap it with
|
||||
*/
|
||||
GRFMappedStringID(StringID str, uint32 grf_id) : grfid(grf_id), string(str) {}
|
||||
|
||||
/**
|
||||
* An empty string.
|
||||
*/
|
||||
GRFMappedStringID() {}
|
||||
|
||||
/** Cast operator, returns the string */
|
||||
inline operator StringID() const
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
/** Assigns the string and resets the GRF ID. */
|
||||
GRFMappedStringID& operator = (StringID str)
|
||||
{
|
||||
string = str;
|
||||
grfid = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the string.
|
||||
*/
|
||||
void MapString();
|
||||
};
|
||||
|
||||
#endif /* NEWGRF_STRING_TYPE_H */
|
@ -1176,7 +1176,7 @@ enum {
|
||||
#define MI(tbl, sndc, snd, d, pc, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \
|
||||
c1, c2, c3, proc, p1, r1, p2, r2, m, a1, im1, a2, im2, a3, im3, pr, clim, bev, in, intx, s1, s2, s3) \
|
||||
{tbl, lengthof(tbl), min(255, d), 0, d, pc, {c1, c2, c3}, proc, {p1, p2}, {r1, r2}, m, \
|
||||
{a1, a2, a3}, {{im1, 0}, {im2, 0}, {im3, 0}}, pr, clim, bev, col, in, intx, s1, s2, s3, {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, \
|
||||
{a1, a2, a3}, {{im1, 0}, {im2, 0}, {im3, 0}}, pr, clim, bev, col, GRFMappedStringID(in, 0), GRFMappedStringID(intx, 0), GRFMappedStringID(s1, 0), GRFMappedStringID(s2, 0), GRFMappedStringID(s3, 0), {ai1, ai2, ai3, ai4}, {ag1, ag2, ag3, ag4}, \
|
||||
sndc, snd, 0, 0, true, {INVALID_INDUSTRYTYPE, 0, NULL, NULL, INVALID_INDUSTRYTYPE}}
|
||||
/* Format:
|
||||
tile table count and sounds table
|
||||
|
@ -3,7 +3,7 @@
|
||||
/* Table of all default cargo types */
|
||||
|
||||
#define MK(bt, label, c, e, f, g, h, fr, te, ks1, ks2, ks3, ks4, ks5, l, m) \
|
||||
{bt, label, 0, c, c, e, f, {g, h}, fr, te, 0, 0, ks1, ks2, ks3, ks4, ks5, l, m, NULL}
|
||||
{bt, label, 0, c, c, e, f, {g, h}, fr, te, 0, 0, GRFMappedStringID(ks1, 0), GRFMappedStringID(ks2, 0), GRFMappedStringID(ks3, 0), GRFMappedStringID(ks4, 0), GRFMappedStringID(ks5, 0), l, m, NULL}
|
||||
static const CargoSpec _default_cargo[] = {
|
||||
MK( 0, 'PASS', 152, 1, 3185, 0, 24, false, TE_PASSENGERS,
|
||||
STR_000F_PASSENGERS, STR_002F_PASSENGER, STR_PASSENGERS, STR_QUANTITY_PASSENGERS, STR_ABBREV_PASSENGERS,
|
||||
|
@ -1803,7 +1803,7 @@ assert_compile(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4);
|
||||
* @see HouseSpec
|
||||
*/
|
||||
#define MS(mnd, mxd, p, rc, bn, rr, mg, ca1, ca2, ca3, bf, ba, cg1, cg2, cg3) \
|
||||
{mnd, mxd, p, rc, bn, rr, mg, {ca1, ca2, ca3}, {cg1, cg2, cg3}, bf, ba, true, \
|
||||
{mnd, mxd, p, rc, GRFMappedStringID(bn, 0), rr, mg, {ca1, ca2, ca3}, {cg1, cg2, cg3}, bf, ba, true, \
|
||||
0, NULL, 0, 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, 0, 2, 0, 0, 0, NULL}
|
||||
/** House specifications from original data */
|
||||
static const HouseSpec _original_house_specs[] = {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "date_type.h"
|
||||
#include "town_type.h"
|
||||
#include "player_type.h"
|
||||
#include "strings_type.h"
|
||||
#include "newgrf_string_type.h"
|
||||
|
||||
enum {
|
||||
HOUSE_NO_CLASS = 0,
|
||||
@ -170,7 +170,7 @@ struct HouseSpec {
|
||||
Year max_date; ///< last year it can be built
|
||||
byte population; ///< population (Zero on other tiles in multi tile house.)
|
||||
byte removal_cost; ///< cost multiplier for removing it
|
||||
StringID building_name; ///< building name
|
||||
GRFMappedStringID building_name; ///< building name
|
||||
uint16 remove_rating_decrease; ///< rating decrease if removed
|
||||
byte mail_generation; ///< mail generation multiplier (tile based, as the acceptances below)
|
||||
byte cargo_acceptance[3]; ///< acceptance level for the cargo slots
|
||||
|
Loading…
Reference in New Issue
Block a user