v0.12.0.2
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal class CheckAfflictionAction : BinaryOptionAction
|
||||
{
|
||||
[Serialize("", true)]
|
||||
public string Identifier { get; set; } = "";
|
||||
|
||||
[Serialize("", true)]
|
||||
public string TargetTag { get; set; } = "";
|
||||
|
||||
[Serialize(LimbType.None, true, "Only check afflictions on the specified limb type")]
|
||||
public LimbType TargetLimb { get; set; }
|
||||
|
||||
[Serialize(true, true, "When set to false when TargetLimb is not specified prevent checking limb-specific afflictions")]
|
||||
public bool AllowLimbAfflictions { get; set; }
|
||||
|
||||
public CheckAfflictionAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element) { }
|
||||
|
||||
protected override bool? DetermineSuccess()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Identifier) || string.IsNullOrWhiteSpace(TargetTag)) { return false; }
|
||||
List<Character> targets = ParentEvent.GetTargets(TargetTag).OfType<Character>().ToList();
|
||||
|
||||
if (!(targets.FirstOrDefault() is { } target)) { return false; }
|
||||
|
||||
if (TargetLimb == LimbType.None)
|
||||
{
|
||||
Affliction? affliction = target.CharacterHealth?.GetAffliction(Identifier, AllowLimbAfflictions);
|
||||
return affliction != null;
|
||||
}
|
||||
|
||||
if (target.CharacterHealth == null) { return false; }
|
||||
|
||||
IEnumerable<Affliction> afflictions = target.CharacterHealth.GetAllAfflictions().Where(affliction =>
|
||||
{
|
||||
LimbType? limbType = target.CharacterHealth.GetAfflictionLimb(affliction)?.type;
|
||||
if (limbType == null) { return false; }
|
||||
|
||||
return limbType == TargetLimb || true;
|
||||
});
|
||||
|
||||
return afflictions.Any(a => a.Identifier.Equals(Identifier, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public override string ToDebugString()
|
||||
{
|
||||
return $"{ToolBox.GetDebugSymbol(HasBeenDetermined())} {nameof(CheckAfflictionAction)} -> (TargetTag: {TargetTag.ColorizeObject()}, " +
|
||||
$"AfflictionIdentifier: {Identifier.ColorizeObject()}, " +
|
||||
$"TargetLimb: {TargetLimb.ColorizeObject()}, " +
|
||||
$"Succeeded: {succeeded.ColorizeObject()})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -11,6 +12,12 @@ namespace Barotrauma
|
||||
[Serialize("", true)]
|
||||
public string Condition { get; set; } = null!;
|
||||
|
||||
[Serialize(false, true, "Forces the comparison to use string instead of attempting to parse it as a boolean or a float first")]
|
||||
public bool ForceString { get; set; }
|
||||
|
||||
[Serialize(false, true, "Performs the comparison against a metadata by identifier instead of a constant value")]
|
||||
public bool CheckAgainstMetadata { get; set; }
|
||||
|
||||
protected object? value2;
|
||||
protected object? value1;
|
||||
|
||||
@@ -41,13 +48,52 @@ namespace Barotrauma
|
||||
Operator = PropertyConditional.GetOperatorType(op);
|
||||
if (Operator == PropertyConditional.OperatorType.None) { return false; }
|
||||
|
||||
bool? tryBoolean = TryBoolean(campaignMode, value);
|
||||
if (tryBoolean != null) { return tryBoolean; }
|
||||
if (CheckAgainstMetadata)
|
||||
{
|
||||
object? metadata1 = campaignMode.CampaignMetadata.GetValue(Identifier);
|
||||
object? metadata2 = campaignMode.CampaignMetadata.GetValue(value);
|
||||
|
||||
bool? tryFloat = TryFloat(campaignMode, value);
|
||||
if (tryFloat != null) { return tryFloat; }
|
||||
if (metadata1 == null || metadata2 == null)
|
||||
{
|
||||
return Operator switch
|
||||
{
|
||||
PropertyConditional.OperatorType.Equals => metadata1 == metadata2,
|
||||
PropertyConditional.OperatorType.NotEquals => metadata1 != metadata2,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
if (!ForceString)
|
||||
{
|
||||
switch (metadata1)
|
||||
{
|
||||
case bool bool1 when metadata2 is bool bool2:
|
||||
return CompareBool(bool1, bool2) ?? false;
|
||||
case float float1 when metadata2 is float float2:
|
||||
return CompareFloat(float1, float2) ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata1 is string string1 && metadata2 is string string2)
|
||||
{
|
||||
return CompareString(string1, string2) ?? false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ForceString)
|
||||
{
|
||||
bool? tryBoolean = TryBoolean(campaignMode, value);
|
||||
if (tryBoolean != null) { return tryBoolean; }
|
||||
|
||||
bool? tryFloat = TryFloat(campaignMode, value);
|
||||
if (tryFloat != null) { return tryFloat; }
|
||||
}
|
||||
|
||||
bool? tryString = TryString(campaignMode, value);
|
||||
if (tryString != null) { return tryString; }
|
||||
|
||||
DebugConsole.ThrowError($"{value2} ({Condition}) did not match a boolean or a float.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -55,53 +101,85 @@ namespace Barotrauma
|
||||
{
|
||||
if (bool.TryParse(value, out bool b))
|
||||
{
|
||||
bool target = GetBool(campaignMode);
|
||||
value1 = target;
|
||||
value2 = b;
|
||||
switch (Operator)
|
||||
{
|
||||
case PropertyConditional.OperatorType.Equals:
|
||||
return target == b;
|
||||
case PropertyConditional.OperatorType.NotEquals:
|
||||
return target != b;
|
||||
default:
|
||||
DebugConsole.Log($"Only \"Equals\" and \"Not equals\" operators are allowed for a boolean (was {Operator} for {value}).");
|
||||
return false;
|
||||
}
|
||||
return CompareBool(GetBool(campaignMode), b);
|
||||
}
|
||||
|
||||
DebugConsole.Log($"{value} != bool");
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool? CompareBool(bool val1, bool val2)
|
||||
{
|
||||
value1 = val1;
|
||||
value2 = val2;
|
||||
switch (Operator)
|
||||
{
|
||||
case PropertyConditional.OperatorType.Equals:
|
||||
return val1 == val2;
|
||||
case PropertyConditional.OperatorType.NotEquals:
|
||||
return val1 != val2;
|
||||
default:
|
||||
DebugConsole.Log($"Only \"Equals\" and \"Not equals\" operators are allowed for a boolean (was {Operator} for {val2}).");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool? TryFloat(CampaignMode campaignMode, string value)
|
||||
{
|
||||
if (float.TryParse(value, out float f))
|
||||
{
|
||||
float target = GetFloat(campaignMode);
|
||||
value1 = target;
|
||||
value2 = f;
|
||||
switch (Operator)
|
||||
{
|
||||
case PropertyConditional.OperatorType.Equals:
|
||||
return MathUtils.NearlyEqual(target, f);
|
||||
case PropertyConditional.OperatorType.GreaterThan:
|
||||
return target > f;
|
||||
case PropertyConditional.OperatorType.GreaterThanEquals:
|
||||
return target >= f;
|
||||
case PropertyConditional.OperatorType.LessThan:
|
||||
return target < f;
|
||||
case PropertyConditional.OperatorType.LessThanEquals:
|
||||
return target <= f;
|
||||
case PropertyConditional.OperatorType.NotEquals:
|
||||
return !MathUtils.NearlyEqual(target, f);
|
||||
}
|
||||
return CompareFloat(GetFloat(campaignMode), f);
|
||||
}
|
||||
|
||||
DebugConsole.Log($"{value} != float");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private bool? CompareFloat(float val1, float val2)
|
||||
{
|
||||
value1 = val1;
|
||||
value2 = val2;
|
||||
switch (Operator)
|
||||
{
|
||||
case PropertyConditional.OperatorType.Equals:
|
||||
return MathUtils.NearlyEqual(val1, val2);
|
||||
case PropertyConditional.OperatorType.GreaterThan:
|
||||
return val1 > val2;
|
||||
case PropertyConditional.OperatorType.GreaterThanEquals:
|
||||
return val1 >= val2;
|
||||
case PropertyConditional.OperatorType.LessThan:
|
||||
return val1 < val2;
|
||||
case PropertyConditional.OperatorType.LessThanEquals:
|
||||
return val1 <= val2;
|
||||
case PropertyConditional.OperatorType.NotEquals:
|
||||
return !MathUtils.NearlyEqual(val1, val2);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool? TryString(CampaignMode campaignMode, string value)
|
||||
{
|
||||
return CompareString(GetString(campaignMode), value);
|
||||
}
|
||||
|
||||
private bool? CompareString(string val1, string val2)
|
||||
{
|
||||
value1 = val1;
|
||||
value2 = val2;
|
||||
bool equals = string.Equals(val1, val2, StringComparison.OrdinalIgnoreCase);
|
||||
switch (Operator)
|
||||
{
|
||||
case PropertyConditional.OperatorType.Equals:
|
||||
return equals;
|
||||
case PropertyConditional.OperatorType.NotEquals:
|
||||
return !equals;
|
||||
default:
|
||||
DebugConsole.Log($"Only \"Equals\" and \"Not equals\" operators are allowed for a string (was {Operator} for {val2}).");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool GetBool(CampaignMode campaignMode)
|
||||
{
|
||||
return campaignMode.CampaignMetadata.GetBoolean(Identifier);
|
||||
@@ -112,6 +190,11 @@ namespace Barotrauma
|
||||
return campaignMode.CampaignMetadata.GetFloat(Identifier);
|
||||
}
|
||||
|
||||
private string GetString(CampaignMode campaignMode)
|
||||
{
|
||||
return campaignMode.CampaignMetadata.GetString(Identifier);
|
||||
}
|
||||
|
||||
public override string ToDebugString()
|
||||
{
|
||||
string condition = "?";
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Xml.Linq;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class ClearTagAction : EventAction
|
||||
{
|
||||
[Serialize("", true)]
|
||||
public string Tag { get; set; }
|
||||
|
||||
private bool isFinished;
|
||||
|
||||
public ClearTagAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element) { }
|
||||
|
||||
public override bool IsFinished(ref string goToLabel) => isFinished;
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
isFinished = false;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (isFinished) { return; }
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Tag) && ParentEvent.Targets.ContainsKey(Tag))
|
||||
{
|
||||
ParentEvent.Targets.Remove(Tag);
|
||||
}
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
public override string ToDebugString()
|
||||
{
|
||||
return $"{ToolBox.GetDebugSymbol(isFinished)} {nameof(ClearTagAction)} -> (Tag: {Tag.ColorizeObject()})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
@@ -40,9 +41,15 @@ namespace Barotrauma
|
||||
[Serialize(true, true)]
|
||||
public bool WaitForInteraction { get; set; }
|
||||
|
||||
[Serialize("", true, "Tag to assign to whoever invokes the conversation")]
|
||||
public string InvokerTag { get; set; }
|
||||
|
||||
[Serialize(false, true)]
|
||||
public bool FadeToBlack { get; set; }
|
||||
|
||||
[Serialize(true, true, "Should the event end if the conversations is interrupted (e.g. if the speaker dies or falls unconscious mid-conversation). Defaults to true.")]
|
||||
public bool EndEventIfInterrupted { get; set; }
|
||||
|
||||
[Serialize("", true)]
|
||||
public string EventSprite { get; set; }
|
||||
|
||||
@@ -104,19 +111,26 @@ namespace Barotrauma
|
||||
{
|
||||
#if CLIENT
|
||||
dialogBox?.Close();
|
||||
GUIMessageBox.MessageBoxes.ForEachMod(mb =>
|
||||
{
|
||||
if (mb.UserData as string == "ConversationAction")
|
||||
{
|
||||
(mb as GUIMessageBox)?.Close();
|
||||
}
|
||||
});
|
||||
#else
|
||||
foreach (Client c in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
if (c.InGame && c.Character != null) { ServerWrite(speaker, c); }
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
ResetSpeaker();
|
||||
dialogOpened = false;
|
||||
}
|
||||
|
||||
if (Interrupted == null)
|
||||
{
|
||||
goTo = "_end";
|
||||
if (EndEventIfInterrupted) { goTo = "_end"; }
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -171,7 +185,7 @@ namespace Barotrauma
|
||||
GameMain.NetworkMember.CreateEntityEvent(speaker, new object[] { NetEntityEvent.Type.AssignCampaignInteraction });
|
||||
#endif
|
||||
var humanAI = speaker.AIController as HumanAIController;
|
||||
if (humanAI != null)
|
||||
if (humanAI != null && !speaker.IsDead && !speaker.Removed)
|
||||
{
|
||||
if (prevSpeakerOrder != null)
|
||||
{
|
||||
@@ -255,7 +269,12 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Options.Any())
|
||||
if (ShouldInterrupt())
|
||||
{
|
||||
ResetSpeaker();
|
||||
interrupt = true;
|
||||
}
|
||||
else if (Options.Any())
|
||||
{
|
||||
Options[selectedOption].Update(deltaTime);
|
||||
}
|
||||
@@ -335,6 +354,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (targetCharacter != null && !string.IsNullOrWhiteSpace(InvokerTag))
|
||||
{
|
||||
ParentEvent.AddTarget(InvokerTag, targetCharacter);
|
||||
}
|
||||
|
||||
ShowDialog(speaker, targetCharacter);
|
||||
|
||||
dialogOpened = true;
|
||||
|
||||
@@ -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?.ToLowerInvariant(), Amount, target.WorldPosition + Vector2.UnitY * 150.0f);
|
||||
target.Info?.IncreaseSkillLevel(Skill?.ToLowerInvariant(), Amount, target.Position + Vector2.UnitY * 150.0f);
|
||||
}
|
||||
isFinished = true;
|
||||
}
|
||||
|
||||
@@ -109,14 +109,14 @@ namespace Barotrauma
|
||||
ISpatialEntity spawnPos = GetSpawnPos();
|
||||
Entity.Spawner.AddToSpawnQueue(CharacterPrefab.HumanSpeciesName, OffsetSpawnPos(spawnPos?.WorldPosition ?? Vector2.Zero, 100.0f), onSpawn: newCharacter =>
|
||||
{
|
||||
newCharacter.TeamID = Character.TeamType.FriendlyNPC;
|
||||
newCharacter.TeamID = CharacterTeamType.FriendlyNPC;
|
||||
newCharacter.EnableDespawn = false;
|
||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
||||
if (LootingIsStealing)
|
||||
{
|
||||
foreach (Item item in newCharacter.Inventory.Items)
|
||||
foreach (Item item in newCharacter.Inventory.AllItems)
|
||||
{
|
||||
if (item != null) { item.SpawnedInOutpost = true; }
|
||||
item.SpawnedInOutpost = true;
|
||||
}
|
||||
}
|
||||
newCharacter.CharacterHealth.MaxVitality *= humanPrefab.HealthMultiplier;
|
||||
@@ -200,12 +200,18 @@ namespace Barotrauma
|
||||
}
|
||||
void onSpawned(Item newItem)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(TargetTag) && newItem != null)
|
||||
if (newItem != null)
|
||||
{
|
||||
ParentEvent.AddTarget(TargetTag, newItem);
|
||||
if (!string.IsNullOrEmpty(TargetTag))
|
||||
{
|
||||
ParentEvent.AddTarget(TargetTag, newItem);
|
||||
}
|
||||
if (IgnoreByAI)
|
||||
{
|
||||
newItem.AddTag("ignorebyai");
|
||||
}
|
||||
}
|
||||
spawnedEntity = newItem;
|
||||
newItem?.SetIgnoreByAI(IgnoreByAI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,12 @@ namespace Barotrauma
|
||||
[Serialize(0.0f, true, description: "Range both entities must be within to activate the trigger.")]
|
||||
public float Radius { get; set; }
|
||||
|
||||
[Serialize(true, true, description: "If true, characters who are being targeted by some enemy cannot trigger the event.")]
|
||||
[Serialize(true, true, description: "If true, characters who are being targeted by some enemy cannot trigger the action.")]
|
||||
public bool DisableInCombat { get; set; }
|
||||
|
||||
[Serialize(true, true, description: "If true, dead/unconscious characters cannot trigger the action.")]
|
||||
public bool DisableIfTargetIncapacitated { get; set; }
|
||||
|
||||
private float distance;
|
||||
|
||||
public TriggerAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element)
|
||||
@@ -59,6 +62,7 @@ namespace Barotrauma
|
||||
foreach (Entity e1 in targets1)
|
||||
{
|
||||
if (DisableInCombat && IsInCombat(e1)) { continue; }
|
||||
if (DisableIfTargetIncapacitated && e1 is Character character1 && (character1.IsDead || character1.IsIncapacitated)) { continue; }
|
||||
if (!string.IsNullOrEmpty(TargetModuleType))
|
||||
{
|
||||
if (IsCloseEnoughToHull(e1, out Hull hull))
|
||||
@@ -75,6 +79,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (e1 == e2) { continue; }
|
||||
if (DisableInCombat && IsInCombat(e2)) { continue; }
|
||||
if (DisableIfTargetIncapacitated && e2 is Character character2 && (character2.IsDead || character2.IsIncapacitated)) { continue; }
|
||||
|
||||
Vector2 pos1 = e1.WorldPosition;
|
||||
Vector2 pos2 = e2.WorldPosition;
|
||||
|
||||
Reference in New Issue
Block a user