core/npc/NpcWolfBrain.cs
public class NpcWolfBrain : Component {
[Property, ReadOnly] public float PlayerDistance {get; set;}
public TimeUntil ExitCombat {get; set;}
private TimeUntil RandomMove {get; set;} = 5f;
private TimeUntil NextAttack {get; set;}
protected override void OnFixedUpdate() {
if (!Components.Get<IsoEntity>().IsValid())
return;
PlayerDistance = WorldPosition.Distance(BasePlayer.Local.IsoMovement.EntityRoot);
var a = Components.GetOrCreate<NpcAnimator>();
var m = Components.GetOrCreate<NpcMovement>();
if (Components.Get<IsoEntity>().Health <= 0)
a.Activity = "die";
if (a.ActivitySet.NonInteruptActivities.Contains(a.Activity))
return;
if (ExitCombat && PlayerDistance < 300)
ExitCombat = 10;
if (ExitCombat) {
if (RandomMove) {
m.Goal = Grid.Snap(WorldPosition + Vector3.Random * 100);
m.Go();
RandomMove = Random.Shared.Float(5,15);
}
return;
}
a.AttackAction = () => {
if (m.EntityRoot.Distance(BasePlayer.Local.IsoMovement.EntityRoot) <= 100) {
BasePlayer.Local.IsoEntity.Health -= Random.Shared.Int(1,3);
var a = BasePlayer.Local.IsoEntity.Components.Get<NpcAnimator>();
if (a.IsValid() && !a.ActivitySet.NonInteruptActivities.Contains(a.Activity))
a.Activity = "flinch";
NextAttack = Random.Shared.Float(0.2f,1f);
}
};
a.Activity = "idle";
if (NextAttack)
a.Activity = "attack";
if (PlayerDistance > 100)
a.Activity = "run";
m.DontUpdateActivity = true;
if (m.Path.Count < 1) {
var start = m.EntityRoot;
if (m.Path.Count > 0)
start = m.Path.Last();
var best = -1f;
var point = m.EntityRoot;
for (int i = 0; i < 6; i++) {
var canidate = Grid.Snap(start + Rotation.FromYaw(i * 60f - 30f).Forward * 30f);
if (Grid.IsBlocked(canidate))
continue;
var dot = Vector3.Direction(start, canidate).Dot(Vector3.Direction(start, BasePlayer.Local.IsoMovement.EntityRoot));
if (dot < best)
continue;
point = canidate;
best = dot;
}
m.Path.Add(point);
}
base.OnFixedUpdate();
base.OnFixedUpdate();
}
}