changeset 15979:19c7eff41501 draft

(svn r20667) -Codechange: implement the autoslope callback for objects
author rubidium <rubidium@openttd.org>
date Sat, 28 Aug 2010 19:00:21 +0000
parents 8447d1d60319
children 0f57aae709d0
files src/newgrf_callbacks.h src/object_cmd.cpp
diffstat 2 files changed, 22 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/newgrf_callbacks.h
+++ b/src/newgrf_callbacks.h
@@ -271,7 +271,7 @@
 	CBID_OBJECT_FUND_MORE_TEXT           = 0x15C, // 15 bit callback, not implemented
 
 	/** Called to determine if one can alter the ground below an object tile */
-	CBID_OBJECT_AUTOSLOPE                = 0x15D, // 15 bit callback, not implemented
+	CBID_OBJECT_AUTOSLOPE                = 0x15D, // 15 bit callback
 };
 
 /**
--- a/src/object_cmd.cpp
+++ b/src/object_cmd.cpp
@@ -621,7 +621,27 @@
 		CommandCost ret = CheckTileOwnership(tile);
 		if (ret.Succeeded()) return CommandCost();
 	} else if (AutoslopeEnabled() && type != OBJECT_TRANSMITTER && type != OBJECT_LIGHTHOUSE) {
-		if (!IsSteepSlope(tileh_new) && (z_new + GetSlopeMaxZ(tileh_new) == GetTileMaxZ(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
+		/* Behaviour:
+		 *  - Both new and old slope must not be steep.
+		 *  - TileMaxZ must not be changed.
+		 *  - Allow autoslope by default.
+		 *  - Disallow autoslope if callback succeeds and returns non-zero.
+		 */
+		Slope tileh_old = GetTileSlope(tile, NULL);
+		/* TileMaxZ must not be changed. Slopes must not be steep. */
+		if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
+			const ObjectSpec *spec = ObjectSpec::Get(type);
+
+			/* Call callback 'disable autosloping for objects'. */
+			if (HasBit(spec->callback_mask, CBM_OBJ_AUTOSLOPE)) {
+				/* If the callback fails, allow autoslope. */
+				uint16 res = GetObjectCallback(CBID_OBJECT_AUTOSLOPE, 0, 0, spec, Object::GetByTile(tile), tile);
+				if ((res == 0) || (res == CALLBACK_FAILED)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
+			} else if (spec->enabled) {
+				/* allow autoslope */
+				return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
+			}
+		}
 	}
 
 	return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);