changeset 4328:09812fd65f12 draft

(svn r6001) -Feature: when removing a farm, his farmland is removed too (over time) (based on peter1138's patch, FS#82) To make this to work, in older games farmland is removed on load, and replanted
author truelight <truelight@openttd.org>
date Sun, 20 Aug 2006 18:44:26 +0000
parents 4e20530809a5
children 802bb06b06cf
files clear_cmd.c clear_map.h industry.h industry_cmd.c openttd.c saveload.c
diffstat 6 files changed, 75 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/clear_cmd.c
+++ b/clear_cmd.c
@@ -16,6 +16,7 @@
 #include "table/sprites.h"
 #include "unmovable_map.h"
 #include "genworld.h"
+#include "industry.h"
 
 typedef struct TerraformerHeightMod {
 	TileIndex tile;
@@ -679,9 +680,14 @@
 				SetClearCounter(tile, 0);
 			}
 
-			field_type = GetFieldType(tile);
-			field_type = (field_type < 8) ? field_type + 1 : 0;
-			SetFieldType(tile, field_type);
+			if (GetIndustryIndexOfField(tile) == INVALID_INDUSTRY) {
+				/* This farmfield is no longer farmfield, so make it grass again */
+				MakeClear(tile, CLEAR_GRASS, 0);
+			} else {
+				field_type = GetFieldType(tile);
+				field_type = (field_type < 8) ? field_type + 1 : 0;
+				SetFieldType(tile, field_type);
+			}
 			break;
 		}
 
--- a/clear_map.h
+++ b/clear_map.h
@@ -83,6 +83,17 @@
 	SB(_m[t].m3, 0, 4, f);
 }
 
+static inline uint16 GetIndustryIndexOfField(TileIndex t)
+{
+	assert(GetClearGround(t) == CLEAR_FIELDS);
+	return _m[t].m2;
+}
+
+static inline void SetIndustryIndexOfField(TileIndex t, uint16 i)
+{
+	assert(GetClearGround(t) == CLEAR_FIELDS);
+	_m[t].m2 = i;
+}
 
 /* Is used by tree tiles, too */
 static inline uint GetFenceSE(TileIndex t)
@@ -121,11 +132,11 @@
 }
 
 
-static inline void MakeField(TileIndex t, uint field_type)
+static inline void MakeField(TileIndex t, uint field_type, uint16 industry)
 {
 	SetTileType(t, MP_CLEAR);
 	SetTileOwner(t, OWNER_NONE);
-	_m[t].m2 = 0;
+	_m[t].m2 = industry;
 	_m[t].m3 = field_type;
 	_m[t].m4 = 0 << 5 | 0 << 2;
 	SetClearGroundDensity(t, CLEAR_FIELDS, 3);
--- a/industry.h
+++ b/industry.h
@@ -8,6 +8,10 @@
 typedef byte IndustryGfx;
 typedef uint8 IndustryType;
 
+enum {
+	INVALID_INDUSTRY = 0xFFFF,
+};
+
 struct Industry {
 	TileIndex xy;
 	byte width; /* swapped order of w/h with town */
@@ -101,6 +105,7 @@
 
 
 void DeleteIndustry(Industry *is);
+void PlantRandomFarmField(const Industry *i);
 
 enum {
 	IT_COAL_MINE = 0,
--- a/industry_cmd.c
+++ b/industry_cmd.c
@@ -753,6 +753,16 @@
 		}
 	END_TILE_LOOP(tile_cur, i->width, i->height, i->xy);
 
+	if (i->type == IT_FARM || i->type == IT_FARM_2) {
+		/* Remove the farmland and convert it to regular tiles over time. */
+		BEGIN_TILE_LOOP(tile_cur, 42, 42, i->xy - TileDiffXY(21, 21)) {
+			if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
+					GetIndustryIndexOfField(tile_cur) == i->index) {
+				SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
+			}
+		} END_TILE_LOOP(tile_cur, 42, 42, i->xy - TileDiff(21, 21))
+	}
+
 	i->xy = 0;
 	_industry_sort_dirty = true;
 	DeleteSubsidyWithIndustry(i->index);
@@ -801,7 +811,7 @@
 	} while (--size);
 }
 
-static void PlantFarmField(TileIndex tile)
+static void PlantFarmField(TileIndex tile, uint16 industry)
 {
 	uint size_x, size_y;
 	uint32 r;
@@ -841,7 +851,7 @@
 	BEGIN_TILE_LOOP(cur_tile, size_x, size_y, tile)
 		cur_tile = TILE_MASK(cur_tile);
 		if (!IsBadFarmFieldTile2(cur_tile)) {
-			MakeField(cur_tile, field_type);
+			MakeField(cur_tile, field_type, industry);
 			SetClearCounter(cur_tile, counter);
 			MarkTileDirtyByTile(cur_tile);
 		}
@@ -858,14 +868,19 @@
 	SetupFarmFieldFence(tile + TileDiffXY(0, size_y - 1), size_x, type, AXIS_X);
 }
 
+void PlantRandomFarmField(const Industry *i)
+{
+	int x = i->width  / 2 + Random() % 31 - 16;
+	int y = i->height / 2 + Random() % 31 - 16;
+
+	TileIndex tile = TileAddWrap(i->xy, x, y);
+
+	if (tile != INVALID_TILE) PlantFarmField(tile, i->index);
+}
+
 static void MaybePlantFarmField(const Industry *i)
 {
-	if (CHANCE16(1, 8)) {
-		int x = i->width  / 2 + Random() % 31 - 16;
-		int y = i->height / 2 + Random() % 31 - 16;
-		TileIndex tile = TileAddWrap(i->xy, x, y);
-		if (tile != INVALID_TILE) PlantFarmField(tile);
-	}
+	if (CHANCE16(1, 8)) PlantRandomFarmField(i);
 }
 
 static void ChopLumberMillTrees(Industry *i)
@@ -1474,14 +1489,7 @@
 	i->height++;
 
 	if (i->type == IT_FARM || i->type == IT_FARM_2) {
-		tile = i->xy + TileDiffXY(i->width / 2, i->height / 2);
-		for (j = 0; j != 50; j++) {
-			int x = Random() % 31 - 16;
-			int y = Random() % 31 - 16;
-			TileIndex new_tile = TileAddWrap(tile, x, y);
-
-			if (new_tile != INVALID_TILE) PlantFarmField(new_tile);
-		}
+		for (j = 0; j != 50; j++) PlantRandomFarmField(i);
 	}
 	_industry_sort_dirty = true;
 	InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0);
--- a/openttd.c
+++ b/openttd.c
@@ -50,6 +50,7 @@
 #include "settings.h"
 #include "genworld.h"
 #include "date.h"
+#include "clear_map.h"
 
 #include <stdarg.h>
 
@@ -1463,5 +1464,27 @@
 		}
 	}
 
+	/* From 32 on we save the industry who made the farmland.
+	 *  To give this prettyness to old savegames, we remove all farmfields and
+	 *  plant new ones. */
+	if (CheckSavegameVersion(32)) {
+		Industry *i;
+
+		BEGIN_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0) {
+			if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS)) {
+				MakeClear(tile_cur, CLEAR_GRASS, 3);
+			}
+		} END_TILE_LOOP(tile_cur, MapSizeX(), MapSizeY(), 0)
+
+		FOR_ALL_INDUSTRIES(i) {
+			uint j;
+
+			if (i->xy == 0) continue;
+			if (i->type == IT_FARM || i->type == IT_FARM_2) {
+				for (j = 0; j != 50; j++) PlantRandomFarmField(i);
+			}
+		}
+	}
+
 	return true;
 }
--- a/saveload.c
+++ b/saveload.c
@@ -30,7 +30,7 @@
 #include "variables.h"
 #include <setjmp.h>
 
-const uint16 SAVEGAME_VERSION = 31;
+const uint16 SAVEGAME_VERSION = 32;
 uint16 _sl_version;       /// the major savegame version identifier
 byte   _sl_minor_version; /// the minor savegame version, DO NOT USE!