4 using Microsoft.Xna.Framework;
6 using System.Collections.Generic;
38 if (i.IsOwnedBy(c)) {
return; }
42 if (it.IsOwnedBy(ch)) {
return; }
91 private IEnumerable<Hull> visibleHulls;
92 private float hullVisibilityTimer;
93 const float hullVisibilityInterval = 0.5f;
108 visibleHulls = value;
119 public bool HasValidPath(
bool requireNonDirty =
true,
bool requireUnfinished =
true, Func<WayPoint, bool> nodePredicate =
null)
122 if (pathSteering.CurrentPath ==
null) {
return false; }
123 if (pathSteering.CurrentPath.Unreachable) {
return false; }
124 if (requireUnfinished && pathSteering.CurrentPath.Finished) {
return false; }
125 if (requireNonDirty && pathSteering.IsPathDirty) {
return false; }
126 if (nodePredicate !=
null)
128 return pathSteering.CurrentPath.Nodes.All(n => nodePredicate(n));
145 hullVisibilityTimer = Rand.Range(0f, hullVisibilityTimer);
160 public virtual void Update(
float deltaTime)
162 if (hullVisibilityTimer > 0)
164 hullVisibilityTimer--;
168 hullVisibilityTimer = hullVisibilityInterval;
191 if (wall ==
null) {
return false; }
192 if (section ==
null) {
return false; }
194 if (gap ==
null) {
return false; }
195 float maxDistance = Math.Min(wall.
Rect.Width, wall.
Rect.Height);
196 if (Vector2.DistanceSquared(
Character.
WorldPosition, targetWorldPos) > maxDistance * maxDistance) {
return false; }
198 if (targetHull ==
null) {
return false; }
201 targetWorldPos.Y = targetHull.
WorldRect.Y - targetHull.
Rect.Height / 2;
205 targetWorldPos.X = targetHull.
WorldRect.Center.X;
207 return SteerThroughGap(gap, targetWorldPos, deltaTime, maxDistance: -1);
210 public virtual bool SteerThroughGap(
Gap gap, Vector2 targetWorldPos,
float deltaTime,
float maxDistance = -1)
213 if (targetHull ==
null) {
return false; }
216 if (Vector2.DistanceSquared(
Character.
WorldPosition, targetWorldPos) > maxDistance * maxDistance) {
return false; }
220 pathSteering.ResetPath();
230 for (
int j = sectionIndex - 1; j > sectionIndex - requiredHoleCount; j--)
241 for (
int j = sectionIndex + 1; j < sectionIndex + requiredHoleCount; j++)
252 return holeCount >= requiredHoleCount;
257 bool isDisabled =
true;
258 for (
int i = 0; i < wall.
Sections.Length; i++)
269 private readonly HashSet<Item> unequippedItems =
new HashSet<Item>();
270 public bool TakeItem(
Item item,
CharacterInventory targetInventory,
bool equip,
bool wear =
false,
bool dropOtherIfCannotMove =
true,
bool allowSwapping =
false,
bool storeUnequipped =
false, IEnumerable<Identifier> targetTags =
null)
272 var pickable = item.GetComponent<
Pickable>();
273 if (pickable ==
null) {
return false; }
276 var wearable = item.GetComponent<
Wearable>();
277 if (wearable !=
null)
285 pickable = item.GetComponent<
Holdable>();
289 if (!itemInventory.Container.HasRequiredItems(
Character, addMessage:
false)) {
return false; }
291 if (equip && pickable !=
null)
295 foreach (
InvSlotType slots
in pickable.AllowedSlots)
306 for (
int i = 0; i < targetInventory.
Capacity; i++)
311 if (!slots.HasFlag(characterInventory.SlotTypes[i])) {
continue; }
315 var otherItem = targetInventory.
GetItemAt(i);
316 if (otherItem ==
null) {
continue; }
322 unequippedItems.Add(otherItem);
326 if (dropOtherIfCannotMove)
328 if (otherItem.Prefab.Identifier == item.
Prefab.
Identifier || otherItem.HasIdentifierOrTags(targetTags))
330 bool switchingToBetterSuit =
331 targetTags !=
null &&
332 targetTags.FirstOrDefault() == Tags.HeavyDivingGear &&
337 if (!switchingToBetterSuit)
347 if (targetSlot < 0) {
return false; }
349 if (pickable.AllowedSlots.Contains(
InvSlotType.Any))
353 return targetInventory.
TryPutItem(item, targetSlot, allowSwapping, allowCombine:
false,
Character);
370 if (inventory ==
null || !inventory.Container.DrawInventory) {
return; }
372 if (predicate ==
null || inventory.AllItems.Any(predicate))
374 foreach (
Item containedItem
in inventory.AllItemsMod)
376 if (containedItem ==
null) {
continue; }
377 if (predicate ==
null || predicate(containedItem))
384 if (unequipMax.HasValue && ++removed >= unequipMax) {
return; }
388 containedItem.
Drop(character);
389 if (unequipMax.HasValue && ++removed >= unequipMax) {
return; }
397 foreach (var item
in unequippedItems)
401 TakeItem(item,
Character.
Inventory, equip:
true, wear:
true, dropOtherIfCannotMove:
true, allowSwapping:
true, storeUnequipped:
false);
404 unequippedItems.Clear();
408 public abstract bool Escape(
float deltaTime);
412 private readonly
float escapeTargetSeekInterval = 2;
413 private float escapeTimer;
421 escapeTimer -= deltaTime;
422 if (escapeTimer <= 0)
432 float closestDistance = 0;
435 if (gap ==
null || gap.
Removed) {
continue; }
440 float multiplier = 1;
451 if (gap.
Open < 1) {
continue; }
464 closestDistance = distance;
468 escapeTimer = escapeTargetSeekInterval;
483 bool isClosedDoor = door !=
null && door.
IsClosed;
485 float sqrDist = diff.LengthSquared();
486 bool isClose = sqrDist < MathUtils.Pow2(100);
493 Vector2 dir = Vector2.Normalize(diff);
511 return sqrDist < MathUtils.Pow2(250);
513 else if (pathSteering !=
null)
static void UnequipContainedItems(Character character, Item parentItem, Func< Item, bool > predicate, bool avoidDroppingInSea=true, int? unequipMax=null)
readonly HashSet< Gap > unreachableGaps
readonly Character Character
void UnequipContainedItems(Item parentItem, Func< Item, bool > predicate=null, bool avoidDroppingInSea=true, int? unequipMax=null)
virtual bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime)
virtual bool IsMentallyUnstable
readonly float minGapSize
virtual void OnTargetChanged(AITarget previousTarget, AITarget newTarget)
void UnequipEmptyItems(Item parentItem, bool avoidDroppingInSea=true)
virtual void OnHealed(Character healer, float healAmount)
virtual void SelectTarget(AITarget target)
bool TakeItem(Item item, CharacterInventory targetInventory, bool equip, bool wear=false, bool dropOtherIfCannotMove=true, bool allowSwapping=false, bool storeUnequipped=false, IEnumerable< Identifier > targetTags=null)
bool IsTryingToSteerThroughGap
readonly float avoidLookAheadDistance
AITarget _selectedAiTarget
AITarget SelectedAiTarget
virtual void Update(float deltaTime)
virtual void OnStateChanged(AIState from, AIState to)
virtual void OnAttacked(Character attacker, AttackResult attackResult)
IEnumerable< Hull > VisibleHulls
Returns hulls that are visible to the character, including the current hull. Note that this is not an...
bool UpdateEscape(float deltaTime, bool canAttackDoors)
virtual bool SteerThroughGap(Gap gap, Vector2 targetWorldPos, float deltaTime, float maxDistance=-1)
bool CanPassThroughHole(Structure wall, int sectionIndex, int requiredHoleCount)
bool IsCurrentPathUnreachable
bool IsWallDisabled(Structure wall)
readonly float colliderLength
AITarget _previousAiTarget
bool IsSteeringThroughGap
SteeringManager steeringManager
readonly float colliderWidth
bool HasValidPath(bool requireNonDirty=true, bool requireUnfinished=true, Func< WayPoint, bool > nodePredicate=null)
Is the current path valid, using the provided parameters.
static void UnequipEmptyItems(Character character, Item parentItem, bool avoidDroppingInSea=true)
bool IsCurrentPathFinished
bool IsCurrentPathNullOrUnreachable
void FaceTarget(ISpatialEntity target)
abstract bool Escape(float deltaTime)
AIController(Character c)
static bool IsSuitablePressureProtection(Item item, Identifier tag, Character character)
override Vector2? SimPosition
CharacterInventory Inventory
bool HasItem(Item item, bool requireEquipped=false, InvSlotType? slotType=null)
void ReleaseSecondaryItem()
readonly AnimController AnimController
List< Hull > GetVisibleHulls()
Returns hulls that are visible to the character, including the current hull. Note that this is not an...
override bool TryPutItem(Item item, Character user, IEnumerable< InvSlotType > allowedSlots=null, bool createNetworkEvent=true, bool ignoreCondition=false)
If there is room, puts the item in the inventory and returns true, otherwise returns false
static readonly List< InvSlotType > AnySlot
virtual Vector2 WorldPosition
static List< Gap > GapList
void SteeringSeek(Vector2 target, float weight, float minGapWidth=0, Func< PathNode, bool > startNodeFilter=null, Func< PathNode, bool > endNodeFilter=null, Func< PathNode, bool > nodeFilter=null, bool checkVisiblity=true)
bool CanAccessDoor(Door door, Func< Controller, bool > buttonFilter=null)
Item GetItemAt(int index)
Get the item stored in the specified inventory slot. If the slot contains a stack of items,...
void Drop(Character dropper, bool createNetworkEvent=true, bool setTransform=true)
ItemInventory OwnInventory
Inventory ParentInventory
override Vector2 SimPosition
readonly Identifier Identifier
CanEnterSubmarine CanEnterSubmarine
void SteeringManual(float deltaTime, Vector2 velocity)
void SteeringSeek(Vector2 targetSimPos, float weight=1)
bool SectionBodyDisabled(int sectionIndex)