diff --git a/src/elrail.cpp b/src/elrail.cpp index 701d17a26a..3fb88122db 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -310,7 +310,6 @@ static void DrawCatenaryRailway(const TileInfo *ti) }; SpriteID pylon_base = (halftile_corner != CORNER_INVALID && HasBit(edge_corners[i], halftile_corner)) ? pylon_halftile : pylon_normal; TileIndex neighbour = ti->tile + TileOffsByDiagDir(i); - Foundation foundation = FOUNDATION_NONE; byte elevation = GetPCPElevation(ti->tile, i); /* Here's one of the main headaches. GetTileSlope does not correct for possibly @@ -361,8 +360,10 @@ static void DrawCatenaryRailway(const TileInfo *ti) PPPallowed[i] = 0; } - /* A station is always "flat", so adjust the tileh accordingly */ - if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; + Foundation foundation = FOUNDATION_NONE; + + /* Station and road crossings are always "flat", so adjust the tileh accordingly */ + if (IsTileType(neighbour, MP_STATION) || IsTileType(neighbour, MP_ROAD)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; /* Read the foundataions if they are present, and adjust the tileh */ if (trackconfig[TS_NEIGHBOUR] != TRACK_BIT_NONE && IsTileType(neighbour, MP_RAILWAY) && HasCatenary(GetRailType(neighbour))) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); diff --git a/src/lang/english.txt b/src/lang/english.txt index b6c55c2c72..73db071a9e 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2483,6 +2483,8 @@ STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{RAW_ST STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contains multiple Action 8 entries STR_NEWGRF_ERROR_READ_BOUNDS :Read past end of pseudo-sprite STR_NEWGRF_ERROR_MISSING_SPRITES :{WHITE}The currently used base graphics set is missing a number of sprites.{}Please update the base graphics set +STR_NEWGRF_ERROR_GRM_FAILED :Requested GRF resources not available +STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{2:RAW_STRING} was disabled by {4:RAW_STRING} # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Caution! diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 450bc8241d..a252a8a1fd 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -282,6 +282,34 @@ static void ClearTemporaryNewGRFData(GRFFile *gf) gf->spritegroups_count = 0; } +/** + * Disable a GRF + * @param message Error message or STR_NULL + * @param config GRFConfig to disable, NULL for current + * @return Error message of the GRF for further customisation + */ +static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL) +{ + GRFFile *file; + if (config != NULL) { + file = GetFileByGRFID(config->ident.grfid); + } else { + config = _cur_grfconfig; + file = _cur_grffile; + } + + config->status = GCS_DISABLED; + if (file != NULL) ClearTemporaryNewGRFData(file); + if (config == _cur_grfconfig) _skip_sprites = -1; + + if (message != STR_NULL) { + delete config->error; + config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message); + } + + return config->error; +} + typedef std::map StringIDToGRFIDMapping; static StringIDToGRFIDMapping _string_to_grf_mapping; @@ -3288,7 +3316,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR break; case 0x12: // Station graphic - rti->total_offset = Clamp(buf->ReadByte(), 0, 2) * 82; + rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2); break; case 0x13: // Construction cost factor @@ -3497,11 +3525,7 @@ static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uin case CIR_INVALID_ID: /* No debug message for an invalid ID, as it has already been output */ - _skip_sprites = -1; - _cur_grfconfig->status = GCS_DISABLED; - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL); - _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY; + DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY); return true; } } @@ -5224,12 +5248,8 @@ static void CfgApply(ByteReader *buf) */ static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c) { - delete c->error; - c->status = GCS_DISABLED; - c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC); - c->error->data = strdup(_cur_grfconfig->GetName()); - - ClearTemporaryNewGRFData(GetFileByGRFID(c->ident.grfid)); + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c); + error->data = strdup(_cur_grfconfig->GetName()); } /* Action 0x07 @@ -5391,8 +5411,7 @@ static void SkipIf(ByteReader *buf) /* If an action 8 hasn't been encountered yet, disable the grf. */ if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) { - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); + DisableGrf(); } } } @@ -5442,11 +5461,7 @@ static void GRFInfo(ByteReader *buf) const char *name = buf->ReadString(); if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) { - _cur_grfconfig->status = GCS_DISABLED; - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_MULTIPLE_ACTION_8); - - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8); return; } @@ -5571,9 +5586,7 @@ static void GRFLoadError(ByteReader *buf) } else if (severity == 3) { /* This is a fatal error, so make sure the GRF is deactivated and no * more of it gets loaded. */ - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(); } if (message_id >= lengthof(msgstr) && message_id != 0xFF) { @@ -5755,9 +5768,7 @@ static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, ui if (op != 4 && op != 5) { /* Deactivate GRF */ grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED); return UINT_MAX; } @@ -5832,9 +5843,7 @@ static void ParamSet(ByteReader *buf) /* Check if the allocated sprites will fit below the original sprite limit */ if (_cur_spriteid + count >= 16384) { grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED); return; } @@ -6111,7 +6120,8 @@ static void GRFInhibit(ByteReader *buf) /* Unset activation flag */ if (file != NULL && file != _cur_grfconfig) { grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename); - file->status = GCS_DISABLED; + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file); + error->data = strdup(_cur_grfconfig->GetName()); } } } @@ -6182,9 +6192,7 @@ static void FeatureTownName(ByteReader *buf) if (townname->nbparts[ref_id] == 0) { grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id); DelGRFTownName(grfid); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; + DisableGrf(STR_NEWGRF_ERROR_INVALID_ID); return; } @@ -6459,16 +6467,12 @@ static void TranslateGRFStrings(ByteReader *buf) if (c->status == GCS_INITIALISED) { /* If the file is not active but will be activated later, give an error * and disable this file. */ - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_LOAD_AFTER); + GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER); char tmp[256]; GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp)); - _cur_grfconfig->error->data = strdup(tmp); + error->data = strdup(tmp); - _cur_grfconfig->status = GCS_DISABLED; - ClearTemporaryNewGRFData(_cur_grffile); - _skip_sprites = -1; return; } @@ -7914,11 +7918,7 @@ static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage) } } catch (...) { grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data"); - - _skip_sprites = -1; - _cur_grfconfig->status = GCS_DISABLED; - delete _cur_grfconfig->error; - _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_READ_BOUNDS); + DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS); } } @@ -7993,9 +7993,7 @@ void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage) } else { if (_skip_sprites == 0) { grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling"); - config->status = GCS_DISABLED; - delete config->error; - config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_UNEXPECTED_SPRITE); + DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE); break; } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index a1e45e3cc2..9ff94b7e0d 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -34,6 +34,9 @@ */ void ShowNewGRFError() { + /* Do not show errors when entering the main screen */ + if (_game_mode == GM_MENU) return; + for (const GRFConfig *c = _grfconfig; c != NULL; c = c->next) { /* We only want to show fatal errors */ if (c->error == NULL || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue; diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index d93b3467a9..83f7b03eb8 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -768,14 +768,14 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID PaletteID pal = sprites->ground.pal; if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) { image += GetCustomStationGroundRelocation(statspec, NULL, INVALID_TILE); - image += rti->custom_ground_offset; + image += rti->fallback_railtype; } else { - image += rti->total_offset; + image += rti->GetRailtypeSpriteOffset(); } DrawSprite(image, GroundSpritePaletteTransform(image, pal, palette), x, y); - DrawRailTileSeqInGUI(x, y, sprites, rti->total_offset, relocation, palette); + DrawRailTileSeqInGUI(x, y, sprites, rti->GetRailtypeSpriteOffset(), relocation, palette); return true; } diff --git a/src/rail.h b/src/rail.h index 586b853247..067db79571 100644 --- a/src/rail.h +++ b/src/rail.h @@ -162,25 +162,15 @@ struct RailtypeInfo { /** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */ RailTypes compatible_railtypes; - /** - * Offset between the current railtype and normal rail. This means that:

- * 1) All the sprites in a railset MUST be in the same order. This order - * is determined by normal rail. Check sprites 1005 and following for this order

- * 2) The position where the railtype is loaded must always be the same, otherwise - * the offset will fail. - * @note: Something more flexible might be desirable in the future. - */ - SpriteID total_offset; - /** * Bridge offset */ SpriteID bridge_offset; /** - * Offset to add to ground sprite when drawing custom waypoints / stations + * Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations. */ - byte custom_ground_offset; + byte fallback_railtype; /** * Multiplier for curve maximum speed advantage @@ -251,6 +241,18 @@ struct RailtypeInfo { { return this->group[RTSG_GROUND] != NULL; } + + /** + * Offset between the current railtype and normal rail. This means that:

+ * 1) All the sprites in a railset MUST be in the same order. This order + * is determined by normal rail. Check sprites 1005 and following for this order

+ * 2) The position where the railtype is loaded must always be the same, otherwise + * the offset will fail. + */ + inline uint GetRailtypeSpriteOffset() const + { + return 82 * this->fallback_railtype; + } }; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 9908316901..cc5162d575 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -2247,7 +2247,7 @@ static void DrawTile_Track(TileInfo *ti) image = SPR_FLAT_GRASS_TILE; } else { image = dts->ground.sprite; - if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset; + if (image != SPR_FLAT_GRASS_TILE) image += rti->GetRailtypeSpriteOffset(); } /* adjust ground tile for desert @@ -2286,7 +2286,7 @@ static void DrawTile_Track(TileInfo *ti) } int depot_sprite = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT); - relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->total_offset; + relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->GetRailtypeSpriteOffset(); } else { /* PBS debugging, draw reserved tracks darker */ if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) { @@ -2299,7 +2299,7 @@ static void DrawTile_Track(TileInfo *ti) } } - relocation = rti->total_offset; + relocation = rti->GetRailtypeSpriteOffset(); } if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti); @@ -2314,7 +2314,7 @@ void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype) const DrawTileSprites *dts = &_depot_gfx_table[dir]; const RailtypeInfo *rti = GetRailTypeInfo(railtype); SpriteID image = rti->UsesOverlay() ? SPR_FLAT_GRASS_TILE : dts->ground.sprite; - uint32 offset = rti->total_offset; + uint32 offset = rti->GetRailtypeSpriteOffset(); x += 33; y += 17; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 859753325c..418056d1f9 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2500,8 +2500,8 @@ static void DrawTile_Station(TileInfo *ti) if (HasStationRail(ti->tile)) { rti = GetRailTypeInfo(GetRailType(ti->tile)); roadtypes = ROADTYPES_NONE; - total_offset = rti->total_offset; - custom_ground_offset = rti->custom_ground_offset; + total_offset = rti->GetRailtypeSpriteOffset(); + custom_ground_offset = rti->fallback_railtype; if (IsCustomStationSpecIndex(ti->tile)) { /* look for customization */ @@ -2706,7 +2706,7 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro if (railtype != INVALID_RAILTYPE) { rti = GetRailTypeInfo(railtype); - total_offset = rti->total_offset; + total_offset = rti->GetRailtypeSpriteOffset(); } SpriteID img = t->ground.sprite; diff --git a/src/table/railtypes.h b/src/table/railtypes.h index e8a1d51e56..191714028b 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -65,13 +65,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible railtypes */ RAILTYPES_RAIL | RAILTYPES_ELECTRIC, - /* main offset */ - 0, - /* bridge offset */ 0, - /* custom ground offset */ + /* fallback_railtype */ 0, /* curve speed advantage (multiplier) */ @@ -160,13 +157,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible railtypes */ RAILTYPES_ELECTRIC | RAILTYPES_RAIL, - /* main offset */ - 0, - /* bridge offset */ 0, - /* custom ground offset */ + /* fallback_railtype */ 0, /* curve speed advantage (multiplier) */ @@ -251,13 +245,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible Railtypes */ RAILTYPES_MONO, - /* main offset */ - 82, - /* bridge offset */ 16, - /* custom ground offset */ + /* fallback_railtype */ 1, /* curve speed advantage (multiplier) */ @@ -342,13 +333,10 @@ static const RailtypeInfo _original_railtypes[] = { /* Compatible Railtypes */ RAILTYPES_MAGLEV, - /* main offset */ - 164, - /* bridge offset */ 24, - /* custom ground offset */ + /* fallback_railtype */ 2, /* curve speed advantage (multiplier) */