(2e0e45e1f) Updated: Localization

This commit is contained in:
Joonas Rikkonen
2019-05-20 20:41:52 +03:00
parent 5e77ed6507
commit b71adc7589
48 changed files with 389 additions and 587 deletions
@@ -82,10 +82,8 @@ namespace Barotrauma
public override void Update(float deltaTime)
{
if (DisableCrewAI || Character.IsUnconscious) return;
float maxDistanceToSub = 3000;
if (Character.Submarine != null || SelectedAiTarget?.Entity?.Submarine != null &&
Vector2.DistanceSquared(Character.WorldPosition, SelectedAiTarget.Entity.Submarine.WorldPosition) < maxDistanceToSub * maxDistanceToSub)
if (Character.Submarine != null || SelectedAiTarget?.Entity?.Submarine != null)
{
if (steeringManager != insideSteering)
{
@@ -485,11 +483,7 @@ namespace Barotrauma
}
else if (ObjectiveManager.CurrentOrder is AIObjectiveRescueAll rescueAll && rescueAll.Targets.None())
{
//TODO: re-enable on all languages after DialogNoRescueTargets has been translated
if (TextManager.Language == "English")
{
Character.Speak(TextManager.Get("DialogNoRescueTargets"), null, 3.0f, "norescuetargets");
}
Character.Speak(TextManager.Get("DialogNoRescueTargets"), null, 3.0f, "norescuetargets");
}
else if (ObjectiveManager.CurrentOrder is AIObjectivePumpWater pumpWater && pumpWater.Targets.None())
{
@@ -540,8 +534,6 @@ namespace Barotrauma
public static bool HasItem(Character character, string tag, string containedTag, float conditionPercentage = 0)
{
if (character == null) { return false; }
if (character.Inventory == null) { return false; }
var item = character.Inventory.FindItemByTag(tag);
return item != null &&
item.ConditionPercentage > conditionPercentage &&
@@ -164,15 +164,7 @@ namespace Barotrauma
}
var newPath = pathFinder.FindPath(pos, target, "(Character: " + character.Name + ")");
bool useNewPath = currentPath == null || needsNewPath;
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
{
// It's possible that the current path was calculated from a start point that is no longer valid.
// Therefore, let's accept also paths with a greater cost than the current, if the current node is much farther than the new start node.
useNewPath = newPath.Cost < currentPath.Cost ||
Vector2.DistanceSquared(character.WorldPosition, currentPath.CurrentNode.WorldPosition) > Math.Pow(Vector2.Distance(character.WorldPosition, newPath.Nodes.First().WorldPosition) * 2, 2);
}
if (useNewPath)
if (currentPath == null || needsNewPath || !newPath.Unreachable && newPath.Cost < currentPath.Cost)
{
currentPath = newPath;
}
@@ -414,7 +406,7 @@ namespace Barotrauma
{
if (door.HasIntegratedButtons)
{
door.Item.TryInteract(character, false, true);
door.Item.TryInteract(character, false, true, true);
buttonPressCooldown = ButtonPressInterval;
break;
}
@@ -422,7 +414,7 @@ namespace Barotrauma
{
if (Vector2.DistanceSquared(closestButton.Item.WorldPosition, character.WorldPosition) < MathUtils.Pow(closestButton.Item.InteractDistance * 2, 2))
{
closestButton.Item.TryInteract(character, false, true);
closestButton.Item.TryInteract(character, false, true, false);
buttonPressCooldown = ButtonPressInterval;
break;
}
@@ -128,7 +128,7 @@ namespace Barotrauma
if (seekAmmunition == null || !subObjectives.Contains(seekAmmunition))
{
Move();
if (WeaponComponent != null)
if (Weapon != null)
{
OperateWeapon(deltaTime);
}
@@ -279,6 +279,24 @@ namespace Barotrauma
Weapon.Drop(character);
}
}
//if (!character.SelectedItems.Contains(Weapon))
if (!character.HasEquippedItem(Weapon))
{
Weapon.TryInteract(character, forceSelectKey: true);
var slots = Weapon.AllowedSlots.FindAll(s => s == InvSlotType.LeftHand || s == InvSlotType.RightHand || s == (InvSlotType.LeftHand | InvSlotType.RightHand));
if (character.Inventory.TryPutItem(Weapon, character, slots))
{
Weapon.Equip(character);
aimTimer = Rand.Range(0.5f, 1f);
}
else
{
Weapon = null;
Mode = CombatMode.Retreat;
return false;
}
}
return true;
}
private bool Equip()
@@ -320,10 +338,7 @@ namespace Barotrauma
{
retreatTarget = findSafety.FindBestHull(HumanAIController.VisibleHulls);
}
if (character.CurrentHull != retreatTarget)
{
TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true));
}
TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true));
}
private void Engage()
@@ -339,7 +354,8 @@ namespace Barotrauma
constructor: () => new AIObjectiveGoTo(Enemy, character, objectiveManager, repeat: true, getDivingGearIfNeeded: true)
{
AllowGoingOutside = true,
IgnoreIfTargetDead = true
IgnoreIfTargetDead = true,
CheckVisibility = true
},
onAbandon: () =>
{
@@ -349,7 +365,7 @@ namespace Barotrauma
if (followTargetObjective != null && subObjectives.Contains(followTargetObjective))
{
followTargetObjective.CloseEnough =
WeaponComponent is RangedWeapon ? 300 :
WeaponComponent is RangedWeapon ? 3 :
WeaponComponent is MeleeWeapon mw ? mw.Range :
WeaponComponent is RepairTool rt ? rt.Range : 50;
}
@@ -439,7 +455,7 @@ namespace Barotrauma
float squaredDistance = Vector2.DistanceSquared(character.Position, Enemy.Position);
character.CursorPosition = Enemy.Position;
float engageDistance = 500;
if (character.CurrentHull != Enemy.CurrentHull && squaredDistance > engageDistance * engageDistance) { return; }
if (squaredDistance > engageDistance * engageDistance) { return; }
if (!character.CanSeeCharacter(Enemy)) { return; }
if (Weapon.RequireAimToUse)
{
@@ -452,7 +468,7 @@ namespace Barotrauma
isOperatingButtons = door.HasIntegratedButtons || door.Item.GetConnectedComponents<Controller>(true).Any();
}
}
if (!isOperatingButtons)
if (!isOperatingButtons && character.SelectedConstruction == null)
{
character.SetInput(InputType.Aim, false, true);
}
@@ -1,6 +1,7 @@
using Microsoft.Xna.Framework;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System;
using Barotrauma.Extensions;
using System.Linq;
namespace Barotrauma
{
@@ -16,21 +17,17 @@ namespace Barotrauma
public Func<bool> customCondition;
public bool followControlledCharacter;
public bool mimic;
/// <summary>
/// Display units
/// </summary>
public float CloseEnough { get; set; } = 50;
public bool IgnoreIfTargetDead { get; set; }
public bool AllowGoingOutside { get; set; }
public ISpatialEntity Target { get; private set; }
public bool CheckVisibility { get; set; }
public override float GetPriority()
{
if (followControlledCharacter && Character.Controlled == null) { return 0.0f; }
if (FollowControlledCharacter && Character.Controlled == null) { return 0.0f; }
if (Target is Entity e && e.Removed) { return 0.0f; }
if (IgnoreIfTargetDead && Target is Character character && character.IsDead) { return 0.0f; }
if (objectiveManager.CurrentOrder == this)
@@ -40,19 +37,23 @@ namespace Barotrauma
return 1.0f;
}
public ISpatialEntity Target { get; private set; }
public bool FollowControlledCharacter;
public AIObjectiveGoTo(ISpatialEntity target, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1)
: base (character, objectiveManager, priorityModifier)
{
this.Target = target;
this.repeat = repeat;
waitUntilPathUnreachable = 3.0f;
waitUntilPathUnreachable = 2.0f;
this.getDivingGearIfNeeded = getDivingGearIfNeeded;
CalculateCloseEnough();
}
protected override void Act(float deltaTime)
{
if (followControlledCharacter)
if (FollowControlledCharacter)
{
if (Character.Controlled == null)
{
@@ -91,18 +92,11 @@ namespace Barotrauma
{
abandon = true;
}
else if (waitUntilPathUnreachable < 0)
else if (!repeat && waitUntilPathUnreachable < 0)
{
if (SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.Unreachable)
if (SteeringManager == PathSteering && PathSteering.CurrentPath != null)
{
if (repeat)
{
SteeringManager.Reset();
}
else
{
abandon = true;
}
abandon = PathSteering.CurrentPath.Unreachable;
}
}
if (abandon)
@@ -121,9 +115,9 @@ namespace Barotrauma
Vector2 currTargetSimPos = Vector2.Zero;
currTargetSimPos = Target.SimPosition;
// Take the sub position into account in the sim pos
if (SteeringManager != PathSteering && character.Submarine == null && Target.Submarine != null)
if (character.Submarine == null && Target.Submarine != null)
{
currTargetSimPos += Target.Submarine.SimPosition;
//currTargetSimPos += Target.Submarine.SimPosition;
}
else if (character.Submarine != null && Target.Submarine == null)
{
@@ -138,15 +132,10 @@ namespace Barotrauma
}
}
character.AIController.SteeringManager.SteeringSeek(currTargetSimPos);
if (SteeringManager != PathSteering)
{
SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: 5, weight: 1, heading: VectorExtensions.Forward(character.AnimController.Collider.Rotation));
}
if (getDivingGearIfNeeded)
{
Character followTarget = Target as Character;
bool needsDivingGear = HumanAIController.NeedsDivingGear(targetHull) || mimic && HumanAIController.HasDivingMask(followTarget);
bool needsDivingSuit = needsDivingGear && (targetHull == null || targetIsOutside || targetHull.WaterPercentage > 90) || mimic && HumanAIController.HasDivingSuit(followTarget);
bool needsDivingGear = HumanAIController.NeedsDivingGear(targetHull);
bool needsDivingSuit = needsDivingGear && (targetHull == null || targetIsOutside || targetHull.WaterPercentage > 90);
bool needsEquipment = false;
if (needsDivingSuit)
{
@@ -239,8 +239,7 @@ namespace Barotrauma
CloseEnough = 150,
AllowGoingOutside = true,
IgnoreIfTargetDead = true,
followControlledCharacter = orderGiver == character,
mimic = true
FollowControlledCharacter = orderGiver == character
};
break;
case "wait":
@@ -259,7 +258,7 @@ namespace Barotrauma
newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
break;
case "repairsystems":
newObjective = new AIObjectiveRepairItems(character, this, priorityModifier) { RequireAdequateSkills = option == "jobspecific" };
newObjective = new AIObjectiveRepairItems(character, this, priorityModifier) { RequireAdequateSkills = option != "all" };
break;
case "pumpwater":
newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
@@ -68,12 +68,6 @@ namespace Barotrauma
{
if (character.CanInteractWith(target.Item, out _, checkLinked: false))
{
// Don't allow to operate an item that someone already operates, unless this objective is an order
if (objectiveManager.CurrentOrder != this && Character.CharacterList.Any(c => c.SelectedConstruction == target.Item && c != character && HumanAIController.IsFriendly(c)))
{
abandon = true;
return;
}
if (character.SelectedConstruction != target.Item)
{
target.Item.TryInteract(character, false, true);
@@ -2,6 +2,7 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Barotrauma
@@ -16,22 +17,13 @@ namespace Barotrauma
private readonly Character targetCharacter;
private AIObjectiveGoTo goToObjective;
private float treatmentTimer;
private Hull safeHull;
public AIObjectiveRescue(Character character, Character targetCharacter, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
if (targetCharacter == null)
{
string errorMsg = "Attempted to create a Rescue objective with no target!\n" + Environment.StackTrace;
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("AIObjectiveRescue:ctor:targetnull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
abandon = true;
return;
}
if (targetCharacter == character)
if (targetCharacter != character)
{
// TODO: enable healing self too
abandon = true;
@@ -48,11 +40,6 @@ namespace Barotrauma
protected override void Act(float deltaTime)
{
if (targetCharacter == null || targetCharacter.Removed)
{
return;
}
// Unconcious target is not in a safe place -> Move to a safe place first
if (targetCharacter.IsUnconscious && HumanAIController.GetHullSafety(targetCharacter.CurrentHull, targetCharacter) < HumanAIController.HULL_SAFETY_THRESHOLD)
{
@@ -84,22 +71,15 @@ namespace Barotrauma
{
goToObjective = null;
}
if (safeHull == null)
var findSafety = objectiveManager.GetObjective<AIObjectiveFindSafety>();
if (findSafety == null)
{
var findSafety = objectiveManager.GetObjective<AIObjectiveFindSafety>();
if (findSafety == null)
{
// Ensure that we have the find safety objective (should always be the case)
findSafety = new AIObjectiveFindSafety(character, objectiveManager);
objectiveManager.AddObjective(findSafety);
}
safeHull = findSafety.FindBestHull(HumanAIController.VisibleHulls);
}
if (character.CurrentHull != safeHull)
{
TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(safeHull, character, objectiveManager));
// Ensure that we have the find safety objective (should always be the case)
objectiveManager.AddObjective(new AIObjectiveFindSafety(character, objectiveManager));
}
TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(findSafety.FindBestHull(HumanAIController.VisibleHulls), character, objectiveManager));
}
return;
}
if (subObjectives.Any()) { return; }
@@ -227,19 +207,13 @@ namespace Barotrauma
public override bool IsCompleted()
{
if (targetCharacter == null || targetCharacter.Removed)
{
abandon = true;
return true;
}
bool isCompleted = targetCharacter.Bleeding <= 0 && targetCharacter.Vitality / targetCharacter.MaxVitality > AIObjectiveRescueAll.GetVitalityThreshold(objectiveManager);
if (isCompleted)
{
character.Speak(TextManager.Get("DialogTargetHealed").Replace("[targetname]", targetCharacter.Name),
null, 1.0f, "targethealed" + targetCharacter.Name, 60.0f);
}
return isCompleted || targetCharacter.IsDead;
return isCompleted || targetCharacter.Removed || targetCharacter.IsDead;
}
public override float GetPriority()
@@ -45,9 +45,9 @@ namespace Barotrauma
steering += DoSteeringWander(weight);
}
public void SteeringAvoid(float deltaTime, float lookAheadDistance, float weight = 1, Vector2? heading = null)
public void SteeringAvoid(float deltaTime, float lookAheadDistance, float weight = 1)
{
steering += DoSteeringAvoid(deltaTime, lookAheadDistance, weight, heading);
steering += DoSteeringAvoid(deltaTime, lookAheadDistance, weight);
}
public void SteeringManual(float deltaTime, Vector2 velocity)
@@ -129,12 +129,10 @@ namespace Barotrauma
return newSteering;
}
protected virtual Vector2 DoSteeringAvoid(float deltaTime, float lookAheadDistance, float weight, Vector2? heading = null)
protected virtual Vector2 DoSteeringAvoid(float deltaTime, float lookAheadDistance, float weight)
{
if (steering == Vector2.Zero || host.Steering == Vector2.Zero)
{
return Vector2.Zero;
}
if (steering == Vector2.Zero || host.Steering == Vector2.Zero) return Vector2.Zero;
float maxDistance = lookAheadDistance;
if (rayCastTimer <= 0.0f)
{
@@ -160,11 +158,19 @@ namespace Barotrauma
{
obstaclePosition.X = closestStructure.SimPosition.X;
}
avoidObstaclePos = obstaclePosition;
//avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - obstaclePosition);
}
/*else if (closestBody.UserData is Item)
{
avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - item.SimPosition);
}*/
else
{
avoidObstaclePos = Submarine.LastPickedPosition;
//avoidSteering = Vector2.Normalize(host.SimPosition - Submarine.LastPickedPosition);
}
}
}
@@ -179,26 +185,14 @@ namespace Barotrauma
Vector2 diff = avoidObstaclePos.Value - host.SimPosition;
float dist = diff.Length();
if (dist > maxDistance)
{
return Vector2.Zero;
}
if (heading.HasValue)
{
var f = heading ?? host.Steering;
// Avoid to left or right depending on the current heading
Vector2 relativeVector = Vector2.Normalize(diff) - Vector2.Normalize(f);
var dir = relativeVector.X > 0 ? diff.Right() : diff.Left();
float factor = 1.0f - Math.Min(dist / maxDistance, 1);
return dir * factor * weight;
}
else
{
// Doesn't work right because it effectively just slows down or reverses the movement, where as we'd like to go right or left to avoid the target.
// There's also another issue, which also affects going right or left: the raycast doesn't hit anything if we turn too much -> avoiding doesn't work well.
// Could probably "remember" the avoidance a bit longer so that the avoid steering is not immedieately disgarded, but kept for a while and reduced gradually?
return -diff * (1.0f - dist / maxDistance) * weight;
}
if (!avoidObstaclePos.HasValue) return Vector2.Zero;
Vector2 diff = avoidObstaclePos.Value - host.SimPosition;
float dist = diff.Length();
if (dist > maxDistance) return Vector2.Zero;
return -diff * (1.0f - dist / maxDistance) * weight;
}
}
}