Skip to content

Commit

Permalink
Animated statics
Browse files Browse the repository at this point in the history
  • Loading branch information
kaczy93 committed Mar 19, 2024
1 parent 92888d3 commit 6b3c7b4
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 2 deletions.
128 changes: 128 additions & 0 deletions CentrED/AnimatedStaticsManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using ClassicUO.Assets;
using ClassicUO.IO;
using ClassicUO.Utility.Collections;
using Microsoft.Xna.Framework;

namespace CentrED;

// This class is almost exact copy from ClassicUO
// The only difference is that it works on GameTime passed to Process() and animated fields option is removed
sealed class AnimatedStaticsManager
{
private readonly FastList<StaticAnimationInfo> _staticInfos = new();
private uint _processTime;

public unsafe void Initialize()
{
UOFile file = AnimDataLoader.Instance.AnimDataFile;

if (file == null)
{
return;
}

long startAddr = file.StartAddress.ToInt64();
uint lastaddr = (uint)(startAddr + file.Length - sizeof(AnimDataFrame));

for (int i = 0; i < TileDataLoader.Instance.StaticData.Length; i++)
{
if (TileDataLoader.Instance.StaticData[i].IsAnimated)
{
uint addr = (uint)(i * 68 + 4 * (i / 8 + 1));
uint offset = (uint)(startAddr + addr);

if (offset <= lastaddr)
{
_staticInfos.Add
(
new StaticAnimationInfo
{
Index = (ushort)i,
// IsField = IsField((ushort)i)
}
);
}
}
}
}

public unsafe void Process(GameTime gameTime)
{
var ticks = (uint)gameTime.TotalGameTime.TotalMilliseconds;
if (_staticInfos == null || _staticInfos.Length == 0 || _processTime >= ticks)
{
return;
}

UOFile file = AnimDataLoader.Instance.AnimDataFile;

if (file == null)
{
return;
}

// fix static animations time to reflect the standard client
uint delay = 50 * 2;
uint next_time = ticks + 250;
// bool no_animated_field = ProfileManager.CurrentProfile != null && ProfileManager.CurrentProfile.FieldsType != 0;
long startAddr = file.StartAddress.ToInt64();
UOFileIndex[] static_data = ArtLoader.Instance.Entries;

for (int i = 0; i < _staticInfos.Length; i++)
{
ref StaticAnimationInfo o = ref _staticInfos.Buffer[i];

// if (no_animated_field && o.IsField)
// {
// o.AnimIndex = 0;
//
// continue;
// }

if (o.Time < ticks)
{
uint addr = (uint)(o.Index * 68 + 4 * (o.Index / 8 + 1));
AnimDataFrame* info = (AnimDataFrame*)(startAddr + addr);

byte offset = o.AnimIndex;

if (info->FrameInterval > 0)
{
o.Time = ticks + info->FrameInterval * delay + 1;
}
else
{
o.Time = ticks + delay;
}

if (offset < info->FrameCount && o.Index + 0x4000 < static_data.Length)
{
static_data[o.Index + 0x4000].AnimOffset = info->FrameData[offset++];
}

if (offset >= info->FrameCount)
{
offset = 0;
}

o.AnimIndex = offset;
}

if (o.Time < next_time)
{
next_time = o.Time;
}
}

_processTime = next_time;
}


private struct StaticAnimationInfo
{
public uint Time;
public ushort Index;
public byte AnimIndex;
// public bool IsField;
}
}
17 changes: 17 additions & 0 deletions CentrED/Map/MapManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class MapManager

public bool DebugDrawSelectionBuffer;
private RenderTarget2D _selectionBuffer;
private AnimatedStaticsManager _animatedStaticsManager;

internal List<Tool> Tools = new();
private Tool _activeTool;
Expand Down Expand Up @@ -285,10 +286,13 @@ public void Load(string clientPath, string clientVersion)
HuesLoader.Instance.Load(),
TileDataLoader.Instance.Load(),
TexmapsLoader.Instance.Load(),
AnimDataLoader.Instance.Load(),
}
).Wait(TimeSpan.FromSeconds(10.0)))
Log.Panic("Loading files timeout.");

_animatedStaticsManager = new AnimatedStaticsManager();
_animatedStaticsManager.Initialize();
TextureAtlas.InitializeSharedTexture(_gfxDevice);
HuesManager.Load(_gfxDevice);
_mapEffect.HueCount = HuesManager.Instance.HuesCount;
Expand Down Expand Up @@ -340,6 +344,7 @@ public static Vector2 ScreenToMapCoordinates(float x, float y)
public Dictionary<LandObject, LandObject> GhostLandTiles = new();
public List<StaticObject>?[,] StaticTiles;
public int StaticTilesCount;
public List<StaticObject> AnimatedStaticTiles = new();
public Dictionary<TileObject, StaticObject> GhostStaticTiles = new();
public VirtualLayerObject VirtualLayer = VirtualLayerObject.Instance; //Used for drawing

Expand Down Expand Up @@ -410,6 +415,10 @@ public void AddTile(StaticTile staticTile)
list.Add(so);
AllTiles.Add(so.ObjectId, so);
StaticTilesCount++;
if (so.IsAnimated)
{
AnimatedStaticTiles.Add(so);
}
}

public void RemoveTile(StaticTile staticTile)
Expand Down Expand Up @@ -657,6 +666,14 @@ public void Update(GameTime gameTime, bool isActive, bool processMouse, bool pro
Client.LoadBlocks(requested);
}
}
if (Client.Initialized)
{
_animatedStaticsManager.Process(gameTime);
foreach (var animatedStaticTile in AnimatedStaticTiles)
{
animatedStaticTile.UpdateId();
}
}
Metrics.Stop("UpdateMap");
}

Expand Down
12 changes: 10 additions & 2 deletions CentrED/Map/StaticObject.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using CentrED.Renderer;
using ClassicUO.Assets;
using Microsoft.Xna.Framework;

Expand All @@ -8,6 +7,7 @@ public class StaticObject : TileObject
{
public const float INVERSE_SQRT2 = 0.70711f;
public StaticTile StaticTile;
public bool IsAnimated;

public StaticObject(StaticTile tile)
{
Expand All @@ -20,6 +20,7 @@ public StaticObject(StaticTile tile)
{
Vertices[i].Normal = Vector3.Zero;
}
IsAnimated = TileDataLoader.Instance.StaticData[Tile.Id].IsAnimated;
}

public void Update()
Expand All @@ -28,9 +29,15 @@ public void Update()
UpdatePos(Tile.X, Tile.Y, Tile.Z);
}

public void UpdateId()
{
UpdateId(Tile.Id);
}

public void UpdateId(ushort newId)
{
Texture = ArtLoader.Instance.GetStaticTexture(Tile.Id, out TextureBounds);
ref var index = ref ArtLoader.Instance.GetValidRefEntry(newId + 0x4000);
Texture = ArtLoader.Instance.GetStaticTexture((ushort)(newId + index.AnimOffset), out TextureBounds);

float onePixel = Math.Max(1.0f / Texture.Width, Epsilon.value);
var texX = TextureBounds.X / (float)Texture.Width + onePixel / 2f;
Expand All @@ -43,6 +50,7 @@ public void UpdateId(ushort newId)
Vertices[2].Texture = new Vector3(texX, texY + texHeight, 0f);
Vertices[3].Texture = new Vector3(texX + texWidth, texY + texHeight, 0f);
UpdateDepthOffset();
IsAnimated = TileDataLoader.Instance.StaticData[newId].IsAnimated;
}

public void UpdateDepthOffset()
Expand Down

0 comments on commit 6b3c7b4

Please sign in to comment.