@@ -66,12 +66,36 @@ public class SummonedNosmate
6666
6767 public Character Owner { get ; }
6868 public LivingEntity Entity => Owner . Map . GetEntity < Npc > ( EntityType . Npc , Nosmate . Id ) ;
69+
70+ private CancellationTokenSource currentTaskCts ;
6971
7072 public SummonedNosmate ( Character owner )
7173 {
7274 Owner = owner ;
7375 }
7476
77+ public void Walk ( Position destination )
78+ {
79+ _ = WalkAsync ( destination ) ;
80+ }
81+
82+ public Task WalkAsync ( Position destination )
83+ {
84+ if ( currentTaskCts is not null )
85+ {
86+ currentTaskCts . Cancel ( ) ;
87+ }
88+
89+ currentTaskCts = new CancellationTokenSource ( ) ;
90+
91+ if ( ! Entity . Map . IsWalkable ( destination ) )
92+ {
93+ return Task . CompletedTask ;
94+ }
95+
96+ return Walk ( destination , currentTaskCts . Token ) ;
97+ }
98+
7599 public void Attack ( LivingEntity target , NosmateSkill skill )
76100 {
77101 if ( ! Skills . Contains ( skill ) )
@@ -86,4 +110,50 @@ public void AttackSelf(NosmateSkill skill)
86110 {
87111 Attack ( Entity , skill ) ;
88112 }
113+
114+ private async Task Walk ( Position destination , CancellationToken cancellationToken )
115+ {
116+ var positiveX = destination . X > Entity . Position . X ;
117+ var positiveY = destination . Y > Entity . Position . Y ;
118+
119+ while ( ! Entity . Position . Equals ( destination ) && ! cancellationToken . IsCancellationRequested )
120+ {
121+ var distance = Entity . Position . Distance ( destination ) ;
122+
123+ var stepX = distance . X >= 5 ? 5 : distance . X ;
124+ var stepY = distance . Y >= 5 ? 5 : distance . Y ;
125+
126+ var stepTotal = stepX + stepY ;
127+ if ( stepTotal > 5 )
128+ {
129+ var difference = stepTotal - 5 ;
130+ var split = difference / 2 + ( difference % 2 ) ;
131+
132+ stepX -= split ;
133+ stepY -= split ;
134+ }
135+
136+ var x = ( positiveX ? 1 : - 1 ) * stepX + Entity . Position . X ;
137+ var y = ( positiveY ? 1 : - 1 ) * stepY + Entity . Position . Y ;
138+
139+ var target = new Position ( x , y ) ;
140+
141+ if ( ! Entity . Map . IsWalkable ( target ) )
142+ {
143+ break ;
144+ }
145+
146+ Owner . GetBridge ( ) . WalkNosmate ( target , Entity . Speed ) ;
147+
148+ try
149+ {
150+ await Task . Delay ( ( stepX + stepY ) * ( 2000 / Entity . Speed ) , cancellationToken ) ;
151+ }
152+ catch ( TaskCanceledException ) { }
153+ finally
154+ {
155+ Entity . Position = target ;
156+ }
157+ }
158+ }
89159}
0 commit comments