1
0
Fork 0

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

- Feature: [NewGRF] Textstack support for CB 38 (r20086)
- Feature: [NewGRF] Add a railtype flag to disallow level crossings per railtype (r20049)
- Fix: Reading deleted memory when selecting a NewGRF in the content download window of which the data has not been acquired from the content server. The crash would occur after the content server's reply was processed and the ContentInfo object was replaced with another [FS#3899] (r20089, r20082)
- Fix: If after loading a savegame (including intro game) one tried to save a game (including autosave) and that failed (very) early on because it could not open the file for writing all pointers would be converted to NULLs which then causes corrupted game states [FS#3876, FS#3887, FS#3920, FS#3923] (r20087)
release/1.0
rubidium 2010-07-08 19:59:13 +00:00
parent 1ac4df08b8
commit 9f041e4884
13 changed files with 72 additions and 23 deletions

View File

@ -14,7 +14,7 @@
- Fix: Pay for the rail/road when constructing tunnels, bridges, depots and stations [FS#3859, FS#3827] (r19925, r19887, r19881) - Fix: Pay for the rail/road when constructing tunnels, bridges, depots and stations [FS#3859, FS#3827] (r19925, r19887, r19881)
- Fix: Closing chatbox could cause glitches when news message was shown [FS#3865] (r19921) - Fix: Closing chatbox could cause glitches when news message was shown [FS#3865] (r19921)
- Fix: [YAPP] Inform the pathfinder as well about the fact that the backside of an one-way path signal can be a safe waiting point [FS#3803] (r19896) - Fix: [YAPP] Inform the pathfinder as well about the fact that the backside of an one-way path signal can be a safe waiting point [FS#3803] (r19896)
- Fix: Allow loading savegames from the console without specifying the ".sav" extension, i.e. make it consistent with saving savegames from the console [FS#3761] (r19885) - Fix: Allow loading savegames from the console without specifying the '.sav' extension, i.e. make it consistent with saving savegames from the console [FS#3761] (r19885)
- Fix: Dropdowns did affect positioning of new windows because they were not yet removed when the new windows were positioned [FS#3812] (r19883) - Fix: Dropdowns did affect positioning of new windows because they were not yet removed when the new windows were positioned [FS#3812] (r19883)
- Fix: [NoAI] AIEngine::IsValidEngine() and AIEngine::IsBuildable() returned false positives. Especially wagons of unavailable railtypes were reported available (r19880) - Fix: [NoAI] AIEngine::IsValidEngine() and AIEngine::IsBuildable() returned false positives. Especially wagons of unavailable railtypes were reported available (r19880)
- Fix: Default vehicle group texts were drawn one pixel too low [FS#3851] (r19878) - Fix: Default vehicle group texts were drawn one pixel too low [FS#3851] (r19878)
@ -140,7 +140,7 @@
- Fix: [NoAI] The AI Debug window did not open if an AI or library fails to compile when loading a savegame [FS#3669] (r19395) - Fix: [NoAI] The AI Debug window did not open if an AI or library fails to compile when loading a savegame [FS#3669] (r19395)
- Fix: One could not level the whole map anymore at once (r19392) - Fix: One could not level the whole map anymore at once (r19392)
- Fix: Only show the 'No AIs available' error message when explicitly changing the number of AI opponents [FS3676] (r19389) - Fix: Only show the 'No AIs available' error message when explicitly changing the number of AI opponents [FS3676] (r19389)
- Fix: [NoAI] When reloading a savegame, an AI failing to compile could trigger (trying) to read the not yet loaded information of another AI via the AI Debug window and its "open with the most recently used AI" feature [FS#3666] (r19388) - Fix: [NoAI] When reloading a savegame, an AI failing to compile could trigger (trying) to read the not yet loaded information of another AI via the AI Debug window and its 'open with the most recently used AI' feature [FS#3666] (r19388)
- Fix: Close all orders windows when switching companies [FS#3671] (r19387) - Fix: Close all orders windows when switching companies [FS#3671] (r19387)
- Fix: [IPv6] Netmask calculations were wrong if cidr >= 32 [FS#3684] (r19385) - Fix: [IPv6] Netmask calculations were wrong if cidr >= 32 [FS#3684] (r19385)
- Fix: Overbuilding bridges, rail stations did not properly update PBS reservation [FS#3680] (r19384, r19383) - Fix: Overbuilding bridges, rail stations did not properly update PBS reservation [FS#3680] (r19384, r19383)
@ -209,7 +209,7 @@
- Fix: Crash when a baseset has an empty metadata field (r19095) - Fix: Crash when a baseset has an empty metadata field (r19095)
- Fix: Possible read/write after free when the client triggered the server to close the connection [FS#3599] (r19072) - Fix: Possible read/write after free when the client triggered the server to close the connection [FS#3599] (r19072)
- Fix: Remove Bidi control characters from the reordered text so they are not drawn [FS#3604] (r19067) - Fix: Remove Bidi control characters from the reordered text so they are not drawn [FS#3604] (r19067)
- Fix: [NewGRF] Settings that are part of the "TTPatch flags" can cause desyncs if they are changed in network games (r19066) - Fix: [NewGRF] Settings that are part of the 'TTPatch flags' can cause desyncs if they are changed in network games (r19066)
- Fix: When banning yourself via rcon do not send the 'command response' to the client as the connection has already been terminated [FS#3598] (r19054) - Fix: When banning yourself via rcon do not send the 'command response' to the client as the connection has already been terminated [FS#3598] (r19054)
- Fix: Mass stopping/starting/autoreplacing gave empty errors when there were no vehicles [FS#3577] (r19024) - Fix: Mass stopping/starting/autoreplacing gave empty errors when there were no vehicles [FS#3577] (r19024)
- Fix: City airport introduction date had become 5 years later (r19023) - Fix: City airport introduction date had become 5 years later (r19023)

View File

@ -14,6 +14,11 @@
* functions may still be available if you return an older API version * functions may still be available if you return an older API version
* in GetAPIVersion() in info.nut. * in GetAPIVersion() in info.nut.
* *
* \b 1.0.3
*
* API additions:
* \li AIRail::ERR_RAILTYPE_DISALLOWS_CROSSING
*
* \b 1.0.2 * \b 1.0.2
* *
* Other changes: * Other changes:

View File

@ -38,6 +38,9 @@ public:
/** Non-uniform stations is diabled */ /** Non-uniform stations is diabled */
ERR_NONUNIFORM_STATIONS_DISABLED, // [STR_ERROR_NONUNIFORM_STATIONS_DISALLOWED] ERR_NONUNIFORM_STATIONS_DISABLED, // [STR_ERROR_NONUNIFORM_STATIONS_DISALLOWED]
/** This railtype cannot have crossings */
ERR_RAILTYPE_DISALLOWS_CROSSING, // [STR_ERROR_CROSSING_DISALLOWED]
}; };
/** /**

View File

@ -42,6 +42,7 @@ void SQAIRail_Register(Squirrel *engine)
SQAIRail.DefSQConst(engine, AIRail::ERR_CROSSING_ON_ONEWAY_ROAD, "ERR_CROSSING_ON_ONEWAY_ROAD"); SQAIRail.DefSQConst(engine, AIRail::ERR_CROSSING_ON_ONEWAY_ROAD, "ERR_CROSSING_ON_ONEWAY_ROAD");
SQAIRail.DefSQConst(engine, AIRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK"); SQAIRail.DefSQConst(engine, AIRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK");
SQAIRail.DefSQConst(engine, AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED"); SQAIRail.DefSQConst(engine, AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED");
SQAIRail.DefSQConst(engine, AIRail::ERR_RAILTYPE_DISALLOWS_CROSSING, "ERR_RAILTYPE_DISALLOWS_CROSSING");
SQAIRail.DefSQConst(engine, AIRail::RAILTYPE_INVALID, "RAILTYPE_INVALID"); SQAIRail.DefSQConst(engine, AIRail::RAILTYPE_INVALID, "RAILTYPE_INVALID");
SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NE_SW, "RAILTRACK_NE_SW"); SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NE_SW, "RAILTRACK_NE_SW");
SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NW_SE, "RAILTRACK_NW_SE"); SQAIRail.DefSQConst(engine, AIRail::RAILTRACK_NW_SE, "RAILTRACK_NW_SE");
@ -71,10 +72,12 @@ void SQAIRail_Register(Squirrel *engine)
AIError::RegisterErrorMap(STR_ERROR_CROSSING_ON_ONEWAY_ROAD, AIRail::ERR_CROSSING_ON_ONEWAY_ROAD); AIError::RegisterErrorMap(STR_ERROR_CROSSING_ON_ONEWAY_ROAD, AIRail::ERR_CROSSING_ON_ONEWAY_ROAD);
AIError::RegisterErrorMap(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK, AIRail::ERR_UNSUITABLE_TRACK); AIError::RegisterErrorMap(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK, AIRail::ERR_UNSUITABLE_TRACK);
AIError::RegisterErrorMap(STR_ERROR_NONUNIFORM_STATIONS_DISALLOWED, AIRail::ERR_NONUNIFORM_STATIONS_DISABLED); AIError::RegisterErrorMap(STR_ERROR_NONUNIFORM_STATIONS_DISALLOWED, AIRail::ERR_NONUNIFORM_STATIONS_DISABLED);
AIError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED, AIRail::ERR_RAILTYPE_DISALLOWS_CROSSING);
AIError::RegisterErrorMapString(AIRail::ERR_CROSSING_ON_ONEWAY_ROAD, "ERR_CROSSING_ON_ONEWAY_ROAD"); AIError::RegisterErrorMapString(AIRail::ERR_CROSSING_ON_ONEWAY_ROAD, "ERR_CROSSING_ON_ONEWAY_ROAD");
AIError::RegisterErrorMapString(AIRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK"); AIError::RegisterErrorMapString(AIRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK");
AIError::RegisterErrorMapString(AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED"); AIError::RegisterErrorMapString(AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED");
AIError::RegisterErrorMapString(AIRail::ERR_RAILTYPE_DISALLOWS_CROSSING, "ERR_RAILTYPE_DISALLOWS_CROSSING");
SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTile, "IsRailTile", 2, ".i"); SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTile, "IsRailTile", 2, ".i");
SQAIRail.DefSQStaticMethod(engine, &AIRail::IsLevelCrossingTile, "IsLevelCrossingTile", 2, ".i"); SQAIRail.DefSQStaticMethod(engine, &AIRail::IsLevelCrossingTile, "IsLevelCrossingTile", 2, ".i");

View File

@ -374,14 +374,12 @@ public:
uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, NULL, this->selected_type, INVALID_TILE); uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, NULL, this->selected_type, INVALID_TILE);
if (callback_res != CALLBACK_FAILED) { // Did it fail? if (callback_res != CALLBACK_FAILED) { // Did it fail?
str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string
if (str != STR_UNDEFINED) {
PrepareTextRefStackUsage(6);
DrawStringMultiLine(left, right, y, bottom, str);
StopTextRefStackUsage();
} }
} }
/* Draw the Additional purchase text, provided by newgrf callback, if any.
* Otherwhise, will print Nothing */
if (str != STR_NULL && str != STR_UNDEFINED) {
SetDParam(0, str);
DrawStringMultiLine(left, right, y, bottom, STR_JUST_STRING);
} }
} break; } break;
} }

View File

@ -3498,6 +3498,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Must rem
STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railway track STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railway track
STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railway track first STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railway track first
STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Road is one way or blocked STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Road is one way or blocked
STR_ERROR_CROSSING_DISALLOWED :{WHITE}Level crossings not allowed for this rail type
STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here... STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here...
STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railway track here... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railway track here...
STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railway track from here... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railway track from here...

View File

@ -27,6 +27,21 @@ ContentInfo::~ContentInfo()
free(this->tags); free(this->tags);
} }
/**
* Copy data from other #ContentInfo and take ownership of allocated stuff.
* @param other Source to copy from. #dependencies and #tags will be NULLed.
*/
void ContentInfo::TransferFrom(ContentInfo *other)
{
if (other != this) {
free(this->dependencies);
free(this->tags);
memcpy(this, other, sizeof(ContentInfo));
other->dependencies = NULL;
other->tags = NULL;
}
}
size_t ContentInfo::Size() const size_t ContentInfo::Size() const
{ {
size_t len = 0; size_t len = 0;

View File

@ -88,6 +88,8 @@ struct ContentInfo {
/** Free everything allocated */ /** Free everything allocated */
~ContentInfo(); ~ContentInfo();
void TransferFrom(ContentInfo *other);
/** /**
* Get the size of the data as send over the network. * Get the size of the data as send over the network.
* @return the size. * @return the size.

View File

@ -132,10 +132,16 @@ DEF_CONTENT_RECEIVE_COMMAND(Client, PACKET_CONTENT_SERVER_INFO)
if (StrEmpty(ci->name)) strecpy(ci->name, ici->name, lastof(ci->name)); if (StrEmpty(ci->name)) strecpy(ci->name, ici->name, lastof(ci->name));
if (ici->IsSelected()) ci->state = ici->state; if (ici->IsSelected()) ci->state = ici->state;
delete ici; /*
*iter = ci; * As ici might be selected by the content window we cannot delete that.
* However, we want to keep most of the values of ci, except the values
* we (just) already preserved.
* So transfer data and ownership of allocated memory from ci to ici.
*/
ici->TransferFrom(ci);
delete ci;
this->OnReceiveContentInfo(ci); this->OnReceiveContentInfo(ici);
return true; return true;
} }
} }

View File

@ -20,13 +20,13 @@
#include "slope_type.h" #include "slope_type.h"
#include "strings_type.h" #include "strings_type.h"
enum RailTypeFlag {
RTF_CATENARY = 0, ///< Set if the rail type should have catenary drawn
};
enum RailTypeFlags { enum RailTypeFlags {
RTFB_NONE = 0, RTF_CATENARY = 0, ///< Bit number for drawing a catenary.
RTFB_CATENARY = 1 << RTF_CATENARY, RTF_NO_LEVEL_CROSSING = 1, ///< Bit number for disallowing level crossings.
RTFB_NONE = 0, ///< All flags cleared.
RTFB_CATENARY = 1 << RTF_CATENARY, ///< Value for drawing a catenary.
RTFB_NO_LEVEL_CROSSING = 1 << RTF_NO_LEVEL_CROSSING, ///< Value for disallowing level crossings.
}; };
DECLARE_ENUM_AS_BIT_SET(RailTypeFlags); DECLARE_ENUM_AS_BIT_SET(RailTypeFlags);
@ -258,6 +258,16 @@ static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype)
return HasBit(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype); return HasBit(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype);
} }
/**
* Test if a RailType disallows build of level crossings.
* @param rt The RailType to check.
* @return Whether level crossings are not allowed.
*/
static inline bool RailNoLevelCrossings(RailType rt)
{
return HasBit(GetRailTypeInfo(rt)->flags, RTF_NO_LEVEL_CROSSING);
}
/** /**
* Returns the cost of building the specified railtype. * Returns the cost of building the specified railtype.
* @param railtype The railtype being built. * @param railtype The railtype being built.

View File

@ -431,6 +431,8 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u
if (GetDisallowedRoadDirections(tile) != DRD_NONE) return_cmd_error(STR_ERROR_CROSSING_ON_ONEWAY_ROAD); if (GetDisallowedRoadDirections(tile) != DRD_NONE) return_cmd_error(STR_ERROR_CROSSING_ON_ONEWAY_ROAD);
if (RailNoLevelCrossings(railtype)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED);
RoadTypes roadtypes = GetRoadTypes(tile); RoadTypes roadtypes = GetRoadTypes(tile);
RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD); RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM); RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);

View File

@ -532,6 +532,10 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear; if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear;
if (RailNoLevelCrossings(GetRailType(tile))) {
return_cmd_error(STR_ERROR_CROSSING_DISALLOWED);
}
Axis roaddir; Axis roaddir;
switch (GetTrackBits(tile)) { switch (GetTrackBits(tile)) {
case TRACK_BIT_X: case TRACK_BIT_X:

View File

@ -1864,6 +1864,10 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
} }
_sl.excpt_uninit = NULL; _sl.excpt_uninit = NULL;
_sl.bufe = _sl.bufp = NULL;
_sl.offs_base = 0;
_sl.action = (mode != 0) ? SLA_SAVE : SLA_LOAD;
try { try {
_sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb); _sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
@ -1875,10 +1879,6 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
} }
_sl.bufe = _sl.bufp = NULL;
_sl.offs_base = 0;
_sl.action = (mode != 0) ? SLA_SAVE : SLA_LOAD;
/* General tactic is to first save the game to memory, then use an available writer /* General tactic is to first save the game to memory, then use an available writer
* to write it to file, either in threaded mode if possible, or single-threaded */ * to write it to file, either in threaded mode if possible, or single-threaded */
if (mode == SL_SAVE) { // SAVE game if (mode == SL_SAVE) { // SAVE game