Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Map/Creatures/State/GrowToTargetState.cs
2022-02-26 02:43:01 +09:00

98 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
namespace Barotrauma.MapCreatures.Behavior
{
class GrowToTargetState: GrowIdleState
{
public readonly List<BallastFloraBranch> TargetBranches = new List<BallastFloraBranch>();
public readonly Item Target;
private bool isFinished;
public GrowToTargetState(BallastFloraBehavior behavior, BallastFloraBranch starter, Item target) : base(behavior)
{
Target = target;
TargetBranches.Add(starter);
}
// do nothing
public override void Enter() { }
public override ExitState GetState() => isFinished ? ExitState.Terminate : ExitState.Running;
protected override void Grow()
{
if (TargetBranches.Any(b => b.Removed))
{
if (!Behavior.IgnoredTargets.ContainsKey(Target))
{
Behavior.IgnoredTargets.Add(Target, 10);
}
isFinished = true;
return;
}
if (Target == null || Target.Removed)
{
isFinished = true;
return;
}
GrowTowardsTarget();
}
private void GrowTowardsTarget()
{
bool succeeded = false;
List<BallastFloraBranch> newList = new List<BallastFloraBranch>(TargetBranches);
foreach (BallastFloraBranch branch in newList)
{
if (branch.FailedGrowthAttempts > 8 || branch.DisconnectedFromRoot || !branch.CanGrowMore()) { continue; }
// Get what side gets us closest to the target
TileSide side = GetClosestSide(branch, Target.WorldPosition);
if (branch.IsSideBlocked(side)) { continue; }
succeeded |= Behavior.TryGrowBranch(branch, side, out List<BallastFloraBranch> newBranches);
TargetBranches.AddRange(newBranches);
foreach (BallastFloraBranch newBranch in newBranches)
{
Rectangle worldRect = newBranch.Rect;
worldRect.Location = Behavior.GetWorldPosition().ToPoint() + worldRect.Location;
if (Behavior.BranchContainsTarget(newBranch, Target))
{
Behavior.ClaimTarget(Target, newBranch);
isFinished = true;
return;
}
}
}
if (!succeeded)
{
if (!Behavior.IgnoredTargets.ContainsKey(Target))
{
Behavior.IgnoredTargets.Add(Target, 1);
}
isFinished = true;
}
}
private TileSide GetClosestSide(VineTile tile, Vector2 targetPos)
{
var (distX, distY) = tile.Position + Behavior.GetWorldPosition() - targetPos;
int absDistX = (int) Math.Abs(distX), absDistY = (int) Math.Abs(distY);
return absDistX > absDistY ? distX > 0 ? TileSide.Left : TileSide.Right : distY > 0 ? TileSide.Bottom : TileSide.Top;
}
}
}