Add NewGRF object property for new edge foundation mode

pull/341/head
Jonathan G Rennison 3 years ago
parent 2c8b462708
commit d9116106ca

@ -4301,6 +4301,14 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, const G
SB(spec->ctrl_flags, OBJECT_CTRL_FLAG_USE_LAND_GROUND, 1, (buf->ReadByte() != 0 ? 1 : 0));
break;
case A0RPI_OBJECT_EDGE_FOUNDATION_MODE:
if (MappedPropertyLengthMismatch(buf, 4, mapping_entry)) break;
SetBit(spec->ctrl_flags, OBJECT_CTRL_FLAG_EDGE_FOUNDATION);
for (int i = 0; i < 4; i++) {
spec->edge_foundation[i] = buf->ReadByte();
}
break;
default:
ret = HandleAction0PropertyDefault(buf, prop);
break;

@ -68,6 +68,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_SIGNAL_RECOLOUR, "signals_enable_signal_recolour"),
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_EXTRA_ASPECTS, "signals_extra_aspects"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_USE_LAND_GROUND, "object_use_land_ground"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"),
GRFPropertyMapDefinition(),
};

@ -33,6 +33,7 @@ enum Action0RemapPropertyIds {
A0RPI_SIGNALS_ENABLE_SIGNAL_RECOLOUR,
A0RPI_SIGNALS_EXTRA_ASPECTS,
A0RPI_OBJECT_USE_LAND_GROUND,
A0RPI_OBJECT_EDGE_FOUNDATION_MODE,
};

@ -418,7 +418,7 @@ uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, cons
* @param group The group of sprites to draw.
* @param spec Object spec to draw.
*/
static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, const ObjectSpec *spec)
static void DrawTileLayout(TileInfo *ti, const TileLayoutSpriteGroup *group, const ObjectSpec *spec, int building_z_offset)
{
const DrawTileSprites *dts = group->ProcessRegisters(nullptr);
PaletteID palette = ((spec->flags & OBJECT_FLAG_2CC_COLOUR) ? SPR_2CCMAP_BASE : PALETTE_RECOLOUR_START) + Object::GetByTile(ti->tile)->colour;
@ -455,7 +455,9 @@ static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *grou
}
}
if (building_z_offset) ti->z += building_z_offset;
DrawNewGRFTileSeq(ti, dts, TO_STRUCTURES, 0, palette);
if (building_z_offset) ti->z -= building_z_offset;
}
/**
@ -463,7 +465,7 @@ static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *grou
* @param ti Information about the tile to draw on.
* @param spec Object spec to draw.
*/
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec)
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec, int building_z_offset)
{
Object *o = Object::GetByTile(ti->tile);
ObjectResolverObject object(spec, o, ti->tile);
@ -471,7 +473,7 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec)
const SpriteGroup *group = object.Resolve();
if (group == nullptr || group->type != SGT_TILELAYOUT) return;
DrawTileLayout(ti, (const TileLayoutSpriteGroup *)group, spec);
DrawTileLayout(ti, (const TileLayoutSpriteGroup *)group, spec, building_z_offset);
}
/**

@ -43,9 +43,17 @@ DECLARE_ENUM_AS_BIT_SET(ObjectFlags)
enum ObjectCtrlFlags {
OBJECT_CTRL_FLAG_NONE = 0, ///< Just nothing.
OBJECT_CTRL_FLAG_USE_LAND_GROUND = 1 << 0, ///< Use land for ground sprite.
OBJECT_CTRL_FLAG_EDGE_FOUNDATION = 1 << 2, ///< Use edge foundation mode.
};
DECLARE_ENUM_AS_BIT_SET(ObjectCtrlFlags)
enum ObjectEdgeFoundationFlags {
/* Bits 0 and 1 use for edge DiagDirection */
OBJECT_EF_FLAG_ADJUST_Z = 1 << 2, ///< Adjust sprite z position to z at edge.
OBJECT_EF_FLAG_FOUNDATION_LOWER = 1 << 3, ///< If edge is lower than tile max z, add foundation.
};
DECLARE_ENUM_AS_BIT_SET(ObjectEdgeFoundationFlags)
void ResetObjects();
/** Class IDs for objects. */
@ -75,6 +83,7 @@ struct ObjectSpec {
Date end_of_life_date; ///< When can't this object be built anymore.
ObjectFlags flags; ///< Flags/settings related to the object.
ObjectCtrlFlags ctrl_flags; ///< Extra control flags.
uint8 edge_foundation[4]; ///< Edge foundation flags
AnimationInfo animation; ///< Information about the animation.
uint16 callback_mask; ///< Bitmask of requested/allowed callbacks.
uint8 height; ///< The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
@ -167,7 +176,7 @@ static const CargoID CT_PURCHASE_OBJECT = 1;
uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8 view = 0);
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec);
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec, int building_z_offset);
void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8 view);
void AnimateNewObjectTile(TileIndex tile);
uint8 GetNewObjectTileAnimationSpeed(TileIndex tile);

@ -517,13 +517,34 @@ static Foundation GetFoundation_Object(TileIndex tile, Slope tileh);
static void DrawTile_Object(TileInfo *ti, DrawTileProcParams params)
{
ObjectType type = GetObjectType(ti->tile);
const Object *obj = Object::GetByTile(ti->tile);
ObjectType type = obj->type;
const ObjectSpec *spec = ObjectSpec::Get(type);
/* Fall back for when the object doesn't exist anymore. */
if (!spec->enabled) type = OBJECT_TRANSMITTER;
int building_z_offset = 0;
if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh));
/* Fall back for when the object doesn't exist anymore. */
if (!spec->enabled) {
type = OBJECT_TRANSMITTER;
} else if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) {
if (spec->ctrl_flags & OBJECT_CTRL_FLAG_EDGE_FOUNDATION) {
uint8 flags = spec->edge_foundation[obj->view];
DiagDirection edge = (DiagDirection)GB(flags, 0, 2);
Slope incline = InclinedSlope(edge);
if (IsSteepSlope(ti->tileh) || IsOddParity(incline & ti->tileh)) {
/* Steep slope, or odd number of matching bits indicating that edge is not level */
DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh));
} else if (flags & OBJECT_EF_FLAG_FOUNDATION_LOWER && !(ti->tileh & incline)) {
/* The edge is the lower edge of an inclined slope */
DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh));
} else if (flags & OBJECT_EF_FLAG_ADJUST_Z && ti->tileh & incline) {
/* The edge is elevated relative to the lowest tile height, adjust z */
building_z_offset = TILE_HEIGHT;
}
} else {
DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh));
}
}
if (type < NEW_OBJECT_OFFSET) {
const DrawTileSprites *dts = nullptr;
@ -564,7 +585,7 @@ static void DrawTile_Object(TileInfo *ti, DrawTileProcParams params)
}
}
} else {
DrawNewObjectTile(ti, spec);
DrawNewObjectTile(ti, spec, building_z_offset);
}
DrawBridgeMiddle(ti);
@ -1065,6 +1086,16 @@ static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_ow
}
}
static int GetObjectEffectiveZ(TileIndex tile, const ObjectSpec *spec, int z, Slope tileh)
{
if ((spec->ctrl_flags & OBJECT_CTRL_FLAG_EDGE_FOUNDATION) && !(spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION)) {
uint8 flags = spec->edge_foundation[Object::GetByTile(tile)->view];
DiagDirection edge = (DiagDirection)GB(flags, 0, 2);
if (!(flags & OBJECT_EF_FLAG_FOUNDATION_LOWER) && !(tileh & InclinedSlope(edge))) return z;
}
return z + GetSlopeMaxZ(tileh);
}
static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
{
ObjectType type = GetObjectType(tile);
@ -1080,10 +1111,11 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int
* - Allow autoslope by default.
* - Disallow autoslope if callback succeeds and returns non-zero.
*/
Slope tileh_old = GetTileSlope(tile);
/* 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);
int z_old;
Slope tileh_old = GetTileSlope(tile, &z_old);
const ObjectSpec *spec = ObjectSpec::Get(type);
/* Object height must not be changed. Slopes must not be steep. */
if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetObjectEffectiveZ(tile, spec, z_old, tileh_old) == GetObjectEffectiveZ(tile, spec, z_new, tileh_new))) {
/* Call callback 'disable autosloping for objects'. */
if (HasBit(spec->callback_mask, CBM_OBJ_AUTOSLOPE)) {

@ -897,6 +897,7 @@ class NIHObject : public NIHelper {
check_flag(OBJECT_FLAG_ANIM_RANDOM_BITS, "OBJECT_FLAG_ANIM_RANDOM_BITS");
check_flag(OBJECT_FLAG_SCALE_BY_WATER, "OBJECT_FLAG_SCALE_BY_WATER");
check_ctrl_flag(OBJECT_CTRL_FLAG_USE_LAND_GROUND, "OBJECT_CTRL_FLAG_USE_LAND_GROUND");
check_ctrl_flag(OBJECT_CTRL_FLAG_EDGE_FOUNDATION, "OBJECT_CTRL_FLAG_EDGE_FOUNDATION");
}
}
}

@ -121,7 +121,7 @@ static const DrawTileSprites _object_hq[] = {
#undef TILE_SPRITE_LINE
#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DAY + 1, flags, OBJECT_CTRL_FLAG_NONE, {0, 0, 0, 0}, 0, height, 1, gen_amount, true }
#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DAY + 1, flags, OBJECT_CTRL_FLAG_NONE, {0, 0, 0, 0}, {0, 0, 0, 0}, 0, height, 1, gen_amount, true }
/* Climates
* T = Temperate

Loading…
Cancel
Save