Unstable 0.1300.0.4
This commit is contained in:
@@ -265,16 +265,22 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void UnequipEmptyItems(Item item, bool avoidDroppingInSea = true) => UnequipEmptyItems(Character, item, avoidDroppingInSea);
|
||||
public void UnequipEmptyItems(Item parentItem, bool avoidDroppingInSea = true) => UnequipEmptyItems(Character, parentItem, avoidDroppingInSea);
|
||||
|
||||
public static void UnequipEmptyItems(Character character, Item item, bool avoidDroppingInSea = true)
|
||||
public void UnequipContainedItems(Item parentItem, Func<Item, bool> predicate, bool avoidDroppingInSea = true) => UnequipContainedItems(Character, parentItem, predicate, avoidDroppingInSea);
|
||||
|
||||
public static void UnequipEmptyItems(Character character, Item parentItem, bool avoidDroppingInSea = true) => UnequipContainedItems(character, parentItem, it => it.Condition <= 0, avoidDroppingInSea);
|
||||
|
||||
public static void UnequipContainedItems(Character character, Item parentItem, Func<Item, bool> predicate, bool avoidDroppingInSea = true)
|
||||
{
|
||||
if (item.OwnInventory.AllItems.Any(it => it.Condition <= 0.0f))
|
||||
var inventory = parentItem.OwnInventory;
|
||||
if (inventory == null) { return; }
|
||||
if (inventory.AllItems.Any(predicate))
|
||||
{
|
||||
foreach (Item containedItem in item.OwnInventory.AllItemsMod)
|
||||
foreach (Item containedItem in inventory.AllItemsMod)
|
||||
{
|
||||
if (containedItem == null) { continue; }
|
||||
if (containedItem.Condition <= 0.0f)
|
||||
if (predicate(containedItem))
|
||||
{
|
||||
if (character.Submarine == null && avoidDroppingInSea)
|
||||
{
|
||||
|
||||
@@ -181,6 +181,7 @@ namespace Barotrauma
|
||||
private set;
|
||||
} = new HashSet<Submarine>();
|
||||
|
||||
public bool IsTargetingPlayer => SelectedAiTarget?.Entity?.Submarine != null && SelectedAiTarget.Entity.Submarine.Info.IsPlayer || SelectedAiTarget?.Entity is Character targetCharacter && targetCharacter.IsPlayer;
|
||||
public bool IsBeingChasedBy(Character c) => c.AIController is EnemyAIController enemyAI && enemyAI.SelectedAiTarget?.Entity is Character && (enemyAI.State == AIState.Aggressive || enemyAI.State == AIState.Attack);
|
||||
private bool IsBeingChased => SelectedAiTarget?.Entity is Character targetCharacter && IsBeingChasedBy(targetCharacter);
|
||||
|
||||
|
||||
@@ -771,17 +771,11 @@ namespace Barotrauma
|
||||
targetHull = hull;
|
||||
}
|
||||
}
|
||||
foreach (var ballastFlora in MapCreatures.Behavior.BallastFloraBehavior.EntityList)
|
||||
if (IsBallastFloraNoticeable(Character, hull))
|
||||
{
|
||||
if (ballastFlora.Parent?.Submarine != Character.Submarine) { continue; }
|
||||
if (!ballastFlora.HasBrokenThrough) { continue; }
|
||||
// Don't react to the first two branches, because they are usually in the very edges of the room.
|
||||
if (ballastFlora.Branches.Count(b => !b.Removed && b.Health > 0 && b.CurrentHull == hull) > 2)
|
||||
{
|
||||
var orderPrefab = Order.GetPrefab("reportballastflora");
|
||||
newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
|
||||
targetHull = hull;
|
||||
}
|
||||
var orderPrefab = Order.GetPrefab("reportballastflora");
|
||||
newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
|
||||
targetHull = hull;
|
||||
}
|
||||
if (!isFighting)
|
||||
{
|
||||
@@ -848,6 +842,21 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsBallastFloraNoticeable(Character character, Hull hull)
|
||||
{
|
||||
foreach (var ballastFlora in MapCreatures.Behavior.BallastFloraBehavior.EntityList)
|
||||
{
|
||||
if (ballastFlora.Parent?.Submarine != character.Submarine) { continue; }
|
||||
if (!ballastFlora.HasBrokenThrough) { continue; }
|
||||
// Don't react to the first two branches, because they are usually in the very edges of the room.
|
||||
if (ballastFlora.Branches.Count(b => !b.Removed && b.Health > 0 && b.CurrentHull == hull) > 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void ReportProblem(Character reporter, Order order)
|
||||
{
|
||||
if (reporter == null || order == null) { return; }
|
||||
|
||||
+3
-9
@@ -58,16 +58,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!EjectEmptyTanks(character, targetItem, out var containedItems))
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError($"{character.Name}: AIObjectiveFindDivingGear failed - the item \"" + targetItem + "\" has no proper inventory");
|
||||
#endif
|
||||
Abandon = true;
|
||||
return;
|
||||
}
|
||||
HumanAIController.UnequipContainedItems(targetItem, it => !it.HasTag("oxygensource"));
|
||||
HumanAIController.UnequipEmptyItems(targetItem);
|
||||
float min = character.Submarine == null ? 0.01f : MIN_OXYGEN;
|
||||
if (containedItems.None(it => it != null && it.HasTag(OXYGEN_SOURCE) && it.Condition > min))
|
||||
if (targetItem.OwnInventory != null && targetItem.OwnInventory.AllItems.None(it => it != null && it.HasTag(OXYGEN_SOURCE) && it.Condition > min))
|
||||
{
|
||||
// No valid oxygen source loaded.
|
||||
// Seek oxygen that has at least 10% condition left.
|
||||
|
||||
+2
-3
@@ -86,10 +86,9 @@ namespace Barotrauma
|
||||
Abandon = true;
|
||||
return;
|
||||
}
|
||||
// Drop empty tanks
|
||||
HumanAIController.UnequipContainedItems(weldingTool, it => !it.HasTag("weldingfuel"));
|
||||
HumanAIController.UnequipEmptyItems(weldingTool);
|
||||
|
||||
if (weldingTool.OwnInventory.AllItems.None(i => i.HasTag("weldingfuel") && i.Condition > 0.0f))
|
||||
if (weldingTool.OwnInventory != null && weldingTool.OwnInventory.AllItems.None(i => i.HasTag("weldingfuel") && i.Condition > 0.0f))
|
||||
{
|
||||
TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, "weldingfuel", weldingTool.GetComponent<ItemContainer>(), objectiveManager, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC),
|
||||
onAbandon: () =>
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ namespace Barotrauma
|
||||
Abandon = true;
|
||||
return;
|
||||
}
|
||||
// Eject empty tanks
|
||||
HumanAIController.UnequipContainedItems(repairTool.Item, it => !it.HasTag("weldingfuel"));
|
||||
HumanAIController.UnequipEmptyItems(repairTool.Item);
|
||||
RelatedItem item = null;
|
||||
Item fuel = null;
|
||||
|
||||
+2
@@ -153,6 +153,8 @@ namespace Barotrauma
|
||||
if (item.IsFullCondition) { return false; }
|
||||
if (item.CurrentHull == null) { return false; }
|
||||
if (item.Submarine == null || character.Submarine == null) { return false; }
|
||||
//player crew ignores items in outposts
|
||||
if (character.IsOnPlayerTeam && item.Submarine.Info.IsOutpost) { return false; }
|
||||
if (!character.Submarine.IsEntityFoundOnThisSub(item, includingConnectedSubs: true)) { return false; }
|
||||
if (item.Repairables.None()) { return false; }
|
||||
return true;
|
||||
|
||||
+5
-4
@@ -78,14 +78,14 @@ namespace Barotrauma
|
||||
// Check if the character needs more oxygen
|
||||
if (!ignoreOxygen && character.SelectedCharacter == targetCharacter || character.CanInteractWith(targetCharacter))
|
||||
{
|
||||
// Replace empty oxygen tank
|
||||
// First remove empty tanks
|
||||
// Replace empty oxygen and welding fuel.
|
||||
if (HumanAIController.HasItem(targetCharacter, AIObjectiveFindDivingGear.HEAVY_DIVING_GEAR, out IEnumerable<Item> suits, requireEquipped: true))
|
||||
{
|
||||
Item suit = suits.FirstOrDefault();
|
||||
if (suit != null)
|
||||
{
|
||||
AIObjectiveFindDivingGear.EjectEmptyTanks(character, suit, out _);
|
||||
AIController.UnequipEmptyItems(character, suit);
|
||||
AIController.UnequipContainedItems(character, suit, it => it.HasTag("weldingfuel"));
|
||||
}
|
||||
}
|
||||
else if (HumanAIController.HasItem(targetCharacter, AIObjectiveFindDivingGear.LIGHT_DIVING_GEAR, out IEnumerable<Item> masks, requireEquipped: true))
|
||||
@@ -93,7 +93,8 @@ namespace Barotrauma
|
||||
Item mask = masks.FirstOrDefault();
|
||||
if (mask != null)
|
||||
{
|
||||
AIObjectiveFindDivingGear.EjectEmptyTanks(character, mask, out _);
|
||||
AIController.UnequipEmptyItems(character, mask);
|
||||
AIController.UnequipContainedItems(character, mask, it => it.HasTag("weldingfuel"));
|
||||
}
|
||||
}
|
||||
bool ShouldRemoveDivingSuit() => targetCharacter.OxygenAvailable < CharacterHealth.InsufficientOxygenThreshold && targetCharacter.CurrentHull?.LethalPressure <= 0;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Barotrauma
|
||||
WayPointID = Waypoint.ID;
|
||||
}
|
||||
|
||||
public static List<PathNode> GenerateNodes(List<WayPoint> wayPoints)
|
||||
public static List<PathNode> GenerateNodes(List<WayPoint> wayPoints, bool removeOrphans)
|
||||
{
|
||||
var nodes = new Dictionary<int, PathNode>();
|
||||
foreach (WayPoint wayPoint in wayPoints)
|
||||
@@ -63,7 +63,10 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
var nodeList = nodes.Values.ToList();
|
||||
nodeList.RemoveAll(n => n.connections.Count == 0);
|
||||
if (removeOrphans)
|
||||
{
|
||||
nodeList.RemoveAll(n => n.connections.Count == 0);
|
||||
}
|
||||
foreach (PathNode node in nodeList)
|
||||
{
|
||||
node.distances = new List<float>();
|
||||
@@ -90,7 +93,7 @@ namespace Barotrauma
|
||||
|
||||
public PathFinder(List<WayPoint> wayPoints, bool indoorsSteering = false)
|
||||
{
|
||||
nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => w.Submarine != null == indoorsSteering));
|
||||
nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => w.Submarine != null == indoorsSteering), removeOrphans: true);
|
||||
|
||||
foreach (WayPoint wp in wayPoints)
|
||||
{
|
||||
|
||||
@@ -69,8 +69,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public bool IsRemotelyControlled
|
||||
{
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GameMain.NetworkMember == null)
|
||||
{
|
||||
return false;
|
||||
@@ -145,14 +145,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private readonly List<Attacker> lastAttackers = new List<Attacker>();
|
||||
public IEnumerable<Attacker> LastAttackers
|
||||
{
|
||||
get { return lastAttackers; }
|
||||
}
|
||||
public Character LastAttacker
|
||||
{
|
||||
get { return lastAttackers.Count > 0 ? lastAttackers[lastAttackers.Count - 1].Character : null; }
|
||||
}
|
||||
public IEnumerable<Attacker> LastAttackers => lastAttackers;
|
||||
public Character LastAttacker => lastAttackers.LastOrDefault()?.Character;
|
||||
|
||||
public Entity LastDamageSource;
|
||||
|
||||
@@ -203,7 +197,7 @@ namespace Barotrauma
|
||||
|
||||
public bool IsTraitor
|
||||
{
|
||||
get;
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
@@ -442,7 +436,7 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public IEnumerable<Item> HeldItems
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
var item1 = Inventory?.GetItemInLimbSlot(InvSlotType.RightHand);
|
||||
var item2 = Inventory?.GetItemInLimbSlot(InvSlotType.LeftHand);
|
||||
@@ -527,7 +521,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public bool UseHullOxygen { get; set; } = true;
|
||||
|
||||
|
||||
public float Stun
|
||||
{
|
||||
get { return IsRagdolled ? 1.0f : CharacterHealth.Stun; }
|
||||
@@ -601,7 +595,7 @@ namespace Barotrauma
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current speed of the character's collider. Can be used by status effects to check if the character is moving.
|
||||
@@ -655,11 +649,11 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private bool isDead;
|
||||
public bool IsDead
|
||||
{
|
||||
public bool IsDead
|
||||
{
|
||||
get { return isDead; }
|
||||
set
|
||||
{
|
||||
set
|
||||
{
|
||||
if (isDead == value) { return; }
|
||||
if (value)
|
||||
{
|
||||
@@ -822,7 +816,7 @@ namespace Barotrauma
|
||||
speciesName = Path.GetFileNameWithoutExtension(speciesName).ToLowerInvariant();
|
||||
}
|
||||
|
||||
var prefab = CharacterPrefab.FindBySpeciesName(speciesName);
|
||||
var prefab = CharacterPrefab.FindBySpeciesName(speciesName);
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to create character \"{speciesName}\". Matching prefab not found.\n" + Environment.StackTrace);
|
||||
@@ -2191,8 +2185,7 @@ namespace Barotrauma
|
||||
#if CLIENT
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
if (GUI.MouseOn == null &&
|
||||
(!CharacterInventory.IsMouseOnInventory() || CharacterInventory.DraggingItemToWorld))
|
||||
if (!IsMouseOnUI)
|
||||
{
|
||||
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
|
||||
{
|
||||
@@ -2910,7 +2903,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent adding duplicate orders (same identifier and same option)
|
||||
// Prevent adding duplicate orders
|
||||
RemoveDuplicateOrders(order, orderOption);
|
||||
|
||||
OrderInfo newOrderInfo = new OrderInfo(order, orderOption, priority);
|
||||
@@ -2971,7 +2964,7 @@ namespace Barotrauma
|
||||
for (int i = CurrentOrders.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var orderInfo = CurrentOrders[i];
|
||||
if (orderInfo.MatchesOrder(order, option))
|
||||
if (order?.Identifier == orderInfo.Order?.Identifier)
|
||||
{
|
||||
priorityOfRemoved = orderInfo.ManualPriority;
|
||||
CurrentOrders.RemoveAt(i);
|
||||
@@ -3316,6 +3309,13 @@ namespace Barotrauma
|
||||
if (attacker.TeamID == TeamID) { return new AttackResult(); }
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
if (attacker == Controlled && Controlled != null && Params.UseBossHealthBar)
|
||||
{
|
||||
CharacterHUD.ShowBossHealthBar(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
Vector2 dir = hitLimb.WorldPosition - worldPosition;
|
||||
if (Math.Abs(attackImpulse) > 0.0f)
|
||||
{
|
||||
@@ -3351,14 +3351,14 @@ namespace Barotrauma
|
||||
if (attackResult.Damage > 0)
|
||||
{
|
||||
LastDamage = attackResult;
|
||||
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||
if (attacker != null)
|
||||
{
|
||||
AddAttacker(attacker, attackResult.Damage);
|
||||
AddEncounter(attacker);
|
||||
attacker.AddEncounter(this);
|
||||
}
|
||||
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||
}
|
||||
return attackResult;
|
||||
}
|
||||
@@ -3418,6 +3418,16 @@ namespace Barotrauma
|
||||
foreach (StatusEffect statusEffect in statusEffects)
|
||||
{
|
||||
if (statusEffect.type != actionType) { continue; }
|
||||
if (statusEffect.type == ActionType.OnDamaged)
|
||||
{
|
||||
if (statusEffect.OnlyPlayerTriggered)
|
||||
{
|
||||
if (LastAttacker == null || !LastAttacker.IsPlayer)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
|
||||
statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||
{
|
||||
|
||||
+8
-4
@@ -148,10 +148,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
public void UnsubscribeFromDeathEvent()
|
||||
{
|
||||
if (character == null) { return; }
|
||||
DeactivateHusk();
|
||||
if (character == null || !subscribedToDeathEvent) { return; }
|
||||
character.OnDeath -= CharacterDead;
|
||||
subscribedToDeathEvent = false;
|
||||
}
|
||||
@@ -159,7 +158,11 @@ namespace Barotrauma
|
||||
private void CharacterDead(Character character, CauseOfDeath causeOfDeath)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (Strength < ActiveThreshold || character.Removed) { return; }
|
||||
if (Strength < ActiveThreshold || character.Removed)
|
||||
{
|
||||
UnsubscribeFromDeathEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
//don't turn the character into a husk if any of its limbs are severed
|
||||
if (character.AnimController?.LimbJoints != null)
|
||||
@@ -185,6 +188,7 @@ namespace Barotrauma
|
||||
|
||||
character.Enabled = false;
|
||||
Entity.Spawner.AddToRemoveQueue(character);
|
||||
UnsubscribeFromDeathEvent();
|
||||
|
||||
string huskedSpeciesName = GetHuskedSpeciesName(character.SpeciesName, Prefab as AfflictionPrefabHusk);
|
||||
CharacterPrefab prefab = CharacterPrefab.FindBySpeciesName(huskedSpeciesName);
|
||||
|
||||
+3
-3
@@ -613,9 +613,6 @@ namespace Barotrauma
|
||||
case "icon":
|
||||
Icon = new Sprite(subElement);
|
||||
break;
|
||||
case "periodiceffect":
|
||||
periodicEffects.Add(new PeriodicEffect(subElement, Name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,6 +646,9 @@ namespace Barotrauma
|
||||
case "effect":
|
||||
effects.Add(new Effect(subElement, Name));
|
||||
break;
|
||||
case "periodiceffect":
|
||||
periodicEffects.Add(new PeriodicEffect(subElement, Name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,6 +1125,16 @@ namespace Barotrauma
|
||||
foreach (StatusEffect statusEffect in statusEffects)
|
||||
{
|
||||
if (statusEffect.type != actionType) { continue; }
|
||||
if (statusEffect.type == ActionType.OnDamaged)
|
||||
{
|
||||
if (statusEffect.OnlyPlayerTriggered)
|
||||
{
|
||||
if (character.LastAttacker == null || !character.LastAttacker.IsPlayer)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
|
||||
statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||
{
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace Barotrauma
|
||||
[Serialize(false, false), Editable]
|
||||
public bool CanSpeak { get; set; }
|
||||
|
||||
[Serialize(false, true), Editable]
|
||||
public bool UseBossHealthBar { get; private set; }
|
||||
|
||||
[Serialize(100f, true, description: "How much noise the character makes when moving?"), Editable(minValue: 0f, maxValue: 100000f)]
|
||||
public float Noise { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user