(svn r13827) [0.6] -Backport from trunk:

- Fix: Building through the wrong side of a drive through station was allowed [FS#2166] (r13822)
- Fix: Check for vehicle length changes outside a depot (callback 0x11) and give a warning about that [FS#2150] (r13816)
- Fix: Remove the unique_id from the message that a client has joined as it is only exposes the unique_id more than needed (r13714)
This commit is contained in:
rubidium 2008-07-25 19:54:14 +00:00
parent c29c7f7932
commit a0f6275c3a
23 changed files with 147 additions and 44 deletions

View File

@ -1,5 +1,7 @@
0.6.2 ?? (2008-??-??)
0.6.2-RC2 (2008-07-25)
------------------------------------------------------------------------
- Fix: Building through the wrong side of a drive through station was allowed [FS#2166] (r13822)
- Fix: Check for vehicle length changes outside a depot (callback 0x11) and give a warning about that [FS#2150] (r13816)
- Fix: Several minor memory leaks. They only happened once per game (r13809, 13810)
- Fix: Checking for train waiting at other side of two-way signal was broken [FS#2162] (r13806)
- Fix: Some revision checking code was unintentionally disabled (r13776)
@ -9,6 +11,7 @@
- Fix: Assumption that non-north tiles of a house do not have the 1x1 building bit set was flawed with some NewGRFs. This caused the amount of houses to differ, which causes the town radii to differ, which causes desyncs when towns are expanded (r13729)
- Fix: Possible desync on the autorenew settings 20+ game years (i.e. 4.5+ hours) after a company was started (r13718)
- Fix: Any player could construct new companies [FS#2144] (r13716)
- Fix: Remove the unique_id from the message that a client has joined as it is only exposes the unique_id more than needed (r13714)
- Fix: Possible crash on creating a network packet (r13713)
- Fix: Enforce the length restrictions of company and president name in the commands too (r13712)

View File

@ -1,28 +1,37 @@
.\" Hey, EMACS: -*- nroff -*-
.\" Please adjust this date whenever revising the manpage.
.Dd Sep 15, 2007
.Dd Jul 20, 2008
.Dt OPENTTD 6
.Sh NAME
.Nm openttd
.Nd An open source clone of the Microprose game "Transport Tycoon Deluxe"
.Sh SYNOPSIS
.Nm
.Op Fl Defhi
.Op Fl Defhix
.Op Fl G Ar seed
.Op Fl b Ar blitter
.Op Fl d Ar [level | cat=lvl[, ...]]
.Op Fl c Ar config_file
.Op Fl g Ar [savegame]
.Op Fl l Ar host[:port]
.Op Fl n Ar host[:port][#player]
.Op Fl r Ar widthxheight
.Op Fl t Ar date
.Op Fl m Ar driver
.Op Fl s Ar driver
.Op Fl v Ar driver
.Op Fl b Ar blitter
.Sh OPTIONS
.Bl -tag -width ".Fl n Ar host[:port][#player]"
.It Fl D
.It Fl D Ar [host][:port]
Start a dedicated server
.It Fl G Ar seed
Seed the pseudo random number generator
.It Fl b Ar blitter
Set the blitter, see
.Fl h
.It Fl c Ar config_file
Use 'config_file' instead of 'openttd.cfg'
.It Fl d Ar [level]
Set debug verbosity for all categories to
.Ar level
@ -42,6 +51,9 @@ at start or start a new game if omitted
Display a summary of all options and available drivers
.It Fl i
Force to use the DOS palette (use this if you see a lot of magenta)
.It Fl l Ar host[:port]
Redirect DEBUG(), See
.Fl D
.It Fl m Ar driver
Set the music driver, see
.Fl h
@ -57,6 +69,8 @@ Set the starting date
.It Fl v Ar driver
Set the video driver, see
.Fl h
.It Fl x
Do not automatically save to config file on exit
.El
.Sh SEE ALSO
http://wiki.openttd.org/, http://www.openttd.org

View File

@ -11,7 +11,7 @@ by the number below on http://bugs.openttd.org.
If the bug report is closed, it has been fixed, which then can be verified
in the latest SVN version of /trunk.
Bugs for 0.6.1
Bugs for 0.6.2-RC2
------------------------------------------------------------------------
URL: http://bugs.openttd.org

View File

@ -1,3 +1,9 @@
openttd (0.6.2~RC2-1) unstable; urgency=low
* New upstream release.
-- Matthijs Kooijman <m.kooijman@student.utwente.nl> Fri, 25 Jul 2008 22:00:00 +0200
openttd (0.6.2~RC1-1) unstable; urgency=low
* New upstream release.

View File

@ -1,6 +1,6 @@
!define APPNAME "OpenTTD" ; Define application name
!define APPVERSION "0.6.2" ; Define application version
!define INSTALLERVERSION 49 ; NEED TO UPDATE THIS FOR EVERY RELEASE!!!
!define INSTALLERVERSION 50 ; NEED TO UPDATE THIS FOR EVERY RELEASE!!!
!define APPURLLINK "http://www.openttd.org"
!define APPNAMEANDVERSION "${APPNAME} ${APPVERSION}"

View File

@ -1,6 +1,6 @@
OpenTTD README
Last updated: 2008-07-16
Release version: 0.6.2-RC1
Last updated: 2008-07-25
Release version: 0.6.2-RC2
------------------------------------------------------------------------

View File

@ -58,7 +58,7 @@ static void MoveVehicleCargo(Vehicle *dest, Vehicle *source)
* the complete train, which is without the weight of cargo we just
* moved back into some (of the) new wagon(s).
*/
if (dest->type == VEH_TRAIN) TrainConsistChanged(dest->First());
if (dest->type == VEH_TRAIN) TrainConsistChanged(dest->First(), true);
}
static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, const EngineID engine_type)

View File

@ -67,7 +67,7 @@ extern const char *_searchpaths[NUM_SEARCHPATHS];
*/
struct TarListEntry {
const char *filename;
TarListEntry() : filename(NULL) {}
~TarListEntry() { free((void*)this->filename); }
};
struct TarFileListEntry {

View File

@ -333,8 +333,7 @@ static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
IndustryGfx gfx = GetIndustryGfx(tile);
/* For NewGRF industry tiles we might not be drawing a foundation. We need to
* account for this, otherwise we might be applying a FOUNDATION_LEVELED
* on a steep slope which is not allowed. Furthermore other structures should
* account for this, as other structures should
* draw the wall of the foundation in this case.
*/
if (gfx >= NEW_INDUSTRYTILEOFFSET) {

View File

@ -76,8 +76,9 @@ uint ApplyFoundationToSlope(Foundation f, Slope *s)
if (!IsFoundation(f)) return 0;
if (IsLeveledFoundation(f)) {
uint dz = TILE_HEIGHT + (IsSteepSlope(*s) ? TILE_HEIGHT : 0);
*s = SLOPE_FLAT;
return TILE_HEIGHT;
return dz;
}
if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) {
@ -384,6 +385,9 @@ void DrawFoundation(TileInfo *ti, Foundation f)
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
OffsetGroundSprite(31, 9);
} else if (IsLeveledFoundation(f)) {
AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT);
OffsetGroundSprite(31, 1);
} else if (f == FOUNDATION_STEEP_LOWER) {
/* one corner raised */
OffsetGroundSprite(31, 1);

View File

@ -3130,6 +3130,10 @@ STR_NEWGRF_NOT_FOUND_WARNING :{WHITE}Missing
STR_NEWGRF_UNPAUSE_WARNING_TITLE :{YELLOW}Missing GRF file(s)
STR_NEWGRF_UNPAUSE_WARNING :{WHITE}Unpausing can crash OpenTTD. Do not file bug reports for subsequent crashes.{}Do you really want to unpause?
STR_NEWGRF_BROKEN :{WHITE}Behaviour of NewGRF '{0:STRING}' is likely to cause desyncs and/or crashes.
STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}It changes vehicle length for '{1:ENGINE}' when not inside a depot.
STR_BROKEN_VEHICLE_LENGTH :{WHITE}Train '{VEHICLE}' belonging to '{COMPANY}' has invalid length. It is probably caused by problems with NewGRFs. Game may desync or crash.
STR_LOADGAME_REMOVED_TRAMS :{WHITE}Game was saved in version without tram support. All trams have been removed.
STR_CURRENCY_WINDOW :{WHITE}Custom currency

View File

@ -397,10 +397,8 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
uint16 index = p->Recv_uint16();
PlayerID playas = (Owner)p->Recv_uint8();
char name[NETWORK_NAME_LENGTH];
char unique_id[NETWORK_UNIQUE_ID_LENGTH];
p->Recv_string(name, sizeof(name));
p->Recv_string(unique_id, sizeof(unique_id));
if (MY_CLIENT->has_quit) return NETWORK_RECV_STATUS_CONN_LOST;
@ -432,7 +430,6 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO)
ci->client_playas = playas;
ttd_strlcpy(ci->client_name, name, sizeof(ci->client_name));
ttd_strlcpy(ci->unique_id, unique_id, sizeof(ci->unique_id));
InvalidateWindow(WC_CLIENT_LIST, 0);

View File

@ -47,7 +47,6 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkTCPSocketHandler
// uint16: The index of the client (always unique on a server. 1 = server)
// uint8: As which player the client is playing
// String: The name of the client
// String: The unique id of the client
//
if (ci->client_index != NETWORK_EMPTY_INDEX) {
@ -55,7 +54,6 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CLIENT_INFO)(NetworkTCPSocketHandler
p->Send_uint16(ci->client_index);
p->Send_uint8 (ci->client_playas);
p->Send_string(ci->client_name);
p->Send_string(ci->unique_id);
cs->Send_Packet(p);
}

View File

@ -26,7 +26,13 @@ enum GRFStatus {
GCS_ACTIVATED ///< GRF file has been activated
};
enum GRFListCompatibility{
/** Encountered GRF bugs */
enum GRFBugs {
GBUG_VEH_LENGTH, ///< Length of rail vehicle changes when not inside a depot
};
/** Status of post-gameload GRF compatibility check */
enum GRFListCompatibility {
GLC_ALL_GOOD,
GLC_COMPATIBLE,
GLC_NOT_FOUND
@ -52,10 +58,11 @@ struct GRFConfig : public GRFIdentifier {
char *info;
GRFError *error;
uint8 flags;
GRFStatus status;
uint32 param[0x80];
uint8 num_params;
uint8 flags; ///< NOSAVE: GCF_Flags, bitset
GRFStatus status; ///< NOSAVE: GRFStatus, enum
uint32 grf_bugs; ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
uint32 param[0x80]; ///< GRF parameters
uint8 num_params; ///< Number of used parameters
struct GRFConfig *next;

View File

@ -107,7 +107,7 @@ void UnloadWagonOverrides()
/* Space for NUM_CARGO real cargos and 2 pseudo cargos, CT_DEFAULT and CT_PURCHASE */
static const SpriteGroup *_engine_custom_sprites[TOTAL_NUM_ENGINES][NUM_CARGO + 2];
static const GRFFile *_engine_grf[TOTAL_NUM_ENGINES];
const GRFFile *_engine_grf[TOTAL_NUM_ENGINES];
void SetCustomEngineSprites(EngineID engine, byte cargo, const SpriteGroup *group)
{

View File

@ -1331,6 +1331,8 @@ static bool InitializeWindowsAndCaches()
players[v->owner]->num_engines[v->engine_type]++;
}
CheckTrainsLengths();
return true;
}
@ -1812,7 +1814,7 @@ bool AfterLoadGame()
}
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v);
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true);
}
}
@ -2482,4 +2484,5 @@ void ReloadNewGRFData()
UpdateHousesAndTowns();
/* redraw the whole screen */
MarkWholeScreenDirty();
CheckTrainsLengths();
}

View File

@ -519,7 +519,12 @@ CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
}
case MP_STATION:
if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
if (!IsRoadStop(tile)) goto do_clear;
if (IsDriveThroughStopTile(tile)) {
if (pieces & ~AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(tile)))) goto do_clear;
} else {
if (pieces & ~DiagDirToRoadBits(GetRoadStopDir(tile))) goto do_clear;
}
if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
break;

View File

@ -1154,7 +1154,7 @@ static int32 UpdateConsists(int32 p1)
Vehicle *v;
FOR_ALL_VEHICLES(v) {
/* Update the consist of all trains so the maximum speed is set correctly. */
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v);
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true);
}
return 0;
}

View File

@ -347,13 +347,11 @@ static inline Corner GetRailFoundationCorner(Foundation f)
* Returns the foundation needed to flatten a slope.
* The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED.
*
* @pre The slope must not be steep.
* @param s The current #Slope.
* @return The needed #Foundation.
*/
static inline Foundation FlatteningFoundation(Slope s)
{
assert(!IsSteepSlope(s));
return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED);
}

View File

@ -275,6 +275,7 @@ byte FreightWagonMult(CargoID cargo);
int CheckTrainInDepot(const Vehicle *v, bool needs_to_be_stopped);
int CheckTrainStoppedInDepot(const Vehicle *v);
void UpdateTrainAcceleration(Vehicle* v);
void CheckTrainsLengths();
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.

View File

@ -47,6 +47,7 @@
#include "autoreplace_gui.h"
#include "gfx_func.h"
#include "settings_type.h"
#include "network/network.h"
#include "table/strings.h"
#include "table/train_cmd.h"
@ -177,13 +178,70 @@ static void TrainCargoChanged(Vehicle* v)
}
/** Logs a bug in GRF and shows a warning message if this
* is for the first time this happened.
* @param u first vehicle of chain
*/
static void RailVehicleLengthChanged(const Vehicle *u)
{
extern const GRFFile *_engine_grf[TOTAL_NUM_ENGINES];
if (_engine_grf[u->engine_type] == NULL) return;
uint32 grfid = _engine_grf[u->engine_type]->grfid;
GRFConfig *grfconfig = GetGRFConfig(grfid);
if (!HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) {
SetBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH);
SetDParamStr(0, grfconfig->name);
SetDParam(1, u->engine_type);
ShowErrorMessage(STR_NEWGRF_BROKEN_VEHICLE_LENGTH, STR_NEWGRF_BROKEN, 0, 0);
/* debug output */
char buffer[512];
SetDParamStr(0, grfconfig->name);
GetString(buffer, STR_NEWGRF_BROKEN, lastof(buffer));
DEBUG(grf, 0, "%s", buffer + 3);
SetDParam(1, u->engine_type);
GetString(buffer, STR_NEWGRF_BROKEN_VEHICLE_LENGTH, lastof(buffer));
DEBUG(grf, 0, "%s", buffer + 3);
if (!_networking) _pause_game = -1;
}
}
/** Checks if lengths of all rail vehicles are valid. If not, shows an error message. */
void CheckTrainsLengths()
{
const Vehicle *v;
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && v->First() == v && !(v->vehstatus & VS_CRASHED)) {
for (const Vehicle *u = v, *w = v->Next(); w != NULL; u = w, w = w->Next()) {
if (u->u.rail.track != TRACK_BIT_DEPOT) {
if ((w->u.rail.track != TRACK_BIT_DEPOT &&
max(abs(u->x_pos - w->x_pos), abs(u->y_pos - w->y_pos)) != u->u.rail.cached_veh_length) ||
(w->u.rail.track == TRACK_BIT_DEPOT && TicksToLeaveDepot(u) <= 0)) {
SetDParam(0, v->index);
SetDParam(1, v->owner);
ShowErrorMessage(INVALID_STRING_ID, STR_BROKEN_VEHICLE_LENGTH, 0, 0);
if (!_networking) _pause_game = -1;
}
}
}
}
}
}
/**
* Recalculates the cached stuff of a train. Should be called each time a vehicle is added
* to/removed from the chain, and when the game is loaded.
* Note: this needs to be called too for 'wagon chains' (in the depot, without an engine)
* @param v First vehicle of the chain.
* @param same_length should length of vehicles stay the same?
*/
void TrainConsistChanged(Vehicle* v)
void TrainConsistChanged(Vehicle *v, bool same_length)
{
uint16 max_speed = 0xFFFF;
@ -291,8 +349,14 @@ void TrainConsistChanged(Vehicle* v)
veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, u->engine_type, u);
}
if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor;
veh_len = Clamp(veh_len, 0, u->Next() == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
u->u.rail.cached_veh_length = 8 - veh_len;
veh_len = 8 - Clamp(veh_len, 0, u->Next() == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
/* verify length hasn't changed */
if (same_length && veh_len != u->u.rail.cached_veh_length) RailVehicleLengthChanged(u);
/* update vehicle length? */
if (!same_length) u->u.rail.cached_veh_length = veh_len;
v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
}
@ -630,7 +694,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla
_new_vehicle_id = v->index;
VehiclePositionChanged(v);
TrainConsistChanged(v->First());
TrainConsistChanged(v->First(), false);
UpdateTrainGroupID(v->First());
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
@ -805,7 +869,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32
AddArticulatedParts(vl, VEH_TRAIN);
}
TrainConsistChanged(v);
TrainConsistChanged(v, false);
UpdateTrainGroupID(v);
if (!HasBit(p2, 1) && !(flags & DC_AUTOREPLACE)) { // check if the cars should be added to the new vehicle
@ -1257,7 +1321,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
if (src_head != NULL) {
NormaliseTrainConsist(src_head);
TrainConsistChanged(src_head);
TrainConsistChanged(src_head, false);
UpdateTrainGroupID(src_head);
if (IsFrontEngine(src_head)) {
/* Update the refit button and window */
@ -1270,7 +1334,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
if (dst_head != NULL) {
NormaliseTrainConsist(dst_head);
TrainConsistChanged(dst_head);
TrainConsistChanged(dst_head, false);
UpdateTrainGroupID(dst_head);
if (IsFrontEngine(dst_head)) {
/* Update the refit button and window */
@ -1443,7 +1507,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* 5. If the train still exists, update its acceleration, window, etc. */
if (first != NULL) {
NormaliseTrainConsist(first);
TrainConsistChanged(first);
TrainConsistChanged(first, false);
UpdateTrainGroupID(first);
if (IsFrontEngine(first)) InvalidateWindow(WC_VEHICLE_REFIT, first->index);
}
@ -1509,7 +1573,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
/* 3. If it is still a valid train after selling, update its acceleration and cached values */
if (flags & DC_EXEC && first != NULL) {
NormaliseTrainConsist(first);
TrainConsistChanged(first);
TrainConsistChanged(first, false);
UpdateTrainGroupID(first);
InvalidateWindow(WC_VEHICLE_REFIT, first->index);
}
@ -1845,7 +1909,7 @@ static void ReverseTrainDirection(Vehicle *v)
ClrBit(v->u.rail.flags, VRF_REVERSING);
/* recalculate cached data */
TrainConsistChanged(v);
TrainConsistChanged(v, true);
/* update all images */
for (Vehicle *u = v; u != NULL; u = u->Next()) u->cur_image = u->GetImage(u->direction);
@ -2022,7 +2086,7 @@ CommandCost CmdRefitRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32
_returned_refit_capacity = num;
/* Update the train's cached variables */
if (flags & DC_EXEC) TrainConsistChanged(GetVehicle(p1)->First());
if (flags & DC_EXEC) TrainConsistChanged(GetVehicle(p1)->First(), false);
return cost;
}
@ -3281,7 +3345,7 @@ static void DeleteLastWagon(Vehicle *v)
InvalidateWindow(WC_COMPANY, v->owner);
} else {
/* Recalculate cached train properties */
TrainConsistChanged(first);
TrainConsistChanged(first, false);
/* Update the depot window if the first vehicle is in depot -
* if v == first, then it is updated in PreDestructor() */
if (first->u.rail.track == TRACK_BIT_DEPOT) {

View File

@ -275,7 +275,7 @@ void AfterLoadVehicles(bool clear_te_id)
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed
TrainConsistChanged(v);
TrainConsistChanged(v, false);
} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
RoadVehUpdateCache(v);
}
@ -2206,7 +2206,7 @@ void VehicleEnterDepot(Vehicle *v)
v->load_unload_time_rem = 0;
/* Reset reversed flag */
for (Vehicle *u = v; u != NULL; u = u->Next()) ClrBit(u->u.rail.flags, VRF_TOGGLE_REVERSE);
TrainConsistChanged(v);
TrainConsistChanged(v, true);
break;
case VEH_ROAD:

View File

@ -63,7 +63,7 @@ void MarkSingleVehicleDirty(const Vehicle *v);
UnitID GetFreeUnitNumber(VehicleType type);
void TrainConsistChanged(Vehicle *v);
void TrainConsistChanged(Vehicle *v, bool same_length);
void TrainPowerChanged(Vehicle *v);
Money GetTrainRunningCost(const Vehicle *v);