v0.14.6.0
This commit is contained in:
@@ -172,14 +172,23 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float scaledDamageRange = propellerDamage.DamageRange * item.Scale;
|
||||
|
||||
Vector2 propellerWorldPos = item.WorldPosition + PropellerPos * item.Scale;
|
||||
Vector2 propellerWorldPos = item.WorldPosition + PropellerPos * item.Scale;
|
||||
float broadRange = Math.Max(scaledDamageRange * 2, 500);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (!character.Enabled || character.Removed) { continue; }
|
||||
float distSqr = Vector2.DistanceSquared(character.WorldPosition, propellerWorldPos);
|
||||
if (distSqr > scaledDamageRange * scaledDamageRange) { continue; }
|
||||
character.LastDamageSource = item;
|
||||
propellerDamage.DoDamage(null, character, propellerWorldPos, 1.0f, true);
|
||||
if (Math.Abs(character.WorldPosition.X - propellerWorldPos.X) > broadRange) { continue; }
|
||||
if (Math.Abs(character.WorldPosition.Y - propellerWorldPos.Y) > broadRange) { continue; }
|
||||
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.IsSevered || !limb.body.Enabled) { continue; }
|
||||
float distSqr = Vector2.DistanceSquared(limb.WorldPosition, propellerWorldPos);
|
||||
if (distSqr > scaledDamageRange * scaledDamageRange) { continue; }
|
||||
character.LastDamageSource = item;
|
||||
propellerDamage.DoDamage(null, character, propellerWorldPos, 1.0f, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -290,10 +290,12 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < ingredient.Amount; i++)
|
||||
{
|
||||
var availableItem = availableIngredients.FirstOrDefault(it => it != null && ingredient.ItemPrefabs.Contains(it.Prefab) && it.ConditionPercentage >= ingredient.MinCondition * 100.0f);
|
||||
var availableItem = availableIngredients.FirstOrDefault(it =>
|
||||
it != null && ingredient.ItemPrefabs.Contains(it.Prefab) &&
|
||||
it.ConditionPercentage >= ingredient.MinCondition * 100.0f &&
|
||||
it.ConditionPercentage <= ingredient.MaxCondition * 100.0f);
|
||||
if (availableItem == null) { continue; }
|
||||
|
||||
//Item4 = use condition bool
|
||||
|
||||
if (ingredient.UseCondition && availableItem.ConditionPercentage - ingredient.MinCondition * 100 > 0.0f) //Leave it behind with reduced condition if it has enough to stay above 0
|
||||
{
|
||||
availableItem.Condition -= availableItem.Prefab.Health * ingredient.MinCondition;
|
||||
@@ -493,7 +495,8 @@ namespace Barotrauma.Items.Components
|
||||
return
|
||||
item != null &&
|
||||
requiredItem.ItemPrefabs.Contains(item.prefab) &&
|
||||
item.Condition / item.Prefab.Health >= requiredItem.MinCondition;
|
||||
item.Condition / item.Prefab.Health >= requiredItem.MinCondition &&
|
||||
item.Condition / item.Prefab.Health <= requiredItem.MaxCondition;
|
||||
}
|
||||
|
||||
public override XElement Save(XElement parentElement)
|
||||
|
||||
@@ -67,6 +67,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public Character LastAIUser { get; private set; }
|
||||
|
||||
[Serialize(defaultValue: false, isSaveable: true)]
|
||||
public bool LastUserWasPlayer { get; private set; }
|
||||
|
||||
private Character lastUser;
|
||||
public Character LastUser
|
||||
{
|
||||
@@ -178,8 +181,6 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(0.0f, true)]
|
||||
public float AvailableFuel { get; set; }
|
||||
|
||||
public bool LastUserWasPlayer { get; private set; }
|
||||
|
||||
public Reactor(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
@@ -241,7 +242,7 @@ namespace Barotrauma.Items.Components
|
||||
optimalTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
||||
tolerance = MathHelper.Lerp(5.0f, 20.0f, degreeOfSuccess);
|
||||
allowedTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
||||
|
||||
|
||||
optimalTemperature = Vector2.Lerp(new Vector2(40.0f, 60.0f), new Vector2(30.0f, 70.0f), degreeOfSuccess);
|
||||
allowedTemperature = Vector2.Lerp(new Vector2(30.0f, 70.0f), new Vector2(10.0f, 90.0f), degreeOfSuccess);
|
||||
|
||||
@@ -251,11 +252,13 @@ namespace Barotrauma.Items.Components
|
||||
allowedFissionRate.X = Math.Min(allowedFissionRate.X, allowedFissionRate.Y - 10);
|
||||
|
||||
float heatAmount = GetGeneratedHeat(fissionRate);
|
||||
|
||||
float temperatureDiff = (heatAmount - turbineOutput) - Temperature;
|
||||
Temperature += MathHelper.Clamp(Math.Sign(temperatureDiff) * 10.0f * deltaTime, -Math.Abs(temperatureDiff), Math.Abs(temperatureDiff));
|
||||
//if (item.InWater && AvailableFuel < 100.0f) Temperature -= 12.0f * deltaTime;
|
||||
|
||||
|
||||
FissionRate = MathHelper.Lerp(fissionRate, Math.Min(targetFissionRate, AvailableFuel), deltaTime);
|
||||
|
||||
TurbineOutput = MathHelper.Lerp(turbineOutput, targetTurbineOutput, deltaTime);
|
||||
|
||||
float temperatureFactor = Math.Min(temperature / 50.0f, 1.0f);
|
||||
@@ -311,6 +314,38 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadQueue.Any() && PowerOn)
|
||||
{
|
||||
//loadQueue is empty, round must've just started
|
||||
//reset the fission rate, turbine output and
|
||||
//temperature to optimal levels to prevent fires
|
||||
//at the start of the round
|
||||
correctTurbineOutput = currentLoad / MaxPowerOutput * 100.0f;
|
||||
tolerance = MathHelper.Lerp(2.5f, 10.0f, degreeOfSuccess);
|
||||
optimalTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
||||
tolerance = MathHelper.Lerp(5.0f, 20.0f, degreeOfSuccess);
|
||||
allowedTurbineOutput = new Vector2(correctTurbineOutput - tolerance, correctTurbineOutput + tolerance);
|
||||
|
||||
DebugConsole.Log($"Degree of success: {degreeOfSuccess}");
|
||||
DebugConsole.Log($"Current load: {currentLoad}");
|
||||
DebugConsole.Log($"Max power output: {MaxPowerOutput}");
|
||||
DebugConsole.Log($"Available fuel: {AvailableFuel}");
|
||||
|
||||
float desiredTurbineOutput = MathHelper.Clamp(correctTurbineOutput, 0.0f, 100.0f);
|
||||
DebugConsole.Log($"Turbine output reset: {targetTurbineOutput}, {turbineOutput} -> {desiredTurbineOutput}");
|
||||
targetTurbineOutput = desiredTurbineOutput;
|
||||
turbineOutput = desiredTurbineOutput;
|
||||
|
||||
float desiredTemperature = (optimalTemperature.X + optimalTemperature.Y) / 2.0f;
|
||||
DebugConsole.Log($"Temperature reset: {temperature} -> {desiredTemperature}");
|
||||
temperature = desiredTemperature;
|
||||
|
||||
float desiredFissionRate = GetFissionRateForTargetTemperatureAndTurbineOutput(desiredTemperature, desiredTurbineOutput);
|
||||
DebugConsole.Log($"Fission rate reset: {targetFissionRate}, {fissionRate} -> {desiredFissionRate}");
|
||||
targetFissionRate = desiredFissionRate;
|
||||
fissionRate = desiredFissionRate;
|
||||
}
|
||||
|
||||
loadQueue.Enqueue(currentLoad);
|
||||
while (loadQueue.Count() > 60.0f)
|
||||
{
|
||||
@@ -390,6 +425,12 @@ namespace Barotrauma.Items.Components
|
||||
return fissionRate * (prevAvailableFuel / 100.0f) * 2.0f;
|
||||
}
|
||||
|
||||
private float GetFissionRateForTargetTemperatureAndTurbineOutput(float temperature, float turbineOutput)
|
||||
{
|
||||
if (MathUtils.NearlyEqual(AvailableFuel, 0f)) { return 0f; }
|
||||
return (temperature + turbineOutput) / (AvailableFuel / 100f) / 2f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do we need more fuel to generate enough power to match the current load.
|
||||
/// </summary>
|
||||
@@ -564,6 +605,7 @@ namespace Barotrauma.Items.Components
|
||||
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
|
||||
character.AIController.SteeringManager.Reset();
|
||||
bool shutDown = objective.Option.Equals("shutdown", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
IsActive = true;
|
||||
@@ -598,6 +640,7 @@ namespace Barotrauma.Items.Components
|
||||
void ReportFuelRodCount()
|
||||
{
|
||||
if (!character.IsOnPlayerTeam) { return; }
|
||||
if (character.Submarine != Submarine.MainSub) { return; }
|
||||
int remainingFuelRods = Submarine.MainSub.GetItems(false).Count(i => i.HasTag("reactorfuel") && i.Condition > 1);
|
||||
if (remainingFuelRods == 0)
|
||||
{
|
||||
@@ -614,6 +657,18 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Item.ConditionPercentage <= 0 && AIObjectiveRepairItems.IsValidTarget(Item, character))
|
||||
{
|
||||
if (Item.Repairables.Average(r => r.DegreeOfSuccess(character)) > 0.4f)
|
||||
{
|
||||
objective.AddSubObjective(new AIObjectiveRepairItem(character, Item, objective.objectiveManager, isPriority: true));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogReactorIsBroken"), identifier: "reactorisbroken", minDurationBetweenSimilar: 30.0f);
|
||||
}
|
||||
}
|
||||
if (TooMuchFuel())
|
||||
{
|
||||
DropFuel(minCondition: 0.1f, maxCondition: 100);
|
||||
@@ -728,7 +783,7 @@ namespace Barotrauma.Items.Components
|
||||
case "set_fissionrate":
|
||||
if (PowerOn && float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newFissionRate))
|
||||
{
|
||||
targetFissionRate = newFissionRate;
|
||||
targetFissionRate = MathHelper.Clamp(newFissionRate, 0.0f, 100.0f);
|
||||
if (GameMain.NetworkMember?.IsServer ?? false) { unsentChanges = true; }
|
||||
#if CLIENT
|
||||
FissionRateScrollBar.BarScroll = targetFissionRate / 100.0f;
|
||||
@@ -738,7 +793,7 @@ namespace Barotrauma.Items.Components
|
||||
case "set_turbineoutput":
|
||||
if (PowerOn && float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newTurbineOutput))
|
||||
{
|
||||
targetTurbineOutput = newTurbineOutput;
|
||||
targetTurbineOutput = MathHelper.Clamp(newTurbineOutput, 0.0f, 100.0f);
|
||||
if (GameMain.NetworkMember?.IsServer ?? false) { unsentChanges = true; }
|
||||
#if CLIENT
|
||||
TurbineOutputScrollBar.BarScroll = targetTurbineOutput / 100.0f;
|
||||
|
||||
@@ -57,6 +57,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private Submarine controlledSub;
|
||||
|
||||
// AI interfacing
|
||||
public Vector2 AITacticalTarget { get; set; }
|
||||
public float AIRamTimer { get; set; }
|
||||
bool navigateTactically; // this will be removed after rewriting steering to use an enum
|
||||
|
||||
private bool showIceSpireWarning;
|
||||
|
||||
private List<Submarine> connectedSubs = new List<Submarine>();
|
||||
@@ -305,7 +310,13 @@ namespace Barotrauma.Items.Components
|
||||
userSkill = user.GetSkillLevel("helm") / 100.0f;
|
||||
}
|
||||
|
||||
if (AutoPilot)
|
||||
// override autopilot pathing while the AI rams, and go full speed ahead
|
||||
if (AIRamTimer > 0f)
|
||||
{
|
||||
AIRamTimer -= deltaTime;
|
||||
TargetVelocity = GetSteeringVelocity(AITacticalTarget, 0f);
|
||||
}
|
||||
else if (AutoPilot)
|
||||
{
|
||||
UpdateAutoPilot(deltaTime);
|
||||
float throttle = 1.0f;
|
||||
@@ -352,6 +363,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float velY = MathHelper.Lerp((neutralBallastLevel * 100 - 50) * 2, -100 * Math.Sign(targetVelocity.Y), Math.Abs(targetVelocity.Y) / 100.0f);
|
||||
item.SendSignal(new Signal(velY.ToString(CultureInfo.InvariantCulture), sender: user), "velocity_y_out");
|
||||
|
||||
// if our tactical AI pilot has left, revert back to maintaining position
|
||||
if (navigateTactically && (user == null || user.SelectedConstruction != item))
|
||||
{
|
||||
navigateTactically = false;
|
||||
AIRamTimer = 0f;
|
||||
SetMaintainPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void IncreaseSkillLevel(Character user, float deltaTime)
|
||||
@@ -580,13 +599,18 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
Vector2 target;
|
||||
if (LevelEndSelected)
|
||||
|
||||
if (navigateTactically)
|
||||
{
|
||||
target = ConvertUnits.ToSimUnits(Level.Loaded.EndPosition);
|
||||
target = ConvertUnits.ToSimUnits(AITacticalTarget);
|
||||
}
|
||||
else if (LevelEndSelected)
|
||||
{
|
||||
target = ConvertUnits.ToSimUnits(Level.Loaded.EndExitPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
target = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
|
||||
target = ConvertUnits.ToSimUnits(Level.Loaded.StartExitPosition);
|
||||
}
|
||||
steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition), target, errorMsgStr: "(Autopilot, target: " + target + ")");
|
||||
}
|
||||
@@ -597,6 +621,7 @@ namespace Barotrauma.Items.Components
|
||||
MaintainPos = false;
|
||||
posToMaintain = null;
|
||||
LevelEndSelected = false;
|
||||
navigateTactically = false;
|
||||
if (!LevelStartSelected)
|
||||
{
|
||||
LevelStartSelected = true;
|
||||
@@ -610,6 +635,7 @@ namespace Barotrauma.Items.Components
|
||||
MaintainPos = false;
|
||||
posToMaintain = null;
|
||||
LevelStartSelected = false;
|
||||
navigateTactically = false;
|
||||
if (!LevelEndSelected)
|
||||
{
|
||||
LevelEndSelected = true;
|
||||
@@ -617,6 +643,36 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDestinationTactical()
|
||||
{
|
||||
AutoPilot = true;
|
||||
MaintainPos = false;
|
||||
posToMaintain = null;
|
||||
LevelStartSelected = false;
|
||||
LevelEndSelected = false;
|
||||
if (!navigateTactically)
|
||||
{
|
||||
navigateTactically = true;
|
||||
UpdatePath();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetMaintainPosition()
|
||||
{
|
||||
if (!MaintainPos)
|
||||
{
|
||||
unsentChanges = true;
|
||||
MaintainPos = true;
|
||||
}
|
||||
if (!posToMaintain.HasValue)
|
||||
{
|
||||
unsentChanges = true;
|
||||
posToMaintain = controlledSub != null ?
|
||||
controlledSub.WorldPosition :
|
||||
item.Submarine == null ? item.WorldPosition : item.Submarine.WorldPosition;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get optimal velocity for moving towards a position
|
||||
/// </summary>
|
||||
@@ -640,6 +696,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
|
||||
{
|
||||
character.AIController.SteeringManager.Reset();
|
||||
if (objective.Override)
|
||||
{
|
||||
if (user != character && user != null && user.SelectedConstruction == item && character.IsOnPlayerTeam)
|
||||
@@ -648,6 +705,20 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
user = character;
|
||||
|
||||
if (Item.ConditionPercentage <= 0 && AIObjectiveRepairItems.IsValidTarget(Item, character))
|
||||
{
|
||||
if (Item.Repairables.Average(r => r.DegreeOfSuccess(character)) > 0.4f)
|
||||
{
|
||||
objective.AddSubObjective(new AIObjectiveRepairItem(character, Item, objective.objectiveManager, isPriority: true));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogNavTerminalIsBroken"), identifier: "navterminalisbroken", minDurationBetweenSimilar: 30.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!AutoPilot)
|
||||
{
|
||||
unsentChanges = true;
|
||||
@@ -659,18 +730,7 @@ namespace Barotrauma.Items.Components
|
||||
case "maintainposition":
|
||||
if (objective.Override)
|
||||
{
|
||||
if (!MaintainPos)
|
||||
{
|
||||
unsentChanges = true;
|
||||
MaintainPos = true;
|
||||
}
|
||||
if (!posToMaintain.HasValue)
|
||||
{
|
||||
unsentChanges = true;
|
||||
posToMaintain = controlledSub != null ?
|
||||
controlledSub.WorldPosition :
|
||||
item.Submarine == null ? item.WorldPosition : item.Submarine.WorldPosition;
|
||||
}
|
||||
SetMaintainPosition();
|
||||
}
|
||||
break;
|
||||
case "navigateback":
|
||||
@@ -681,7 +741,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
if (objective.Override)
|
||||
{
|
||||
if (MaintainPos || LevelEndSelected || !LevelStartSelected)
|
||||
if (MaintainPos || LevelEndSelected || !LevelStartSelected || navigateTactically)
|
||||
{
|
||||
unsentChanges = true;
|
||||
}
|
||||
@@ -696,13 +756,28 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
if (objective.Override)
|
||||
{
|
||||
if (MaintainPos || !LevelEndSelected || LevelStartSelected)
|
||||
if (MaintainPos || !LevelEndSelected || LevelStartSelected || navigateTactically)
|
||||
{
|
||||
unsentChanges = true;
|
||||
}
|
||||
SetDestinationLevelEnd();
|
||||
}
|
||||
break;
|
||||
case "navigatetactical":
|
||||
if (Level.IsLoadedOutpost) { break; }
|
||||
if (DockingSources.Any(d => d.Docked))
|
||||
{
|
||||
item.SendSignal("1", "toggle_docking");
|
||||
}
|
||||
if (objective.Override)
|
||||
{
|
||||
if (MaintainPos || LevelEndSelected || LevelStartSelected || !navigateTactically)
|
||||
{
|
||||
unsentChanges = true;
|
||||
}
|
||||
SetDestinationTactical();
|
||||
}
|
||||
break;
|
||||
}
|
||||
sonar?.AIOperate(deltaTime, character, objective);
|
||||
if (!MaintainPos && showIceSpireWarning && character.IsOnPlayerTeam)
|
||||
|
||||
Reference in New Issue
Block a user