44using Intersect . Client . Framework . GenericClasses ;
55using Intersect . Client . Framework . Maps ;
66using Intersect . Client . General ;
7+ using Intersect . Core ;
78using Intersect . Enums ;
89using Intersect . Framework . Core . GameObjects . Resources ;
910using Intersect . GameObjects ;
1011using Intersect . Network . Packets . Server ;
12+ using Microsoft . Extensions . Logging ;
1113
1214namespace Intersect . Client . Entities ;
1315
@@ -20,7 +22,9 @@ public partial class Resource : Entity, IResource
2022 private bool _waitingForTilesets ;
2123
2224 private bool _isDead ;
25+ private Guid _descriptorId ;
2326 private ResourceDescriptor ? _descriptor ;
27+ private IAnimation ? _activeAnimation ;
2428
2529 public Resource ( Guid id , ResourceEntityPacket packet ) : base ( id , packet , EntityType . Resource )
2630 {
@@ -108,14 +112,67 @@ public override void Load(EntityPacket? packet)
108112 return ;
109113 }
110114
115+ var wasDead = IsDead ;
111116 IsDead = resourceEntityPacket . IsDead ;
112117
113- if ( ! ResourceDescriptor . TryGet ( resourceEntityPacket . ResourceId , out _descriptor ) )
118+ var descriptorId = resourceEntityPacket . ResourceId ;
119+ _descriptorId = descriptorId ;
120+
121+ var justDied = ! wasDead && resourceEntityPacket . IsDead ;
122+ if ( ! ResourceDescriptor . TryGet ( descriptorId , out var descriptor ) )
114123 {
124+ if ( justDied )
125+ {
126+ ApplicationContext . CurrentContext . Logger . LogError (
127+ "Unable to play resource exhaustion animation because resource {EntityId} ({EntityName}) is missing the descriptor ({DescriptorId})" ,
128+ Id ,
129+ Name ,
130+ descriptorId
131+ ) ;
132+ }
133+
115134 return ;
116135 }
117136
137+ _descriptor = descriptor ;
118138 UpdateFromDescriptor ( _descriptor ) ;
139+
140+ if ( ! justDied )
141+ {
142+ return ;
143+ }
144+
145+ if ( MapInstance is { } mapInstance )
146+ {
147+ var animation = mapInstance . AddTileAnimation ( descriptor . AnimationId , X , Y , Direction . Up ) ;
148+ if ( animation is { IsDisposed : false } )
149+ {
150+ animation . Finished += OnAnimationDisposedOrFinished ;
151+ animation . Disposed += OnAnimationDisposedOrFinished ;
152+ }
153+ _activeAnimation = animation ;
154+ }
155+ else
156+ {
157+ ApplicationContext . CurrentContext . Logger . LogError (
158+ "Unable to play resource exhaustion animation because resource {EntityId} ({EntityName}) has no reference to the map instance for map {MapId}" ,
159+ Id ,
160+ Name ,
161+ MapId
162+ ) ;
163+ }
164+ }
165+
166+ private void OnAnimationDisposedOrFinished ( IAnimation animation )
167+ {
168+ if ( _activeAnimation != animation )
169+ {
170+ return ;
171+ }
172+
173+ _activeAnimation = null ;
174+ animation . Disposed -= OnAnimationDisposedOrFinished ;
175+ animation . Finished -= OnAnimationDisposedOrFinished ;
119176 }
120177
121178 private void UpdateFromDescriptor ( ResourceDescriptor ? descriptor )
@@ -353,9 +410,17 @@ public override void Draw()
353410 return ;
354411 }
355412
356- if ( Texture ! = null )
413+ if ( Texture = = null )
357414 {
358- Graphics . DrawGameTexture ( Texture , _renderBoundsSrc , _renderBoundsDest , Intersect . Color . White ) ;
415+ return ;
359416 }
417+
418+ // TODO: Add an option to hide the exhausted sprite until the exhaustion animation is finished, but this is not necessary if the graphics line up like Blinkuz' sample provided to fix #2572
419+ // if (_activeAnimation != null)
420+ // {
421+ // return;
422+ // }
423+
424+ Graphics . DrawGameTexture ( Texture , _renderBoundsSrc , _renderBoundsDest , Intersect . Color . White ) ;
360425 }
361426}
0 commit comments