Previous commits removed the async loading of videos, which can be a problem for videos played in the radar widget mid-game because it can cause a lag spike. This loads the video on a separate thread and runs it on the main thread whenever it is loaded, not blocking the main thread meanwhile and allowing the game to continue while the video loads.
Also add back cancelling of already playing video and add a check to not try to run onComplete if it is null.
Somehow this would divide by 0 on the next line, not crashing but resulting in an integer overflow on `overlayHeight`, which would crash when trying to render.
- Improve consistency
- Remove dead code
- Removed AsyncAction!
- Delegate.BeginInvoke is unsupported since .NET Core and throws an "Operation is not supported on this platform." exception.
This moves initialization of Initialize getters for left/right arrow image from constructor Initialize method making it possible to override fields Decorations, DecorationScrollLeft and DecorationScrollRight after widget creation.
All magic behaviour for constructing sprite filenames
has been removed in favour of an explicit Filename
(and TilesetFilenames for tileset-specific sequences)
property.
The previous MiniYaml.Merge implementation interacted
poorly with yaml inheritance, making it complicated
(or impossible) to override certain keys from Defaults.
The new implementation is simpler: If a key is defined
it will be used. If it isn't, the default (if defined)
will be used. Defaults can be masked by making sure
the same key is defined (even with an empty value)
in the sequence.
This also fixes naming within the sequence code to
distinguish between images (a group of sequences),
sequences (defining a specific sprite/animation),
and filenames for a specific sprite/animation.
The cache in Locomotor that is populated via the UpdateCellBlocking method disagreed with the non-cached logic of IsBlockedBy when dealing with Mobile actors. The cache determined an actor to be moving if it was both movable and had horizontal movement types. IsBlockedBy determined an actor to be moving if it had horizontal movement types, but did not check if it was movable. This difference in checks could allow a mobile trait that was disabled or paused and which had horizontal movement to be treated differently be the two methods. UpdateCellBlocking would consider it not moving due to the disabled/paused trait. IsBlockedBy would consider it moving as it didn't care about the disabled/paused state of the trait.
Now, we unify the two methods to consider a mobile trait that is disabled/paused as not moving. This prevents HierarchicalPathFinder from crashing on the inconsistent state, i.e. when asked to path search through a cell of a mobile unit which has disabled or paused movement, but which has horizontal movement types from prior movement.