(ce8e185aa) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev

This commit is contained in:
Joonas Rikkonen
2019-04-16 17:12:09 +03:00
parent bd07acf26d
commit 6262b3ea54
96 changed files with 1972 additions and 825 deletions
@@ -221,29 +221,64 @@ namespace Barotrauma.Items.Components
{
if (item.Condition <= RepairThreshold) return true; //For repairing
var idCard = character.Inventory.FindItemByIdentifier("idcard");
hasValidIdCard = requiredItems.Any(ri => ri.Value.Any(r => r.MatchesItem(idCard)));
Msg = requiredItems.None() || hasValidIdCard ? "ItemMsgOpen" : "ItemMsgForceOpenCrowbar";
ParseMsg();
if (addMessage)
{
msg = msg ?? (HasIntegratedButtons ? accessDeniedTxt : cannotOpenText);
}
//this is a bit pointless atm because if canBePicked is false it won't allow you to do Pick() anyway, however it's still good for future-proofing.
return requiredItems.Any() ? base.HasRequiredItems(character, addMessage, msg) : canBePicked;
}
public override bool Pick(Character picker)
{
return item.Condition <= RepairThreshold ? true : base.Pick(picker);
if (item.Condition <= RepairThreshold) { return true; }
if (requiredItems.None()) { return false; }
if (HasRequiredItems(picker, false) && hasValidIdCard) { return false; }
return base.Pick(picker);
}
public override bool OnPicked(Character picker)
{
if (item.Condition <= RepairThreshold) return true; //repairs
if (requiredItems.Any() && !hasValidIdCard)
{
ForceOpen(ActionType.OnPicked);
}
return false;
}
private void ForceOpen(ActionType actionType)
{
SetState(PredictedState == null ? !isOpen : !PredictedState.Value, false, true); //crowbar function
#if CLIENT
PlaySound(ActionType.OnPicked, item.WorldPosition, picker);
PlaySound(actionType, item.WorldPosition, picker);
#endif
}
public override bool Select(Character character)
{
//can only be selected if the item is broken
return item.Condition <= RepairThreshold;
if (item.Condition <= RepairThreshold) return true; //repairs
bool hasRequiredItems = HasRequiredItems(character, false);
if (requiredItems.None() || hasRequiredItems && hasValidIdCard)
{
float originalPickingTime = PickingTime;
PickingTime = 0;
ForceOpen(ActionType.OnUse);
PickingTime = originalPickingTime;
}
else if (hasRequiredItems)
{
#if CLIENT
GUI.AddMessage(accessDeniedTxt, Color.Red);
#endif
}
return false;
}
public override void Update(float deltaTime, Camera cam)
@@ -34,6 +34,20 @@ namespace Barotrauma.Items.Components
}
}
public override bool IsActive
{
get { return base.IsActive; }
set
{
base.IsActive = value;
if (!value)
{
nodes.Clear();
charactersInRange.Clear();
}
}
}
[Serialize(100.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 5000.0f)]
public float Range
{
@@ -126,14 +140,19 @@ namespace Barotrauma.Items.Components
}
else
{
nodes.Clear();
charactersInRange.Clear();
IsActive = false;
}
voltage = 0.0f;
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
base.UpdateBroken(deltaTime, cam);
nodes.Clear();
charactersInRange.Clear();
}
private void Discharge()
{
ApplyStatusEffects(ActionType.OnUse, 1.0f);
@@ -58,13 +58,6 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(true, true)]
public bool Aimable
{
get;
set;
}
[Serialize(false, false)]
public bool ControlPose
{
@@ -11,6 +11,12 @@ namespace Barotrauma.Items.Components
{
private float lastSentDeattachTimer;
private PhysicsBody trigger;
private Holdable holdable;
private float deattachTimer;
[Serialize(1.0f, false)]
public float DeattachDuration
{
@@ -49,13 +55,7 @@ namespace Barotrauma.Items.Components
#endif
}
}
private PhysicsBody trigger;
private Holdable holdable;
private float deattachTimer;
public LevelResource(Item item, XElement element) : base(item, element)
{
IsActive = true;
@@ -142,8 +142,6 @@ namespace Barotrauma.Items.Components
pickTimer / requiredTime,
Color.Red, Color.Green);
#endif
picker.AnimController.UpdateUseItem(true, item.WorldPosition + new Vector2(0.0f, 100.0f) * ((pickTimer / 10.0f) % 0.1f));
picker.AnimController.UpdateUseItem(true, item.WorldPosition + new Vector2(0.0f, 100.0f) * ((pickTimer / 10.0f) % 0.1f));
pickTimer += CoroutineManager.DeltaTime;
@@ -322,6 +322,7 @@ namespace Barotrauma.Items.Components
// If the character is climbing, ignore the check, because we cannot aim while climbing.
if (VectorExtensions.Angle(VectorExtensions.Forward(item.body.TransformedRotation), fromItemToLeak) < MathHelper.PiOver4)
{
character.SetInput(InputType.Shoot, false, true);
Use(deltaTime, character);
}
else
@@ -337,11 +338,11 @@ namespace Barotrauma.Items.Components
sinTime = 0;
if (!leak.FlowTargetHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f))
{
character.Speak(TextManager.Get("DialogLeaksFixed").Replace("[roomname]", leak.FlowTargetHull.RoomName), null, 0.0f, "leaksfixed", 10.0f);
character.Speak(TextManager.Get("DialogLeaksFixed").Replace("[roomname]", leak.FlowTargetHull.DisplayName), null, 0.0f, "leaksfixed", 10.0f);
}
else
{
character.Speak(TextManager.Get("DialogLeakFixed").Replace("[roomname]", leak.FlowTargetHull.RoomName), null, 0.0f, "leakfixed", 10.0f);
character.Speak(TextManager.Get("DialogLeakFixed").Replace("[roomname]", leak.FlowTargetHull.DisplayName), null, 0.0f, "leakfixed", 10.0f);
}
}
@@ -190,7 +190,7 @@ namespace Barotrauma.Items.Components
get { return name; }
}
[Editable, Serialize("", true)]
[Editable, Serialize("", true, translationTextTag: "ItemMsg")]
public string Msg
{
get;
@@ -538,7 +538,6 @@ namespace Barotrauma.Items.Components
GameAnalyticsManager.AddErrorEventOnce("ItemComponent.DegreeOfSuccess:CharacterNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return 0.0f;
}
float average = skillSuccessSum / requiredSkills.Count;
float skillSuccessSum = 0.0f;
for (int i = 0; i < requiredSkills.Count; i++)
@@ -555,7 +554,7 @@ namespace Barotrauma.Items.Components
public virtual void FlipY(bool relativeToSub) { }
public bool HasRequiredContainedItems(bool addMessage)
public bool HasRequiredContainedItems(bool addMessage, string msg = null)
{
if (!requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) return true;
if (item.OwnInventory == null) return false;
@@ -582,33 +581,52 @@ namespace Barotrauma.Items.Components
{
if (!requiredItems.Any()) return true;
if (character.Inventory == null) return false;
bool hasRequiredItems = false;
bool canContinue = true;
if (requiredItems.ContainsKey(RelatedItem.RelationType.Equipped))
{
foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Equipped])
{
if (character.SelectedItems.FirstOrDefault(it => it != null && it.Condition > 0.0f && ri.MatchesItem(it)) == null)
canContinue = CheckItems(ri, character.SelectedItems);
if (!canContinue) { break; }
}
}
if (canContinue)
{
if (requiredItems.ContainsKey(RelatedItem.RelationType.Picked))
{
foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Picked])
{
#if CLIENT
if (addMessage && !string.IsNullOrEmpty(ri.Msg)) GUI.AddMessage(ri.Msg, Color.Red);
#endif
return false;
if (!CheckItems(ri, character.Inventory.Items)) { break; }
}
}
}
if (requiredItems.ContainsKey(RelatedItem.RelationType.Picked))
{
foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Picked])
{
if (character.Inventory.Items.FirstOrDefault(it => it != null && it.Condition > 0.0f && ri.MatchesItem(it)) == null)
{
#if CLIENT
if (!hasRequiredItems && addMessage && !string.IsNullOrEmpty(msg))
{
GUI.AddMessage(msg, Color.Red);
}
#endif
return false;
return hasRequiredItems;
bool CheckItems(RelatedItem relatedItem, IEnumerable<Item> itemList)
{
bool Predicate(Item it) => it != null && it.Condition > 0.0f && relatedItem.MatchesItem(it);
bool shouldBreak = false;
if (relatedItem.IsOptional)
{
if (!hasRequiredItems)
{
hasRequiredItems = itemList.Any(Predicate);
}
}
else
{
hasRequiredItems = itemList.Any(Predicate);
if (!hasRequiredItems)
{
shouldBreak = true;
}
}
if (!hasRequiredItems)
@@ -620,8 +638,6 @@ namespace Barotrauma.Items.Components
}
return !shouldBreak;
}
return true;
}
public void ApplyStatusEffects(ActionType type, float deltaTime, Character character = null, Limb targetLimb = null, Character user = null)
@@ -766,6 +782,7 @@ namespace Barotrauma.Items.Components
{
newRequiredItem.statusEffects = prevRequiredItem.statusEffects;
newRequiredItem.Msg = prevRequiredItem.Msg;
newRequiredItem.IsOptional = prevRequiredItem.IsOptional;
}
if (!requiredItems.ContainsKey(newRequiredItem.Type))
@@ -343,5 +343,7 @@ namespace Barotrauma.Items.Components
limbPositions[i] = new LimbPos(limbPositions[i].limbType, flippedPos);
}
}
partial void HideHUDs(bool value);
}
}
@@ -8,11 +8,19 @@ namespace Barotrauma.Items.Components
{
partial class CustomInterface : ItemComponent, IClientSerializable, IServerSerializable
{
class CustomInterfaceElement
class CustomInterfaceElement : ISerializableEntity
{
public bool ContinuousSignal;
public bool State;
public string Label, Connection, Signal;
public string Connection;
[Serialize("", false, translationTextTag = "Label.")]
public string Label { get; set; }
[Serialize("1", false)]
public string Signal { get; set; }
public string Name => "CustomInterfaceElement";
public Dictionary<string, SerializableProperty> SerializableProperties { get; set; }
public List<StatusEffect> StatusEffects = new List<StatusEffect>();
@@ -33,7 +41,7 @@ namespace Barotrauma.Items.Components
}
private string[] labels;
[Serialize("", true), Editable()]
[Serialize("", true)]
public string Labels
{
get { return string.Join(",", labels); }
@@ -48,7 +56,7 @@ namespace Barotrauma.Items.Components
}
}
private string[] signals;
[Serialize("", true), Editable()]
[Serialize("", true)]
public string Signals
{
//use semicolon as a separator because comma may be needed in the signals (for color or vector values for example)
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -66,6 +67,8 @@ namespace Barotrauma
public LightComponent LightComponent { get; set; }
public int Variant { get; set; }
private Gender _gender;
/// <summary>
/// None = Any/Not Defined -> no effect.
@@ -112,30 +115,65 @@ namespace Barotrauma
/// <summary>
/// Note: this constructor cannot initialize automatically, because the gender is unknown at this point. We only know it when the item is equipped.
/// </summary>
public WearableSprite(XElement subElement, Wearable wearable)
public WearableSprite(XElement subElement, Wearable wearable, int variant = 0)
{
Type = WearableType.Item;
WearableComponent = wearable;
Variant = Math.Max(variant, 0);
SpritePath = ParseSpritePath(subElement.GetAttributeString("texture", string.Empty));
SourceElement = subElement;
}
private string ParseSpritePath(string texturePath) => texturePath.Contains("/") ? texturePath : $"{Path.GetDirectoryName(WearableComponent.Item.Prefab.ConfigFile)}/{texturePath}";
public void RefreshPath()
{
if (Variant > 0)
{
// Restore the tag so that we can parse it again.
ReplaceNumbersWith("[VARIANT]");
}
ParsePath(true);
}
private void ReplaceNumbersWith(string replacement)
{
var fileName = Path.GetFileName(SpritePath);
var path = Path.GetDirectoryName(SpritePath);
fileName = fileName.Replace(replacement, c => char.IsNumber(c));
SpritePath = Path.Combine(path, fileName);
}
private void ParsePath(bool parseSpritePath)
{
if (_gender != Gender.None)
{
SpritePath = SpritePath.Replace("[GENDER]", (_gender == Gender.Female) ? "female" : "male");
}
SpritePath = SpritePath.Replace("[VARIANT]", Variant.ToString());
if (!File.Exists(SpritePath))
{
// If the variant does not exist, parse the path so that it uses first variant.
Variant = 1;
ReplaceNumbersWith(Variant.ToString());
}
if (parseSpritePath)
{
Sprite.ParseTexturePath(file: SpritePath);
}
}
public bool IsInitialized { get; private set; }
public void Init(Gender gender = Gender.None)
{
if (IsInitialized) { return; }
_gender = SpritePath.Contains("[GENDER]") ? gender : Gender.None;
if (_gender != Gender.None)
{
SpritePath = SpritePath.Replace("[GENDER]", (_gender == Gender.Female) ? "female" : "male");
}
ParsePath(false);
if (Sprite != null)
{
Sprite.Remove();
}
Sprite = new Sprite(SourceElement, "", SpritePath);
Sprite = new Sprite(SourceElement, file: SpritePath);
Limb = (LimbType)Enum.Parse(typeof(LimbType), SourceElement.GetAttributeString("limb", "Head"), true);
HideLimb = SourceElement.GetAttributeBool("hidelimb", false);
HideOtherWearables = SourceElement.GetAttributeBool("hideotherwearables", false);
@@ -170,7 +208,7 @@ namespace Barotrauma.Items.Components
get { return damageModifiers; }
}
public Wearable (Item item, XElement element) : base(item, element)
public Wearable(Item item, XElement element) : base(item, element)
{
this.item = item;
@@ -197,7 +235,7 @@ namespace Barotrauma.Items.Components
limbType[i] = (LimbType)Enum.Parse(typeof(LimbType),
subElement.GetAttributeString("limb", "Head"), true);
wearableSprites[i] = new WearableSprite(subElement, this);
wearableSprites[i] = new WearableSprite(subElement, this, variant);
foreach (XElement lightElement in subElement.Elements())
{