Skip to content

Commit f4f2f9e

Browse files
committed
Introduce CanTarget()
1 parent c9f4bbd commit f4f2f9e

File tree

2 files changed

+57
-59
lines changed

2 files changed

+57
-59
lines changed

Intersect.Server.Core/Entities/Entity.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public abstract partial class Entity : IEntity
4848
public IReadOnlyDictionary<Vital, long> VitalsLookup => _vitals.Select((value, index) => (value, index))
4949
.ToDictionary(t => (Vital)t.index, t => t.value).AsReadOnly();
5050

51-
[NotMapped, JsonIgnore] public Entity Target { get; set; } = null;
51+
[NotMapped, JsonIgnore] public Entity? Target { get; set; }
5252

5353
public Entity() : this(Guid.NewGuid(), Guid.Empty)
5454
{
@@ -318,6 +318,8 @@ public virtual void Dispose()
318318
}
319319
}
320320

321+
public bool HasStatusEffect(SpellEffect spellEffect) => CachedStatuses.Any(s => s.Type == spellEffect);
322+
321323
public virtual void Update(long timeMs)
322324
{
323325
var lockObtained = false;
@@ -1261,7 +1263,7 @@ public virtual void Move(Direction moveDir, Player forPlayer, bool doNotUpdate =
12611263

12621264
protected virtual bool CanLookInDirection(Direction direction) => true;
12631265

1264-
public virtual void ChangeDir(Direction dir)
1266+
public void ChangeDir(Direction dir)
12651267
{
12661268
if (!CanLookInDirection(dir))
12671269
{
@@ -1408,6 +1410,24 @@ public virtual int GetWeaponDamage()
14081410

14091411
public virtual bool CanAttack(Entity entity, SpellBase spell) => !IsCasting;
14101412

1413+
public virtual bool CanTarget(Entity? entity)
1414+
{
1415+
if (entity == null)
1416+
{
1417+
// If it's not an entity we can't target it
1418+
return false;
1419+
}
1420+
1421+
if (IsAllyOf(entity))
1422+
{
1423+
// If it's an ally we can always target them
1424+
return true;
1425+
}
1426+
1427+
// If it's not an ally we can't target it if it's stealthed
1428+
return !entity.HasStatusEffect(SpellEffect.Stealth);
1429+
}
1430+
14111431
public virtual void ProcessRegen()
14121432
{
14131433
}

Intersect.Server.Core/Entities/Npc.cs

Lines changed: 35 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public bool TargetHasStealth(Entity target)
190190
}
191191

192192
//Targeting
193-
public void AssignTarget(Entity en)
193+
public void AssignTarget(Entity? en)
194194
{
195195
var oldTarget = Target;
196196

@@ -199,16 +199,7 @@ public void AssignTarget(Entity en)
199199
if (AggroCenterMap != null && pathTarget != null &&
200200
pathTarget.TargetMapId == AggroCenterMap.Id && pathTarget.TargetX == AggroCenterX && pathTarget.TargetY == AggroCenterY)
201201
{
202-
if (en == null)
203-
{
204-
return;
205-
206-
}
207-
else
208-
{
209-
return;
210-
211-
}
202+
return;
212203
}
213204

214205
//Why are we doing all of this logic if we are assigning a target that we already have?
@@ -229,7 +220,7 @@ public void AssignTarget(Entity en)
229220

230221
if (en is Projectile projectile)
231222
{
232-
if (projectile.Owner != this && !TargetHasStealth(projectile))
223+
if (projectile.Owner != this && !projectile.HasStatusEffect(SpellEffect.Stealth))
233224
{
234225
Target = projectile.Owner;
235226
}
@@ -246,21 +237,17 @@ public void AssignTarget(Entity en)
246237
}
247238
}
248239
}
249-
250-
if (en is Player)
240+
else if (en is Player player)
251241
{
252242
//TODO Make sure that the npc can target the player
253-
if (this != en && !TargetHasStealth(en))
243+
if (CanTarget(player))
254244
{
255-
Target = en;
245+
Target = player;
256246
}
257247
}
258-
else
248+
else if (CanTarget(en))
259249
{
260-
if (this != en && !TargetHasStealth(en))
261-
{
262-
Target = en;
263-
}
250+
Target = en;
264251
}
265252
}
266253

@@ -310,16 +297,6 @@ public override int CalculateAttackTime()
310297
return base.CalculateAttackTime();
311298
}
312299

313-
public override void ChangeDir(Direction dir)
314-
{
315-
if (Target.CachedStatuses.Any(s => s.Type == SpellEffect.Stealth))
316-
{
317-
return;
318-
}
319-
320-
base.ChangeDir(dir);
321-
}
322-
323300
public override bool CanAttack(Entity entity, SpellBase spell)
324301
{
325302
if (!base.CanAttack(entity, spell))
@@ -341,7 +318,7 @@ public override bool CanAttack(Entity entity, SpellBase spell)
341318
}
342319
}
343320

344-
if (TargetHasStealth(entity))
321+
if (entity.HasStatusEffect(SpellEffect.Stealth))
345322
{
346323
// if spell is area or projectile, we can attack without knowing the target location
347324
if (spell?.Combat is { TargetType: SpellTargetType.AoE or SpellTargetType.Projectile })
@@ -692,10 +669,10 @@ private void TryCastSpells()
692669
}
693670

694671
//TODO: try cast spell to find out hidden targets?
695-
if (TargetHasStealth(target) /* && spellBase.Combat.TargetType != SpellTargetType.AoE*/)
696-
{
697-
return;
698-
}
672+
// if (target.HasStatusEffect(SpellEffect.Stealth) /* && spellBase.Combat.TargetType != SpellTargetType.AoE*/)
673+
// {
674+
// return;
675+
// }
699676

700677
// Check if we are even allowed to cast this spell.
701678
if (!CanCastSpell(spellBase, target, true, out _))
@@ -803,12 +780,12 @@ public override void Update(long timeMs)
803780
{
804781
var curMapLink = MapId;
805782
base.Update(timeMs);
783+
806784
var tempTarget = Target;
807-
var targetIsHidden = TargetHasStealth(tempTarget);
808785

809786
foreach (var status in CachedStatuses)
810787
{
811-
if (status.Type == SpellEffect.Stun || status.Type == SpellEffect.Sleep)
788+
if (status.Type is SpellEffect.Stun or SpellEffect.Sleep)
812789
{
813790
return;
814791
}
@@ -823,6 +800,12 @@ public override void Update(long timeMs)
823800
var targetY = 0;
824801
var targetZ = 0;
825802

803+
if (tempTarget != null && (tempTarget.IsDead() || !InRangeOf(tempTarget, Options.MapWidth * 2) || !CanTarget(tempTarget)))
804+
{
805+
_ = TryFindNewTarget(Timing.Global.Milliseconds, tempTarget.Id, !CanTarget(tempTarget));
806+
tempTarget = Target;
807+
}
808+
826809
//TODO Clear Damage Map if out of combat (target is null and combat timer is to the point that regen has started)
827810
if (tempTarget != null && (Options.Instance.NpcOpts.ResetIfCombatTimerExceeded && Timing.Global.Milliseconds > CombatTimer))
828811
{
@@ -868,14 +851,8 @@ public override void Update(long timeMs)
868851
}
869852
}
870853

871-
if (tempTarget != null && (tempTarget.IsDead() || !InRangeOf(tempTarget, Options.MapWidth * 2) || targetIsHidden))
872-
{
873-
TryFindNewTarget(Timing.Global.Milliseconds, tempTarget.Id, targetIsHidden);
874-
tempTarget = Target;
875-
}
876-
877854
//Check if there is a target, if so, run their ass down.
878-
if (tempTarget != null && !targetIsHidden)
855+
if (tempTarget != null && CanTarget(tempTarget))
879856
{
880857
if (!tempTarget.IsDead() && CanAttack(tempTarget, null))
881858
{
@@ -929,7 +906,7 @@ public override void Update(long timeMs)
929906
{
930907
mPathFinder.SetTarget(new PathfinderTarget(targetMap, targetX, targetY, targetZ));
931908

932-
if (tempTarget != Target)
909+
if (tempTarget != null && tempTarget != Target)
933910
{
934911
tempTarget = Target;
935912
}
@@ -1397,11 +1374,11 @@ public bool ShouldAttackPlayerOnSight(Player en)
13971374
return false;
13981375
}
13991376

1400-
public void TryFindNewTarget(long timeMs, Guid avoidId = new Guid(), bool ignoreTimer = false, Entity attackedBy = null)
1377+
public bool TryFindNewTarget(long timeMs, Guid avoidId = new(), bool ignoreTimer = false, Entity attackedBy = null)
14011378
{
14021379
if (!ignoreTimer && FindTargetWaitTime > timeMs)
14031380
{
1404-
return;
1381+
return false;
14051382
}
14061383

14071384
// Are we resetting? If so, do not allow for a new target.
@@ -1411,16 +1388,14 @@ public bool ShouldAttackPlayerOnSight(Player en)
14111388
{
14121389
if (!Options.Instance.NpcOpts.AllowEngagingWhileResetting || attackedBy == null || attackedBy.GetDistanceTo(AggroCenterMap, AggroCenterX, AggroCenterY) > Math.Max(Options.Instance.NpcOpts.ResetRadius, Base.ResetRadius))
14131390
{
1414-
return;
1415-
}
1416-
else
1417-
{
1418-
//We're resetting and just got attacked, and we allow reengagement.. let's stop resetting and fight!
1419-
mPathFinder?.SetTarget(null);
1420-
mResetting = false;
1421-
AssignTarget(attackedBy);
1422-
return;
1391+
return false;
14231392
}
1393+
1394+
//We're resetting and just got attacked, and we allow reengagement.. let's stop resetting and fight!
1395+
mPathFinder?.SetTarget(null);
1396+
mResetting = false;
1397+
AssignTarget(attackedBy);
1398+
return true;
14241399
}
14251400

14261401
var possibleTargets = new List<Entity>();
@@ -1557,9 +1532,12 @@ public bool ShouldAttackPlayerOnSight(Player en)
15571532
{
15581533
CheckForResetLocation(true);
15591534
}
1535+
1536+
AssignTarget(null);
15601537
}
15611538

15621539
FindTargetWaitTime = timeMs + FindTargetDelay;
1540+
return Target != null;
15631541
}
15641542

15651543
public override void ProcessRegen()

0 commit comments

Comments
 (0)