v0.10.5.1

This commit is contained in:
Juan Pablo Arce
2020-09-22 11:31:56 -03:00
parent 44032d0ae0
commit 0002ad2c50
343 changed files with 12276 additions and 5023 deletions
@@ -67,6 +67,11 @@ namespace Barotrauma
return false;
}
protected bool HasBeenDetermined()
{
return succeeded.HasValue;
}
public override bool SetGoToTarget(string goTo)
{
if (Success != null && Success.SetGoToTarget(goTo))
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
@@ -34,11 +33,11 @@ namespace Barotrauma
if (!(target is Character chr)) { continue; }
if (chr.Inventory == null) { continue; }
if (itemTags.Any(tag => chr.Inventory.Items.Any(item => item != null && item.HasTag(tag)))) { return true; }
if (itemTags.Any(tag => chr.Inventory.FindItemByTag(tag, recursive: true) != null)) { return true; }
foreach (var identifier in itemIdentifierSplit)
{
if (chr.Inventory.Items.Any(it => it != null && it.Prefab.Identifier.Equals(identifier, StringComparison.InvariantCultureIgnoreCase)))
if (chr.Inventory.FindItemByIdentifier(identifier, recursive: true) != null)
{
return true;
}
@@ -50,15 +49,9 @@ namespace Barotrauma
public override string ToDebugString()
{
string subActionStr = "";
if (succeeded.HasValue)
{
subActionStr = $"\n Sub action: {(succeeded.Value ? Success : Failure)?.CurrentSubAction.ColorizeObject()}";
}
return $"{ToolBox.GetDebugSymbol(DetermineFinished())} {nameof(CheckItemAction)} -> (TargetTag: {TargetTag.ColorizeObject()}, " +
return $"{ToolBox.GetDebugSymbol(HasBeenDetermined())} {nameof(CheckItemAction)} -> (TargetTag: {TargetTag.ColorizeObject()}, " +
$"ItemIdentifiers: {ItemIdentifiers.ColorizeObject()}" +
$"Succeeded: {(succeeded.HasValue ? succeeded.Value.ToString() : "not determined").ColorizeObject()})" +
subActionStr;
$"Succeeded: {succeeded.ColorizeObject()})";
}
}
}
@@ -0,0 +1,35 @@
using System.Xml.Linq;
namespace Barotrauma
{
class CheckMoneyAction : BinaryOptionAction
{
[Serialize(0, true)]
public int Amount { get; set; }
public CheckMoneyAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element)
{
}
protected override bool? DetermineSuccess()
{
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
return campaign.Money >= Amount;
}
return false;
}
public override string ToDebugString()
{
string subActionStr = "";
if (succeeded.HasValue)
{
subActionStr = $"\n Sub action: {(succeeded.Value ? Success : Failure)?.CurrentSubAction.ColorizeObject()}";
}
return $"{ToolBox.GetDebugSymbol(DetermineFinished())} {nameof(CheckMoneyAction)} -> (Amount: {Amount.ColorizeObject()}" +
$" Succeeded: {(succeeded.HasValue ? succeeded.Value.ToString() : "not determined").ColorizeObject()})" +
subActionStr;
}
}
}
@@ -10,6 +10,15 @@ namespace Barotrauma
[Serialize(AIObjectiveCombat.CombatMode.Offensive, true)]
public AIObjectiveCombat.CombatMode CombatMode { get; set; }
[Serialize(false, true, description: "Did this NPC start the fight (as an aggressor)?")]
public bool IsInstigator { get; set; }
[Serialize(AIObjectiveCombat.CombatMode.None, true)]
public AIObjectiveCombat.CombatMode GuardReaction { get; set; }
[Serialize(AIObjectiveCombat.CombatMode.None, true)]
public AIObjectiveCombat.CombatMode WitnessReaction { get; set; }
[Serialize("", true)]
public string NPCTag { get; set; }
@@ -50,7 +59,8 @@ namespace Barotrauma
}
if (enemy == null) { continue; }
npc.TurnedHostileByEvent = true;
npc.CombatAction = this;
var objectiveManager = humanAiController.ObjectiveManager;
foreach (var goToObjective in objectiveManager.GetActiveObjectives<AIObjectiveGoTo>())
{
@@ -55,6 +55,7 @@ namespace Barotrauma
private Character speaker;
private OrderInfo? prevSpeakerOrder;
private AIObjective prevIdleObjective, prevGotoObjective;
public List<SubactionGroup> Options { get; private set; }
@@ -169,13 +170,19 @@ namespace Barotrauma
#if SERVER
GameMain.NetworkMember.CreateEntityEvent(speaker, new object[] { NetEntityEvent.Type.AssignCampaignInteraction });
#endif
if (prevSpeakerOrder != null)
var humanAI = speaker.AIController as HumanAIController;
if (humanAI != null)
{
(speaker.AIController as HumanAIController)?.SetOrder(prevSpeakerOrder.Value.Order, prevSpeakerOrder.Value.OrderOption, orderGiver: null, speak: false);
}
else
{
(speaker.AIController as HumanAIController)?.SetOrder(null, string.Empty, orderGiver: null, speak: false);
if (prevSpeakerOrder != null)
{
humanAI.SetOrder(prevSpeakerOrder.Value.Order, prevSpeakerOrder.Value.OrderOption, orderGiver: null, speak: false);
}
else
{
humanAI.SetOrder(null, string.Empty, orderGiver: null, speak: false);
}
if (prevIdleObjective != null) { humanAI.ObjectiveManager.AddObjective(prevIdleObjective); }
if (prevGotoObjective != null) { humanAI.ObjectiveManager.AddObjective(prevGotoObjective); }
}
}
@@ -246,9 +253,12 @@ namespace Barotrauma
TryStartConversation(null);
}
}
else if (Options.Any())
else
{
Options[selectedOption].Update(deltaTime);
if (Options.Any())
{
Options[selectedOption].Update(deltaTime);
}
}
}
@@ -300,6 +310,8 @@ namespace Barotrauma
{
prevSpeakerOrder = new OrderInfo(humanAI.CurrentOrder, humanAI.CurrentOrderOption);
}
prevIdleObjective = humanAI.ObjectiveManager.GetObjective<AIObjectiveIdle>();
prevGotoObjective = humanAI.ObjectiveManager.GetObjective<AIObjectiveGoTo>();
humanAI.SetOrder(
Order.PrefabList.Find(o => o.Identifier.Equals("wait", StringComparison.OrdinalIgnoreCase)),
option: string.Empty, orderGiver: null, speak: false);
@@ -334,25 +346,11 @@ namespace Barotrauma
{
if (!interrupt)
{
SubactionGroup selOtion = null;
if (selectedOption >= 0 && Options.Count > selectedOption)
{
selOtion = Options[selectedOption];
}
EventAction subAction = null;
if (selOtion != null)
{
subAction = selOtion.CurrentSubAction;
}
return $"{ToolBox.GetDebugSymbol(selectedOption > -1)} {nameof(ConversationAction)} -> (Selected option: {selOtion?.Text.ColorizeObject()})\n" +
$" Sub action: {subAction.ColorizeObject()}";
return $"{ToolBox.GetDebugSymbol(selectedOption > -1, selectedOption < 0 && dialogOpened)} {nameof(ConversationAction)} -> (Selected option: {selectedOption.ColorizeObject()})";
}
else
{
return $"{ToolBox.GetDebugSymbol(true)} {nameof(ConversationAction)} -> (Interrupted)\n" +
$" Sub action: {Interrupted?.CurrentSubAction.ColorizeObject()}";
return $"{ToolBox.GetDebugSymbol(true, selectedOption < 0 && dialogOpened)} {nameof(ConversationAction)} -> (Interrupted)";
}
}
}
@@ -42,7 +42,7 @@ namespace Barotrauma
var targets = ParentEvent.GetTargets(TargetTag).Where(e => e is Character).Select(e => e as Character);
foreach (var target in targets)
{
target.Info?.IncreaseSkillLevel(Skill, Amount, target.WorldPosition + Vector2.UnitY * 150.0f);
target.Info?.IncreaseSkillLevel(Skill?.ToLowerInvariant(), Amount, target.WorldPosition + Vector2.UnitY * 150.0f);
}
isFinished = true;
}
@@ -19,6 +19,8 @@ namespace Barotrauma
private List<Character> affectedNpcs = null;
private AIObjectiveGoTo gotoObjective;
public override void Update(float deltaTime)
{
if (isFinished) { return; }
@@ -31,21 +33,18 @@ namespace Barotrauma
if (Wait)
{
var newObjective = new AIObjectiveGoTo(npc, npc, humanAiController.ObjectiveManager, repeat: true)
gotoObjective = new AIObjectiveGoTo(npc, npc, humanAiController.ObjectiveManager, repeat: true)
{
OverridePriority = 100.0f
};
humanAiController.ObjectiveManager.AddObjective(newObjective);
humanAiController.ObjectiveManager.AddObjective(gotoObjective);
humanAiController.ObjectiveManager.WaitTimer = 0.0f;
}
else
{
foreach (var goToObjective in humanAiController.ObjectiveManager.GetActiveObjectives<AIObjectiveGoTo>())
if (gotoObjective != null)
{
if (goToObjective.Target == npc)
{
goToObjective.Abandon = true;
}
gotoObjective.Abandon = true;
}
}
}
@@ -64,13 +63,10 @@ namespace Barotrauma
foreach (var npc in affectedNpcs)
{
if (npc.Removed || !(npc.AIController is HumanAIController humanAiController)) { continue; }
foreach (var goToObjective in humanAiController.ObjectiveManager.GetActiveObjectives<AIObjectiveGoTo>())
if (gotoObjective != null)
{
if (goToObjective.Target == npc)
{
goToObjective.Abandon = true;
}
}
gotoObjective.Abandon = true;
}
}
affectedNpcs = null;
}
@@ -11,21 +11,18 @@ namespace Barotrauma
public RNGAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element) { }
private bool isFinished;
protected override bool? DetermineSuccess()
{
isFinished = true;
return Rand.Range(0.0, 1.0) <= Chance;
}
public override string ToDebugString()
{
string subActionStr = "";
if (succeeded.HasValue)
{
subActionStr = $"\n Sub action: {(succeeded.Value ? Success : Failure)?.CurrentSubAction.ColorizeObject()}";
}
return $"{ToolBox.GetDebugSymbol(DetermineFinished())} {nameof(RNGAction)} -> (Chance: {Chance.ColorizeObject()}, "+
$"Succeeded: {(succeeded.HasValue ? succeeded.Value.ToString() : "not determined").ColorizeObject()})" +
subActionStr;
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(RNGAction)} -> (Chance: {Chance.ColorizeObject()}, "+
$"Succeeded: {succeeded.ColorizeObject()})";
}
}
}
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
@@ -15,7 +16,17 @@ namespace Barotrauma
[Serialize(1, true)]
public int Amount { get; set; }
public RemoveItemAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element) { }
public RemoveItemAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element)
{
if (string.IsNullOrWhiteSpace(ItemIdentifier))
{
ItemIdentifier = element.GetAttributeString("itemidentifiers", "");
}
if (string.IsNullOrWhiteSpace(ItemIdentifier))
{
DebugConsole.ThrowError($"Error in event \"{parentEvent.Prefab.Identifier}\" - RemoveItemAction without an item identifier.");
}
}
private bool isFinished = false;
@@ -32,25 +43,33 @@ namespace Barotrauma
{
if (isFinished) { return; }
var targets = ParentEvent.GetTargets(TargetTag)
.Where(t => t is Character chr && chr.Inventory != null)
.Select(t => t as Character).ToList();
if (targets.Count <= 0) { return; }
int count = Amount;
while (count > 0 && targets.Count > 0)
var targets = ParentEvent.GetTargets(TargetTag);
bool hasValidTargets = false;
foreach (Entity target in targets)
{
var items = targets[0].Inventory.Items;
for (int i = 0; i < items.Length; i++)
if (target is Character character && character.Inventory != null)
{
if (items[i] != null && items[i].Prefab.Identifier.Equals(ItemIdentifier, StringComparison.InvariantCultureIgnoreCase))
{
Entity.Spawner.AddToRemoveQueue(items[i]);
count--;
if (count <= 0) { break; }
}
hasValidTargets = true;
break;
}
}
if (!hasValidTargets) { return; }
List<Item> usedItems = new List<Item>();
foreach (Entity target in targets)
{
Inventory inventory = (target as Character)?.Inventory;
if (inventory == null) { continue; }
while (usedItems.Count < Amount)
{
var item = inventory.FindItem(it =>
it != null &&
!usedItems.Contains(it) &&
it.Prefab.Identifier.Equals(ItemIdentifier, StringComparison.InvariantCultureIgnoreCase), recursive: true);
if (item == null) { break; }
Entity.Spawner.AddToRemoveQueue(item);
usedItems.Add(item);
}
targets.RemoveAt(0);
}
isFinished = true;
}
@@ -40,38 +40,42 @@ namespace Barotrauma
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
object currentValue = campaign.CampaignMetadata.GetValue(Identifier);
object xmlValue = ConvertXMLValue();
float? originalValue = ConvertValueToFloat(currentValue ?? 0);
float? newValue = ConvertValueToFloat(xmlValue);
if ((originalValue == null || newValue == null) && Operation != OperationType.Set)
{
DebugConsole.ThrowError($"Tried to perform numeric operations to a non number via SetDataAction (Existing: {currentValue?.GetType()}, New: {xmlValue.GetType()})");
return;
}
if (Identifier != null)
{
switch (Operation)
{
case OperationType.Set:
campaign.CampaignMetadata.SetValue(Identifier, xmlValue);
break;
case OperationType.Add:
campaign.CampaignMetadata.SetValue(Identifier, originalValue + newValue ?? 0);
break;
case OperationType.Multiply:
campaign.CampaignMetadata.SetValue(Identifier, originalValue * newValue ?? 0);
break;
}
}
object xmlValue = ConvertXMLValue(Value);
PerformOperation(campaign.CampaignMetadata, Identifier, xmlValue, Operation);
}
isFinished = true;
}
public static void PerformOperation(CampaignMetadata metadata, string identifier, object value, OperationType operation)
{
if (metadata == null) { return; }
object currentValue = metadata.GetValue(identifier);
float? originalValue = ConvertValueToFloat(currentValue ?? 0);
float? newValue = ConvertValueToFloat(value);
if ((originalValue == null || newValue == null) && operation != OperationType.Set)
{
DebugConsole.ThrowError($"Tried to perform numeric operations to a non number via SetDataAction (Existing: {currentValue?.GetType()}, New: {value.GetType()})");
return;
}
switch (operation)
{
case OperationType.Set:
metadata.SetValue(identifier, value);
break;
case OperationType.Add:
metadata.SetValue(identifier, originalValue + newValue ?? 0);
break;
case OperationType.Multiply:
metadata.SetValue(identifier, originalValue * newValue ?? 0);
break;
}
}
private static float? ConvertValueToFloat(object value)
{
if (value is float || value is int)
@@ -82,24 +86,24 @@ namespace Barotrauma
return null;
}
private object ConvertXMLValue()
public static object ConvertXMLValue(string value)
{
if (bool.TryParse(Value, out bool b))
if (bool.TryParse(value, out bool b))
{
return b;
}
if (float.TryParse(Value, out float f))
if (float.TryParse(value, out float f))
{
return f;
}
return Value;
return value;
}
public override string ToDebugString()
{
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(SetDataAction)} -> (Identifier: {Identifier.ColorizeObject()}, Value: {ConvertXMLValue().ColorizeObject()}, Operation: {Operation.ColorizeObject()})";
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(SetDataAction)} -> (Identifier: {Identifier.ColorizeObject()}, Value: {ConvertXMLValue(Value).ColorizeObject()}, Operation: {Operation.ColorizeObject()})";
}
}
}
@@ -32,15 +32,9 @@ namespace Barotrauma
public override string ToDebugString()
{
string subActionStr = "";
if (succeeded.HasValue)
{
subActionStr = $"\n Sub action: {(succeeded.Value ? Success : Failure)?.CurrentSubAction.ColorizeObject()}";
}
return $"{ToolBox.GetDebugSymbol(DetermineFinished())} {nameof(SkillCheckAction)} -> (TargetTag: {TargetTag.ColorizeObject()}, " +
$"Required skill: {RequiredSkill.ColorizeObject()}, Required level: {RequiredLevel.ColorizeObject()}, " +
$"Succeeded: {(succeeded.HasValue ? succeeded.Value.ToString() : "not determined").ColorizeObject()})" +
subActionStr;
return $"{ToolBox.GetDebugSymbol(HasBeenDetermined())} {nameof(SkillCheckAction)} -> (Target: {TargetTag.ColorizeObject()}, " +
$"Skill: {RequiredSkill.ColorizeObject()}, Level: {RequiredLevel.ColorizeObject()}, " +
$"Succeeded: {succeeded.ColorizeObject()})";
}
}
}
@@ -41,13 +41,18 @@ namespace Barotrauma
}
public override void Reset()
{
isRunning = false;
isFinished = false;
}
public bool isRunning = false;
public override void Update(float deltaTime)
{
if (isFinished) { return; }
isRunning = true;
var targets1 = ParentEvent.GetTargets(Target1Tag);
if (!targets1.Any()) { return; }
@@ -155,6 +160,8 @@ namespace Barotrauma
{
ParentEvent.AddTarget(ApplyToTarget2, entity2);
}
isRunning = false;
isFinished = true;
}
@@ -162,11 +169,11 @@ namespace Barotrauma
{
if (string.IsNullOrEmpty(TargetModuleType))
{
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(TriggerAction)} -> (Distance: {((int)distance).ColorizeObject()}, Radius: {Radius.ColorizeObject()}, TargetTags: {Target1Tag.ColorizeObject()}, {Target2Tag.ColorizeObject()})";
return $"{ToolBox.GetDebugSymbol(isFinished, isRunning)} {nameof(TriggerAction)} -> (Distance: {((int)distance).ColorizeObject()}, Radius: {Radius.ColorizeObject()}, TargetTags: {Target1Tag.ColorizeObject()}, {Target2Tag.ColorizeObject()})";
}
else
{
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(TriggerAction)} -> (TargetTags: {Target1Tag.ColorizeObject()}, {TargetModuleType.ColorizeObject()})";
return $"{ToolBox.GetDebugSymbol(isFinished, isRunning)} {nameof(TriggerAction)} -> (TargetTags: {Target1Tag.ColorizeObject()}, {TargetModuleType.ColorizeObject()})";
}
}
}
@@ -19,6 +19,8 @@ namespace Barotrauma
const float CalculateDistanceTraveledInterval = 5.0f;
const int MaxEventHistory = 20;
private Level level;
private readonly List<Sprite> preloadedSprites = new List<Sprite>();
@@ -110,10 +112,25 @@ namespace Barotrauma
if (level?.LevelData?.Type == LevelData.LevelType.Outpost)
{
level.LevelData.EventHistory.AddRange(selectedEvents.Values.SelectMany(v => v).Select(e => e.Prefab));
if (level.LevelData.EventHistory.Count > 10)
level.LevelData.EventHistory.AddRange(selectedEvents.Values.SelectMany(v => v).Select(e => e.Prefab).Where(e => !level.LevelData.EventHistory.Contains(e)));
if (level.LevelData.EventHistory.Count > MaxEventHistory)
{
level.LevelData.EventHistory.RemoveRange(0, level.LevelData.EventHistory.Count - 10);
level.LevelData.EventHistory.RemoveRange(0, level.LevelData.EventHistory.Count - MaxEventHistory);
}
AddChildEvents(initialEventSet);
void AddChildEvents(EventSet eventSet)
{
foreach (EventPrefab ep in eventSet.EventPrefabs.Select(e => e.First))
{
if (!level.LevelData.NonRepeatableEvents.Contains(ep))
{
level.LevelData.NonRepeatableEvents.Add(ep);
}
}
foreach (EventSet childSet in eventSet.ChildSets)
{
AddChildEvents(childSet);
}
}
}
@@ -301,6 +318,7 @@ namespace Barotrauma
private float CalculateCommonness(Pair<EventPrefab, float> eventPrefab)
{
if (level.LevelData.NonRepeatableEvents.Contains(eventPrefab.First)) { return 0.0f; }
float retVal = eventPrefab.Second;
if (level.LevelData.EventHistory.Contains(eventPrefab.First)) { retVal *= 0.1f; }
return retVal;
@@ -324,7 +342,13 @@ namespace Barotrauma
{
if (eventSet.EventPrefabs.Count > 0)
{
MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));
int seed = ToolBox.StringToInt(level.Seed);
foreach (var previousEvent in level.LevelData.EventHistory)
{
seed |= ToolBox.StringToInt(previousEvent.Identifier);
}
MTRandom rand = new MTRandom(seed);
List<Pair<EventPrefab, float>> unusedEvents = new List<Pair<EventPrefab, float>>(eventSet.EventPrefabs);
for (int j = 0; j < eventSet.EventCount; j++)
{
@@ -476,37 +500,42 @@ namespace Barotrauma
eventThreshold += settings.EventThresholdIncrease * deltaTime;
eventCoolDown -= deltaTime;
if (currentIntensity < eventThreshold)
{
//activate pending event sets that can be activated
for (int i = pendingEventSets.Count - 1; i >= 0; i--)
bool recheck = false;
do
{
var eventSet = pendingEventSets[i];
if (eventCoolDown > 0.0f && !eventSet.IgnoreCoolDown) { continue; }
if (!CanStartEventSet(eventSet)) { continue; }
eventThreshold = settings.DefaultEventThreshold;
eventCoolDown = settings.EventCooldown;
pendingEventSets.RemoveAt(i);
if (selectedEvents.ContainsKey(eventSet))
recheck = false;
//activate pending event sets that can be activated
for (int i = pendingEventSets.Count - 1; i >= 0; i--)
{
//start events in this set
foreach (Event ev in selectedEvents[eventSet])
var eventSet = pendingEventSets[i];
if (eventCoolDown > 0.0f && !eventSet.IgnoreCoolDown) { continue; }
if (!CanStartEventSet(eventSet)) { continue; }
pendingEventSets.RemoveAt(i);
if (selectedEvents.ContainsKey(eventSet))
{
activeEvents.Add(ev);
//start events in this set
foreach (Event ev in selectedEvents[eventSet])
{
activeEvents.Add(ev);
eventThreshold = settings.DefaultEventThreshold;
eventCoolDown = settings.EventCooldown;
}
}
//add child event sets to pending
foreach (EventSet childEventSet in eventSet.ChildSets)
{
pendingEventSets.Add(childEventSet);
recheck = true;
}
}
//add child event sets to pending
foreach (EventSet childEventSet in eventSet.ChildSets)
{
pendingEventSets.Add(childEventSet);
}
}
} while (recheck);
}
foreach (Event ev in activeEvents)
@@ -568,7 +597,7 @@ namespace Barotrauma
{
//enemy outside and targeting the sub or something in it
//moloch adds 0.24 to enemy danger, a crawler 0.02
enemyDanger += enemyAI.CombatStrength / 5000.0f;
enemyDanger += enemyAI.CombatStrength / 2000.0f;
}
}
enemyDanger = MathHelper.Clamp(enemyDanger, 0.0f, 1.0f);
@@ -86,6 +86,8 @@ namespace Barotrauma
public readonly bool PerRuin;
public readonly bool PerWreck;
public readonly bool OncePerOutpost;
public readonly Dictionary<string, float> Commonness;
//Pair.First: event prefab, Pair.Second: commonness
@@ -134,6 +136,7 @@ namespace Barotrauma
IgnoreCoolDown = element.GetAttributeBool("ignorecooldown", parentSet?.IgnoreCoolDown ?? false);
PerRuin = element.GetAttributeBool("perruin", false);
PerWreck = element.GetAttributeBool("perwreck", false);
OncePerOutpost = element.GetAttributeBool("perwreck", false);
Commonness[""] = 1.0f;
foreach (XElement subElement in element.Elements())
@@ -131,11 +131,9 @@ namespace Barotrauma
if (Submarine.MainSub != null && Submarine.MainSub.AtEndPosition)
{
int deliveredItemCount = items.Count(i => i.CurrentHull != null && !i.Removed && i.Condition > 0.0f);
if (deliveredItemCount >= requiredDeliveryAmount)
{
GiveReward();
completed = true;
}
}
@@ -145,6 +143,7 @@ namespace Barotrauma
if (!item.Removed) { item.Remove(); }
}
items.Clear();
failed = !completed;
}
}
}
@@ -10,7 +10,7 @@ namespace Barotrauma
abstract partial class Mission
{
public readonly MissionPrefab Prefab;
protected bool completed;
protected bool completed, failed;
protected int state;
public int State
{
@@ -74,7 +74,12 @@ namespace Barotrauma
get { return completed; }
set { completed = value; }
}
public bool Failed
{
get { return failed; }
}
public virtual bool AllowRespawn
{
get { return true; }
@@ -219,6 +224,14 @@ namespace Barotrauma
if (faction != null) { faction.Reputation.Value += reputationReward.Value; }
}
}
if (Prefab.DataRewards != null)
{
foreach (var (identifier, value, operation) in Prefab.DataRewards)
{
SetDataAction.PerformOperation(campaign.CampaignMetadata, identifier, value, operation);
}
}
}
}
}
@@ -54,7 +54,8 @@ namespace Barotrauma
public readonly string AchievementIdentifier;
public readonly Dictionary<string, float> ReputationRewards = new Dictionary<string, float>();
public readonly Dictionary<string, float> ReputationRewards = new Dictionary<string, float>();
public readonly List<Tuple<string, object, SetDataAction.OperationType>> DataRewards = new List<Tuple<string, object, SetDataAction.OperationType>>();
public readonly int Commonness;
@@ -178,6 +179,23 @@ namespace Barotrauma
}
}
break;
case "metadata":
string identifier = subElement.GetAttributeString("identifier", string.Empty);
string stringValue = subElement.GetAttributeString("value", string.Empty);
if (!string.IsNullOrWhiteSpace(stringValue) && !string.IsNullOrWhiteSpace(identifier))
{
object value = SetDataAction.ConvertXMLValue(stringValue);
SetDataAction.OperationType operation = SetDataAction.OperationType.Set;
string operatingString = subElement.GetAttributeString("operation", string.Empty);
if (!string.IsNullOrWhiteSpace(operatingString))
{
operation = (SetDataAction.OperationType) Enum.Parse(typeof(SetDataAction.OperationType), operatingString);
}
DataRewards.Add(Tuple.Create(identifier, value, operation));
}
break;
}
}
@@ -37,7 +37,7 @@ namespace Barotrauma
}
else
{
yield return item.WorldPosition;
yield return item.GetRootInventoryOwner()?.WorldPosition ?? item.WorldPosition;
}
}
}
@@ -241,7 +241,8 @@ namespace Barotrauma
public override void End()
{
if (item.CurrentHull?.Submarine == null || (!item.CurrentHull.Submarine.AtEndPosition && !item.CurrentHull.Submarine.AtStartPosition) || item.Removed)
var root = item.GetRootContainer() ?? item;
if (root.CurrentHull?.Submarine == null || (!root.CurrentHull.Submarine.AtEndPosition && !root.CurrentHull.Submarine.AtStartPosition) || item.Removed)
{
return;
}
@@ -250,6 +251,7 @@ namespace Barotrauma
item = null;
GiveReward();
completed = true;
failed = !completed && state > 0;
}
}
}
@@ -202,16 +202,40 @@ namespace Barotrauma
foreach (var position in availablePositions)
{
Vector2 pos = position.Position.ToVector2();
float dist = Vector2.DistanceSquared(pos, GetReferenceSub().WorldPosition);
Submarine refSub = GetReferenceSub();
float dist = Vector2.DistanceSquared(pos, refSub.WorldPosition);
foreach (Submarine sub in Submarine.Loaded)
{
if (sub.Info.Type != SubmarineType.Player) { continue; }
float minDistToSub = GetMinDistanceToSub(sub);
if (dist > minDistToSub * minDistToSub && dist < closestDist)
if (dist < minDistToSub * minDistToSub) { continue; }
if (closestDist == float.PositiveInfinity)
{
closestDist = dist;
chosenPosition = position;
continue;
}
//chosen position behind the sub -> override with anything that's closer or to the right
if (chosenPosition.Position.X < refSub.WorldPosition.X)
{
if (dist < closestDist || pos.X > refSub.WorldPosition.X)
{
closestDist = dist;
chosenPosition = position;
}
}
//chosen position ahead of the sub -> only override with a position that's also ahead
else if (chosenPosition.Position.X > refSub.WorldPosition.X)
{
if (dist < closestDist && pos.X > refSub.WorldPosition.X)
{
closestDist = dist;
chosenPosition = position;
}
}
}
}
//only found a spawnpos that's very far from the sub, pick one that's closer