Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaServer/Source/Traitors/Goals/GoalFindItem.cs
T
2019-08-26 19:58:44 +03:00

165 lines
6.9 KiB
C#

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);
}
}
}
}