(a00338777) v0.9.2.1
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlServer.Server;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public abstract class Goal
|
||||
{
|
||||
public Traitor Traitor { get; private set; }
|
||||
public TraitorMission Mission { get; internal set; }
|
||||
|
||||
public virtual string StatusTextId { get; set; } = "TraitorGoalStatusTextFormat";
|
||||
|
||||
public virtual string InfoTextId { get; set; } = null;
|
||||
|
||||
public virtual string CompletedTextId { get; set; } = null;
|
||||
|
||||
public virtual string StatusValueTextId => IsCompleted ? "complete" : "inprogress";
|
||||
|
||||
public virtual IEnumerable<string> StatusTextKeys => new [] { "[infotext]", "[status]" };
|
||||
public virtual IEnumerable<string> StatusTextValues => new [] { InfoText, TextManager.FormatServerMessage(StatusValueTextId) };
|
||||
|
||||
public virtual IEnumerable<string> InfoTextKeys => new string[] { };
|
||||
public virtual IEnumerable<string> InfoTextValues => new string[] { };
|
||||
|
||||
public virtual IEnumerable<string> CompletedTextKeys => new string[] { };
|
||||
public virtual IEnumerable<string> CompletedTextValues => new string[] { };
|
||||
|
||||
protected virtual string FormatText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => TextManager.FormatServerMessageWithGenderPronouns(traitor?.Character?.Info?.Gender ?? Gender.None, textId, keys, values);
|
||||
|
||||
protected internal virtual string GetStatusText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => FormatText(traitor, textId, keys, values);
|
||||
protected internal virtual string GetInfoText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => FormatText(traitor, textId, keys, values);
|
||||
protected internal virtual string GetCompletedText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => FormatText(traitor, textId, keys, values);
|
||||
|
||||
public virtual string StatusText => GetStatusText(Traitor, StatusTextId, StatusTextKeys, StatusTextValues);
|
||||
public virtual string InfoText => GetInfoText(Traitor, InfoTextId, InfoTextKeys, InfoTextValues);
|
||||
|
||||
public virtual string CompletedText => CompletedTextId != null ? GetCompletedText(Traitor, CompletedTextId, CompletedTextKeys, CompletedTextValues) : StatusText;
|
||||
|
||||
public abstract bool IsCompleted { get; }
|
||||
public virtual bool IsStarted => Traitor != null;
|
||||
public virtual bool CanBeCompleted => !(Traitor?.Character?.IsDead ?? true);
|
||||
|
||||
public virtual bool IsEnemy(Character character) => false;
|
||||
|
||||
public virtual bool Start(Traitor traitor)
|
||||
{
|
||||
Traitor = traitor;
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Update(float deltaTime)
|
||||
{
|
||||
}
|
||||
|
||||
protected Goal()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalDestroyItemsWithTag : Goal
|
||||
{
|
||||
private readonly string tag;
|
||||
private readonly bool matchIdentifier;
|
||||
private readonly bool matchTag;
|
||||
private readonly bool matchInventory;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[percentage]", "[tag]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { string.Format("{0:0}", DestroyPercent * 100.0f), tagPrefabName ?? "" });
|
||||
|
||||
private readonly float destroyPercent;
|
||||
private float DestroyPercent => destroyPercent;
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
private int totalCount = 0;
|
||||
private int targetCount = 0;
|
||||
private string tagPrefabName = null;
|
||||
|
||||
private int CountMatchingItems()
|
||||
{
|
||||
int result = 0;
|
||||
foreach (var item in Item.ItemList)
|
||||
{
|
||||
if (!matchInventory && item.FindParentInventory(inventory => inventory.Owner is Character && inventory.Owner != Traitor.Character) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.Submarine == null)
|
||||
{
|
||||
if (!(item.ParentInventory?.Owner is Character)) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.Submarine.TeamID != Traitor.Character.TeamID) { continue; }
|
||||
}
|
||||
|
||||
if (item.Condition <= 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var identifierMatches = matchIdentifier && item.prefab.Identifier == tag;
|
||||
if (identifierMatches && tagPrefabName == null)
|
||||
{
|
||||
var textId = item.Prefab.GetItemNameTextId();
|
||||
tagPrefabName = textId != null ? TextManager.FormatServerMessage(textId) : item.Prefab.Name;
|
||||
}
|
||||
if (identifierMatches || (matchTag && item.HasTag(tag)))
|
||||
{
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
isCompleted = CountMatchingItems() <= targetCount;
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
totalCount = CountMatchingItems();
|
||||
if (totalCount <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
targetCount = (int)((1.0f - destroyPercent) * totalCount - 0.5f);
|
||||
return true;
|
||||
}
|
||||
|
||||
public GoalDestroyItemsWithTag(string tag, float destroyPercent, bool matchTag, bool matchIdentifier, bool matchInventory) : base()
|
||||
{
|
||||
InfoTextId = "TraitorGoalDestroyItems";
|
||||
this.tag = tag;
|
||||
this.destroyPercent = destroyPercent;
|
||||
this.matchTag = matchTag;
|
||||
this.matchIdentifier = matchIdentifier;
|
||||
this.matchInventory = matchInventory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public class GoalFindItem : HumanoidGoal
|
||||
{
|
||||
private readonly string identifier;
|
||||
private readonly bool preferNew;
|
||||
private readonly bool allowNew;
|
||||
private readonly bool allowExisting;
|
||||
private readonly HashSet<string> allowedContainerIdentifiers = new HashSet<string>();
|
||||
|
||||
private ItemPrefab targetPrefab;
|
||||
private Item targetContainer;
|
||||
private Item target;
|
||||
private HashSet<Item> existingItems = new HashSet<Item>();
|
||||
private string targetNameText;
|
||||
private string targetContainerNameText;
|
||||
private string targetHullNameText;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[identifier]", "[target]", "[targethullname]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { targetNameText ?? "", targetContainerNameText ?? "", targetHullNameText ?? "" });
|
||||
|
||||
public override bool IsCompleted => target != null && target.ParentInventory == Traitor.Character.Inventory;
|
||||
public override bool CanBeCompleted {
|
||||
get
|
||||
{
|
||||
if (!base.CanBeCompleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (target == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (target.Removed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (target.Submarine == null)
|
||||
{
|
||||
if (!(target.ParentInventory?.Owner is Character))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target.Submarine.TeamID != Traitor.Character.TeamID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsEnemy(Character character) => base.IsEnemy(character) || (target != null && target.FindParentInventory(inventory => inventory == character.Inventory) != null);
|
||||
|
||||
protected ItemPrefab FindItemPrefab(string identifier)
|
||||
{
|
||||
return (ItemPrefab)MapEntityPrefab.List.Find(prefab => prefab is ItemPrefab && prefab.Identifier == identifier);
|
||||
}
|
||||
|
||||
protected Item FindRandomContainer(bool includeNew, bool includeExisting)
|
||||
{
|
||||
int itemsCount = Item.ItemList.Count;
|
||||
int startIndex = TraitorMission.Random(itemsCount);
|
||||
Item fallback = null;
|
||||
for (int i = 0; i < itemsCount; ++i)
|
||||
{
|
||||
var item = Item.ItemList[(i + startIndex) % itemsCount];
|
||||
if (item.Submarine == null || item.Submarine.TeamID != Traitor.Character.TeamID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.GetComponent<ItemContainer>() != null && allowedContainerIdentifiers.Contains(item.prefab.Identifier))
|
||||
{
|
||||
if ((includeNew && !item.OwnInventory.IsFull()) || (includeExisting && item.OwnInventory.FindItemByIdentifier(targetPrefab.Identifier) != null))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
targetPrefab = FindItemPrefab(identifier);
|
||||
if (targetPrefab == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var targetPrefabTextId = targetPrefab.GetItemNameTextId();
|
||||
targetNameText = targetPrefabTextId != null ? TextManager.FormatServerMessage(targetPrefabTextId) : targetPrefab.Name;
|
||||
targetContainer = null;
|
||||
if (preferNew)
|
||||
{
|
||||
targetContainer = FindRandomContainer(true, false);
|
||||
}
|
||||
if (targetContainer == null)
|
||||
{
|
||||
targetContainer = FindRandomContainer(allowNew, allowExisting);
|
||||
}
|
||||
if (targetContainer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var containerPrefabTextId = targetContainer.Prefab.GetItemNameTextId();
|
||||
targetContainerNameText = containerPrefabTextId != null ? TextManager.FormatServerMessage(containerPrefabTextId) : targetContainer.Prefab.Name;
|
||||
var targetHullTextId = targetContainer.CurrentHull != null ? targetContainer.CurrentHull.prefab.GetHullNameTextId() : null;
|
||||
targetHullNameText = targetHullTextId != null ? TextManager.FormatServerMessage(targetHullTextId) : targetContainer?.CurrentHull?.DisplayName ?? "";
|
||||
if (allowNew && !targetContainer.OwnInventory.IsFull())
|
||||
{
|
||||
existingItems.Clear();
|
||||
foreach (var item in targetContainer.OwnInventory.Items)
|
||||
{
|
||||
existingItems.Add(item);
|
||||
}
|
||||
Entity.Spawner.AddToSpawnQueue(targetPrefab, targetContainer.OwnInventory);
|
||||
target = null;
|
||||
}
|
||||
else if (allowExisting)
|
||||
{
|
||||
target = targetContainer.OwnInventory.FindItemByIdentifier(targetPrefab.Identifier);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
if (target == null)
|
||||
{
|
||||
target = targetContainer.OwnInventory.Items.FirstOrDefault(item => item != null && item.Prefab.Identifier == identifier && !existingItems.Contains(item));
|
||||
if (target != null)
|
||||
{
|
||||
existingItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GoalFindItem(string identifier, bool preferNew, bool allowNew, bool allowExisting, params string[] allowedContainerIdentifiers)
|
||||
{
|
||||
this.identifier = identifier;
|
||||
this.preferNew = preferNew;
|
||||
this.allowNew = allowNew;
|
||||
this.allowExisting = allowExisting;
|
||||
this.allowedContainerIdentifiers.UnionWith(allowedContainerIdentifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalFloodPercentOfSub : Goal
|
||||
{
|
||||
private readonly float minimumFloodingAmount;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[percentage]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { string.Format("{0:0}", minimumFloodingAmount * 100.0f) });
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
var validHullsCount = 0;
|
||||
var floodingAmount = 0.0f;
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Submarine == null || hull.Submarine.IsOutpost || hull.Submarine.TeamID != Traitor.Character.TeamID) { continue; }
|
||||
++validHullsCount;
|
||||
floodingAmount += hull.WaterVolume / hull.Volume;
|
||||
}
|
||||
if (validHullsCount > 0)
|
||||
{
|
||||
floodingAmount /= validHullsCount;
|
||||
}
|
||||
isCompleted = floodingAmount >= minimumFloodingAmount;
|
||||
}
|
||||
|
||||
public GoalFloodPercentOfSub(float minimumFloodingAmount) : base()
|
||||
{
|
||||
InfoTextId = "TraitorGoalFloodPercentOfSub";
|
||||
this.minimumFloodingAmount = minimumFloodingAmount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalKillTarget : Goal
|
||||
{
|
||||
public TraitorMission.CharacterFilter Filter { get; private set; }
|
||||
public Character Target { get; private set; }
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[targetname]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { Target?.Name ?? "(unknown)" });
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
public override bool IsEnemy(Character character) => base.IsEnemy(character) || (!isCompleted && character == Target);
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
isCompleted = Target?.IsDead ?? false;
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Target = traitor.Mission.FindKillTarget(traitor.Character, Filter);
|
||||
return Target != null && !Target.IsDead;
|
||||
}
|
||||
|
||||
public GoalKillTarget(TraitorMission.CharacterFilter filter) : base()
|
||||
{
|
||||
InfoTextId = "TraitorGoalKillTargetInfo";
|
||||
Filter = filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public class GoalRandom : Goal
|
||||
{
|
||||
private readonly List<Goal> allGoals;
|
||||
|
||||
private readonly List<Goal> selectedGoals = new List<Goal>();
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[targetname]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { Target?.Name ?? "(unknown)" });
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
public override bool IsEnemy(Character character) => base.IsEnemy(character) || (!isCompleted && character == Target);
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
isCompleted = Target?.IsDead ?? false;
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Target = traitor.Mission.FindKillTarget(traitor.Character, Filter);
|
||||
return Target != null && !Target.IsDead;
|
||||
}
|
||||
|
||||
public GoalRandom(params Goal[] goals, int count)
|
||||
{
|
||||
this.goals = goals;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalReachDistanceFromSub : Goal
|
||||
{
|
||||
private readonly float requiredDistance;
|
||||
private readonly float requiredDistanceSqr;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[distance]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { $"{requiredDistance:0.00}" });
|
||||
|
||||
public override bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Traitor == null || Traitor.Character == null || Traitor.Character.Submarine == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var characterPosition = Traitor.Character.WorldPosition;
|
||||
var submarinePosition = Traitor.Character.Submarine.WorldPosition;
|
||||
var distance = Vector2.DistanceSquared(characterPosition, submarinePosition);
|
||||
return distance >= requiredDistanceSqr;
|
||||
}
|
||||
}
|
||||
|
||||
public GoalReachDistanceFromSub(float requiredDistance) : base()
|
||||
{
|
||||
InfoTextId = "TraitorGoalReachDistanceFromSub";
|
||||
this.requiredDistance = requiredDistance;
|
||||
requiredDistanceSqr = requiredDistance * requiredDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public class GoalReplaceInventory : HumanoidGoal
|
||||
{
|
||||
private readonly HashSet<string> sabotageContainerIds = new HashSet<string>();
|
||||
private readonly HashSet<string> validReplacementIds = new HashSet<string>();
|
||||
|
||||
private readonly float replaceAmount;
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
public override IEnumerable<string> StatusTextKeys => base.StatusTextKeys.Concat(new string[] { "[percentage]" });
|
||||
public override IEnumerable<string> StatusTextValues => base.StatusTextValues.Concat(new string[] { string.Format("{0:0}", replaceAmount * 100.0f) });
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
int totalAmount = 0, replacedAmount = 0;
|
||||
foreach (var item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine == null || item.Submarine.TeamID != Traitor.Character.TeamID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (item.FindParentInventory(inventory => inventory.Owner is Character) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (sabotageContainerIds.Contains(item.prefab.Identifier))
|
||||
{
|
||||
++totalAmount;
|
||||
if (item.OwnInventory.Items.Length <= 0 || item.OwnInventory.Items.All(containedItem => containedItem != null && !validReplacementIds.Contains(containedItem.Prefab.Identifier)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++replacedAmount;
|
||||
}
|
||||
}
|
||||
isCompleted = replacedAmount >= (int)(replaceAmount * totalAmount + 0.5f);
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (sabotageContainerIds.Count <= 0 || validReplacementIds.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public GoalReplaceInventory(string[] containerIds, string[] replacementIds, float replaceAmount)
|
||||
{
|
||||
sabotageContainerIds.UnionWith(containerIds);
|
||||
validReplacementIds.UnionWith(replacementIds);
|
||||
this.replaceAmount = replaceAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalSabotageItems : HumanoidGoal
|
||||
{
|
||||
private readonly string tag;
|
||||
private readonly float conditionThreshold;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[tag]", "[target]", "[threshold]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { tag ?? "", targetItemPrefabName ?? "", string.Format("{0:0}", conditionThreshold) });
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
private readonly List<Item> targetItems = new List<Item>();
|
||||
private string targetItemPrefabName = null;
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foreach (var item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine == null || item.Submarine.TeamID != Traitor.Character.TeamID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (item.Condition > conditionThreshold && (item.Prefab?.Identifier == tag || item.HasTag(tag)))
|
||||
{
|
||||
targetItems.Add(item);
|
||||
}
|
||||
}
|
||||
if (targetItems.Count > 0)
|
||||
{
|
||||
var textId = targetItems[0].Prefab.GetItemNameTextId();
|
||||
targetItemPrefabName = TextManager.FormatServerMessage(textId) ?? targetItems[0].Prefab.Name;
|
||||
}
|
||||
return targetItems.Count > 0;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
isCompleted = targetItems.All(item => item.Condition <= conditionThreshold);
|
||||
}
|
||||
|
||||
public GoalSabotageItems(string tag, float conditionThreshold) : base()
|
||||
{
|
||||
this.tag = tag;
|
||||
this.conditionThreshold = conditionThreshold;
|
||||
InfoTextId = "TraitorGoalSabotageInfo";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public abstract class HumanoidGoal : Goal
|
||||
{
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Traitor?.Character?.IsHumanoid ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalHasDuration : Modifier
|
||||
{
|
||||
private readonly float requiredDuration;
|
||||
private readonly bool countTotalDuration;
|
||||
private readonly string durationInfoTextId;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[duration]" });
|
||||
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { $"{TimeSpan.FromSeconds(requiredDuration):g}" });
|
||||
|
||||
protected internal override string GetInfoText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values)
|
||||
{
|
||||
var infoText = base.GetInfoText(traitor, textId, keys, values);
|
||||
return !string.IsNullOrEmpty(durationInfoTextId) ? TextManager.FormatServerMessage(durationInfoTextId, new[] { "[infotext]", "[duration]" }, new[] { infoText, $"{TimeSpan.FromSeconds(requiredDuration):g}" }) : infoText;
|
||||
}
|
||||
|
||||
private bool isCompleted = false;
|
||||
public override bool IsCompleted => isCompleted;
|
||||
|
||||
private float remainingDuration = float.NaN;
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
if (Goal.IsCompleted)
|
||||
{
|
||||
if (!float.IsNaN(remainingDuration))
|
||||
{
|
||||
remainingDuration -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainingDuration = requiredDuration;
|
||||
}
|
||||
isCompleted |= remainingDuration <= 0.0f;
|
||||
}
|
||||
else if (!countTotalDuration)
|
||||
{
|
||||
remainingDuration = float.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
public GoalHasDuration(Goal goal, float requiredDuration, bool countTotalDuration, string durationInfoTextId) : base(goal)
|
||||
{
|
||||
this.requiredDuration = requiredDuration;
|
||||
this.countTotalDuration = countTotalDuration;
|
||||
this.durationInfoTextId = durationInfoTextId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalHasTimeLimit : Modifier
|
||||
{
|
||||
private readonly float timeLimit;
|
||||
private readonly string timeLimitInfoTextId;
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => base.InfoTextKeys.Concat(new string[] { "[timelimit]" });
|
||||
public override IEnumerable<string> InfoTextValues => base.InfoTextValues.Concat(new string[] { $"{TimeSpan.FromSeconds(timeLimit):g}" });
|
||||
|
||||
protected internal override string GetInfoText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values)
|
||||
{
|
||||
var infoText = base.GetInfoText(traitor, textId, keys, values);
|
||||
return !string.IsNullOrEmpty(timeLimitInfoTextId) ? TextManager.FormatServerMessage(timeLimitInfoTextId, new[] { "[infotext]", "[timelimit]" }, new[] { infoText, $"{TimeSpan.FromSeconds(timeLimit):g}" }) : infoText;
|
||||
}
|
||||
|
||||
public override bool CanBeCompleted => base.CanBeCompleted && (!IsStarted || timeRemaining > 0.0f);
|
||||
|
||||
private float timeRemaining;
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
timeRemaining = System.Math.Max(0.0f, timeRemaining - deltaTime);
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
timeRemaining = timeLimit;
|
||||
return true;
|
||||
}
|
||||
|
||||
public GoalHasTimeLimit(Goal goal, float timeLimit, string timeLimitInfoTextId) : base(goal)
|
||||
{
|
||||
this.timeLimit = timeLimit;
|
||||
this.timeLimitInfoTextId = timeLimitInfoTextId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public sealed class GoalIsOptional : Modifier
|
||||
{
|
||||
private readonly string optionalInfoTextId;
|
||||
|
||||
public override string StatusValueTextId => (base.IsStarted && !base.CanBeCompleted) ? "failed" : base.StatusValueTextId;
|
||||
|
||||
public override IEnumerable<string> StatusTextValues
|
||||
{
|
||||
get {
|
||||
var values = base.StatusTextValues.ToArray();
|
||||
values[1] = TextManager.GetServerMessage(StatusValueTextId);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCompleted => base.IsCompleted || (base.IsStarted && !base.CanBeCompleted);
|
||||
public override bool CanBeCompleted => true;
|
||||
|
||||
protected internal override string GetInfoText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values)
|
||||
{
|
||||
var infoText = base.GetInfoText(traitor, textId, keys, values);
|
||||
return !string.IsNullOrEmpty(optionalInfoTextId) ? TextManager.FormatServerMessage(optionalInfoTextId, new[] { "[infotext]" }, new[] { infoText }) : infoText;
|
||||
}
|
||||
|
||||
public GoalIsOptional(Goal goal, string optionalInfoTextId) : base(goal)
|
||||
{
|
||||
this.optionalInfoTextId = optionalInfoTextId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Traitor
|
||||
{
|
||||
public abstract class Modifier : Goal
|
||||
{
|
||||
protected Goal Goal { get; }
|
||||
|
||||
public override string StatusValueTextId => Goal.StatusValueTextId;
|
||||
|
||||
public override string StatusTextId
|
||||
{
|
||||
get => Goal.StatusTextId;
|
||||
set => Goal.StatusTextId = value;
|
||||
}
|
||||
|
||||
public override string InfoTextId
|
||||
{
|
||||
get => Goal.InfoTextId;
|
||||
set => Goal.InfoTextId = value;
|
||||
}
|
||||
|
||||
public override string CompletedTextId
|
||||
{
|
||||
get => Goal.CompletedTextId;
|
||||
set => Goal.CompletedTextId = value;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> StatusTextKeys => Goal.StatusTextKeys;
|
||||
public override IEnumerable<string> StatusTextValues => new [] { InfoText, TextManager.FormatServerMessage(StatusValueTextId) };
|
||||
|
||||
public override IEnumerable<string> InfoTextKeys => Goal.InfoTextKeys;
|
||||
public override IEnumerable<string> InfoTextValues => Goal.InfoTextValues;
|
||||
|
||||
public override IEnumerable<string> CompletedTextKeys => Goal.CompletedTextKeys;
|
||||
public override IEnumerable<string> CompletedTextValues => Goal.CompletedTextValues;
|
||||
|
||||
protected internal override string GetStatusText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => Goal.GetStatusText(traitor, textId, keys, values);
|
||||
protected internal override string GetInfoText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => Goal.GetInfoText(traitor, textId, keys, values);
|
||||
protected internal override string GetCompletedText(Traitor traitor, string textId, IEnumerable<string> keys, IEnumerable<string> values) => Goal.GetCompletedText(traitor, textId, keys, values);
|
||||
|
||||
public override string StatusText => GetStatusText(Traitor, StatusTextId, StatusTextKeys, StatusTextValues);
|
||||
public override string InfoText => GetInfoText(Traitor, InfoTextId, InfoTextKeys, InfoTextValues);
|
||||
public override string CompletedText => CompletedTextId != null ? GetCompletedText(Traitor, CompletedTextId, CompletedTextKeys, CompletedTextValues) : StatusText;
|
||||
|
||||
public override bool IsCompleted => Goal.IsCompleted;
|
||||
public override bool IsStarted => base.IsStarted && Goal.IsStarted;
|
||||
public override bool CanBeCompleted => base.CanBeCompleted && Goal.CanBeCompleted;
|
||||
|
||||
public override bool IsEnemy(Character character) => base.IsEnemy(character) || Goal.IsEnemy(character);
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
Goal.Update(deltaTime);
|
||||
}
|
||||
|
||||
public override bool Start(Traitor traitor)
|
||||
{
|
||||
if (!base.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Goal.Start(traitor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Modifier(Goal goal) : base()
|
||||
{
|
||||
Goal = goal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user