1
0
Fork 0

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

- Change: Log the _date and _date_fract in the desync log for saved games (r19638)
- Fix: Do not allow building cacti outside of the desert or rain forest trees outside of the rain forest area. This to prevent people from thinking planting rain forest trees makes the rain forest bigger and thus adds more place to build a lumber mill [FS#3728] (r19644, r19635, r19634)
- Fix: Industry generation failed for large maps and lots of industry types (r19643)
- Fix: Desync when taking over companies (r19636)
- Fix: Chat message caused glitch when rejoining a network game [FS#3757] (r19629)
release/1.0
rubidium 2010-04-16 22:02:33 +00:00
parent 7c3487501c
commit 4fada121bd
12 changed files with 54 additions and 33 deletions

View File

@ -177,3 +177,11 @@ OpenTTD not properly resizing with SDL on X [FS#3305]
Window managers that are known to exhibit this behaviour are KDE's
and GNOME's. With the XFCE's and LXDE's window managers the resize
event is sent when the user releases the mouse.
Content files not properly extracted with zlib 1.2.3.5-1.2.4 [FS#3753]
With zlib 1.2.3.5 up to and including 1.2.4 the function "gzeof",
which tells when we read the whole file, is broken in such a way
that OpenTTD thinks it has extracted and written the whole file
while the last few hundred/thousand bytes are not extracted yet.
This causes problems for everything that is downloaded from the
online content system when using one of those versions of zlib.

View File

@ -248,7 +248,7 @@
{
EnforcePrecondition(false, ::IsValidTile(tile));
return AIObject::DoCommand(tile, UINT_MAX, tile, CMD_PLANT_TREE);
return AIObject::DoCommand(tile, TREE_INVALID, tile, CMD_PLANT_TREE);
}
/* static */ bool AITile::PlantTreeRectangle(TileIndex tile, uint width, uint height)
@ -258,7 +258,7 @@
EnforcePrecondition(false, height >= 1 && height <= 20);
TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1);
return AIObject::DoCommand(tile, UINT_MAX, end_tile, CMD_PLANT_TREE);
return AIObject::DoCommand(tile, TREE_INVALID, end_tile, CMD_PLANT_TREE);
}
/* static */ bool AITile::IsWithinTownInfluence(TileIndex tile, TownID town_id)

View File

@ -591,14 +591,11 @@ static void HandleBankruptcyTakeover(Company *c)
SetBit(c->bankrupt_asked, best->index);
if (IsInteractiveCompany(best->index)) {
c->bankrupt_timeout = TAKE_OVER_TIMEOUT;
ShowBuyCompanyDialog(c->index);
return;
}
c->bankrupt_timeout = TAKE_OVER_TIMEOUT;
if (best->is_ai) {
AI::NewEvent(best->index, new AIEventCompanyAskMerger(c->index, ClampToI32(c->bankrupt_value)));
} else if (IsInteractiveCompany(best->index)) {
ShowBuyCompanyDialog(c->index);
}
}

View File

@ -57,6 +57,7 @@ uint32 DoRandom(int line, const char *file)
uint DoRandomRange(uint max, int line, const char *file)
{
assert(max <= UINT16_MAX);
return GB(DoRandom(line, file), 0, 16) * max >> 16;
}
#endif /* RANDOM_DEBUG */

View File

@ -99,8 +99,9 @@ void SetRandomSeed(uint32 seed);
return _random.Next();
}
static FORCEINLINE uint32 RandomRange(uint16 max)
static FORCEINLINE uint32 RandomRange(uint max)
{
assert(max <= UINT16_MAX);
return _random.Next(max);
}
#endif

View File

@ -1892,7 +1892,8 @@ void GenerateIndustries()
/* Add the remaining industries according to their probabilities */
for (uint i = 0; i < total_amount; i++) {
uint32 r = RandomRange(total_prob);
/* RandomRange() can only deal with 16 bit, which is not enough here. */
uint32 r = ((uint64)Random() * (uint64)total_prob) >> 32;
IndustryType it = 0;
while (it < NUM_INDUSTRYTYPES && r >= industry_probs[it]) {
r -= industry_probs[it];

View File

@ -3508,6 +3508,7 @@ STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE :{WHITE}Can't bu
# Tree related errors
STR_ERROR_TREE_ALREADY_HERE :{WHITE}... tree already here
STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE :{WHITE}... wrong terrain for tree type
STR_ERROR_CAN_T_PLANT_TREE_HERE :{WHITE}Can't plant tree here...
# Bridge related errors

View File

@ -116,14 +116,15 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint8 duration, const char *
void NetworkInitChatMessage()
{
MAX_CHAT_MESSAGES = _settings_client.gui.network_chat_box_height;
MAX_CHAT_MESSAGES = _settings_client.gui.network_chat_box_height;
_chatmsg_list = ReallocT(_chatmsg_list, _settings_client.gui.network_chat_box_height);
_chatmsg_box.x = 10;
_chatmsg_box.y = 3 * FONT_HEIGHT_NORMAL;
_chatmsg_box.width = _settings_client.gui.network_chat_box_width;
_chatmsg_box.height = _settings_client.gui.network_chat_box_height * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) + 2;
_chatmessage_backup = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactoryBase::GetCurrentBlitter()->GetBytesPerPixel());
_chatmsg_list = ReallocT(_chatmsg_list, _settings_client.gui.network_chat_box_height);
_chatmsg_box.x = 10;
_chatmsg_box.y = 3 * FONT_HEIGHT_NORMAL;
_chatmsg_box.width = _settings_client.gui.network_chat_box_width;
_chatmsg_box.height = _settings_client.gui.network_chat_box_height * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) + 2;
_chatmessage_backup = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactoryBase::GetCurrentBlitter()->GetBytesPerPixel());
_chatmessage_visible = false;
for (uint i = 0; i < MAX_CHAT_MESSAGES; i++) {
_chatmsg_list[i].message[0] = '\0';

View File

@ -1882,7 +1882,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
/* 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 */
if (mode == SL_SAVE) { // SAVE game
DEBUG(desync, 1, "save: %s", filename);
DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
_sl.write_bytes = WriteMem;
_sl.excpt_uninit = UnInitMem;

View File

@ -336,7 +336,7 @@ void GenerateTrees()
/** Plant a tree.
* @param tile start tile of area-drag of tree plantation
* @param flags type of operation
* @param p1 tree type, -1 means random.
* @param p1 tree type, TREE_INVALID means random.
* @param p2 end tile of area-drag
* @param text unused
* @return the cost of this operation or an error
@ -345,10 +345,11 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
{
StringID msg = INVALID_STRING_ID;
CommandCost cost(EXPENSES_OTHER);
const byte tree_to_plant = GB(p1, 0, 8); // We cannot use Extract as min and max are climate specific.
if (p2 >= MapSize()) return CMD_ERROR;
/* Check the tree type. It can be random or some valid value within the current climate */
if (p1 != UINT_MAX && p1 - _tree_base_by_landscape[_settings_game.game_creation.landscape] >= _tree_count_by_landscape[_settings_game.game_creation.landscape]) return CMD_ERROR;
/* Check the tree type within the current climate */
if (tree_to_plant != TREE_INVALID && !IsInsideBS(tree_to_plant, _tree_base_by_landscape[_settings_game.game_creation.landscape], _tree_count_by_landscape[_settings_game.game_creation.landscape])) return CMD_ERROR;
TileArea ta(tile, p2);
TILE_AREA_LOOP(tile, ta) {
@ -374,12 +375,25 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
continue;
}
/* FALL THROUGH */
case MP_CLEAR:
case MP_CLEAR: {
if (IsBridgeAbove(tile)) {
msg = STR_ERROR_SITE_UNSUITABLE;
continue;
}
TreeType treetype = (TreeType)tree_to_plant;
/* Be a bit picky about which trees go where. */
if (_settings_game.game_creation.landscape == LT_TROPIC && treetype != TREE_INVALID && (
/* No cacti outside the desert */
(treetype == TREE_CACTUS && GetTropicZone(tile) != TROPICZONE_DESERT) ||
/* No rain forest trees outside the rain forest, except in the editor mode where it makes those tiles rain forest tile */
(IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS) && GetTropicZone(tile) != TROPICZONE_RAINFOREST && _game_mode != GM_EDITOR) ||
/* And no subtropical trees in the desert/rain forest */
(IsInsideMM(treetype, TREE_SUB_TROPICAL, TREE_TOYLAND) && GetTropicZone(tile) != TROPICZONE_NORMAL))) {
msg = STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE;
continue;
}
if (IsTileType(tile, MP_CLEAR)) {
/* Remove fields or rocks. Note that the ground will get barrened */
switch (GetRawClearGround(tile)) {
@ -401,9 +415,6 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
}
if (flags & DC_EXEC) {
TreeType treetype;
treetype = (TreeType)p1;
if (treetype == TREE_INVALID) {
treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
if (treetype == TREE_INVALID) treetype = TREE_CACTUS;
@ -414,11 +425,12 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
MarkTileDirtyByTile(tile);
/* When planting rainforest-trees, set tropiczone to rainforest in editor. */
if (_game_mode == GM_EDITOR && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS))
if (_game_mode == GM_EDITOR && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS)) {
SetTropicZone(tile, TROPICZONE_RAINFOREST);
}
}
cost.AddCost(_price[PR_BUILD_TREES]);
break;
} break;
default:
msg = STR_ERROR_SITE_UNSUITABLE;

View File

@ -18,6 +18,7 @@
#include "company_base.h"
#include "command_func.h"
#include "sound_func.h"
#include "tree_map.h"
#include "table/sprites.h"
#include "table/strings.h"
@ -50,7 +51,7 @@ class BuildTreesWindow : public Window
{
uint16 base; ///< Base tree number used for drawing the window.
uint16 count; ///< Number of different trees available.
uint tree_to_plant; ///< Tree number to plant, \c UINT_MAX for a random tree.
TreeType tree_to_plant; ///< Tree number to plant, \c TREE_INVALID for a random tree.
public:
BuildTreesWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
@ -105,13 +106,13 @@ public:
if (widget - BTW_TYPE_11 >= this->count) break;
if (HandlePlacePushButton(this, widget, SPR_CURSOR_TREE, HT_RECT, NULL)) {
this->tree_to_plant = this->base + widget - BTW_TYPE_11;
this->tree_to_plant = (TreeType)(this->base + widget - BTW_TYPE_11);
}
break;
case BTW_TYPE_RANDOM: // tree of random type.
if (HandlePlacePushButton(this, BTW_TYPE_RANDOM, SPR_CURSOR_TREE, HT_RECT, NULL)) {
this->tree_to_plant = UINT_MAX;
this->tree_to_plant = TREE_INVALID;
}
break;

View File

@ -22,17 +22,15 @@
* offsets from the grfs files. These points to the start of
* the tree list for a landscape. See the TREE_COUNT_* enumerations
* for the amount of different trees for a specific landscape.
*
* @note TREE_INVALID may be 0xFF according to the coding style, not -1 (Progman)
*/
enum TreeType {
TREE_INVALID = -1, ///< An invalid tree
TREE_TEMPERATE = 0x00, ///< temperate tree
TREE_SUB_ARCTIC = 0x0C, ///< tree on a sub_arctic landscape
TREE_RAINFOREST = 0x14, ///< tree on the 'green part' on a sub-tropical map
TREE_CACTUS = 0x1B, ///< a catus for the 'desert part' on a sub-tropical map
TREE_SUB_TROPICAL = 0x1C, ///< tree on a sub-tropical map, non-rainforest, non-desert
TREE_TOYLAND = 0x20, ///< tree on a toyland map
TREE_INVALID = 0xFF, ///< An invalid tree
};
/**