diff options
-rw-r--r-- | src/landscape.cpp | 2 | ||||
-rw-r--r-- | src/newgrf_callbacks.h | 6 | ||||
-rw-r--r-- | src/newgrf_object.cpp | 54 | ||||
-rw-r--r-- | src/newgrf_object.h | 3 | ||||
-rw-r--r-- | src/object_cmd.cpp | 25 |
5 files changed, 84 insertions, 6 deletions
diff --git a/src/landscape.cpp b/src/landscape.cpp index 4804ea215..1672e2f60 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -952,6 +952,7 @@ void GenerateLandscape(byte mode) if (_settings_game.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest(); } +void OnTick_Objects(); void OnTick_Town(); void OnTick_Trees(); void OnTick_Station(); @@ -966,5 +967,6 @@ void CallLandscapeTick() OnTick_Station(); OnTick_Industry(); + OnTick_Objects(); OnTick_Companies(); } diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h index 4dcc24d5a..ec871f27b 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.h @@ -256,13 +256,13 @@ enum CallbackID { CBID_OBJECT_LAND_SLOPE_CHECK = 0x157, // 15 bit callback, not implemented /** Determine the next animation frame for a house. */ - CBID_OBJECT_ANIMATION_NEXT_FRAME = 0x158, // 15 bit callback, not implemented + CBID_OBJECT_ANIMATION_NEXT_FRAME = 0x158, // 15 bit callback /** Called for periodically starting or stopping the animation. */ - CBID_OBJECT_ANIMATION_START_STOP = 0x159, // 15 bit callback, not implemented + CBID_OBJECT_ANIMATION_START_STOP = 0x159, // 15 bit callback /** Called to indicate how long the current animation frame should last. */ - CBID_OBJECT_ANIMATION_SPEED = 0x15A, // 8 bit callback, not implemented + CBID_OBJECT_ANIMATION_SPEED = 0x15A, // 8 bit callback /** Called to determine the colour of a town building. */ CBID_OBJECT_COLOUR = 0x15B, // 15 bit callback diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 02e33bc20..c86bc62f1 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -13,12 +13,11 @@ #include "company_base.h" #include "company_func.h" #include "core/mem_func.hpp" -#include "date_func.h" #include "debug.h" -#include "landscape.h" #include "newgrf.h" #include "newgrf_class_func.h" #include "newgrf_object.h" +#include "newgrf_sound.h" #include "newgrf_spritegroup.h" #include "newgrf_town.h" #include "object_base.h" @@ -27,6 +26,7 @@ #include "town.h" #include "viewport_func.h" #include "water.h" +#include "newgrf_animation_base.h" /** The override manager for our objects. */ ObjectOverrideManager _object_mngr(NEW_OBJECT_OFFSET, NUM_OBJECTS, INVALID_OBJECT_TYPE); @@ -475,3 +475,53 @@ void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec) DrawNewGRFTileSeqInGUI(x, y, dts, 0, palette); } + +/** Helper class for animation control. */ +struct ObjectAnimationBase : public AnimationBase<ObjectAnimationBase, ObjectSpec, Object, GetObjectCallback> { + static const CallbackID cb_animation_speed = CBID_OBJECT_ANIMATION_SPEED; + static const CallbackID cb_animation_next_frame = CBID_OBJECT_ANIMATION_NEXT_FRAME; + + static const ObjectCallbackMask cbm_animation_speed = CBM_OBJ_ANIMATION_SPEED; + static const ObjectCallbackMask cbm_animation_next_frame = CBM_OBJ_ANIMATION_NEXT_FRAME; +}; + +/** + * Handle the animation of the object tile. + * @param tile The tile to animate. + */ +void AnimateNewObjectTile(TileIndex tile) +{ + const ObjectSpec *spec = ObjectSpec::GetByTile(tile); + if (spec == NULL || !(spec->flags & OBJECT_FLAG_ANIMATION)) return; + + ObjectAnimationBase::AnimateTile(spec, Object::GetByTile(tile), tile, (spec->flags & OBJECT_FLAG_ANIM_RANDOM_BITS) != 0); +} + +/** + * Trigger the update of animation on a single tile. + * @param o The object that got triggered. + * @param tile The location of the triggered tile. + * @param trigger The trigger that is triggered. + * @param spec The spec associated with the object. + */ +void TriggerObjectTileAnimation(const Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec) +{ + if (!HasBit(spec->animation.triggers, trigger)) return; + + ObjectAnimationBase::ChangeAnimationFrame(CBID_OBJECT_ANIMATION_START_STOP, spec, o, tile, Random(), trigger); +} + +/** + * Trigger the update of animation on a whole object. + * @param o The object that got triggered. + * @param trigger The trigger that is triggered. + * @param spec The spec associated with the object. + */ +void TriggerObjectAnimation(const Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec) +{ + if (!HasBit(spec->animation.triggers, trigger)) return; + + TILE_AREA_LOOP(tile, o->location) { + TriggerObjectTileAnimation(o, tile, trigger, spec); + } +} diff --git a/src/newgrf_object.h b/src/newgrf_object.h index 0035ede93..aceca6943 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -120,5 +120,8 @@ uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, cons void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec); void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec); +void AnimateNewObjectTile(TileIndex tile); +void TriggerObjectTileAnimation(const Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec); +void TriggerObjectAnimation(const Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec); #endif /* NEWGRF_OBJECT_H */ diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index c4f17f576..8978fb9cd 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -89,6 +89,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town) } Object::IncTypeCount(type); + if (spec->flags & OBJECT_FLAG_ANIMATION) TriggerObjectAnimation(o, OAT_BUILT, spec); } /** @@ -379,6 +380,9 @@ static void GetTileDesc_Object(TileIndex tile, TileDesc *td) static void TileLoop_Object(TileIndex tile) { + const ObjectSpec *spec = ObjectSpec::GetByTile(tile); + if (spec->flags & OBJECT_FLAG_ANIMATION) TriggerObjectTileAnimation(Object::GetByTile(tile), tile, OAT_TILELOOP, spec); + if (IsTileOnWater(tile)) TileLoop_Water(tile); if (!IsCompanyHQ(tile)) return; @@ -424,6 +428,25 @@ static bool ClickTile_Object(TileIndex tile) return true; } +static void AnimateTile_Object(TileIndex tile) +{ + AnimateNewObjectTile(tile); +} + +/** Call the ticks on the objects. */ +void OnTick_Objects() +{ + const Object *o; + FOR_ALL_OBJECTS(o) { + /* Run 250 tick interval trigger for object animation. + * Object index is included so that triggers are not all done + * at the same time. */ + if ((_tick_counter + o->index) % 250 == 0) { + const ObjectSpec *spec = ObjectSpec::GetByTile(o->location.tile); + if (spec->flags & OBJECT_FLAG_ANIMATION) TriggerObjectAnimation(o, OAT_250_TICKS, spec); + } + } +} /* checks, if a radio tower is within a 9x9 tile square around tile */ static bool IsRadioTowerNearby(TileIndex tile) @@ -564,7 +587,7 @@ extern const TileTypeProcs _tile_type_object_procs = { GetTileDesc_Object, // get_tile_desc_proc GetTileTrackStatus_Object, // get_tile_track_status_proc ClickTile_Object, // click_tile_proc - NULL, // animate_tile_proc + AnimateTile_Object, // animate_tile_proc TileLoop_Object, // tile_loop_clear ChangeTileOwner_Object, // change_tile_owner_clear NULL, // add_produced_cargo_proc |