1
0
Fork 0

(svn r22993) [1.1] -Backport from trunk:

- Fix: The savegame description and loading of savegames would crash with savegames from a patched stable (which did not bump the savegame version) [FS#4778] (r22958, r22957)
- Fix: Guard from reading outside the silly name list (r22955)
- Fix: [NewGRF] Properly limit the length of strings in a choice list (r22952)
- Fix: [NewGRF] Do not call CB 32 for disaster, effect vehicles or aircraft shadows/rotors (r22947)
release/1.1
rubidium 2011-10-04 20:15:50 +00:00
parent 997a4aee46
commit 3daf4d012b
9 changed files with 40 additions and 17 deletions

View File

@ -349,7 +349,7 @@ static void GenerateCompanyName(Company *c)
StringID str;
uint32 strp;
if (t->name == NULL && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) {
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START;
strp = t->townnameparts;
verify_name:;

View File

@ -371,7 +371,9 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator {
for (int i = 0; i < count; i++) {
int idx = (this->type == SCC_GENDER_LIST ? lm->GetReverseMapping(i, true) : i + 1);
const char *str = this->strings[this->strings.Contains(idx) ? idx : 0];
size_t len = strlen(str);
/* Limit the length of the string we copy to 0xFE. The length is written above
* as a byte and we need room for the final '\0'. */
size_t len = min(0xFE, strlen(str));
memcpy(d, str, len);
d += len;
*d++ = '\0';

View File

@ -349,8 +349,7 @@ static void Check_PLYR()
SaveLoad_PLYR_common(NULL, cprops);
/* We do not load old custom names */
if (IsSavegameVersionBefore(84))
{
if (IsSavegameVersionBefore(84)) {
if (GB(cprops->name_1, 11, 5) == 15) {
cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
@ -360,6 +359,13 @@ static void Check_PLYR()
}
}
if (cprops->name == NULL && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) &&
cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED &&
cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME &&
cprops->name_1 != SPECSTR_SILLY_NAME) {
cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
if (!_load_check_data.companies.Insert(index, cprops)) delete cprops;
}
}

View File

@ -29,8 +29,8 @@ StringID RemapOldStringID(StringID s)
switch (s) {
case 0x0006: return STR_SV_EMPTY;
case 0x7000: return STR_SV_UNNAMED;
case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
case 0x70E4: return SPECSTR_COMPANY_NAME_START;
case 0x70E9: return SPECSTR_COMPANY_NAME_START;
case 0x8864: return STR_SV_TRAIN_NAME;
case 0x902B: return STR_SV_ROAD_VEHICLE_NAME;
case 0x9830: return STR_SV_SHIP_NAME;

View File

@ -204,6 +204,10 @@ static void Load_TOWN()
while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town();
SlObject(t, _town_desc);
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST)) {
SlErrorCorrupt("Invalid town name generator");
}
}
}

View File

@ -1413,7 +1413,7 @@ static char *GetSpecialNameString(char *buff, int ind, int64 *argv, const int64
{
switch (ind) {
case 1: // not used
return strecpy(buff, _silly_company_names[GetInt32(&argv, argve, &argt) & 0xFFFF], last);
return strecpy(buff, _silly_company_names[min(GetInt32(&argv, argve, &argt) & 0xFFFF, lengthof(_silly_company_names) - 1)], last);
case 2: // used for Foobar & Co company names
return GenAndCoName(buff, GetInt32(&argv, argve, &argt), last);

View File

@ -54,16 +54,11 @@ enum SpecialStrings {
SPECSTR_TOWNNAME_CATALAN,
SPECSTR_TOWNNAME_LAST = SPECSTR_TOWNNAME_CATALAN,
/* special strings for player names on the form "TownName transport". */
SPECSTR_PLAYERNAME_START = 0x70EA,
SPECSTR_PLAYERNAME_ENGLISH = SPECSTR_PLAYERNAME_START,
SPECSTR_PLAYERNAME_FRENCH,
SPECSTR_PLAYERNAME_GERMAN,
SPECSTR_PLAYERNAME_AMERICAN,
SPECSTR_PLAYERNAME_LATIN,
SPECSTR_PLAYERNAME_SILLY,
SPECSTR_PLAYERNAME_LAST = SPECSTR_PLAYERNAME_SILLY,
/* special strings for company names on the form "TownName transport". */
SPECSTR_COMPANY_NAME_START = 0x70EA,
SPECSTR_COMPANY_NAME_LAST = SPECSTR_COMPANY_NAME_START + SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START,
SPECSTR_SILLY_NAME = 0x70E5,
SPECSTR_ANDCO_NAME = 0x70E6,
SPECSTR_PRESIDENT_NAME = 0x70E7,

View File

@ -634,6 +634,21 @@ bool Vehicle::IsEngineCountable() const
}
}
/**
* Check whether Vehicle::engine_type has any meaning.
* @return true if the vehicle has a useable engine type.
*/
bool Vehicle::HasEngineType() const
{
switch (this->type) {
case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft();
case VEH_TRAIN:
case VEH_ROAD:
case VEH_SHIP: return true;
default: return false;
}
}
/**
* Handle the pathfinding result, especially the lost status.
* If the vehicle is now lost and wasn't previously fire an
@ -784,7 +799,7 @@ static void RunVehicleDayProc()
if (v == NULL) continue;
/* Call the 32-day callback if needed */
if ((v->day_counter & 0x1F) == 0) {
if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) {
uint16 callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
if (callback != CALLBACK_FAILED) {
if (HasBit(callback, 0)) TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10

View File

@ -701,6 +701,7 @@ public:
}
bool IsEngineCountable() const;
bool HasEngineType() const;
bool HasDepotOrder() const;
void HandlePathfindingResult(bool path_found);