Unstable 0.1500.1.0 (BaroDev edition)
This commit is contained in:
@@ -623,6 +623,7 @@ namespace Barotrauma
|
|||||||
bool removeOnDeath = inc.ReadBoolean();
|
bool removeOnDeath = inc.ReadBoolean();
|
||||||
ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath);
|
ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath);
|
||||||
}
|
}
|
||||||
|
ch.ExperiencePoints = inc.ReadUInt16();
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using Microsoft.Xna.Framework;
|
namespace Barotrauma
|
||||||
using System.Collections.Generic;
|
|
||||||
using Barotrauma.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
|
||||||
{
|
{
|
||||||
partial class AfflictionHusk : Affliction
|
partial class AfflictionHusk : Affliction
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -632,7 +632,7 @@ namespace Barotrauma
|
|||||||
RefreshDeformations();
|
RefreshDeformations();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null)
|
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null, bool disableDeformations = false)
|
||||||
{
|
{
|
||||||
float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f;
|
float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f;
|
||||||
var spriteParams = Params.GetSprite();
|
var spriteParams = Params.GetSprite();
|
||||||
@@ -678,7 +678,7 @@ namespace Barotrauma
|
|||||||
if (!hideLimb)
|
if (!hideLimb)
|
||||||
{
|
{
|
||||||
var deformSprite = DeformSprite;
|
var deformSprite = DeformSprite;
|
||||||
if (deformSprite != null)
|
if (deformSprite != null && !disableDeformations)
|
||||||
{
|
{
|
||||||
if (ActiveDeformations.Any())
|
if (ActiveDeformations.Any())
|
||||||
{
|
{
|
||||||
@@ -999,10 +999,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
float textureScale = wearable.InheritTextureScale ? TextureScale : wearable.Scale;
|
float textureScale = wearable.InheritTextureScale ? TextureScale : wearable.Scale;
|
||||||
|
|
||||||
|
float rotation = -body.DrawRotation - wearable.Rotation * Dir;
|
||||||
|
|
||||||
wearable.Sprite.Draw(spriteBatch,
|
wearable.Sprite.Draw(spriteBatch,
|
||||||
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
||||||
new Color((color.R * wearableColor.R) / (255.0f * 255.0f), (color.G * wearableColor.G) / (255.0f * 255.0f), (color.B * wearableColor.B) / (255.0f * 255.0f)) * ((color.A * wearableColor.A) / (255.0f * 255.0f)),
|
new Color((color.R * wearableColor.R) / (255.0f * 255.0f), (color.G * wearableColor.G) / (255.0f * 255.0f), (color.B * wearableColor.B) / (255.0f * 255.0f)) * ((color.A * wearableColor.A) / (255.0f * 255.0f)),
|
||||||
origin, -body.DrawRotation,
|
origin, rotation,
|
||||||
Scale * textureScale, spriteEffect, depth);
|
Scale * textureScale, spriteEffect, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1320,11 +1320,13 @@ namespace Barotrauma
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float avgOutCondition = (deconstructItem.OutConditionMin + deconstructItem.OutConditionMax) / 2;
|
||||||
|
|
||||||
int? deconstructProductPrice = targetItem.GetMinPrice();
|
int? deconstructProductPrice = targetItem.GetMinPrice();
|
||||||
if (deconstructProductPrice.HasValue)
|
if (deconstructProductPrice.HasValue)
|
||||||
{
|
{
|
||||||
if (!deconstructProductCost.HasValue) { deconstructProductCost = 0; }
|
if (!deconstructProductCost.HasValue) { deconstructProductCost = 0; }
|
||||||
deconstructProductCost += (int)(deconstructProductPrice * deconstructItem.OutCondition);
|
deconstructProductCost += (int)(deconstructProductPrice * avgOutCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabricationRecipe != null)
|
if (fabricationRecipe != null)
|
||||||
@@ -1334,9 +1336,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
NewMessage("Deconstructing \"" + itemPrefab.Name + "\" produces \"" + deconstructItem.ItemIdentifier + "\", which isn't required in the fabrication recipe of the item.", Color.Red);
|
NewMessage("Deconstructing \"" + itemPrefab.Name + "\" produces \"" + deconstructItem.ItemIdentifier + "\", which isn't required in the fabrication recipe of the item.", Color.Red);
|
||||||
}
|
}
|
||||||
else if (ingredient.UseCondition && ingredient.MinCondition < deconstructItem.OutCondition)
|
else if (ingredient.UseCondition && ingredient.MinCondition < avgOutCondition)
|
||||||
{
|
{
|
||||||
NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {targetItem.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(deconstructItem.OutCondition * 100)}%)", Color.Red);
|
NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {targetItem.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(avgOutCondition * 100)}%)", Color.Red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,6 +251,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly bool isHorizontal;
|
private readonly bool isHorizontal;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setting this to true and CanBeFocused to false allows the list background to be unfocusable while the elements can still be interacted with.
|
||||||
|
/// </summary>
|
||||||
|
public bool CanInteractWhenUnfocusable { get; set; } = false;
|
||||||
|
|
||||||
/// <param name="isScrollBarOnDefaultSide">For horizontal listbox, default side is on the bottom. For vertical, it's on the right.</param>
|
/// <param name="isScrollBarOnDefaultSide">For horizontal listbox, default side is on the bottom. For vertical, it's on the right.</param>
|
||||||
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "", bool isScrollBarOnDefaultSide = true, bool useMouseDownToSelect = false) : base(style, rectT)
|
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "", bool isScrollBarOnDefaultSide = true, bool useMouseDownToSelect = false) : base(style, rectT)
|
||||||
{
|
{
|
||||||
@@ -570,7 +575,7 @@ namespace Barotrauma
|
|||||||
if (child == null || !child.Visible) { continue; }
|
if (child == null || !child.Visible) { continue; }
|
||||||
|
|
||||||
// selecting
|
// selecting
|
||||||
if (Enabled && CanBeFocused && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
|
if (Enabled && (CanBeFocused || CanInteractWhenUnfocusable) && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
|
||||||
{
|
{
|
||||||
child.State = ComponentState.Hover;
|
child.State = ComponentState.Hover;
|
||||||
|
|
||||||
|
|||||||
@@ -79,14 +79,14 @@ namespace Barotrauma
|
|||||||
new Rectangle(
|
new Rectangle(
|
||||||
sliderArea.X + (int)sliceBorderSizes.X,
|
sliderArea.X + (int)sliceBorderSizes.X,
|
||||||
sliderArea.Y,
|
sliderArea.Y,
|
||||||
(int)((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount),
|
(int)Math.Round((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount),
|
||||||
sliderArea.Height)
|
sliderArea.Height)
|
||||||
:
|
:
|
||||||
new Rectangle(
|
new Rectangle(
|
||||||
sliderArea.X,
|
sliderArea.X,
|
||||||
(int)(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W),
|
(int)Math.Round(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W),
|
||||||
sliderArea.Width,
|
sliderArea.Width,
|
||||||
(int)((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount));
|
(int)Math.Round((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount));
|
||||||
|
|
||||||
sliderRect.Width = Math.Max(sliderRect.Width, 1);
|
sliderRect.Width = Math.Max(sliderRect.Width, 1);
|
||||||
sliderRect.Height = Math.Max(sliderRect.Height, 1);
|
sliderRect.Height = Math.Max(sliderRect.Height, 1);
|
||||||
|
|||||||
@@ -1219,7 +1219,11 @@ namespace Barotrauma
|
|||||||
GUIFrame characterInfoFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.3f), talentInfoLayoutGroup.RectTransform, Anchor.TopLeft), style: null);
|
GUIFrame characterInfoFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.3f), talentInfoLayoutGroup.RectTransform, Anchor.TopLeft), style: null);
|
||||||
GUILayoutGroup characterInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), characterInfoFrame.RectTransform, anchor: Anchor.TopLeft), childAnchor: Anchor.TopLeft, isHorizontal: true);
|
GUILayoutGroup characterInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), characterInfoFrame.RectTransform, anchor: Anchor.TopLeft), childAnchor: Anchor.TopLeft, isHorizontal: true);
|
||||||
|
|
||||||
CreateCharacterSheet(characterInfoColumn);
|
// move to a different tab menu
|
||||||
|
if (GameSettings.VerboseLogging)
|
||||||
|
{
|
||||||
|
CreateCharacterSheet(characterInfoColumn);
|
||||||
|
}
|
||||||
|
|
||||||
if (!TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
|
if (!TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
|
||||||
|
|
||||||
@@ -1254,7 +1258,7 @@ namespace Barotrauma
|
|||||||
Stretch = true,
|
Stretch = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (Talent talent in talentOption.Talents)
|
foreach (TalentPrefab talent in talentOption.Talents)
|
||||||
{
|
{
|
||||||
int optionPadding = GUI.IntScale(10);
|
int optionPadding = GUI.IntScale(10);
|
||||||
GUIFrame talentFrame = new GUIFrame(new RectTransform(new Point(talentOptionFrame.Rect.Width, talentOptionFrame.Rect.Height - optionPadding), talentOptionLayoutGroup.RectTransform), style: null)
|
GUIFrame talentFrame = new GUIFrame(new RectTransform(new Point(talentOptionFrame.Rect.Width, talentOptionFrame.Rect.Height - optionPadding), talentOptionLayoutGroup.RectTransform), style: null)
|
||||||
@@ -1269,13 +1273,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUIButton talentButton = new GUIButton(new RectTransform(Vector2.One, talentFrame.RectTransform, anchor: Anchor.Center), style: "TalentFrame")
|
GUIButton talentButton = new GUIButton(new RectTransform(Vector2.One, talentFrame.RectTransform, anchor: Anchor.Center), style: "TalentFrame")
|
||||||
{
|
{
|
||||||
ToolTip = $"{TextManager.Get("talentname." + talent.Identifier, returnNull: true) ?? talent.Identifier} \n\n{TextManager.Get("talentdescription." + talent.Identifier, returnNull: true) ?? string.Empty}",
|
ToolTip = $"{talent.DisplayName}\n\n{talent.Description}",
|
||||||
UserData = talent.Identifier,
|
UserData = talent.Identifier,
|
||||||
PressedColor = pressedColor,
|
PressedColor = pressedColor,
|
||||||
OnClicked = (button, userData) =>
|
OnClicked = (button, userData) =>
|
||||||
{
|
{
|
||||||
talentTitleText.Text = TextManager.Get("talentname." + talent.Identifier, returnNull: true) ?? string.Empty;
|
talentTitleText.Text = talent.DisplayName;
|
||||||
talentDescriptionText.Text = TextManager.Get("talentdescription." + talent.Identifier, returnNull: true) ?? string.Empty;
|
talentDescriptionText.Text = talent.Description;
|
||||||
|
|
||||||
// deselect other buttons in tier by removing their selected talents from pool
|
// deselect other buttons in tier by removing their selected talents from pool
|
||||||
foreach (GUIButton guiButton in talentOptionLayoutGroup.GetAllChildren<GUIButton>())
|
foreach (GUIButton guiButton in talentOptionLayoutGroup.GetAllChildren<GUIButton>())
|
||||||
@@ -1440,10 +1444,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly StatTypes[] combatStats = new StatTypes[]
|
private readonly StatTypes[] combatStats = new StatTypes[]
|
||||||
{
|
{
|
||||||
StatTypes.MaximumHealthMultiplier,
|
StatTypes.MeleeAttackMultiplier,
|
||||||
StatTypes.MovementSpeed,
|
StatTypes.MeleeAttackSpeed,
|
||||||
StatTypes.SwimmingSpeed,
|
StatTypes.RangedAttackSpeed,
|
||||||
StatTypes.RepairSpeed,
|
StatTypes.TurretAttackSpeed,
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly StatTypes[] miscStats = new StatTypes[]
|
private readonly StatTypes[] miscStats = new StatTypes[]
|
||||||
|
|||||||
@@ -99,7 +99,9 @@ namespace Barotrauma
|
|||||||
crewList = new GUIListBox(new RectTransform(Vector2.One, crewArea.RectTransform), style: null, isScrollBarOnDefaultSide: false)
|
crewList = new GUIListBox(new RectTransform(Vector2.One, crewArea.RectTransform), style: null, isScrollBarOnDefaultSide: false)
|
||||||
{
|
{
|
||||||
AutoHideScrollBar = false,
|
AutoHideScrollBar = false,
|
||||||
|
CanBeFocused = false,
|
||||||
CanDragElements = true,
|
CanDragElements = true,
|
||||||
|
CanInteractWhenUnfocusable = true,
|
||||||
OnSelected = (component, userData) => false,
|
OnSelected = (component, userData) => false,
|
||||||
SelectMultiple = false,
|
SelectMultiple = false,
|
||||||
Spacing = (int)(GUI.Scale * 10),
|
Spacing = (int)(GUI.Scale * 10),
|
||||||
@@ -770,7 +772,7 @@ namespace Barotrauma
|
|||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
{
|
{
|
||||||
character.SetOrder(order, option, priority, orderGiver, speak: orderGiver != character);
|
character.SetOrder(order, option, priority, orderGiver, speak: orderGiver != character);
|
||||||
string message = order?.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority);
|
string message = order?.GetChatMessage(character.Name, orderGiver?.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority);
|
||||||
orderGiver?.Speak(message);
|
orderGiver?.Speak(message);
|
||||||
}
|
}
|
||||||
else if (orderGiver != null)
|
else if (orderGiver != null)
|
||||||
@@ -1905,13 +1907,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanSomeoneHearCharacter()
|
private bool CanCharacterBeHeard()
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (Character.Controlled == null) { return true; }
|
if (Character.Controlled == null) { return true; }
|
||||||
#endif
|
#endif
|
||||||
return Character.Controlled != null &&
|
if (Character.Controlled != null)
|
||||||
(characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)));
|
{
|
||||||
|
if (characterContext == null)
|
||||||
|
{
|
||||||
|
return characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return characterContext.CanHearCharacter(Character.Controlled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entity FindEntityContext()
|
private Entity FindEntityContext()
|
||||||
@@ -2580,7 +2592,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < orders.Count; i++)
|
for (int i = 0; i < orders.Count; i++)
|
||||||
{
|
{
|
||||||
order = orders[i];
|
order = orders[i];
|
||||||
disableNode = !CanSomeoneHearCharacter() ||
|
disableNode = !CanCharacterBeHeard() ||
|
||||||
(order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) &&
|
(order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) &&
|
||||||
order.GetMatchingItems(true, interactableFor: characterContext ?? Character.Controlled).None());
|
order.GetMatchingItems(true, interactableFor: characterContext ?? Character.Controlled).None());
|
||||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||||
@@ -2728,7 +2740,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count));
|
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count));
|
||||||
bool disableNode = !CanSomeoneHearCharacter();
|
bool disableNode = !CanCharacterBeHeard();
|
||||||
for (int i = 0; i < contextualOrders.Count; i++)
|
for (int i = 0; i < contextualOrders.Count; i++)
|
||||||
{
|
{
|
||||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||||
@@ -2766,7 +2778,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (checkIfOrderCanBeHeard && !disableNode)
|
if (checkIfOrderCanBeHeard && !disableNode)
|
||||||
{
|
{
|
||||||
disableNode = !CanSomeoneHearCharacter();
|
disableNode = !CanCharacterBeHeard();
|
||||||
}
|
}
|
||||||
|
|
||||||
var mustSetOptionOrTarget = order.HasOptions;
|
var mustSetOptionOrTarget = order.HasOptions;
|
||||||
@@ -2827,7 +2839,7 @@ namespace Barotrauma
|
|||||||
if (disableNode)
|
if (disableNode)
|
||||||
{
|
{
|
||||||
node.CanBeFocused = icon.CanBeFocused = false;
|
node.CanBeFocused = icon.CanBeFocused = false;
|
||||||
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get("nocharactercanhear"));
|
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get(characterContext == null ? "nocharactercanhear" : "thischaractercanthear"));
|
||||||
}
|
}
|
||||||
else if (hotkey >= 0)
|
else if (hotkey >= 0)
|
||||||
{
|
{
|
||||||
@@ -2999,11 +3011,11 @@ namespace Barotrauma
|
|||||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") +
|
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") +
|
||||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip"));
|
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip"));
|
||||||
}
|
}
|
||||||
if (!CanSomeoneHearCharacter())
|
if (!CanCharacterBeHeard())
|
||||||
{
|
{
|
||||||
node.CanBeFocused = false;
|
node.CanBeFocused = false;
|
||||||
if (icon != null) { icon.CanBeFocused = false; }
|
if (icon != null) { icon.CanBeFocused = false; }
|
||||||
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get("nocharactercanhear"));
|
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get(characterContext == null ? "nocharactercanhear" : "thischaractercanthear"));
|
||||||
}
|
}
|
||||||
else if (hotkey >= 0)
|
else if (hotkey >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -174,6 +174,12 @@ namespace Barotrauma
|
|||||||
(int)SlotPositions[i].X,
|
(int)SlotPositions[i].X,
|
||||||
(int)SlotPositions[i].Y,
|
(int)SlotPositions[i].Y,
|
||||||
(int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier));
|
(int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier));
|
||||||
|
|
||||||
|
if (SlotTypes[i] == InvSlotType.HealthInterface &&
|
||||||
|
character.CharacterHealth?.InventorySlotContainer != null)
|
||||||
|
{
|
||||||
|
slotRect.Width = slotRect.Height = (int)(character.CharacterHealth.InventorySlotContainer.Rect.Width * 1.2f);
|
||||||
|
}
|
||||||
|
|
||||||
ItemContainer itemContainer = slots[i].FirstOrDefault()?.GetComponent<ItemContainer>();
|
ItemContainer itemContainer = slots[i].FirstOrDefault()?.GetComponent<ItemContainer>();
|
||||||
if (itemContainer != null)
|
if (itemContainer != null)
|
||||||
@@ -238,6 +244,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (visualSlots[i].Disabled || (slots[i].HideIfEmpty && slots[i].Empty())) { return true; }
|
if (visualSlots[i].Disabled || (slots[i].HideIfEmpty && slots[i].Empty())) { return true; }
|
||||||
|
|
||||||
|
if (CharacterHealth.OpenHealthWindow != Character.Controlled?.CharacterHealth && SlotTypes[i] == InvSlotType.HealthInterface) { return true; }
|
||||||
|
|
||||||
if (layout == Layout.Default)
|
if (layout == Layout.Default)
|
||||||
{
|
{
|
||||||
if (PersonalSlots.HasFlag(SlotTypes[i]) && !personalSlotArea.Contains(visualSlots[i].Rect.Center + visualSlots[i].DrawOffset.ToPoint())) { return true; }
|
if (PersonalSlots.HasFlag(SlotTypes[i]) && !personalSlotArea.Contains(visualSlots[i].Rect.Center + visualSlots[i].DrawOffset.ToPoint())) { return true; }
|
||||||
@@ -359,7 +367,7 @@ namespace Barotrauma
|
|||||||
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing;
|
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing;
|
||||||
for (int i = 0; i < visualSlots.Length; i++)
|
for (int i = 0; i < visualSlots.Length; i++)
|
||||||
{
|
{
|
||||||
if (HideSlot(i)) { continue; }
|
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
|
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
|
||||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||||
{
|
{
|
||||||
@@ -383,7 +391,7 @@ namespace Barotrauma
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HideSlot(i)) { continue; }
|
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||||
{
|
{
|
||||||
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
|
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
|
||||||
@@ -399,7 +407,7 @@ namespace Barotrauma
|
|||||||
x = lowerX;
|
x = lowerX;
|
||||||
for (int i = 0; i < SlotPositions.Length; i++)
|
for (int i = 0; i < SlotPositions.Length; i++)
|
||||||
{
|
{
|
||||||
if (!HideSlot(i)) { continue; }
|
if (!HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
|
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
|
||||||
x -= visualSlots[i].Rect.Width + Spacing;
|
x -= visualSlots[i].Rect.Width + Spacing;
|
||||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||||
@@ -414,7 +422,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
for (int i = 0; i < SlotPositions.Length; i++)
|
for (int i = 0; i < SlotPositions.Length; i++)
|
||||||
{
|
{
|
||||||
if (HideSlot(i)) { continue; }
|
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
|
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
|
||||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||||
{
|
{
|
||||||
@@ -436,7 +444,7 @@ namespace Barotrauma
|
|||||||
SlotPositions[i] = new Vector2(rightSlot ? handSlotX : handSlotX - visualSlots[0].Rect.Width - Spacing, personalSlotY);
|
SlotPositions[i] = new Vector2(rightSlot ? handSlotX : handSlotX - visualSlots[0].Rect.Width - Spacing, personalSlotY);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!HideSlot(i)) { continue; }
|
if (!HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||||
x += visualSlots[i].Rect.Width + Spacing;
|
x += visualSlots[i].Rect.Width + Spacing;
|
||||||
}
|
}
|
||||||
@@ -450,7 +458,7 @@ namespace Barotrauma
|
|||||||
int x = startX, y = startY;
|
int x = startX, y = startY;
|
||||||
for (int i = 0; i < SlotPositions.Length; i++)
|
for (int i = 0; i < SlotPositions.Length; i++)
|
||||||
{
|
{
|
||||||
if (HideSlot(i)) continue;
|
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes)
|
if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes)
|
||||||
{
|
{
|
||||||
SlotPositions[i] = new Vector2(x, y);
|
SlotPositions[i] = new Vector2(x, y);
|
||||||
@@ -462,7 +470,7 @@ namespace Barotrauma
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
for (int i = 0; i < SlotPositions.Length; i++)
|
for (int i = 0; i < SlotPositions.Length; i++)
|
||||||
{
|
{
|
||||||
if (HideSlot(i)) continue;
|
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes)
|
if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes)
|
||||||
{
|
{
|
||||||
SlotPositions[i] = new Vector2(x, y);
|
SlotPositions[i] = new Vector2(x, y);
|
||||||
@@ -479,13 +487,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (character.CharacterHealth?.UseHealthWindow ?? false)
|
||||||
|
{
|
||||||
|
Vector2 pos = character.CharacterHealth.InventorySlotContainer.Rect.Location.ToVector2();
|
||||||
|
for (int i = 0; i < capacity; i++)
|
||||||
|
{
|
||||||
|
if (SlotTypes[i] != InvSlotType.HealthInterface) { continue; }
|
||||||
|
SlotPositions[i] = pos;
|
||||||
|
pos.Y += visualSlots[i].Rect.Height + Spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CreateSlots();
|
CreateSlots();
|
||||||
if (layout == Layout.Default)
|
if (layout == Layout.Default)
|
||||||
{
|
{
|
||||||
HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ControlInput(Camera cam)
|
protected override void ControlInput(Camera cam)
|
||||||
@@ -679,7 +697,7 @@ namespace Barotrauma
|
|||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
var slot = visualSlots[i];
|
var slot = visualSlots[i];
|
||||||
if (item.AllowedSlots.Any(a => a != InvSlotType.Any))
|
if (item.AllowedSlots.Any(a => a != InvSlotType.Any && a != InvSlotType.HealthInterface))
|
||||||
{
|
{
|
||||||
HandleButtonEquipStates(item, slot, deltaTime);
|
HandleButtonEquipStates(item, slot, deltaTime);
|
||||||
}
|
}
|
||||||
@@ -858,7 +876,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private QuickUseAction GetQuickUseAction(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment)
|
private QuickUseAction GetQuickUseAction(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment)
|
||||||
{
|
{
|
||||||
if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null)
|
if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null &&
|
||||||
|
//if the item can be equipped in the health interface slot, don't use it as a treatment but try to equip it
|
||||||
|
!item.AllowedSlots.Contains(InvSlotType.HealthInterface))
|
||||||
{
|
{
|
||||||
return QuickUseAction.UseTreatment;
|
return QuickUseAction.UseTreatment;
|
||||||
}
|
}
|
||||||
@@ -1153,7 +1173,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
for (int i = 0; i < capacity; i++)
|
for (int i = 0; i < capacity; i++)
|
||||||
{
|
{
|
||||||
if (HideSlot(i)) { continue; }
|
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
|
||||||
|
|
||||||
//don't draw the item if it's being dragged out of the slot
|
//don't draw the item if it's being dragged out of the slot
|
||||||
bool drawItem = !DraggingItems.Any() || !slots[i].Items.All(it => DraggingItems.Contains(it)) || visualSlots[i].MouseOn();
|
bool drawItem = !DraggingItems.Any() || !slots[i].Items.All(it => DraggingItems.Contains(it)) || visualSlots[i].MouseOn();
|
||||||
@@ -1207,7 +1227,7 @@ namespace Barotrauma
|
|||||||
highlightedQuickUseSlot = visualSlots[i];
|
highlightedQuickUseSlot = visualSlots[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any))
|
if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any) || SlotTypes[i] == InvSlotType.HealthInterface)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using Barotrauma.Networking;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Items.Components
|
||||||
|
{
|
||||||
|
partial class GeneticMaterial : ItemComponent
|
||||||
|
{
|
||||||
|
[Serialize(0.0f, false)]
|
||||||
|
public float TooltipValueMin { get; set; }
|
||||||
|
|
||||||
|
[Serialize(0.0f, false)]
|
||||||
|
public float TooltipValueMax { get; set; }
|
||||||
|
|
||||||
|
public override void AddTooltipInfo(ref string name, ref string description)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(materialName))
|
||||||
|
{
|
||||||
|
string mergedMaterialName = materialName;
|
||||||
|
foreach (Item containedItem in item.ContainedItems)
|
||||||
|
{
|
||||||
|
var containedMaterial = containedItem.GetComponent<GeneticMaterial>();
|
||||||
|
if (containedMaterial == null) { continue; }
|
||||||
|
mergedMaterialName += ", " + containedMaterial.materialName;
|
||||||
|
}
|
||||||
|
name = TextManager.GetWithVariable("entityname.geneticmaterial", "[type]", mergedMaterialName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Tainted)
|
||||||
|
{
|
||||||
|
name = TextManager.GetWithVariable("entityname.taintedgeneticmaterial", "[geneticmaterialname]", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TextManager.ContainsTag("entitydescription."+Item.prefab.Identifier))
|
||||||
|
{
|
||||||
|
int value = (int)MathHelper.Lerp(TooltipValueMin, TooltipValueMax, item.ConditionPercentage / 100.0f);
|
||||||
|
description = TextManager.GetWithVariable("entitydescription." + Item.prefab.Identifier, "[value]", value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ModifyDeconstructInfo(Deconstructor deconstructor, ref string buttonText, ref string infoText)
|
||||||
|
{
|
||||||
|
if (deconstructor.InputContainer.Inventory.AllItems.Count() == 2)
|
||||||
|
{
|
||||||
|
if (!deconstructor.InputContainer.Inventory.AllItems.All(it => it.prefab == item.prefab))
|
||||||
|
{
|
||||||
|
buttonText = TextManager.Get("researchstation.combine");
|
||||||
|
infoText = TextManager.Get("researchstation.combine.infotext");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buttonText = TextManager.Get("researchstation.refine");
|
||||||
|
int taintedProbability = (int)(GetTaintedProbabilityOnRefine(Character.Controlled) * 100);
|
||||||
|
infoText = TextManager.GetWithVariable("researchstation.refine.infotext", "[taintedprobability]", taintedProbability.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
|
{
|
||||||
|
Tainted = msg.ReadBoolean();
|
||||||
|
if (Tainted)
|
||||||
|
{
|
||||||
|
uint selectedTaintedEffectId = msg.ReadUInt32();
|
||||||
|
selectedTaintedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedTaintedEffectId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint selectedEffectId = msg.ReadUInt32();
|
||||||
|
selectedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedEffectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -621,6 +621,6 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
OnResolutionChanged();
|
OnResolutionChanged();
|
||||||
}
|
}
|
||||||
public virtual void AddTooltipInfo(ref string description) { }
|
public virtual void AddTooltipInfo(ref string name, ref string description) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ namespace Barotrauma.Items.Components
|
|||||||
[Serialize(null, false)]
|
[Serialize(null, false)]
|
||||||
public string ContainedStateIndicatorStyle { get; set; }
|
public string ContainedStateIndicatorStyle { get; set; }
|
||||||
|
|
||||||
|
[Serialize(-1, false, description: "Can be used to make the contained state indicator display the condition of the item in a specific slot even when the container's capacity is more than 1.")]
|
||||||
|
public int ContainedStateIndicatorSlot { get; set; }
|
||||||
|
|
||||||
[Serialize(true, false, description: "Should an indicator displaying the state of the contained items be displayed on this item's inventory slot. "+
|
[Serialize(true, false, description: "Should an indicator displaying the state of the contained items be displayed on this item's inventory slot. "+
|
||||||
"If this item can only contain one item, the indicator will display the condition of the contained item, otherwise it will indicate how full the item is.")]
|
"If this item can only contain one item, the indicator will display the condition of the contained item, otherwise it will indicate how full the item is.")]
|
||||||
public bool ShowContainedStateIndicator { get; set; }
|
public bool ShowContainedStateIndicator { get; set; }
|
||||||
|
|||||||
+97
-13
@@ -14,12 +14,19 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
private GUIButton activateButton;
|
private GUIButton activateButton;
|
||||||
private GUIComponent inputInventoryHolder, outputInventoryHolder;
|
private GUIComponent inputInventoryHolder, outputInventoryHolder;
|
||||||
private GUICustomComponent inputInventoryOverlay;
|
|
||||||
|
|
||||||
private GUIComponent inSufficientPowerWarning;
|
private GUIComponent inSufficientPowerWarning;
|
||||||
|
|
||||||
private bool pendingState;
|
private bool pendingState;
|
||||||
|
|
||||||
|
private GUITextBlock infoArea;
|
||||||
|
|
||||||
|
[Serialize("DeconstructorDeconstruct", true)]
|
||||||
|
public string ActivateButtonText { get; set; }
|
||||||
|
|
||||||
|
[Serialize(0.0f, true)]
|
||||||
|
public float InfoAreaWidth { get; set; }
|
||||||
|
|
||||||
partial void InitProjSpecific(XElement element)
|
partial void InitProjSpecific(XElement element)
|
||||||
{
|
{
|
||||||
CreateGUI();
|
CreateGUI();
|
||||||
@@ -39,6 +46,12 @@ namespace Barotrauma.Items.Components
|
|||||||
RelativeSpacing = 0.08f
|
RelativeSpacing = 0.08f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1f, 0.07f), paddedFrame.RectTransform), item.Name, font: GUI.SubHeadingFont)
|
||||||
|
{
|
||||||
|
TextAlignment = Alignment.Center,
|
||||||
|
AutoScaleHorizontal = true
|
||||||
|
};
|
||||||
|
|
||||||
var topFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null);
|
var topFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null);
|
||||||
|
|
||||||
// === INPUT LABEL === //
|
// === INPUT LABEL === //
|
||||||
@@ -55,22 +68,23 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
// === INPUT SLOTS === //
|
// === INPUT SLOTS === //
|
||||||
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null);
|
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null);
|
||||||
inputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false };
|
new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false };
|
||||||
|
|
||||||
// === ACTIVATE BUTTON === //
|
// === ACTIVATE BUTTON === //
|
||||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.7f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft);
|
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft);
|
||||||
activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton")
|
activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton")
|
||||||
{
|
{
|
||||||
TextBlock = { AutoScaleHorizontal = true },
|
TextBlock = { AutoScaleHorizontal = true },
|
||||||
OnClicked = ToggleActive
|
OnClicked = ToggleActive
|
||||||
};
|
};
|
||||||
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform),
|
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform),
|
||||||
TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
|
TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow", wrap: true)
|
||||||
{
|
{
|
||||||
HoverColor = Color.Black,
|
HoverColor = Color.Black,
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
Visible = false,
|
Visible = false,
|
||||||
CanBeFocused = false
|
CanBeFocused = false,
|
||||||
|
AutoScaleHorizontal = true
|
||||||
};
|
};
|
||||||
|
|
||||||
// === OUTPUT AREA === //
|
// === OUTPUT AREA === //
|
||||||
@@ -86,8 +100,62 @@ namespace Barotrauma.Items.Components
|
|||||||
outputLabel.RectTransform.Resize(new Point((int) outputLabel.Font.MeasureString(outputLabel.Text).X, outputLabel.RectTransform.Rect.Height));
|
outputLabel.RectTransform.Resize(new Point((int) outputLabel.Font.MeasureString(outputLabel.Text).X, outputLabel.RectTransform.Rect.Height));
|
||||||
new GUIFrame(new RectTransform(Vector2.One, outputLabelArea.RectTransform), style: "HorizontalLine");
|
new GUIFrame(new RectTransform(Vector2.One, outputLabelArea.RectTransform), style: "HorizontalLine");
|
||||||
|
|
||||||
|
var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), bottomFrame.RectTransform, Anchor.CenterLeft), childAnchor: Anchor.BottomLeft, isHorizontal: true) { Stretch = true, RelativeSpacing = 0.05f };
|
||||||
|
|
||||||
// === OUTPUT SLOTS === //
|
// === OUTPUT SLOTS === //
|
||||||
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1f), bottomFrame.RectTransform, Anchor.CenterLeft), style: null);
|
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f - InfoAreaWidth, 1f), outputArea.RectTransform, Anchor.CenterLeft), style: null);
|
||||||
|
|
||||||
|
if (InfoAreaWidth >= 0.0f)
|
||||||
|
{
|
||||||
|
var infoAreaContainer = new GUILayoutGroup(new RectTransform(new Vector2(InfoAreaWidth, 0.8f), outputArea.RectTransform), childAnchor: Anchor.CenterLeft);
|
||||||
|
infoArea = new GUITextBlock(new RectTransform(new Vector2(0.95f, 0.95f), infoAreaContainer.RectTransform), string.Empty, wrap: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivateButton.OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||||
|
{
|
||||||
|
activateButton.Enabled = true;
|
||||||
|
infoArea.Text = string.Empty;
|
||||||
|
if (IsActive)
|
||||||
|
{
|
||||||
|
activateButton.Text = TextManager.Get("DeconstructorCancel");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool outputsFound = false;
|
||||||
|
foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: true))
|
||||||
|
{
|
||||||
|
outputsFound = true;
|
||||||
|
if (!string.IsNullOrEmpty(deconstructItem.ActivateButtonText))
|
||||||
|
{
|
||||||
|
string buttonText = TextManager.Get(deconstructItem.ActivateButtonText, returnNull: true) ?? deconstructItem.ActivateButtonText;
|
||||||
|
string infoText = string.Empty;
|
||||||
|
if (!string.IsNullOrEmpty(deconstructItem.InfoText))
|
||||||
|
{
|
||||||
|
infoText = TextManager.Get(deconstructItem.InfoText, returnNull: true) ?? deconstructItem.InfoText;
|
||||||
|
}
|
||||||
|
inputItem.GetComponent<GeneticMaterial>()?.ModifyDeconstructInfo(this, ref buttonText, ref infoText);
|
||||||
|
activateButton.Text = buttonText;
|
||||||
|
if (infoArea != null)
|
||||||
|
{
|
||||||
|
infoArea.Text = infoText;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//no valid outputs found: check if we're missing some required items from the input slots and display a message about it if possible
|
||||||
|
if (!outputsFound && infoArea != null)
|
||||||
|
{
|
||||||
|
foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: false))
|
||||||
|
{
|
||||||
|
if (deconstructItem.RequiredOtherItem.Any() && !string.IsNullOrEmpty(deconstructItem.InfoTextOnOtherItemMissing))
|
||||||
|
{
|
||||||
|
string missingItemName = TextManager.Get("entityname." + deconstructItem.RequiredOtherItem.First(), returnNull: true);
|
||||||
|
infoArea.Text = TextManager.GetWithVariable(deconstructItem.InfoTextOnOtherItemMissing, "[itemname]", missingItemName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
activateButton.Enabled = inputContainer.Inventory.AllItems.Any();
|
||||||
|
activateButton.Text = TextManager.Get(ActivateButtonText);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Select(Character character)
|
public override bool Select(Character character)
|
||||||
@@ -126,14 +194,30 @@ namespace Barotrauma.Items.Components
|
|||||||
private void DrawOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
private void DrawOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
||||||
{
|
{
|
||||||
overlayComponent.RectTransform.SetAsLastChild();
|
overlayComponent.RectTransform.SetAsLastChild();
|
||||||
if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) { return; }
|
|
||||||
var lastSlot = visualSlots.Last();
|
|
||||||
|
|
||||||
GUI.DrawRectangle(spriteBatch,
|
if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) { return; }
|
||||||
new Rectangle(
|
|
||||||
lastSlot.Rect.X, lastSlot.Rect.Y + (int)(lastSlot.Rect.Height * (1.0f - progressState)),
|
if (DeconstructItemsSimultaneously)
|
||||||
lastSlot.Rect.Width, (int)(lastSlot.Rect.Height * progressState)),
|
{
|
||||||
GUI.Style.Green * 0.5f, isFilled: true);
|
for (int i = 0; i < InputContainer.Inventory.Capacity; i++)
|
||||||
|
{
|
||||||
|
if (InputContainer.Inventory.GetItemAt(i) == null) { continue; }
|
||||||
|
DrawProgressBar(InputContainer.Inventory.visualSlots[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawProgressBar(inputContainer.Inventory.visualSlots.Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawProgressBar(VisualSlot slot)
|
||||||
|
{
|
||||||
|
GUI.DrawRectangle(spriteBatch,
|
||||||
|
new Rectangle(
|
||||||
|
slot.Rect.X, slot.Rect.Y + (int)(slot.Rect.Height * (1.0f - progressState)),
|
||||||
|
slot.Rect.Width, (int)(slot.Rect.Height * progressState)),
|
||||||
|
GUI.Style.Green * 0.5f, isFilled: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ namespace Barotrauma.Items.Components
|
|||||||
scissorComponent = new GUIScissorComponent(new RectTransform(Vector2.One, submarineContainer.RectTransform, Anchor.Center));
|
scissorComponent = new GUIScissorComponent(new RectTransform(Vector2.One, submarineContainer.RectTransform, Anchor.Center));
|
||||||
miniMapContainer = new GUIFrame(new RectTransform(Vector2.One, scissorComponent.Content.RectTransform, Anchor.Center), style: null) { CanBeFocused = false };
|
miniMapContainer = new GUIFrame(new RectTransform(Vector2.One, scissorComponent.Content.RectTransform, Anchor.Center), style: null) { CanBeFocused = false };
|
||||||
|
|
||||||
miniMapFrame = CreateMiniMap(item.Submarine, miniMapContainer, MiniMapSettings.Default, null, out hullStatusComponents);
|
miniMapFrame = CreateMiniMap(item.Submarine, submarineContainer, MiniMapSettings.Default, null, out hullStatusComponents);
|
||||||
|
|
||||||
IEnumerable<Item> pointsOfInterest = Item.ItemList.Where(it => it.Submarine == item.Submarine && !it.HiddenInGame && !it.NonInteractable && it.GetComponent<Repairable>() != null);
|
IEnumerable<Item> pointsOfInterest = Item.ItemList.Where(it => it.Submarine == item.Submarine && !it.HiddenInGame && !it.NonInteractable && it.GetComponent<Repairable>() != null);
|
||||||
electricalFrame = CreateMiniMap(item.Submarine, miniMapContainer, new MiniMapSettings(createHullElements: false), pointsOfInterest, out electricalMapComponents);
|
electricalFrame = CreateMiniMap(item.Submarine, miniMapContainer, new MiniMapSettings(createHullElements: false), pointsOfInterest, out electricalMapComponents);
|
||||||
@@ -458,7 +458,7 @@ namespace Barotrauma.Items.Components
|
|||||||
CreateHUD();
|
CreateHUD();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PlayerInput.PrimaryMouseButtonDown())
|
if (PlayerInput.PrimaryMouseButtonDown() && currentMode != MiniMapMode.HullStatus)
|
||||||
{
|
{
|
||||||
if (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn))
|
if (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn))
|
||||||
{
|
{
|
||||||
@@ -466,20 +466,16 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float newZoom = Zoom;
|
|
||||||
|
|
||||||
if (Math.Abs(PlayerInput.ScrollWheelSpeed) > 0 && (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn)))
|
if (currentMode != MiniMapMode.HullStatus && Math.Abs(PlayerInput.ScrollWheelSpeed) > 0 && (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn)))
|
||||||
{
|
{
|
||||||
newZoom = Math.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f * Zoom, minZoom, maxZoom);
|
float newZoom = Math.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f * Zoom, minZoom, maxZoom);
|
||||||
float distanceScale = newZoom / Zoom;
|
float distanceScale = newZoom / Zoom;
|
||||||
mapOffset *= distanceScale;
|
mapOffset *= distanceScale;
|
||||||
|
recalculate |= !MathUtils.NearlyEqual(Zoom, newZoom);
|
||||||
|
Zoom = newZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
recalculate |= !MathUtils.NearlyEqual(Zoom, newZoom);
|
|
||||||
Zoom = newZoom;
|
|
||||||
|
|
||||||
Vector2 elementScale = new Vector2(Zoom);
|
|
||||||
|
|
||||||
if (dragMapStart is { } dragStart)
|
if (dragMapStart is { } dragStart)
|
||||||
{
|
{
|
||||||
if (dragMap || Vector2.DistanceSquared(dragStart, PlayerInput.MousePosition) > GUI.IntScale(dragTreshold * dragTreshold))
|
if (dragMap || Vector2.DistanceSquared(dragStart, PlayerInput.MousePosition) > GUI.IntScale(dragTreshold * dragTreshold))
|
||||||
@@ -487,16 +483,11 @@ namespace Barotrauma.Items.Components
|
|||||||
mapOffset.X += PlayerInput.MouseSpeed.X;
|
mapOffset.X += PlayerInput.MouseSpeed.X;
|
||||||
mapOffset.Y += PlayerInput.MouseSpeed.Y;
|
mapOffset.Y += PlayerInput.MouseSpeed.Y;
|
||||||
|
|
||||||
recalculate |= PlayerInput.MouseSpeed != Vector2.Zero;
|
recalculate = true;
|
||||||
dragMap = true;
|
dragMap = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (maxWidth, maxHeight) = miniMapContainer.Rect.Size.ToVector2() / 2f / Zoom;
|
|
||||||
|
|
||||||
mapOffset.X = Math.Clamp(mapOffset.X, -maxWidth, maxWidth);
|
|
||||||
mapOffset.Y = Math.Clamp(mapOffset.Y, -maxHeight, maxHeight);
|
|
||||||
|
|
||||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||||
{
|
{
|
||||||
dragMapStart = null;
|
dragMapStart = null;
|
||||||
@@ -505,10 +496,15 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (recalculate)
|
if (recalculate)
|
||||||
{
|
{
|
||||||
miniMapContainer.RectTransform.LocalScale = elementScale;
|
miniMapContainer.RectTransform.LocalScale = new Vector2(Zoom);
|
||||||
miniMapContainer.RectTransform.RecalculateChildren(true, true);
|
miniMapContainer.RectTransform.RecalculateChildren(true, true);
|
||||||
miniMapContainer.RectTransform.AbsoluteOffset = mapOffset.ToPoint();
|
miniMapContainer.RectTransform.AbsoluteOffset = mapOffset.ToPoint();
|
||||||
recalculate = false;
|
recalculate = false;
|
||||||
|
|
||||||
|
var (maxWidth, maxHeight) = miniMapContainer.Rect.Size.ToVector2() / 2f / Zoom;
|
||||||
|
|
||||||
|
mapOffset.X = Math.Clamp(mapOffset.X, -maxWidth, maxWidth);
|
||||||
|
mapOffset.Y = Math.Clamp(mapOffset.Y, -maxHeight, maxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// is there a better way to do this?
|
// is there a better way to do this?
|
||||||
@@ -583,6 +579,7 @@ namespace Barotrauma.Items.Components
|
|||||||
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
|
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||||
{
|
{
|
||||||
// TODO remove
|
// TODO remove
|
||||||
|
#warning remove
|
||||||
if (currentMode == MiniMapMode.HullCondition)
|
if (currentMode == MiniMapMode.HullCondition)
|
||||||
{
|
{
|
||||||
const string wipText = "work in progress";
|
const string wipText = "work in progress";
|
||||||
@@ -757,7 +754,7 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (Item foundItem in foundItems)
|
foreach (Item foundItem in foundItems)
|
||||||
{
|
{
|
||||||
RelativeEntityRect scaledRect = new RelativeEntityRect(dockedBorders, foundItem.WorldRect);
|
RelativeEntityRect scaledRect = new RelativeEntityRect(dockedBorders, foundItem.WorldRect);
|
||||||
Vector2 pos = (scaledRect.PositionRelativeTo(parentRect, skipOffset: true) + scaledRect.SizeRelativeTo(parentRect) / 2f) / Zoom;
|
Vector2 pos = scaledRect.PositionRelativeTo(parentRect, skipOffset: true) + scaledRect.SizeRelativeTo(parentRect) / 2f;
|
||||||
positions.Add(pos);
|
positions.Add(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,10 +870,14 @@ namespace Barotrauma.Items.Components
|
|||||||
string line1 = gapOpenSum > 0.1f ? TextManager.Get("MiniMapHullBreach") : string.Empty;
|
string line1 = gapOpenSum > 0.1f ? TextManager.Get("MiniMapHullBreach") : string.Empty;
|
||||||
Color line1Color = GUI.Style.Red;
|
Color line1Color = GUI.Style.Red;
|
||||||
|
|
||||||
string line2 = oxygenAmount == null ? TextManager.Get("MiniMapAirQualityUnavailable") : TextManager.AddPunctuation(':', TextManager.Get("MiniMapAirQuality"), +(int)oxygenAmount + " %");
|
string line2 = oxygenAmount == null ?
|
||||||
|
TextManager.Get("MiniMapAirQualityUnavailable") :
|
||||||
|
TextManager.AddPunctuation(':', TextManager.Get("MiniMapAirQuality"), (int)Math.Round(oxygenAmount.Value) + "%");
|
||||||
Color line2Color = oxygenAmount == null ? GUI.Style.Red : Color.Lerp(GUI.Style.Red, Color.LightGreen, (float)oxygenAmount / 100.0f);
|
Color line2Color = oxygenAmount == null ? GUI.Style.Red : Color.Lerp(GUI.Style.Red, Color.LightGreen, (float)oxygenAmount / 100.0f);
|
||||||
|
|
||||||
string line3 = waterAmount == null ? TextManager.Get("MiniMapWaterLevelUnavailable") : TextManager.AddPunctuation(':', TextManager.Get("MiniMapWaterLevel"), (int)(waterAmount * 100.0f) + " %");
|
string line3 = waterAmount == null ?
|
||||||
|
TextManager.Get("MiniMapWaterLevelUnavailable") :
|
||||||
|
TextManager.AddPunctuation(':', TextManager.Get("MiniMapWaterLevel"), (int)Math.Round(waterAmount.Value * 100.0f) + "%");
|
||||||
Color line3Color = waterAmount == null ? GUI.Style.Red : Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)waterAmount);
|
Color line3Color = waterAmount == null ? GUI.Style.Red : Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)waterAmount);
|
||||||
|
|
||||||
SetTooltip(borderComponent.Rect.Center, header, line1, line2, line3, line1Color, line2Color, line3Color);
|
SetTooltip(borderComponent.Rect.Center, header, line1, line2, line3, line1Color, line2Color, line3Color);
|
||||||
@@ -958,7 +959,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Rectangle parentRect = container.Rect;
|
Rectangle parentRect = container.Rect;
|
||||||
if (miniMapFrame is { } miniMap) { parentRect = miniMap.Rect; }
|
if (miniMapFrame is { } miniMap) { parentRect = miniMap.Rect; }
|
||||||
|
|
||||||
DrawSubmarine(spriteBatch, parentRect);
|
DrawSubmarine(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Voltage < MinVoltage) { return; }
|
if (Voltage < MinVoltage) { return; }
|
||||||
@@ -979,7 +980,7 @@ namespace Barotrauma.Items.Components
|
|||||||
Vector2 spriteScale = targetSize / pingCircle.size;
|
Vector2 spriteScale = targetSize / pingCircle.size;
|
||||||
float scale = Math.Min(blipState, maxBlipState / 2f);
|
float scale = Math.Min(blipState, maxBlipState / 2f);
|
||||||
float alpha = 1.0f - Math.Clamp((blipState - maxBlipState * 0.25f) * 2f, 0f, 1f);
|
float alpha = 1.0f - Math.Clamp((blipState - maxBlipState * 0.25f) * 2f, 0f, 1f);
|
||||||
pingCircle.Draw(spriteBatch, miniMapFrame.Rect.Location.ToVector2() + (blip * Zoom), GUI.Style.Red * alpha, pingCircle.Origin, 0f, spriteScale * scale, SpriteEffects.None);
|
pingCircle.Draw(spriteBatch, electricalFrame.Rect.Location.ToVector2() + blip * Zoom, GUI.Style.Red * alpha, pingCircle.Origin, 0f, spriteScale * scale, SpriteEffects.None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1002,8 +1003,15 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
RectangleF waterRect = new RectangleF(hullFrame.Rect.X, hullFrame.Rect.Y + hullFrame.Rect.Height * (1.0f - waterAmount), hullFrame.Rect.Width, hullFrame.Rect.Height * waterAmount);
|
RectangleF waterRect = new RectangleF(hullFrame.Rect.X, hullFrame.Rect.Y + hullFrame.Rect.Height * (1.0f - waterAmount), hullFrame.Rect.Width, hullFrame.Rect.Height * waterAmount);
|
||||||
|
|
||||||
|
const float width = 1f;
|
||||||
|
|
||||||
GUI.DrawFilledRectangle(spriteBatch, waterRect, HullWaterColor);
|
GUI.DrawFilledRectangle(spriteBatch, waterRect, HullWaterColor);
|
||||||
GUI.DrawLine(spriteBatch, waterRect.Location, new Vector2(waterRect.Right, waterRect.Y), HullWaterLineColor);
|
|
||||||
|
if (!MathUtils.NearlyEqual(waterAmount, 1.0f))
|
||||||
|
{
|
||||||
|
Vector2 offset = new Vector2(0, width);
|
||||||
|
GUI.DrawLine(spriteBatch, waterRect.Location + offset, new Vector2(waterRect.Right, waterRect.Y) + offset, HullWaterLineColor, width: width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1079,7 +1087,7 @@ namespace Barotrauma.Items.Components
|
|||||||
submarinePreview = rt;
|
submarinePreview = rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawSubmarine(SpriteBatch spriteBatch, Rectangle parentRect)
|
private void DrawSubmarine(SpriteBatch spriteBatch)
|
||||||
{
|
{
|
||||||
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
@@ -1094,7 +1102,8 @@ namespace Barotrauma.Items.Components
|
|||||||
Color blueprintBlue = BlueprintBlue * currentMode switch { MiniMapMode.HullStatus => 0.1f, MiniMapMode.ElectricalView => 0.1f, _ => 0.5f };
|
Color blueprintBlue = BlueprintBlue * currentMode switch { MiniMapMode.HullStatus => 0.1f, MiniMapMode.ElectricalView => 0.1f, _ => 0.5f };
|
||||||
|
|
||||||
Vector2 origin = new Vector2(texture.Width / 2f, texture.Height / 2f);
|
Vector2 origin = new Vector2(texture.Width / 2f, texture.Height / 2f);
|
||||||
spriteBatch.Draw(texture, parentRect.Center.ToVector2(), null, blueprintBlue, 0f, origin, Zoom, SpriteEffects.None, 0f);
|
float scale = currentMode == MiniMapMode.HullStatus ? 1.0f : Zoom;
|
||||||
|
spriteBatch.Draw(texture, miniMapContainer.Center, null, blueprintBlue, 0f, origin, scale, SpriteEffects.None, 0f);
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
@@ -1281,12 +1290,12 @@ namespace Barotrauma.Items.Components
|
|||||||
GUIFrame hullContainer = new GUIFrame(new RectTransform(containerScale * elementPadding, parent.RectTransform, Anchor.Center), style: null);
|
GUIFrame hullContainer = new GUIFrame(new RectTransform(containerScale * elementPadding, parent.RectTransform, Anchor.Center), style: null);
|
||||||
|
|
||||||
ImmutableHashSet<Submarine> connectedSubs = sub.GetConnectedSubs().ToImmutableHashSet();
|
ImmutableHashSet<Submarine> connectedSubs = sub.GetConnectedSubs().ToImmutableHashSet();
|
||||||
ImmutableHashSet<Hull> hullList = ImmutableHashSet<Hull>.Empty;
|
ImmutableArray<Hull> hullList = ImmutableArray<Hull>.Empty;
|
||||||
ImmutableDictionary<Hull, ImmutableHashSet<Hull>> combinedHulls = ImmutableDictionary<Hull, ImmutableHashSet<Hull>>.Empty;
|
ImmutableDictionary<Hull, ImmutableArray<Hull>> combinedHulls = ImmutableDictionary<Hull, ImmutableArray<Hull>>.Empty;
|
||||||
|
|
||||||
if (settings.CreateHullElements)
|
if (settings.CreateHullElements)
|
||||||
{
|
{
|
||||||
hullList = Hull.hullList.Where(IsPartofSub).ToImmutableHashSet();
|
hullList = Hull.hullList.Where(IsPartofSub).ToImmutableArray();
|
||||||
combinedHulls = CombinedHulls(hullList);
|
combinedHulls = CombinedHulls(hullList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1436,7 +1445,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ImmutableDictionary<Hull, ImmutableHashSet<Hull>> CombinedHulls(ImmutableHashSet<Hull> hulls)
|
private static ImmutableDictionary<Hull, ImmutableArray<Hull>> CombinedHulls(ImmutableArray<Hull> hulls)
|
||||||
{
|
{
|
||||||
Dictionary<Hull, HashSet<Hull>> combinedHulls = new Dictionary<Hull, HashSet<Hull>>();
|
Dictionary<Hull, HashSet<Hull>> combinedHulls = new Dictionary<Hull, HashSet<Hull>>();
|
||||||
|
|
||||||
@@ -1460,10 +1469,10 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return combinedHulls.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableHashSet());
|
return combinedHulls.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MiniMapHullData ConstructHullPolygon(Hull mainHull, ImmutableHashSet<Hull> linkedHulls, GUIComponent parent, RectangleF worldBorders)
|
private static MiniMapHullData ConstructHullPolygon(Hull mainHull, ImmutableArray<Hull> linkedHulls, GUIComponent parent, RectangleF worldBorders)
|
||||||
{
|
{
|
||||||
Rectangle parentRect = parent.Rect;
|
Rectangle parentRect = parent.Rect;
|
||||||
|
|
||||||
@@ -1500,6 +1509,8 @@ namespace Barotrauma.Items.Components
|
|||||||
hullRefs.Add(hull);
|
hullRefs.Add(hull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hullRefs.Reverse(); // I have no idea why this is required
|
||||||
|
|
||||||
ImmutableArray<RectangleF> snappedRectangles = ToolBox.SnapRectangles(normalizedRects, treshold: 1);
|
ImmutableArray<RectangleF> snappedRectangles = ToolBox.SnapRectangles(normalizedRects, treshold: 1);
|
||||||
|
|
||||||
List<List<Vector2>> polygon = ToolBox.CombineRectanglesIntoShape(snappedRectangles);
|
List<List<Vector2>> polygon = ToolBox.CombineRectanglesIntoShape(snappedRectangles);
|
||||||
@@ -1508,6 +1519,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
foreach (List<Vector2> list in polygon)
|
foreach (List<Vector2> list in polygon)
|
||||||
{
|
{
|
||||||
|
// scale down the polygon just a tiny bit
|
||||||
var (polySizeX, polySizeY) = ToolBox.GetPolygonBoundingBoxSize(list);
|
var (polySizeX, polySizeY) = ToolBox.GetPolygonBoundingBoxSize(list);
|
||||||
float sizeX = polySizeX - 1f,
|
float sizeX = polySizeX - 1f,
|
||||||
sizeY = polySizeY - 1f;
|
sizeY = polySizeY - 1f;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Barotrauma.Items.Components
|
||||||
|
{
|
||||||
|
partial class RemoteController : ItemComponent
|
||||||
|
{
|
||||||
|
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||||
|
{
|
||||||
|
currentTarget?.DrawHUD(spriteBatch, Screen.Selected.Cam, character);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
|
{
|
||||||
|
currentTarget?.UpdateHUD(cam, character,deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AddToGUIUpdateList()
|
||||||
|
{
|
||||||
|
currentTarget?.AddToGUIUpdateList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,6 +54,11 @@ namespace Barotrauma.Items.Components
|
|||||||
if (wireComponent != null)
|
if (wireComponent != null)
|
||||||
{
|
{
|
||||||
equippedWire = wireComponent;
|
equippedWire = wireComponent;
|
||||||
|
var connectedEnd = equippedWire.OtherConnection(null);
|
||||||
|
if (connectedEnd?.Item.Submarine != null && panel.Item.Submarine != connectedEnd.Item.Submarine)
|
||||||
|
{
|
||||||
|
equippedWire = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
OutputValue = input;
|
OutputValue = input;
|
||||||
ShowOnDisplay(input);
|
ShowOnDisplay(input, addToHistory: true);
|
||||||
item.SendSignal(input, "signal_out");
|
item.SendSignal(input, "signal_out");
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void ShowOnDisplay(string input, bool addToHistory = true)
|
partial void ShowOnDisplay(string input, bool addToHistory)
|
||||||
{
|
{
|
||||||
if (addToHistory)
|
if (addToHistory)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,6 +39,34 @@ namespace Barotrauma.Items.Components
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serialize(false, false)]
|
||||||
|
public bool SeeThroughWalls
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serialize(true, false)]
|
||||||
|
public bool ShowDeadCharacters
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serialize(true, false)]
|
||||||
|
public bool ShowTexts
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serialize("72,119,72,120", false)]
|
||||||
|
public Color OverlayColor
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly List<Character> visibleCharacters = new List<Character>();
|
private readonly List<Character> visibleCharacters = new List<Character>();
|
||||||
|
|
||||||
private const float UpdateInterval = 0.5f;
|
private const float UpdateInterval = 0.5f;
|
||||||
@@ -91,12 +119,13 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (Character c in Character.CharacterList)
|
foreach (Character c in Character.CharacterList)
|
||||||
{
|
{
|
||||||
if (c == equipper || !c.Enabled || c.Removed) { continue; }
|
if (c == equipper || !c.Enabled || c.Removed) { continue; }
|
||||||
|
if (!ShowDeadCharacters && c.IsDead) { continue; }
|
||||||
|
|
||||||
float dist = Vector2.DistanceSquared(refEntity.WorldPosition, c.WorldPosition);
|
float dist = Vector2.DistanceSquared(refEntity.WorldPosition, c.WorldPosition);
|
||||||
if (dist < Range * Range)
|
if (dist < Range * Range)
|
||||||
{
|
{
|
||||||
Vector2 diff = c.WorldPosition - refEntity.WorldPosition;
|
Vector2 diff = c.WorldPosition - refEntity.WorldPosition;
|
||||||
if (Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
|
if (SeeThroughWalls || Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
|
||||||
{
|
{
|
||||||
visibleCharacters.Add(c);
|
visibleCharacters.Add(c);
|
||||||
}
|
}
|
||||||
@@ -123,27 +152,54 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (character == null) { return; }
|
if (character == null) { return; }
|
||||||
|
|
||||||
GUI.UIGlow.Draw(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
|
if (OverlayColor.A > 0)
|
||||||
Color.LightGreen * 0.5f);
|
|
||||||
|
|
||||||
Character closestCharacter = null;
|
|
||||||
float closestDist = float.PositiveInfinity;
|
|
||||||
foreach (Character c in visibleCharacters)
|
|
||||||
{
|
{
|
||||||
if (c == character || !c.Enabled || c.Removed) { continue; }
|
GUI.UIGlow.Draw(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), OverlayColor);
|
||||||
|
|
||||||
float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition);
|
|
||||||
if (dist < closestDist)
|
|
||||||
{
|
|
||||||
closestCharacter = c;
|
|
||||||
closestDist = dist;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closestCharacter != null)
|
if (ShowTexts)
|
||||||
{
|
{
|
||||||
float dist = Vector2.Distance(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), closestCharacter.WorldPosition);
|
Character closestCharacter = null;
|
||||||
DrawCharacterInfo(spriteBatch, closestCharacter, 1.0f - MathHelper.Max((dist - (Range - FadeOutRange)) / FadeOutRange, 0.0f));
|
float closestDist = float.PositiveInfinity;
|
||||||
|
foreach (Character c in visibleCharacters)
|
||||||
|
{
|
||||||
|
if (c == character || !c.Enabled || c.Removed) { continue; }
|
||||||
|
|
||||||
|
float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition);
|
||||||
|
if (dist < closestDist)
|
||||||
|
{
|
||||||
|
closestCharacter = c;
|
||||||
|
closestDist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closestCharacter != null)
|
||||||
|
{
|
||||||
|
float dist = Vector2.Distance(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), closestCharacter.WorldPosition);
|
||||||
|
DrawCharacterInfo(spriteBatch, closestCharacter, 1.0f - MathHelper.Max((dist - (Range - FadeOutRange)) / FadeOutRange, 0.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SeeThroughWalls)
|
||||||
|
{
|
||||||
|
spriteBatch.End();
|
||||||
|
GameMain.LightManager.SolidColorEffect.Parameters["color"].SetValue(Color.Red.ToVector4() * (0.35f + (float)Math.Sin(Timing.TotalTime * 1.6f) * 0.05f));
|
||||||
|
GameMain.LightManager.SolidColorEffect.CurrentTechnique = GameMain.LightManager.SolidColorEffect.Techniques["SolidColorBlur"];
|
||||||
|
GameMain.LightManager.SolidColorEffect.Parameters["blurDistance"].SetValue(0.03f + (float)Math.Sin(Timing.TotalTime) * 0.01f);
|
||||||
|
GameMain.LightManager.SolidColorEffect.CurrentTechnique.Passes[0].Apply();
|
||||||
|
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: Screen.Selected.Cam.Transform, effect: GameMain.LightManager.SolidColorEffect);
|
||||||
|
|
||||||
|
foreach (Character c in visibleCharacters)
|
||||||
|
{
|
||||||
|
if (c == character || !c.Enabled || c.Removed) { continue; }
|
||||||
|
foreach (Limb limb in c.AnimController.Limbs)
|
||||||
|
{
|
||||||
|
limb.Draw(spriteBatch, Screen.Selected.Cam, disableDeformations: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteBatch.End();
|
||||||
|
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components
|
|||||||
description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ?? afflictionIdentifier}";
|
description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ?? afflictionIdentifier}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddTooltipInfo(ref string description)
|
public override void AddTooltipInfo(ref string name, ref string description)
|
||||||
{
|
{
|
||||||
if (damageModifiers.Any(d => !MathUtils.NearlyEqual(d.DamageMultiplier, 1f)) || SkillModifiers.Any())
|
if (damageModifiers.Any(d => !MathUtils.NearlyEqual(d.DamageMultiplier, 1f)) || SkillModifiers.Any())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -297,9 +297,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string name = item.Name;
|
||||||
foreach (ItemComponent component in item.Components)
|
foreach (ItemComponent component in item.Components)
|
||||||
{
|
{
|
||||||
component.AddTooltipInfo(ref description);
|
component.AddTooltipInfo(ref name, ref description);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.Prefab.ShowContentsInTooltip && item.OwnInventory != null)
|
if (item.Prefab.ShowContentsInTooltip && item.OwnInventory != null)
|
||||||
@@ -315,7 +316,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
string colorStr = XMLExtensions.ColorToString(!item.AllowStealing ? GUI.Style.Red : Color.White);
|
string colorStr = XMLExtensions.ColorToString(!item.AllowStealing ? GUI.Style.Red : Color.White);
|
||||||
|
|
||||||
toolTip = $"‖color:{colorStr}‖{item.Name}‖color:end‖";
|
toolTip = $"‖color:{colorStr}‖{name}‖color:end‖";
|
||||||
if (itemsInSlot.All(it => it.NonInteractable || it.NonPlayerTeamInteractable))
|
if (itemsInSlot.All(it => it.NonInteractable || it.NonPlayerTeamInteractable))
|
||||||
{
|
{
|
||||||
toolTip += " " + TextManager.Get("connectionlocked");
|
toolTip += " " + TextManager.Get("connectionlocked");
|
||||||
@@ -719,7 +720,7 @@ namespace Barotrauma
|
|||||||
spacing = new Vector2(10 * UIScale, (10 + UnequippedIndicator.size.Y) * UIScale);
|
spacing = new Vector2(10 * UIScale, (10 + UnequippedIndicator.size.Y) * UIScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
int columns = (int)Math.Max(Math.Floor(Math.Sqrt(itemCapacity)), 1);
|
int columns = MathHelper.Clamp((int)Math.Floor(Math.Sqrt(itemCapacity)), 1, container.SlotsPerRow);
|
||||||
while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f)
|
while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f)
|
||||||
{
|
{
|
||||||
columns++;
|
columns++;
|
||||||
@@ -1543,13 +1544,13 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var containedItem = itemContainer.Inventory.slots[0].FirstOrDefault();
|
var containedItem = itemContainer.Inventory.slots[Math.Max(itemContainer.ContainedStateIndicatorSlot, 0)].FirstOrDefault();
|
||||||
containedState = itemContainer.Inventory.Capacity == 1 ?
|
containedState = itemContainer.Inventory.Capacity == 1 || itemContainer.ContainedStateIndicatorSlot > -1 ?
|
||||||
(containedItem == null ? 0.0f : containedItem.Condition / containedItem.MaxCondition) :
|
(containedItem == null ? 0.0f : containedItem.Condition / containedItem.MaxCondition) :
|
||||||
itemContainer.Inventory.slots.Count(i => !i.Empty()) / (float)itemContainer.Inventory.capacity;
|
itemContainer.Inventory.slots.Count(i => !i.Empty()) / (float)itemContainer.Inventory.capacity;
|
||||||
if (containedItem != null && itemContainer.Inventory.Capacity == 1)
|
if (containedItem != null && itemContainer.Inventory.Capacity == 1)
|
||||||
{
|
{
|
||||||
int maxStackSize = Math.Min(containedItem.Prefab.MaxStackSize, itemContainer.MaxStackSize);
|
int maxStackSize = Math.Min(containedItem.Prefab.MaxStackSize, itemContainer.GetMaxStackSize(0));
|
||||||
if (maxStackSize > 1)
|
if (maxStackSize > 1)
|
||||||
{
|
{
|
||||||
containedState = itemContainer.Inventory.slots[0].ItemCount / (float)maxStackSize;
|
containedState = itemContainer.Inventory.slots[0].ItemCount / (float)maxStackSize;
|
||||||
@@ -1631,7 +1632,7 @@ namespace Barotrauma
|
|||||||
int maxStackSize = item.Prefab.MaxStackSize;
|
int maxStackSize = item.Prefab.MaxStackSize;
|
||||||
if (item.Container != null)
|
if (item.Container != null)
|
||||||
{
|
{
|
||||||
maxStackSize = Math.Min(maxStackSize, item.Container.GetComponent<ItemContainer>()?.MaxStackSize ?? maxStackSize);
|
maxStackSize = Math.Min(maxStackSize, item.Container.GetComponent<ItemContainer>()?.GetMaxStackSize(slotIndex) ?? maxStackSize);
|
||||||
}
|
}
|
||||||
if (maxStackSize > 1 && inventory != null)
|
if (maxStackSize > 1 && inventory != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1194,7 +1194,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this) { return; }
|
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this)
|
||||||
|
{
|
||||||
|
if (Character.Controlled.SelectedConstruction?.GetComponent<RemoteController>()?.TargetItem != this &&
|
||||||
|
!Character.Controlled.HeldItems.Any(it => it.GetComponent<RemoteController>()?.TargetItem == this))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool needsLayoutUpdate = false;
|
bool needsLayoutUpdate = false;
|
||||||
foreach (ItemComponent ic in activeHUDs)
|
foreach (ItemComponent ic in activeHUDs)
|
||||||
|
|||||||
@@ -423,20 +423,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//select wire if both items it's connected to are selected
|
//select wire if both items it's connected to are selected
|
||||||
var selectedItems = SelectedList.Where(e => e is Item).Cast<Item>().ToList();
|
var selectedItems = SelectedList.Where(e => e is Item).Cast<Item>().ToList();
|
||||||
foreach (Item item in selectedItems)
|
foreach (Item item in Item.ItemList)
|
||||||
{
|
{
|
||||||
if (item.Connections == null) continue;
|
var wire = item.GetComponent<Wire>();
|
||||||
foreach (Connection c in item.Connections)
|
if (wire == null) { continue; }
|
||||||
{
|
Item item0 = wire.Connections[0]?.Item;
|
||||||
foreach (Wire w in c.Wires)
|
Item item1 = wire.Connections[1]?.Item;
|
||||||
{
|
|
||||||
if (w == null || SelectedList.Contains(w.Item)) continue;
|
|
||||||
|
|
||||||
if (w.OtherConnection(c) != null && SelectedList.Contains(w.OtherConnection(c).Item))
|
if (item0 == null && item1 != null)
|
||||||
{
|
{
|
||||||
SelectedList.Add(w.Item);
|
item0 = Item.ItemList.Find(it => it.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(wire) ?? false);
|
||||||
}
|
}
|
||||||
}
|
else if (item0 != null && item1 == null)
|
||||||
|
{
|
||||||
|
item1 = Item.ItemList.Find(it => it.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(wire) ?? false);
|
||||||
|
}
|
||||||
|
if (item0 != null && item1 != null && SelectedList.Contains(item0) && SelectedList.Contains(item1))
|
||||||
|
{
|
||||||
|
SelectedList.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ namespace Barotrauma
|
|||||||
depthSortedDamageable.Insert(i, structure);
|
depthSortedDamageable.Insert(i, structure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Structure s in depthSortedDamageable)
|
foreach (Structure s in depthSortedDamageable)
|
||||||
{
|
{
|
||||||
s.DrawDamage(spriteBatch, damageEffect, editing);
|
s.DrawDamage(spriteBatch, damageEffect, editing);
|
||||||
@@ -418,8 +418,8 @@ namespace Barotrauma
|
|||||||
float scale = 0.9f;
|
float scale = 0.9f;
|
||||||
|
|
||||||
GUIFrame hullContainer = new GUIFrame(new RectTransform(
|
GUIFrame hullContainer = new GUIFrame(new RectTransform(
|
||||||
(parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
|
(parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
|
||||||
parent.RectTransform, Anchor.Center),
|
parent.RectTransform, Anchor.Center),
|
||||||
style: null)
|
style: null)
|
||||||
{
|
{
|
||||||
UserData = "hullcontainer"
|
UserData = "hullcontainer"
|
||||||
@@ -444,9 +444,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!combinedHulls.ContainsKey(hull))
|
if (!combinedHulls.ContainsKey(hull))
|
||||||
{
|
{
|
||||||
combinedHulls.Add(hull, new HashSet<Hull>());
|
combinedHulls.Add(hull, new HashSet<Hull>());
|
||||||
}
|
}
|
||||||
|
|
||||||
combinedHulls[hull].Add(linkedHull);
|
combinedHulls[hull].Add(linkedHull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,14 +454,14 @@ namespace Barotrauma
|
|||||||
foreach (Hull hull in hullList)
|
foreach (Hull hull in hullList)
|
||||||
{
|
{
|
||||||
Vector2 relativeHullPos = new Vector2(
|
Vector2 relativeHullPos = new Vector2(
|
||||||
(hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
|
(hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
|
||||||
(worldBorders.Y - hull.WorldRect.Y) / (float)worldBorders.Height);
|
(worldBorders.Y - hull.WorldRect.Y) / (float)worldBorders.Height);
|
||||||
Vector2 relativeHullSize = new Vector2(hull.Rect.Width / (float)worldBorders.Width, hull.Rect.Height / (float)worldBorders.Height);
|
Vector2 relativeHullSize = new Vector2(hull.Rect.Width / (float)worldBorders.Width, hull.Rect.Height / (float)worldBorders.Height);
|
||||||
|
|
||||||
bool hideHull = combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull));
|
bool hideHull = combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull));
|
||||||
|
|
||||||
if (hideHull) { continue; }
|
if (hideHull) { continue; }
|
||||||
|
|
||||||
Color color = Color.DarkCyan * 0.8f;
|
Color color = Color.DarkCyan * 0.8f;
|
||||||
|
|
||||||
var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, style: "MiniMapRoom", color: color)
|
var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, style: "MiniMapRoom", color: color)
|
||||||
@@ -477,7 +477,7 @@ namespace Barotrauma
|
|||||||
MiniMapHullData data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);
|
MiniMapHullData data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);
|
||||||
|
|
||||||
Vector2 relativeHullPos = new Vector2(
|
Vector2 relativeHullPos = new Vector2(
|
||||||
(data.Bounds.X - worldBorders.X) / worldBorders.Width,
|
(data.Bounds.X - worldBorders.X) / worldBorders.Width,
|
||||||
(worldBorders.Y - data.Bounds.Y) / worldBorders.Height);
|
(worldBorders.Y - data.Bounds.Y) / worldBorders.Height);
|
||||||
|
|
||||||
Vector2 relativeHullSize = new Vector2(data.Bounds.Width / worldBorders.Width, data.Bounds.Height / worldBorders.Height);
|
Vector2 relativeHullSize = new Vector2(data.Bounds.Width / worldBorders.Width, data.Bounds.Height / worldBorders.Height);
|
||||||
@@ -507,9 +507,6 @@ namespace Barotrauma
|
|||||||
var (parentW, parentH) = hullContainer.Rect.Size.ToVector2();
|
var (parentW, parentH) = hullContainer.Rect.Size.ToVector2();
|
||||||
Vector2 size = new Vector2(rect.Width / parentW, rect.Height / parentH);
|
Vector2 size = new Vector2(rect.Width / parentW, rect.Height / parentH);
|
||||||
// TODO this won't be required if we some day switch RectTransform to use RectangleF
|
// TODO this won't be required if we some day switch RectTransform to use RectangleF
|
||||||
const float padding = 0.001f;
|
|
||||||
size.X += padding;
|
|
||||||
size.Y += padding;
|
|
||||||
Vector2 pos = new Vector2(rect.X / parentW, rect.Y / parentH);
|
Vector2 pos = new Vector2(rect.X / parentW, rect.Y / parentH);
|
||||||
|
|
||||||
GUIFrame hullFrame = new GUIFrame(new RectTransform(size, hullContainer.RectTransform) { RelativeOffset = pos }, style: "ScanLinesSeamless", color: color)
|
GUIFrame hullFrame = new GUIFrame(new RectTransform(size, hullContainer.RectTransform) { RelativeOffset = pos }, style: "ScanLinesSeamless", color: color)
|
||||||
@@ -586,7 +583,7 @@ namespace Barotrauma
|
|||||||
wRect.Y = -wRect.Y;
|
wRect.Y = -wRect.Y;
|
||||||
|
|
||||||
var (posX, posY) = new Vector2(
|
var (posX, posY) = new Vector2(
|
||||||
(wRect.X - worldBorders.X) / (float)worldBorders.Width,
|
(wRect.X - worldBorders.X) / (float)worldBorders.Width,
|
||||||
(worldBorders.Y - wRect.Y) / (float)worldBorders.Height);
|
(worldBorders.Y - wRect.Y) / (float)worldBorders.Height);
|
||||||
|
|
||||||
var (scaleX, scaleY) = new Vector2(wRect.Width / (float)worldBorders.Width, wRect.Height / (float)worldBorders.Height);
|
var (scaleX, scaleY) = new Vector2(wRect.Width / (float)worldBorders.Width, wRect.Height / (float)worldBorders.Height);
|
||||||
@@ -629,7 +626,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Info.Type != SubmarineType.OutpostModule ||
|
if (Info.Type != SubmarineType.OutpostModule ||
|
||||||
(Info.OutpostModuleInfo?.ModuleFlags.Any(f => !f.Equals("hallwayvertical", StringComparison.OrdinalIgnoreCase) && !f.Equals("hallwayhorizontal", StringComparison.OrdinalIgnoreCase)) ?? true))
|
(Info.OutpostModuleInfo?.ModuleFlags.Any(f => !f.Equals("hallwayvertical", StringComparison.OrdinalIgnoreCase) && !f.Equals("hallwayhorizontal", StringComparison.OrdinalIgnoreCase)) ?? true))
|
||||||
{
|
{
|
||||||
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
|
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
|
||||||
@@ -697,7 +694,7 @@ namespace Barotrauma
|
|||||||
int wireCount = item.Connections[i].Wires.Count(w => w != null);
|
int wireCount = item.Connections[i].Wires.Count(w => w != null);
|
||||||
if (doorLinks + wireCount > item.Connections[i].MaxWires)
|
if (doorLinks + wireCount > item.Connections[i].MaxWires)
|
||||||
{
|
{
|
||||||
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
|
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
|
||||||
new string[] { "[doorcount]", "[freeconnectioncount]" },
|
new string[] { "[doorcount]", "[freeconnectioncount]" },
|
||||||
new string[] { doorLinks.ToString(), (item.Connections[i].MaxWires - wireCount).ToString() }));
|
new string[] { doorLinks.ToString(), (item.Connections[i].MaxWires - wireCount).ToString() }));
|
||||||
break;
|
break;
|
||||||
@@ -794,7 +791,7 @@ namespace Barotrauma
|
|||||||
return SubEditorScreen.SuppressedWarnings.Contains(type);
|
return SubEditorScreen.SuppressedWarnings.Contains(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||||
{
|
{
|
||||||
if (type != ServerNetObject.ENTITY_POSITION)
|
if (type != ServerNetObject.ENTITY_POSITION)
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ namespace Barotrauma.Particles
|
|||||||
|
|
||||||
public ParticlePrefab FindPrefab(string prefabName)
|
public ParticlePrefab FindPrefab(string prefabName)
|
||||||
{
|
{
|
||||||
return Prefabs.Find(p => p.Identifier == prefabName);
|
return Prefabs.Find(p => p.Identifier.Equals(prefabName, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveParticle(int index)
|
private void RemoveParticle(int index)
|
||||||
|
|||||||
@@ -1366,6 +1366,7 @@ namespace Barotrauma
|
|||||||
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||||
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
|
||||||
roundControlsHolder.Children.ForEach(c => c.IgnoreLayoutGroups = !c.Visible);
|
roundControlsHolder.Children.ForEach(c => c.IgnoreLayoutGroups = !c.Visible);
|
||||||
|
roundControlsHolder.Children.ForEach(c => c.RectTransform.RelativeSize = Vector2.One);
|
||||||
roundControlsHolder.Recalculate();
|
roundControlsHolder.Recalculate();
|
||||||
|
|
||||||
ReadyToStartBox.Parent.Visible = !GameMain.Client.GameStarted;
|
ReadyToStartBox.Parent.Visible = !GameMain.Client.GameStarted;
|
||||||
|
|||||||
@@ -51,11 +51,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ????????
|
// ????????
|
||||||
submarine = new Submarine(SubmarineInfo.SavedSubmarines.FirstOrDefault(info => info.Name.Equals("Kastrull", StringComparison.OrdinalIgnoreCase)));
|
submarine = new Submarine(SubmarineInfo.SavedSubmarines.FirstOrDefault(info => info.Name.Equals("Crescent", StringComparison.OrdinalIgnoreCase)));
|
||||||
miniMapItem = new Item(ItemPrefab.Find(null, "statusmonitor"), Vector2.Zero, submarine);
|
miniMapItem = new Item(ItemPrefab.Find(null, "statusmonitor"), Vector2.Zero, submarine);
|
||||||
MiniMap miniMap = miniMapItem.GetComponent<MiniMap>();
|
MiniMap miniMap = miniMapItem.GetComponent<MiniMap>();
|
||||||
miniMap.PowerConsumption = 0;
|
miniMap.PowerConsumption = 0;
|
||||||
|
|
||||||
|
foreach (var hull in Hull.hullList)
|
||||||
|
{
|
||||||
|
hull.WaterVolume = hull.Volume / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
|
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
|
||||||
dummyCharacter.Info.Name = "Galldren";
|
dummyCharacter.Info.Name = "Galldren";
|
||||||
dummyCharacter.Inventory.CreateSlots();
|
dummyCharacter.Inventory.CreateSlots();
|
||||||
|
|||||||
@@ -1012,7 +1012,8 @@ namespace Barotrauma
|
|||||||
Screen.Selected == GameMain.SpriteEditorScreen ||
|
Screen.Selected == GameMain.SpriteEditorScreen ||
|
||||||
Screen.Selected == GameMain.SubEditorScreen ||
|
Screen.Selected == GameMain.SubEditorScreen ||
|
||||||
Screen.Selected == GameMain.EventEditorScreen ||
|
Screen.Selected == GameMain.EventEditorScreen ||
|
||||||
(Screen.Selected == GameMain.GameScreen && GameMain.GameSession?.GameMode is TestGameMode))
|
(Screen.Selected == GameMain.GameScreen && GameMain.GameSession?.GameMode is TestGameMode) ||
|
||||||
|
Screen.Selected == GameMain.NetLobbyScreen)
|
||||||
{
|
{
|
||||||
return "editor";
|
return "editor";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,14 +110,14 @@ namespace Barotrauma
|
|||||||
foreach (StatusEffect statusEffect in successEffects)
|
foreach (StatusEffect statusEffect in successEffects)
|
||||||
{
|
{
|
||||||
float duration = statusEffect.Duration;
|
float duration = statusEffect.Duration;
|
||||||
onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.First), -pair.Second, duration)));
|
onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration)));
|
||||||
onSuccessAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
|
onSuccessAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (StatusEffect statusEffect in failureEffects)
|
foreach (StatusEffect statusEffect in failureEffects)
|
||||||
{
|
{
|
||||||
float duration = statusEffect.Duration;
|
float duration = statusEffect.Duration;
|
||||||
onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.First), -pair.Second, duration)));
|
onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration)));
|
||||||
onFailureAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
|
onFailureAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.1500.0.0</Version>
|
<Version>0.1500.1.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.1500.0.0</Version>
|
<Version>0.1500.1.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.1500.0.0</Version>
|
<Version>0.1500.1.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.1500.0.0</Version>
|
<Version>0.1500.1.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.1500.0.0</Version>
|
<Version>0.1500.1.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -28,6 +28,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasAbilityFlag(AbilityFlags.RetainExperienceForNewCharacter))
|
||||||
|
{
|
||||||
|
var ownerClient = GameMain.Server.ConnectedClients.Find(c => c.Character == this);
|
||||||
|
if (ownerClient != null)
|
||||||
|
{
|
||||||
|
(GameMain.GameSession?.GameMode as MultiPlayerCampaign)?.SaveExperiencePoints(ownerClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
healthUpdateTimer = 0.0f;
|
healthUpdateTimer = 0.0f;
|
||||||
|
|
||||||
if (CauseOfDeath.Killer != null && CauseOfDeath.Killer.IsTraitor && CauseOfDeath.Killer != this)
|
if (CauseOfDeath.Killer != null && CauseOfDeath.Killer.IsTraitor && CauseOfDeath.Killer != this)
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ namespace Barotrauma
|
|||||||
msg.Write(savedStatValue.RemoveOnDeath);
|
msg.Write(savedStatValue.RemoveOnDeath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
msg.Write((ushort)ExperiencePoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,29 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool GameOver { get; private set; }
|
public bool GameOver { get; private set; }
|
||||||
|
|
||||||
|
class SavedExperiencePoints
|
||||||
|
{
|
||||||
|
public readonly ulong SteamID;
|
||||||
|
public readonly string EndPoint;
|
||||||
|
public readonly int ExperiencePoints;
|
||||||
|
|
||||||
|
public SavedExperiencePoints(Client client)
|
||||||
|
{
|
||||||
|
SteamID = client.SteamID;
|
||||||
|
EndPoint = client.Connection.EndPointString;
|
||||||
|
ExperiencePoints = client.Character?.Info?.ExperiencePoints ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavedExperiencePoints(XElement element)
|
||||||
|
{
|
||||||
|
SteamID = element.GetAttributeUInt64("steamid", 0);
|
||||||
|
EndPoint = element.GetAttributeString("endpoint", string.Empty);
|
||||||
|
ExperiencePoints = element.GetAttributeInt("points", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<SavedExperiencePoints> savedExperiencePoints = new List<SavedExperiencePoints>();
|
||||||
|
|
||||||
public override bool Paused
|
public override bool Paused
|
||||||
{
|
{
|
||||||
get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"); }
|
get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"); }
|
||||||
@@ -155,6 +178,20 @@ namespace Barotrauma
|
|||||||
c.InGame && (IsOwner(c) || c.HasPermission(ClientPermissions.ManageCampaign)));
|
c.InGame && (IsOwner(c) || c.HasPermission(ClientPermissions.ManageCampaign)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExperiencePoints(Client client)
|
||||||
|
{
|
||||||
|
ClearSavedExperiencePoints(client);
|
||||||
|
savedExperiencePoints.Add(new SavedExperiencePoints(client));
|
||||||
|
}
|
||||||
|
public int GetSavedExperiencePoints(Client client)
|
||||||
|
{
|
||||||
|
return savedExperiencePoints.Find(s => s.SteamID != 0 && client.SteamID == s.SteamID || client.EndpointMatches(s.EndPoint))?.ExperiencePoints ?? 0;
|
||||||
|
}
|
||||||
|
public void ClearSavedExperiencePoints(Client client)
|
||||||
|
{
|
||||||
|
savedExperiencePoints.RemoveAll(s => s.SteamID != 0 && client.SteamID == s.SteamID || client.EndpointMatches(s.EndPoint));
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadPets()
|
public void LoadPets()
|
||||||
{
|
{
|
||||||
if (petsElement != null)
|
if (petsElement != null)
|
||||||
@@ -259,6 +296,16 @@ namespace Barotrauma
|
|||||||
Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime));
|
Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime));
|
||||||
|
|
||||||
bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead);
|
bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead);
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
foreach (Client c in GameMain.Server.ConnectedClients)
|
||||||
|
{
|
||||||
|
if (c.Character?.HasAbilityFlag(AbilityFlags.RetainExperienceForNewCharacter) ?? false)
|
||||||
|
{
|
||||||
|
(GameMain.GameSession?.GameMode as MultiPlayerCampaign)?.SaveExperiencePoints(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GameMain.GameSession.EndRound("", traitorResults, transitionType);
|
GameMain.GameSession.EndRound("", traitorResults, transitionType);
|
||||||
|
|
||||||
@@ -965,6 +1012,15 @@ namespace Barotrauma
|
|||||||
// save bots
|
// save bots
|
||||||
CrewManager.SaveMultiplayer(modeElement);
|
CrewManager.SaveMultiplayer(modeElement);
|
||||||
|
|
||||||
|
XElement savedExperiencePointsElement = new XElement("SavedExperiencePoints");
|
||||||
|
foreach (var savedExperiencePoint in savedExperiencePoints)
|
||||||
|
{
|
||||||
|
savedExperiencePointsElement.Add(new XElement("Point",
|
||||||
|
new XAttribute("steamid", savedExperiencePoint.SteamID),
|
||||||
|
new XAttribute("endpoint", savedExperiencePoint?.EndPoint ?? string.Empty),
|
||||||
|
new XAttribute("points", savedExperiencePoint.ExperiencePoints)));
|
||||||
|
}
|
||||||
|
|
||||||
// save available submarines
|
// save available submarines
|
||||||
XElement availableSubsElement = new XElement("AvailableSubs");
|
XElement availableSubsElement = new XElement("AvailableSubs");
|
||||||
for (int i = 0; i < GameMain.NetLobbyScreen.CampaignSubmarines.Count; i++)
|
for (int i = 0; i < GameMain.NetLobbyScreen.CampaignSubmarines.Count; i++)
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
|
namespace Barotrauma.Items.Components
|
||||||
|
{
|
||||||
|
partial class GeneticMaterial : ItemComponent
|
||||||
|
{
|
||||||
|
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
|
||||||
|
{
|
||||||
|
msg.Write(tainted);
|
||||||
|
if (tainted)
|
||||||
|
{
|
||||||
|
msg.Write(selectedTaintedEffect?.UIntIdentifier ?? 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg.Write(selectedEffect?.UIntIdentifier ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,13 +19,13 @@ namespace Barotrauma.Items.Components
|
|||||||
GameServer.Log(GameServer.CharacterLogName(c.Character) + " entered \"" + newOutputValue + "\" on " + item.Name,
|
GameServer.Log(GameServer.CharacterLogName(c.Character) + " entered \"" + newOutputValue + "\" on " + item.Name,
|
||||||
ServerLog.MessageType.ItemInteraction);
|
ServerLog.MessageType.ItemInteraction);
|
||||||
OutputValue = newOutputValue;
|
OutputValue = newOutputValue;
|
||||||
ShowOnDisplay(newOutputValue);
|
ShowOnDisplay(newOutputValue, addToHistory: true);
|
||||||
item.SendSignal(newOutputValue, "signal_out");
|
item.SendSignal(newOutputValue, "signal_out");
|
||||||
item.CreateServerEvent(this);
|
item.CreateServerEvent(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void ShowOnDisplay(string input, bool addToHistory = true)
|
partial void ShowOnDisplay(string input, bool addToHistory)
|
||||||
{
|
{
|
||||||
if (addToHistory)
|
if (addToHistory)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2358,6 +2358,12 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
characterData.HasSpawned = true;
|
characterData.HasSpawned = true;
|
||||||
}
|
}
|
||||||
|
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign && spawnedCharacter.Info != null)
|
||||||
|
{
|
||||||
|
spawnedCharacter.Info.SetExperience(Math.Max(spawnedCharacter.Info.ExperiencePoints, mpCampaign.GetSavedExperiencePoints(teamClients[i])));
|
||||||
|
mpCampaign.ClearSavedExperiencePoints(teamClients[i]);
|
||||||
|
}
|
||||||
|
|
||||||
spawnedCharacter.OwnerClientEndPoint = teamClients[i].Connection.EndPointString;
|
spawnedCharacter.OwnerClientEndPoint = teamClients[i].Connection.EndPointString;
|
||||||
spawnedCharacter.OwnerClientName = teamClients[i].Name;
|
spawnedCharacter.OwnerClientName = teamClients[i].Name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -379,6 +379,12 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign && character.Info != null)
|
||||||
|
{
|
||||||
|
character.Info.SetExperience(Math.Max(character.Info.ExperiencePoints, mpCampaign.GetSavedExperiencePoints(clients[i])));
|
||||||
|
mpCampaign.ClearSavedExperiencePoints(clients[i]);
|
||||||
|
}
|
||||||
|
|
||||||
//tell the respawning client they're no longer a traitor
|
//tell the respawning client they're no longer a traitor
|
||||||
if (GameMain.Server.TraitorManager?.Traitors != null && clients[i].Character != null)
|
if (GameMain.Server.TraitorManager?.Traitors != null && clients[i].Character != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.1500.0.0</Version>
|
<Version>0.1500.1.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
<Item file="Content/Items/Electricity/signalitems.xml" />
|
<Item file="Content/Items/Electricity/signalitems.xml" />
|
||||||
<Item file="Content/Items/Engine/engine.xml" />
|
<Item file="Content/Items/Engine/engine.xml" />
|
||||||
<Item file="Content/Items/Fabricators/fabricators.xml" />
|
<Item file="Content/Items/Fabricators/fabricators.xml" />
|
||||||
|
<Item file="Content/Items/Genetic/genetic.xml" />
|
||||||
<Item file="Content/Items/Labels/labels.xml" />
|
<Item file="Content/Items/Labels/labels.xml" />
|
||||||
<Item file="Content/Items/Ladder/ladder.xml" />
|
<Item file="Content/Items/Ladder/ladder.xml" />
|
||||||
<Item file="Content/Items/Materials/materials.xml" />
|
<Item file="Content/Items/Materials/materials.xml" />
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
<Item file="Content/Items/Gardening/gardeningtools.xml" />
|
<Item file="Content/Items/Gardening/gardeningtools.xml" />
|
||||||
<Item file="Content/Items/Gardening/plantproducts.xml" />
|
<Item file="Content/Items/Gardening/plantproducts.xml" />
|
||||||
<Item file="Content/Map/Pirates/PirateItems.xml" />
|
<Item file="Content/Map/Pirates/PirateItems.xml" />
|
||||||
|
<Item file="Content/Items/Jobgear/Assistant/assistant_talent_items.xml" />
|
||||||
<Item file="Content/Items/Jobgear/Mechanic/mechanic_talent_items.xml" />
|
<Item file="Content/Items/Jobgear/Mechanic/mechanic_talent_items.xml" />
|
||||||
<Item file="Content/Items/Jobgear/Security/securityofficer_talent_items.xml" />
|
<Item file="Content/Items/Jobgear/Security/securityofficer_talent_items.xml" />
|
||||||
<Item file="Content/Items/Jobgear/Engineer/engineer_talent_items.xml" />
|
<Item file="Content/Items/Jobgear/Engineer/engineer_talent_items.xml" />
|
||||||
@@ -152,6 +154,7 @@
|
|||||||
<Text file="Content/Texts/Korean/KoreanVanilla.xml" />
|
<Text file="Content/Texts/Korean/KoreanVanilla.xml" />
|
||||||
<UIStyle file="Content/UI/style.xml" />
|
<UIStyle file="Content/UI/style.xml" />
|
||||||
<Afflictions file="Content/Afflictions.xml" />
|
<Afflictions file="Content/Afflictions.xml" />
|
||||||
|
<Afflictions file="Content/AfflictionsGeneticMaterial.xml" />
|
||||||
<Afflictions file="Content/Talents/Assistant/AfflictionsAssistant.xml" />
|
<Afflictions file="Content/Talents/Assistant/AfflictionsAssistant.xml" />
|
||||||
<Afflictions file="Content/Talents/Captain/AfflictionsCaptain.xml" />
|
<Afflictions file="Content/Talents/Captain/AfflictionsCaptain.xml" />
|
||||||
<Afflictions file="Content/Talents/Doctor/AfflictionsDoctor.xml" />
|
<Afflictions file="Content/Talents/Doctor/AfflictionsDoctor.xml" />
|
||||||
|
|||||||
@@ -1915,12 +1915,12 @@ namespace Barotrauma
|
|||||||
#if SERVER
|
#if SERVER
|
||||||
GameMain.NetworkMember.CreateEntityEvent(Character, new object[]
|
GameMain.NetworkMember.CreateEntityEvent(Character, new object[]
|
||||||
{
|
{
|
||||||
Networking.NetEntityEvent.Type.SetAttackTarget,
|
Networking.NetEntityEvent.Type.SetAttackTarget,
|
||||||
attackingLimb,
|
attackingLimb,
|
||||||
(damageTarget as Entity)?.ID ?? Entity.NullEntityID,
|
(damageTarget as Entity)?.ID ?? Entity.NullEntityID,
|
||||||
damageTarget is Character character && targetLimb != null ? Array.IndexOf(character.AnimController.Limbs, targetLimb) : 0,
|
damageTarget is Character character && targetLimb != null ? Array.IndexOf(character.AnimController.Limbs, targetLimb) : 0,
|
||||||
SimPosition.X,
|
SimPosition.X,
|
||||||
SimPosition.Y
|
SimPosition.Y
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
Character.PlaySound(CharacterSound.SoundType.Attack, maxInterval: 3);
|
Character.PlaySound(CharacterSound.SoundType.Attack, maxInterval: 3);
|
||||||
|
|||||||
+3
-2
@@ -588,8 +588,9 @@ namespace Barotrauma
|
|||||||
// assume that it's required for the stun effect
|
// assume that it's required for the stun effect
|
||||||
// as we can't check the status effect conditions here.
|
// as we can't check the status effect conditions here.
|
||||||
var mobileBatteryTag = "mobilebattery";
|
var mobileBatteryTag = "mobilebattery";
|
||||||
var containers = weapon.Item.Components.Where(ic => ic is ItemContainer container &&
|
var containers = weapon.Item.Components.Where(ic =>
|
||||||
container.ContainableItems.Any(containable => containable.Identifiers.Any(id => id.Equals(mobileBatteryTag))));
|
ic is ItemContainer container &&
|
||||||
|
container.ContainableItemIdentifiers.Contains(mobileBatteryTag));
|
||||||
// If there's no such container, assume that the melee weapon can stun without a battery.
|
// If there's no such container, assume that the melee weapon can stun without a battery.
|
||||||
return containers.None() || containers.Any(container =>
|
return containers.None() || containers.Any(container =>
|
||||||
(container as ItemContainer)?.Inventory.AllItems.Any(i => i != null && i.HasTag(mobileBatteryTag) && i.Condition > 0.0f) ?? false);
|
(container as ItemContainer)?.Inventory.AllItems.Any(i => i != null && i.HasTag(mobileBatteryTag) && i.Condition > 0.0f) ?? false);
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public virtual void UpdateAnim(float deltaTime) { }
|
public virtual void UpdateAnim(float deltaTime) { }
|
||||||
|
|
||||||
public virtual void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f) { }
|
public virtual void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f, bool aimingMelee = false) { }
|
||||||
|
|
||||||
public virtual void DragCharacter(Character target, float deltaTime) { }
|
public virtual void DragCharacter(Character target, float deltaTime) { }
|
||||||
|
|
||||||
|
|||||||
@@ -390,11 +390,17 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (eatTimer % 1.0f < 0.5f && (eatTimer - deltaTime * eatSpeed) % 1.0f > 0.5f)
|
if (eatTimer % 1.0f < 0.5f && (eatTimer - deltaTime * eatSpeed) % 1.0f > 0.5f)
|
||||||
{
|
{
|
||||||
bool CanBeSevered(LimbJoint j) => !j.IsSevered && j.CanBeSevered && j.LimbA != null && !j.LimbA.IsSevered && j.LimbB != null && !j.LimbB.IsSevered;
|
static bool CanBeSevered(LimbJoint j) => !j.IsSevered && j.CanBeSevered && j.LimbA != null && !j.LimbA.IsSevered && j.LimbB != null && !j.LimbB.IsSevered;
|
||||||
//keep severing joints until there is only one limb left
|
//keep severing joints until there is only one limb left
|
||||||
var nonSeveredJoints = target.AnimController.LimbJoints.Where(CanBeSevered);
|
var nonSeveredJoints = target.AnimController.LimbJoints.Where(CanBeSevered);
|
||||||
if (nonSeveredJoints.None())
|
if (nonSeveredJoints.None())
|
||||||
{
|
{
|
||||||
|
//small monsters don't eat the contents of the character's inventory
|
||||||
|
if (Mass < target.AnimController.Mass)
|
||||||
|
{
|
||||||
|
target.Inventory?.AllItemsMod.ForEach(it => it?.Drop(dropper: null));
|
||||||
|
}
|
||||||
|
|
||||||
//only one limb left, the character is now full eaten
|
//only one limb left, the character is now full eaten
|
||||||
Entity.Spawner?.AddToRemoveQueue(target);
|
Entity.Spawner?.AddToRemoveQueue(target);
|
||||||
|
|
||||||
|
|||||||
+13
-2
@@ -150,6 +150,13 @@ namespace Barotrauma
|
|||||||
private float upperLegLength = 0.0f, lowerLegLength = 0.0f;
|
private float upperLegLength = 0.0f, lowerLegLength = 0.0f;
|
||||||
|
|
||||||
private bool aiming;
|
private bool aiming;
|
||||||
|
private bool wasAiming;
|
||||||
|
|
||||||
|
private bool aimingMelee;
|
||||||
|
private bool wasAimingMelee;
|
||||||
|
|
||||||
|
public bool IsAiming => wasAiming;
|
||||||
|
public bool IsAimingMelee => wasAimingMelee;
|
||||||
|
|
||||||
private readonly float movementLerp;
|
private readonly float movementLerp;
|
||||||
|
|
||||||
@@ -532,7 +539,10 @@ namespace Barotrauma
|
|||||||
limb.Disabled = false;
|
limb.Disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasAiming = aiming;
|
||||||
aiming = false;
|
aiming = false;
|
||||||
|
wasAimingMelee = aimingMelee;
|
||||||
|
aimingMelee = false;
|
||||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) return;
|
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1718,7 +1728,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: refactor this method, it's way too convoluted
|
//TODO: refactor this method, it's way too convoluted
|
||||||
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f)
|
public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f, bool aimingMelee = false)
|
||||||
{
|
{
|
||||||
if (character.Stun > 0.0f || character.IsIncapacitated)
|
if (character.Stun > 0.0f || character.IsIncapacitated)
|
||||||
{
|
{
|
||||||
@@ -1748,6 +1758,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Holdable holdable = item.GetComponent<Holdable>();
|
Holdable holdable = item.GetComponent<Holdable>();
|
||||||
|
|
||||||
|
this.aimingMelee = aimingMelee;
|
||||||
|
|
||||||
if (!isClimbing && !usingController && character.Stun <= 0.0f && aim && itemPos != Vector2.Zero && !character.IsIncapacitated)
|
if (!isClimbing && !usingController && character.Stun <= 0.0f && aim && itemPos != Vector2.Zero && !character.IsIncapacitated)
|
||||||
{
|
{
|
||||||
Vector2 mousePos = ConvertUnits.ToSimUnits(character.SmoothedCursorPosition);
|
Vector2 mousePos = ConvertUnits.ToSimUnits(character.SmoothedCursorPosition);
|
||||||
@@ -1771,7 +1783,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
aiming = true;
|
aiming = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -395,12 +395,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (character.IsHusk && character.Params.UseHuskAppendage)
|
if (character.IsHusk && character.Params.UseHuskAppendage)
|
||||||
{
|
{
|
||||||
|
bool inEditor = false;
|
||||||
|
#if CLIENT
|
||||||
|
inEditor = Screen.Selected == GameMain.CharacterEditorScreen;
|
||||||
|
#endif
|
||||||
|
|
||||||
var characterPrefab = CharacterPrefab.FindByFilePath(character.ConfigPath);
|
var characterPrefab = CharacterPrefab.FindByFilePath(character.ConfigPath);
|
||||||
if (characterPrefab?.XDocument != null)
|
if (characterPrefab?.XDocument != null)
|
||||||
{
|
{
|
||||||
var mainElement = characterPrefab.XDocument.Root.IsOverride() ? characterPrefab.XDocument.Root.FirstElement() : characterPrefab.XDocument.Root;
|
var mainElement = characterPrefab.XDocument.Root.IsOverride() ? characterPrefab.XDocument.Root.FirstElement() : characterPrefab.XDocument.Root;
|
||||||
foreach (var huskAppendage in mainElement.GetChildElements("huskappendage"))
|
foreach (var huskAppendage in mainElement.GetChildElements("huskappendage"))
|
||||||
{
|
{
|
||||||
|
if (!inEditor && huskAppendage.GetAttributeBool("onlyfromafflictions", false)) { continue; }
|
||||||
AfflictionHusk.AttachHuskAppendage(character, huskAppendage.GetAttributeString("affliction", string.Empty), huskAppendage, ragdoll: this);
|
AfflictionHusk.AttachHuskAppendage(character, huskAppendage.GetAttributeString("affliction", string.Empty), huskAppendage, ragdoll: this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ namespace Barotrauma
|
|||||||
public enum HitDetection
|
public enum HitDetection
|
||||||
{
|
{
|
||||||
Distance,
|
Distance,
|
||||||
Contact
|
Contact,
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AttackContext
|
public enum AttackContext
|
||||||
@@ -74,20 +75,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttackData
|
|
||||||
{
|
|
||||||
public float DamageMultiplier { get; set; } = 1f;
|
|
||||||
public float AddedPenetration { get; set; } = 0f;
|
|
||||||
public List<Affliction> Afflictions { get; set; }
|
|
||||||
public Attack SourceAttack { get; }
|
|
||||||
|
|
||||||
public AttackData(Attack sourceAttack)
|
|
||||||
{
|
|
||||||
SourceAttack = sourceAttack;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
partial class Attack : ISerializableEntity
|
partial class Attack : ISerializableEntity
|
||||||
{
|
{
|
||||||
[Serialize(AttackContext.Any, true, description: "The attack will be used only in this context."), Editable]
|
[Serialize(AttackContext.Any, true, description: "The attack will be used only in this context."), Editable]
|
||||||
@@ -466,7 +453,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
DamageParticles(deltaTime, worldPosition);
|
DamageParticles(deltaTime, worldPosition);
|
||||||
|
|
||||||
var attackResult = target.AddDamage(attacker, worldPosition, this, deltaTime, playSound);
|
var attackResult = target?.AddDamage(attacker, worldPosition, this, deltaTime, playSound) ?? new AttackResult();
|
||||||
var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure;
|
var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure;
|
||||||
if (targetCharacter != null && targetCharacter.IsDead)
|
if (targetCharacter != null && targetCharacter.IsDead)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using System.Xml.Linq;
|
|||||||
using Barotrauma.Items.Components;
|
using Barotrauma.Items.Components;
|
||||||
using FarseerPhysics.Dynamics;
|
using FarseerPhysics.Dynamics;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Abilities;
|
||||||
#if SERVER
|
#if SERVER
|
||||||
using System.Text;
|
using System.Text;
|
||||||
#endif
|
#endif
|
||||||
@@ -1366,7 +1367,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private List<Item> wearableItems = new List<Item>();
|
|
||||||
|
|
||||||
public float GetSkillLevel(string skillIdentifier)
|
public float GetSkillLevel(string skillIdentifier)
|
||||||
{
|
{
|
||||||
@@ -2075,11 +2075,10 @@ namespace Barotrauma
|
|||||||
return SelectedCharacter == owner && owner.CanInventoryBeAccessed;
|
return SelectedCharacter == owner && owner.CanInventoryBeAccessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inventory.Owner is Item)
|
if (inventory.Owner is Item item)
|
||||||
{
|
{
|
||||||
var owner = (Item)inventory.Owner;
|
if (!CanInteractWith(item) && !item.linkedTo.Any(lt => lt is Item item && item.DisplaySideBySideWhenLinked && CanInteractWith(item))) { return false; }
|
||||||
if (!CanInteractWith(owner) && !owner.linkedTo.Any(lt => lt is Item item && item.DisplaySideBySideWhenLinked && CanInteractWith(item))) { return false; }
|
ItemContainer container = item.GetComponents<ItemContainer>().FirstOrDefault(ic => ic.Inventory == inventory);
|
||||||
ItemContainer container = owner.GetComponents<ItemContainer>().FirstOrDefault(ic => ic.Inventory == inventory);
|
|
||||||
if (container != null && !container.HasRequiredItems(this, addMessage: false)) { return false; }
|
if (container != null && !container.HasRequiredItems(this, addMessage: false)) { return false; }
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2218,6 +2217,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SelectedConstruction?.GetComponent<RemoteController>()?.TargetItem == item ||
|
||||||
|
HeldItems.Any(it => it.GetComponent<RemoteController>()?.TargetItem == item))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.InteractDistance == 0.0f && !item.Prefab.Triggers.Any()) { return false; }
|
if (item.InteractDistance == 0.0f && !item.Prefab.Triggers.Any()) { return false; }
|
||||||
|
|
||||||
Pickable pickableComponent = item.GetComponent<Pickable>();
|
Pickable pickableComponent = item.GetComponent<Pickable>();
|
||||||
@@ -3355,10 +3360,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
float attackImpulse = attack.TargetImpulse + attack.TargetForce * deltaTime;
|
float attackImpulse = attack.TargetImpulse + attack.TargetForce * deltaTime;
|
||||||
|
|
||||||
AttackData attackData = new AttackData(attack);
|
AbilityAttackData attackData = new AbilityAttackData(attack, this);
|
||||||
attacker.CheckTalents(AbilityEffectType.OnAttack, attackData);
|
if (attacker != null)
|
||||||
CheckTalents(AbilityEffectType.OnAttacked, attackData);
|
{
|
||||||
attackData.DamageMultiplier *= (1 + attacker.GetStatValue(StatTypes.AttackMultiplier));
|
attackData.Attacker = attacker;
|
||||||
|
attacker.CheckTalents(AbilityEffectType.OnAttack, attackData);
|
||||||
|
CheckTalents(AbilityEffectType.OnAttacked, attackData);
|
||||||
|
attackData.DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.AttackMultiplier);
|
||||||
|
if (attacker.TeamID == TeamID)
|
||||||
|
{
|
||||||
|
attackData.DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.TeamAttackMultiplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IEnumerable<Affliction> attackAfflictions;
|
IEnumerable<Affliction> attackAfflictions;
|
||||||
|
|
||||||
@@ -3495,6 +3508,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
attackerCrewmember.CheckTalents(AbilityEffectType.OnCrewKillCharacter, target);
|
attackerCrewmember.CheckTalents(AbilityEffectType.OnCrewKillCharacter, target);
|
||||||
}
|
}
|
||||||
|
CheckTalents(AbilityEffectType.OnKillCharacter, target);
|
||||||
|
|
||||||
if (!IsOnPlayerTeam) { return; }
|
if (!IsOnPlayerTeam) { return; }
|
||||||
if (GameMain.Config.KilledCreatures.Any(name => name.Equals(target.SpeciesName, StringComparison.OrdinalIgnoreCase))) { return; }
|
if (GameMain.Config.KilledCreatures.Any(name => name.Equals(target.SpeciesName, StringComparison.OrdinalIgnoreCase))) { return; }
|
||||||
@@ -3653,10 +3667,7 @@ namespace Barotrauma
|
|||||||
if (statusEffect.type != actionType) { continue; }
|
if (statusEffect.type != actionType) { continue; }
|
||||||
if (statusEffect.type == ActionType.OnDamaged)
|
if (statusEffect.type == ActionType.OnDamaged)
|
||||||
{
|
{
|
||||||
if (statusEffect.AllowedAfflictions != null && (LastDamage.Afflictions == null || LastDamage.Afflictions.None(a => statusEffect.AllowedAfflictions.Contains(a.Prefab.AfflictionType) || statusEffect.AllowedAfflictions.Contains(a.Prefab.Identifier))))
|
if (!statusEffect.HasRequiredAfflictions(LastDamage)) { continue; }
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (statusEffect.OnlyPlayerTriggered)
|
if (statusEffect.OnlyPlayerTriggered)
|
||||||
{
|
{
|
||||||
if (LastAttacker == null || !LastAttacker.IsPlayer)
|
if (LastAttacker == null || !LastAttacker.IsPlayer)
|
||||||
@@ -3719,7 +3730,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Implode(bool isNetworkMessage = false)
|
public void Implode(bool isNetworkMessage = false)
|
||||||
{
|
{
|
||||||
if (CharacterHealth.Unkillable || GodMode || IsDead) { return; }
|
if (CharacterHealth.Unkillable || GodMode || IsDead) { return; }
|
||||||
|
|
||||||
@@ -3829,7 +3840,7 @@ namespace Barotrauma
|
|||||||
if (info != null)
|
if (info != null)
|
||||||
{
|
{
|
||||||
info.CauseOfDeath = CauseOfDeath;
|
info.CauseOfDeath = CauseOfDeath;
|
||||||
info.ResetSavedStatValues();
|
info.MissionsCompletedSinceDeath = 0;
|
||||||
}
|
}
|
||||||
AnimController.movement = Vector2.Zero;
|
AnimController.movement = Vector2.Zero;
|
||||||
AnimController.TargetMovement = Vector2.Zero;
|
AnimController.TargetMovement = Vector2.Zero;
|
||||||
@@ -4434,7 +4445,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private StatTypes GetSkillStatType(string skillIdentifier)
|
public static StatTypes GetSkillStatType(string skillIdentifier)
|
||||||
{
|
{
|
||||||
// Using this method to translate between skill identifiers and stat types. Feel free to replace it if there's a better way
|
// Using this method to translate between skill identifiers and stat types. Feel free to replace it if there's a better way
|
||||||
switch (skillIdentifier)
|
switch (skillIdentifier)
|
||||||
|
|||||||
@@ -462,6 +462,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1;
|
public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1;
|
||||||
|
|
||||||
|
// talent-relevant values
|
||||||
|
public int MissionsCompletedSinceDeath = 0;
|
||||||
|
|
||||||
// Used for creating the data
|
// Used for creating the data
|
||||||
public CharacterInfo(string speciesName, string name = "", string originalName = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, string npcIdentifier = "")
|
public CharacterInfo(string speciesName, string name = "", string originalName = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, string npcIdentifier = "")
|
||||||
{
|
{
|
||||||
@@ -605,7 +608,10 @@ namespace Barotrauma
|
|||||||
if (!string.IsNullOrEmpty(personalityName))
|
if (!string.IsNullOrEmpty(personalityName))
|
||||||
{
|
{
|
||||||
personalityTrait = NPCPersonalityTrait.List.Find(p => p.Name == personalityName);
|
personalityTrait = NPCPersonalityTrait.List.Find(p => p.Name == personalityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MissionsCompletedSinceDeath = infoElement.GetAttributeInt("missionscompletedsincedeath", 0);
|
||||||
|
|
||||||
foreach (XElement subElement in infoElement.Elements())
|
foreach (XElement subElement in infoElement.Elements())
|
||||||
{
|
{
|
||||||
bool jobCreated = false;
|
bool jobCreated = false;
|
||||||
@@ -973,16 +979,17 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
float prevLevel = Job.GetSkillLevel(skillIdentifier);
|
float prevLevel = Job.GetSkillLevel(skillIdentifier);
|
||||||
Job.IncreaseSkillLevel(skillIdentifier, increase);
|
Job.IncreaseSkillLevel(skillIdentifier, increase, Character.HasAbilityFlag(AbilityFlags.GainSkillPastMaximum));
|
||||||
|
|
||||||
float newLevel = Job.GetSkillLevel(skillIdentifier);
|
float newLevel = Job.GetSkillLevel(skillIdentifier);
|
||||||
|
|
||||||
if ((int)newLevel > (int)prevLevel)
|
if ((int)newLevel > (int)prevLevel)
|
||||||
{
|
{
|
||||||
Character.CheckTalents(AbilityEffectType.OnGainSkillPoint, skillIdentifier);
|
Character.CheckTalents(AbilityEffectType.OnGainSkillPoint, skillIdentifier);
|
||||||
|
|
||||||
foreach (Character character in Character.GetFriendlyCrew(Character))
|
foreach (Character character in Character.GetFriendlyCrew(Character))
|
||||||
{
|
{
|
||||||
character.CheckTalents(AbilityEffectType.OnAllyGainSkillPoint, (skillIdentifier, Character));
|
var abilityStringCharacter = new AbilityStringCharacter(skillIdentifier, Character);
|
||||||
|
character.CheckTalents(AbilityEffectType.OnAllyGainSkillPoint, abilityStringCharacter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,9 +1146,10 @@ namespace Barotrauma
|
|||||||
new XAttribute("startitemsgiven", StartItemsGiven),
|
new XAttribute("startitemsgiven", StartItemsGiven),
|
||||||
new XAttribute("ragdoll", ragdollFileName),
|
new XAttribute("ragdoll", ragdollFileName),
|
||||||
new XAttribute("personality", personalityTrait == null ? "" : personalityTrait.Name));
|
new XAttribute("personality", personalityTrait == null ? "" : personalityTrait.Name));
|
||||||
|
|
||||||
// TODO: animations?
|
// TODO: animations?
|
||||||
|
|
||||||
|
charElement.Add(new XAttribute("missionscompletedsincedeath", MissionsCompletedSinceDeath));
|
||||||
|
|
||||||
if (Character != null)
|
if (Character != null)
|
||||||
{
|
{
|
||||||
if (Character.AnimController.CurrentHull != null)
|
if (Character.AnimController.CurrentHull != null)
|
||||||
@@ -1158,6 +1166,7 @@ namespace Barotrauma
|
|||||||
foreach (var savedStat in statValuePair.Value)
|
foreach (var savedStat in statValuePair.Value)
|
||||||
{
|
{
|
||||||
if (savedStat.StatValue == 0f) { continue; }
|
if (savedStat.StatValue == 0f) { continue; }
|
||||||
|
if (savedStat.RemoveAfterRound) { continue; }
|
||||||
|
|
||||||
savedStatElement.Add(new XElement("savedstatvalue",
|
savedStatElement.Add(new XElement("savedstatvalue",
|
||||||
new XAttribute("stattype", statValuePair.Key.ToString()),
|
new XAttribute("stattype", statValuePair.Key.ToString()),
|
||||||
@@ -1168,6 +1177,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
charElement.Add(savedStatElement);
|
charElement.Add(savedStatElement);
|
||||||
|
|
||||||
parentElement.Add(charElement);
|
parentElement.Add(charElement);
|
||||||
@@ -1496,7 +1507,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetSavedStatValue(string statIdentifier)
|
public void ResetSavedStatValue(string statIdentifier)
|
||||||
{
|
{
|
||||||
savedStatValues.SelectMany(s => s.Value).Where(s => s.StatIdentifier == statIdentifier).ForEach(v => v.StatValue = 0f);
|
savedStatValues.SelectMany(s => s.Value).Where(s => s.StatIdentifier == statIdentifier).ForEach(v => v.StatValue = 0f);
|
||||||
@@ -1514,7 +1524,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeSavedStatValue(StatTypes statType, float value, string statIdentifier, bool removeOnDeath)
|
public void ChangeSavedStatValue(StatTypes statType, float value, string statIdentifier, bool removeOnDeath, bool removeAfterRound = false, float maxValue = float.MaxValue)
|
||||||
{
|
{
|
||||||
if (!savedStatValues.ContainsKey(statType))
|
if (!savedStatValues.ContainsKey(statType))
|
||||||
{
|
{
|
||||||
@@ -1523,12 +1533,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (savedStatValues[statType].FirstOrDefault(s => s.StatIdentifier == statIdentifier) is SavedStatValue savedStat)
|
if (savedStatValues[statType].FirstOrDefault(s => s.StatIdentifier == statIdentifier) is SavedStatValue savedStat)
|
||||||
{
|
{
|
||||||
savedStat.StatValue += value;
|
savedStat.StatValue = MathHelper.Min(savedStat.StatValue + value, maxValue);
|
||||||
savedStat.RemoveOnDeath = removeOnDeath;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
savedStatValues[statType].Add(new SavedStatValue(statIdentifier, value, removeOnDeath));
|
savedStatValues[statType].Add(new SavedStatValue(statIdentifier, MathHelper.Min(value, maxValue), removeOnDeath, removeAfterRound));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1538,12 +1547,14 @@ namespace Barotrauma
|
|||||||
public string StatIdentifier { get; set; }
|
public string StatIdentifier { get; set; }
|
||||||
public float StatValue { get; set; }
|
public float StatValue { get; set; }
|
||||||
public bool RemoveOnDeath { get; set; }
|
public bool RemoveOnDeath { get; set; }
|
||||||
|
public bool RemoveAfterRound { get; set; }
|
||||||
|
|
||||||
public SavedStatValue(string statIdentifier, float value, bool removeOnDeath)
|
public SavedStatValue(string statIdentifier, float value, bool removeOnDeath, bool retainAfterRound)
|
||||||
{
|
{
|
||||||
StatValue = value;
|
StatValue = value;
|
||||||
RemoveOnDeath = removeOnDeath;
|
RemoveOnDeath = removeOnDeath;
|
||||||
StatIdentifier = statIdentifier;
|
StatIdentifier = statIdentifier;
|
||||||
|
RemoveAfterRound = retainAfterRound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-25
@@ -17,6 +17,8 @@ namespace Barotrauma
|
|||||||
public float PendingAdditionStrength { get; set; }
|
public float PendingAdditionStrength { get; set; }
|
||||||
public float AdditionStrength { get; set; }
|
public float AdditionStrength { get; set; }
|
||||||
|
|
||||||
|
private float fluctuationTimer;
|
||||||
|
|
||||||
protected float _strength;
|
protected float _strength;
|
||||||
|
|
||||||
[Serialize(0f, true), Editable]
|
[Serialize(0f, true), Editable]
|
||||||
@@ -56,6 +58,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly Dictionary<AfflictionPrefab.PeriodicEffect, float> PeriodicEffectTimers = new Dictionary<AfflictionPrefab.PeriodicEffect, float>();
|
public readonly Dictionary<AfflictionPrefab.PeriodicEffect, float> PeriodicEffectTimers = new Dictionary<AfflictionPrefab.PeriodicEffect, float>();
|
||||||
|
|
||||||
|
public double AppliedAsSuccessfulTreatmentTime, AppliedAsFailedTreatmentTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Which character gave this affliction
|
/// Which character gave this affliction
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,7 +127,7 @@ namespace Barotrauma
|
|||||||
float amount = MathHelper.Lerp(
|
float amount = MathHelper.Lerp(
|
||||||
currentEffect.MinGrainStrength,
|
currentEffect.MinGrainStrength,
|
||||||
currentEffect.MaxGrainStrength,
|
currentEffect.MaxGrainStrength,
|
||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||||
|
|
||||||
if (Prefab.GrainBurst > 0 && AdditionStrength > amount)
|
if (Prefab.GrainBurst > 0 && AdditionStrength > amount)
|
||||||
{
|
{
|
||||||
@@ -138,12 +142,12 @@ namespace Barotrauma
|
|||||||
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return 0.0f; }
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxScreenDistortStrength - currentEffect.MinScreenDistortStrength < 0.0f) { return 0.0f; }
|
if (currentEffect.MaxScreenDistort - currentEffect.MinScreenDistort < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinScreenDistortStrength,
|
currentEffect.MinScreenDistort,
|
||||||
currentEffect.MaxScreenDistortStrength,
|
currentEffect.MaxScreenDistort,
|
||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetRadialDistortStrength()
|
public float GetRadialDistortStrength()
|
||||||
@@ -151,12 +155,12 @@ namespace Barotrauma
|
|||||||
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return 0.0f; }
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxRadialDistortStrength - currentEffect.MinRadialDistortStrength < 0.0f) { return 0.0f; }
|
if (currentEffect.MaxRadialDistort - currentEffect.MinRadialDistort < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinRadialDistortStrength,
|
currentEffect.MinRadialDistort,
|
||||||
currentEffect.MaxRadialDistortStrength,
|
currentEffect.MaxRadialDistort,
|
||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetChromaticAberrationStrength()
|
public float GetChromaticAberrationStrength()
|
||||||
@@ -164,12 +168,12 @@ namespace Barotrauma
|
|||||||
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return 0.0f; }
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxChromaticAberrationStrength - currentEffect.MinChromaticAberrationStrength < 0.0f) { return 0.0f; }
|
if (currentEffect.MaxChromaticAberration - currentEffect.MinChromaticAberration < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinChromaticAberrationStrength,
|
currentEffect.MinChromaticAberration,
|
||||||
currentEffect.MaxChromaticAberrationStrength,
|
currentEffect.MaxChromaticAberration,
|
||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetScreenBlurStrength()
|
public float GetScreenBlurStrength()
|
||||||
@@ -177,12 +181,18 @@ namespace Barotrauma
|
|||||||
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return 0.0f; }
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxScreenBlurStrength - currentEffect.MinScreenBlurStrength < 0.0f) { return 0.0f; }
|
if (currentEffect.MaxScreenBlur - currentEffect.MinScreenBlur < 0.0f) { return 0.0f; }
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinScreenBlurStrength,
|
currentEffect.MinScreenBlur,
|
||||||
currentEffect.MaxScreenBlurStrength,
|
currentEffect.MaxScreenBlur,
|
||||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetScreenEffectFluctuation(AfflictionPrefab.Effect currentEffect)
|
||||||
|
{
|
||||||
|
if (currentEffect == null || currentEffect.ScreenEffectFluctuationFrequency <= 0.0f) { return 1.0f; }
|
||||||
|
return ((float)Math.Sin(fluctuationTimer * MathHelper.TwoPi) + 1.0f) * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetSkillMultiplier()
|
public float GetSkillMultiplier()
|
||||||
@@ -210,14 +220,17 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetResistance(string afflictionId)
|
public float GetResistance(AfflictionPrefab affliction)
|
||||||
{
|
{
|
||||||
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return 0.0f; }
|
if (currentEffect == null) { return 0.0f; }
|
||||||
if (currentEffect.MaxResistance - currentEffect.MinResistance <= 0.0f) { return 0.0f; }
|
if (!currentEffect.ResistanceFor.Any(r =>
|
||||||
if (afflictionId != null && afflictionId != currentEffect.ResistanceFor) { return 0.0f; }
|
r.Equals(affliction.Identifier, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
r.Equals(affliction.AfflictionType, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinResistance,
|
currentEffect.MinResistance,
|
||||||
currentEffect.MaxResistance,
|
currentEffect.MaxResistance,
|
||||||
@@ -229,8 +242,6 @@ namespace Barotrauma
|
|||||||
if (Strength < Prefab.ActivationThreshold) { return 1.0f; }
|
if (Strength < Prefab.ActivationThreshold) { return 1.0f; }
|
||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return 1.0f; }
|
if (currentEffect == null) { return 1.0f; }
|
||||||
if (currentEffect.MaxSpeedMultiplier - currentEffect.MinSpeedMultiplier <= 0.0f) { return 1.0f; }
|
|
||||||
|
|
||||||
return MathHelper.Lerp(
|
return MathHelper.Lerp(
|
||||||
currentEffect.MinSpeedMultiplier,
|
currentEffect.MinSpeedMultiplier,
|
||||||
currentEffect.MaxSpeedMultiplier,
|
currentEffect.MaxSpeedMultiplier,
|
||||||
@@ -282,6 +293,9 @@ namespace Barotrauma
|
|||||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||||
if (currentEffect == null) { return; }
|
if (currentEffect == null) { return; }
|
||||||
|
|
||||||
|
fluctuationTimer += deltaTime * currentEffect.ScreenEffectFluctuationFrequency;
|
||||||
|
fluctuationTimer %= 1.0f;
|
||||||
|
|
||||||
if (currentEffect.StrengthChange < 0) // Reduce diminishing of buffs if boosted
|
if (currentEffect.StrengthChange < 0) // Reduce diminishing of buffs if boosted
|
||||||
{
|
{
|
||||||
float durationMultiplier = 1 / (1 + (Prefab.IsBuff ? characterHealth.Character.GetStatValue(StatTypes.BuffDurationMultiplier)
|
float durationMultiplier = 1 / (1 + (Prefab.IsBuff ? characterHealth.Character.GetStatValue(StatTypes.BuffDurationMultiplier)
|
||||||
@@ -290,9 +304,9 @@ namespace Barotrauma
|
|||||||
_strength += currentEffect.StrengthChange * deltaTime * StrengthDiminishMultiplier * durationMultiplier;
|
_strength += currentEffect.StrengthChange * deltaTime * StrengthDiminishMultiplier * durationMultiplier;
|
||||||
|
|
||||||
}
|
}
|
||||||
else // Reduce strengthening of afflictions if resistant
|
else if (currentEffect.StrengthChange > 0) // Reduce strengthening of afflictions if resistant
|
||||||
{
|
{
|
||||||
_strength += currentEffect.StrengthChange * deltaTime * (1f - characterHealth.GetResistance(Prefab.Identifier));
|
_strength += currentEffect.StrengthChange * deltaTime * (1f - characterHealth.GetResistance(Prefab));
|
||||||
}
|
}
|
||||||
// Don't use the property, because it's virtual and some afflictions like husk overload it for external use.
|
// Don't use the property, because it's virtual and some afflictions like husk overload it for external use.
|
||||||
_strength = MathHelper.Clamp(_strength, 0.0f, Prefab.MaxStrength);
|
_strength = MathHelper.Clamp(_strength, 0.0f, Prefab.MaxStrength);
|
||||||
|
|||||||
+9
-3
@@ -34,6 +34,10 @@ namespace Barotrauma
|
|||||||
float threshold = _strength > ActiveThreshold ? ActiveThreshold + 1 : DormantThreshold - 1;
|
float threshold = _strength > ActiveThreshold ? ActiveThreshold + 1 : DormantThreshold - 1;
|
||||||
float max = Math.Max(threshold, previousValue);
|
float max = Math.Max(threshold, previousValue);
|
||||||
_strength = Math.Clamp(value, 0, max);
|
_strength = Math.Clamp(value, 0, max);
|
||||||
|
if (previousValue > 0.0f && value <= 0.0f)
|
||||||
|
{
|
||||||
|
DeactivateHusk();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,8 +55,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float DormantThreshold => Prefab.MaxStrength * 0.5f;
|
private float DormantThreshold => (Prefab as AfflictionPrefabHusk)?.DormantThreshold ?? Prefab.MaxStrength * 0.5f;
|
||||||
private float ActiveThreshold => Prefab.MaxStrength * 0.75f;
|
private float ActiveThreshold => (Prefab as AfflictionPrefabHusk)?.ActiveThreshold ?? Prefab.MaxStrength * 0.75f;
|
||||||
|
|
||||||
|
private float TransitionThreshold => (Prefab as AfflictionPrefabHusk)?.TransitionThreshold ?? Prefab.MaxStrength * 0.75f;
|
||||||
|
|
||||||
public AfflictionHusk(AfflictionPrefab prefab, float strength) : base(prefab, strength) { }
|
public AfflictionHusk(AfflictionPrefab prefab, float strength) : base(prefab, strength) { }
|
||||||
|
|
||||||
@@ -83,7 +89,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
State = InfectionState.Transition;
|
State = InfectionState.Transition;
|
||||||
}
|
}
|
||||||
else if (Strength < Prefab.MaxStrength)
|
else if (Strength < TransitionThreshold)
|
||||||
{
|
{
|
||||||
if (State != InfectionState.Active)
|
if (State != InfectionState.Active)
|
||||||
{
|
{
|
||||||
|
|||||||
+27
-10
@@ -97,6 +97,10 @@ namespace Barotrauma
|
|||||||
CauseSpeechImpediment = element.GetAttributeBool("causespeechimpediment", true);
|
CauseSpeechImpediment = element.GetAttributeBool("causespeechimpediment", true);
|
||||||
NeedsAir = element.GetAttributeBool("needsair", false);
|
NeedsAir = element.GetAttributeBool("needsair", false);
|
||||||
ControlHusk = element.GetAttributeBool("controlhusk", false);
|
ControlHusk = element.GetAttributeBool("controlhusk", false);
|
||||||
|
|
||||||
|
DormantThreshold = element.GetAttributeFloat("dormantthreshold", MaxStrength * 0.5f);
|
||||||
|
ActiveThreshold = element.GetAttributeFloat("activethreshold", MaxStrength * 0.75f);
|
||||||
|
TransitionThreshold = element.GetAttributeFloat("transitionthreshold", MaxStrength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use any of these to define which limb the appendage is attached to.
|
// Use any of these to define which limb the appendage is attached to.
|
||||||
@@ -105,6 +109,8 @@ namespace Barotrauma
|
|||||||
public readonly string AttachLimbName;
|
public readonly string AttachLimbName;
|
||||||
public readonly LimbType AttachLimbType;
|
public readonly LimbType AttachLimbType;
|
||||||
|
|
||||||
|
public float ActiveThreshold, DormantThreshold, TransitionThreshold;
|
||||||
|
|
||||||
public readonly string HuskedSpeciesName;
|
public readonly string HuskedSpeciesName;
|
||||||
public readonly string[] TargetSpecies;
|
public readonly string[] TargetSpecies;
|
||||||
public const string Tag = "[speciesname]";
|
public const string Tag = "[speciesname]";
|
||||||
@@ -141,28 +147,31 @@ namespace Barotrauma
|
|||||||
public bool MultiplyByMaxVitality { get; private set; }
|
public bool MultiplyByMaxVitality { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MinScreenBlurStrength { get; private set; }
|
public float MinScreenBlur { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MaxScreenBlurStrength { get; private set; }
|
public float MaxScreenBlur { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MinScreenDistortStrength { get; private set; }
|
public float MinScreenDistort { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MaxScreenDistortStrength { get; private set; }
|
public float MaxScreenDistort { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MinRadialDistortStrength { get; private set; }
|
public float MinRadialDistort { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MaxRadialDistortStrength { get; private set; }
|
public float MaxRadialDistort { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MinChromaticAberrationStrength { get; private set; }
|
public float MinChromaticAberration { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MaxChromaticAberrationStrength { get; private set; }
|
public float MaxChromaticAberration { get; private set; }
|
||||||
|
|
||||||
|
[Serialize("255,255,255,255", false)]
|
||||||
|
public Color GrainColor { get; private set; }
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MinGrainStrength { get; private set; }
|
public float MinGrainStrength { get; private set; }
|
||||||
@@ -170,6 +179,9 @@ namespace Barotrauma
|
|||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MaxGrainStrength { get; private set; }
|
public float MaxGrainStrength { get; private set; }
|
||||||
|
|
||||||
|
[Serialize(0.0f, false)]
|
||||||
|
public float ScreenEffectFluctuationFrequency { get; private set; }
|
||||||
|
|
||||||
[Serialize(1.0f, false)]
|
[Serialize(1.0f, false)]
|
||||||
public float MinBuffMultiplier { get; private set; }
|
public float MinBuffMultiplier { get; private set; }
|
||||||
|
|
||||||
@@ -188,8 +200,11 @@ namespace Barotrauma
|
|||||||
[Serialize(1.0f, false)]
|
[Serialize(1.0f, false)]
|
||||||
public float MaxSkillMultiplier { get; private set; }
|
public float MaxSkillMultiplier { get; private set; }
|
||||||
|
|
||||||
[Serialize("", false)]
|
private readonly string[] resistanceFor;
|
||||||
public string ResistanceFor { get; private set; }
|
public IEnumerable<string> ResistanceFor
|
||||||
|
{
|
||||||
|
get { return resistanceFor; }
|
||||||
|
}
|
||||||
|
|
||||||
[Serialize(0.0f, false)]
|
[Serialize(0.0f, false)]
|
||||||
public float MinResistance { get; private set; }
|
public float MinResistance { get; private set; }
|
||||||
@@ -209,6 +224,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
SerializableProperty.DeserializeProperties(this, element);
|
SerializableProperty.DeserializeProperties(this, element);
|
||||||
|
|
||||||
|
resistanceFor = element.GetAttributeStringArray("resistancefor", new string[0], convertToLowerInvariant: true);
|
||||||
|
|
||||||
foreach (XElement subElement in element.Elements())
|
foreach (XElement subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
|
|||||||
@@ -266,6 +266,12 @@ namespace Barotrauma
|
|||||||
private LimbHealth GetMatchingLimbHealth(Limb limb) => limb == null ? null : limbHealths[limb.HealthIndex];
|
private LimbHealth GetMatchingLimbHealth(Limb limb) => limb == null ? null : limbHealths[limb.HealthIndex];
|
||||||
private LimbHealth GetMatchingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb, excludeSevered: false));
|
private LimbHealth GetMatchingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb, excludeSevered: false));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
|
||||||
|
/// </summary>
|
||||||
|
private IEnumerable<Affliction> GetMatchingAfflictions(LimbHealth limb)
|
||||||
|
=> limb.Afflictions.Union(afflictions.Where(a => GetMatchingLimbHealth(a) == limb));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
|
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -426,18 +432,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetResistance(string resistanceId)
|
public float GetResistance(AfflictionPrefab affliction)
|
||||||
{
|
{
|
||||||
float resistance = 0.0f;
|
float resistance = 0.0f;
|
||||||
for (int i = 0; i < afflictions.Count; i++)
|
for (int i = 0; i < afflictions.Count; i++)
|
||||||
{
|
{
|
||||||
if (!afflictions[i].Prefab.IsBuff) continue;
|
resistance += afflictions[i].GetResistance(affliction);
|
||||||
float temp = afflictions[i].GetResistance(resistanceId);
|
|
||||||
if (temp > resistance) resistance = temp;
|
|
||||||
}
|
}
|
||||||
resistance = 1 - ((1 - resistance) * Character.GetAbilityResistance(resistanceId));
|
return 1 - ((1 - resistance) * Character.GetAbilityResistance(affliction.Identifier));
|
||||||
|
|
||||||
return resistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetStatValue(StatTypes statType)
|
public float GetStatValue(StatTypes statType)
|
||||||
@@ -451,7 +453,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<Affliction> matchingAfflictions = new List<Affliction>();
|
private readonly List<Affliction> matchingAfflictions = new List<Affliction>();
|
||||||
public void ReduceAffliction(Limb targetLimb, string affliction, float amount)
|
public void ReduceAffliction(Limb targetLimb, string affliction, float amount, ActionType? treatmentAction = null)
|
||||||
{
|
{
|
||||||
matchingAfflictions.Clear();
|
matchingAfflictions.Clear();
|
||||||
matchingAfflictions.AddRange(afflictions);
|
matchingAfflictions.AddRange(afflictions);
|
||||||
@@ -499,6 +501,17 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
matchingAffliction.Strength -= reduceAmount;
|
matchingAffliction.Strength -= reduceAmount;
|
||||||
amount -= reduceAmount;
|
amount -= reduceAmount;
|
||||||
|
if (treatmentAction != null)
|
||||||
|
{
|
||||||
|
if (treatmentAction.Value == ActionType.OnUse)
|
||||||
|
{
|
||||||
|
matchingAffliction.AppliedAsSuccessfulTreatmentTime = Timing.TotalTime;
|
||||||
|
}
|
||||||
|
else if (treatmentAction.Value == ActionType.OnFailure)
|
||||||
|
{
|
||||||
|
matchingAffliction.AppliedAsFailedTreatmentTime = Timing.TotalTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CalculateVitality();
|
CalculateVitality();
|
||||||
@@ -610,7 +623,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (newAffliction.Prefab == affliction.Prefab)
|
if (newAffliction.Prefab == affliction.Prefab)
|
||||||
{
|
{
|
||||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier));
|
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab));
|
||||||
if (allowStacking)
|
if (allowStacking)
|
||||||
{
|
{
|
||||||
// Add the existing strength
|
// Add the existing strength
|
||||||
@@ -632,7 +645,7 @@ namespace Barotrauma
|
|||||||
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
||||||
//or modify the affliction instance of an Attack or a StatusEffect
|
//or modify the affliction instance of an Attack or a StatusEffect
|
||||||
var copyAffliction = newAffliction.Prefab.Instantiate(
|
var copyAffliction = newAffliction.Prefab.Instantiate(
|
||||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab.Identifier))),
|
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))),
|
||||||
newAffliction.Source);
|
newAffliction.Source);
|
||||||
limbHealth.Afflictions.Add(copyAffliction);
|
limbHealth.Afflictions.Add(copyAffliction);
|
||||||
|
|
||||||
@@ -666,7 +679,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (newAffliction.Prefab == affliction.Prefab)
|
if (newAffliction.Prefab == affliction.Prefab)
|
||||||
{
|
{
|
||||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier));
|
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab));
|
||||||
if (allowStacking)
|
if (allowStacking)
|
||||||
{
|
{
|
||||||
// Add the existing strength
|
// Add the existing strength
|
||||||
@@ -688,7 +701,7 @@ namespace Barotrauma
|
|||||||
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
||||||
//or modify the affliction instance of an Attack or a StatusEffect
|
//or modify the affliction instance of an Attack or a StatusEffect
|
||||||
afflictions.Add(newAffliction.Prefab.Instantiate(
|
afflictions.Add(newAffliction.Prefab.Instantiate(
|
||||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab.Identifier))),
|
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))),
|
||||||
source: newAffliction.Source));
|
source: newAffliction.Source));
|
||||||
|
|
||||||
Character.HealthUpdateInterval = 0.0f;
|
Character.HealthUpdateInterval = 0.0f;
|
||||||
@@ -700,8 +713,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void UpdateProjSpecific(float deltaTime);
|
|
||||||
|
|
||||||
partial void UpdateLimbAfflictionOverlays();
|
partial void UpdateLimbAfflictionOverlays();
|
||||||
|
|
||||||
public void Update(float deltaTime)
|
public void Update(float deltaTime)
|
||||||
@@ -741,7 +752,7 @@ namespace Barotrauma
|
|||||||
for (int i = afflictions.Count - 1; i >= 0; i--)
|
for (int i = afflictions.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var affliction = afflictions[i];
|
var affliction = afflictions[i];
|
||||||
if (irremovableAfflictions.Contains(affliction)) continue;
|
if (irremovableAfflictions.Contains(affliction)) { continue; }
|
||||||
if (affliction.Strength <= 0.0f)
|
if (affliction.Strength <= 0.0f)
|
||||||
{
|
{
|
||||||
SteamAchievementManager.OnAfflictionRemoved(affliction, Character);
|
SteamAchievementManager.OnAfflictionRemoved(affliction, Character);
|
||||||
@@ -763,6 +774,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.SwimmingSpeed));
|
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.SwimmingSpeed));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.WalkingSpeed));
|
||||||
|
}
|
||||||
|
|
||||||
UpdateLimbAfflictionOverlays();
|
UpdateLimbAfflictionOverlays();
|
||||||
|
|
||||||
@@ -786,7 +801,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OxygenAmount = MathHelper.Clamp(OxygenAmount + deltaTime * (Character.OxygenAvailable < InsufficientOxygenThreshold ? -5.0f : 10.0f), -100.0f, 100.0f);
|
float decreaseSpeed = -5.0f;
|
||||||
|
float increaseSpeed = 10.0f;
|
||||||
|
float oxygenlowResistance = GetResistance(oxygenLowAffliction.Prefab);
|
||||||
|
decreaseSpeed *= (1f - oxygenlowResistance);
|
||||||
|
increaseSpeed *= (1f + oxygenlowResistance);
|
||||||
|
OxygenAmount = MathHelper.Clamp(OxygenAmount + deltaTime * (Character.OxygenAvailable < InsufficientOxygenThreshold ? decreaseSpeed : increaseSpeed), -100.0f, 100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateOxygenProjSpecific(prevOxygen, deltaTime);
|
UpdateOxygenProjSpecific(prevOxygen, deltaTime);
|
||||||
@@ -807,8 +827,6 @@ namespace Barotrauma
|
|||||||
Vitality = MaxVitality;
|
Vitality = MaxVitality;
|
||||||
if (Unkillable || Character.GodMode) { return; }
|
if (Unkillable || Character.GodMode) { return; }
|
||||||
|
|
||||||
float damageResistanceMultiplier = 1f - GetResistance("damage");
|
|
||||||
|
|
||||||
foreach (LimbHealth limbHealth in limbHealths)
|
foreach (LimbHealth limbHealth in limbHealths)
|
||||||
{
|
{
|
||||||
foreach (Affliction affliction in limbHealth.Afflictions)
|
foreach (Affliction affliction in limbHealth.Afflictions)
|
||||||
@@ -824,7 +842,6 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
vitalityDecrease *= limbHealth.VitalityTypeMultipliers[type];
|
vitalityDecrease *= limbHealth.VitalityTypeMultipliers[type];
|
||||||
}
|
}
|
||||||
vitalityDecrease *= damageResistanceMultiplier;
|
|
||||||
Vitality -= vitalityDecrease;
|
Vitality -= vitalityDecrease;
|
||||||
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
||||||
}
|
}
|
||||||
@@ -833,7 +850,6 @@ namespace Barotrauma
|
|||||||
foreach (Affliction affliction in afflictions)
|
foreach (Affliction affliction in afflictions)
|
||||||
{
|
{
|
||||||
float vitalityDecrease = affliction.GetVitalityDecrease(this);
|
float vitalityDecrease = affliction.GetVitalityDecrease(this);
|
||||||
vitalityDecrease *= damageResistanceMultiplier;
|
|
||||||
Vitality -= vitalityDecrease;
|
Vitality -= vitalityDecrease;
|
||||||
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
affliction.CalculateDamagePerSecond(vitalityDecrease);
|
||||||
}
|
}
|
||||||
@@ -951,13 +967,13 @@ namespace Barotrauma
|
|||||||
/// <param name="treatmentSuitability">A dictionary where the key is the identifier of the item and the value the suitability</param>
|
/// <param name="treatmentSuitability">A dictionary where the key is the identifier of the item and the value the suitability</param>
|
||||||
/// <param name="normalize">If true, the suitability values are normalized between 0 and 1. If not, they're arbitrary values defined in the medical item XML, where negative values are unsuitable, and positive ones suitable.</param>
|
/// <param name="normalize">If true, the suitability values are normalized between 0 and 1. If not, they're arbitrary values defined in the medical item XML, where negative values are unsuitable, and positive ones suitable.</param>
|
||||||
/// <param name="randomization">Amount of randomization to apply to the values (0 = the values are accurate, 1 = the values are completely random)</param>
|
/// <param name="randomization">Amount of randomization to apply to the values (0 = the values are accurate, 1 = the values are completely random)</param>
|
||||||
public void GetSuitableTreatments(Dictionary<string, float> treatmentSuitability, bool normalize, float randomization = 0.0f)
|
public void GetSuitableTreatments(Dictionary<string, float> treatmentSuitability, bool normalize, Limb limb = null, float randomization = 0.0f)
|
||||||
{
|
{
|
||||||
//key = item identifier
|
//key = item identifier
|
||||||
//float = suitability
|
//float = suitability
|
||||||
treatmentSuitability.Clear();
|
treatmentSuitability.Clear();
|
||||||
float minSuitability = -10, maxSuitability = 10;
|
float minSuitability = -10, maxSuitability = 10;
|
||||||
foreach (Affliction affliction in GetAllAfflictions())
|
foreach (Affliction affliction in getAfflictions(limb))
|
||||||
{
|
{
|
||||||
if (affliction.Strength < affliction.Prefab.TreatmentThreshold) { continue; }
|
if (affliction.Strength < affliction.Prefab.TreatmentThreshold) { continue; }
|
||||||
foreach (KeyValuePair<string, float> treatment in affliction.Prefab.TreatmentSuitability)
|
foreach (KeyValuePair<string, float> treatment in affliction.Prefab.TreatmentSuitability)
|
||||||
@@ -990,6 +1006,18 @@ namespace Barotrauma
|
|||||||
treatmentSuitability[treatment] += Rand.Range(-100.0f, 100.0f) * randomization;
|
treatmentSuitability[treatment] += Rand.Range(-100.0f, 100.0f) * randomization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IEnumerable<Affliction> getAfflictions(Limb limb)
|
||||||
|
{
|
||||||
|
if (limb == null)
|
||||||
|
{
|
||||||
|
return GetAllAfflictions();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GetMatchingAfflictions(GetMatchingLimbHealth(limb));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<Affliction> activeAfflictions = new List<Affliction>();
|
private readonly List<Affliction> activeAfflictions = new List<Affliction>();
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ namespace Barotrauma
|
|||||||
return (skill == null) ? 0.0f : skill.Level;
|
return (skill == null) ? 0.0f : skill.Level;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void IncreaseSkillLevel(string skillIdentifier, float increase)
|
public void IncreaseSkillLevel(string skillIdentifier, float increase, bool increasePastMax)
|
||||||
{
|
{
|
||||||
if (skills.TryGetValue(skillIdentifier, out Skill skill))
|
if (skills.TryGetValue(skillIdentifier, out Skill skill))
|
||||||
{
|
{
|
||||||
skill.Level += increase;
|
skill.IncreaseSkill(increase, increasePastMax);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,11 +7,18 @@ namespace Barotrauma
|
|||||||
private float level;
|
private float level;
|
||||||
|
|
||||||
public string Identifier { get; }
|
public string Identifier { get; }
|
||||||
|
|
||||||
|
public const float MaximumSkill = 100.0f;
|
||||||
|
|
||||||
public float Level
|
public float Level
|
||||||
{
|
{
|
||||||
get { return level; }
|
get { return level; }
|
||||||
set { level = MathHelper.Clamp(value, 0.0f, 100.0f); }
|
set { level = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void IncreaseSkill(float value, bool increasePastMax)
|
||||||
|
{
|
||||||
|
level = MathHelper.Clamp(level + value, 0.0f, increasePastMax ? float.MaxValue : MaximumSkill);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Sprite icon;
|
private Sprite icon;
|
||||||
|
|||||||
@@ -868,7 +868,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1, Limb targetLimb = null)
|
public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1, Limb targetLimb = null)
|
||||||
{
|
{
|
||||||
attackResult = default(AttackResult);
|
attackResult = default;
|
||||||
Vector2 simPos = ragdoll.SimplePhysicsEnabled ? character.SimPosition : SimPosition;
|
Vector2 simPos = ragdoll.SimplePhysicsEnabled ? character.SimPosition : SimPosition;
|
||||||
float dist = distance > -1 ? distance : ConvertUnits.ToDisplayUnits(Vector2.Distance(simPos, attackSimPos));
|
float dist = distance > -1 ? distance : ConvertUnits.ToDisplayUnits(Vector2.Distance(simPos, attackSimPos));
|
||||||
bool wasRunning = attack.IsRunning;
|
bool wasRunning = attack.IsRunning;
|
||||||
@@ -971,7 +971,7 @@ namespace Barotrauma
|
|||||||
wasHit = damageTarget != null;
|
wasHit = damageTarget != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasHit)
|
if (wasHit || attack.HitDetectionType == HitDetection.None)
|
||||||
{
|
{
|
||||||
if (character == Character.Controlled || GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
|
if (character == Character.Controlled || GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
|
||||||
{
|
{
|
||||||
@@ -1132,10 +1132,7 @@ namespace Barotrauma
|
|||||||
if (statusEffect.type != actionType) { continue; }
|
if (statusEffect.type != actionType) { continue; }
|
||||||
if (statusEffect.type == ActionType.OnDamaged)
|
if (statusEffect.type == ActionType.OnDamaged)
|
||||||
{
|
{
|
||||||
if (statusEffect.AllowedAfflictions != null && (character.LastDamage.Afflictions == null || character.LastDamage.Afflictions.None(a => statusEffect.AllowedAfflictions.Contains(a.Prefab.AfflictionType) || statusEffect.AllowedAfflictions.Contains(a.Prefab.Identifier))))
|
if (!statusEffect.HasRequiredAfflictions(character.LastDamage)) { continue; }
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (statusEffect.OnlyPlayerTriggered)
|
if (statusEffect.OnlyPlayerTriggered)
|
||||||
{
|
{
|
||||||
if (character.LastAttacker == null || !character.LastAttacker.IsPlayer)
|
if (character.LastAttacker == null || !character.LastAttacker.IsPlayer)
|
||||||
|
|||||||
+3
-3
@@ -15,7 +15,7 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
private readonly string itemIdentifier;
|
private readonly string itemIdentifier;
|
||||||
private readonly string[] tags;
|
private readonly string[] tags;
|
||||||
private WeaponType weapontype;
|
private readonly WeaponType weapontype;
|
||||||
public AbilityConditionAttackData(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
public AbilityConditionAttackData(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
{
|
{
|
||||||
itemIdentifier = conditionElement.GetAttributeString("itemidentifier", "");
|
itemIdentifier = conditionElement.GetAttributeString("itemidentifier", "");
|
||||||
@@ -33,7 +33,7 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected override bool MatchesConditionSpecific(object abilityData)
|
protected override bool MatchesConditionSpecific(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is AttackData attackData)
|
if (abilityData is AbilityAttackData attackData)
|
||||||
{
|
{
|
||||||
Item item = attackData?.SourceAttack?.SourceItem;
|
Item item = attackData?.SourceAttack?.SourceItem;
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ namespace Barotrauma.Abilities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogAbilityConditionError(abilityData, typeof(AttackData));
|
LogAbilityConditionError(abilityData, typeof(AbilityAttackData));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ namespace Barotrauma.Abilities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogAbilityConditionError(abilityData, typeof(AttackData));
|
LogAbilityConditionError(abilityData, typeof(AbilityAttackData));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -1,7 +1,4 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma.Abilities
|
namespace Barotrauma.Abilities
|
||||||
|
|||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Abilities
|
|
||||||
{
|
|
||||||
class AbilityConditionHandsomeStranger : AbilityConditionData
|
|
||||||
{
|
|
||||||
string skillIdentifier;
|
|
||||||
|
|
||||||
public AbilityConditionHandsomeStranger(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
|
||||||
{
|
|
||||||
skillIdentifier = conditionElement.GetAttributeString("skillidentifier", "").ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool MatchesConditionSpecific(object abilityData)
|
|
||||||
{
|
|
||||||
if (abilityData is string skillIdentifier)
|
|
||||||
{
|
|
||||||
return this.skillIdentifier == skillIdentifier;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogAbilityConditionError(abilityData, typeof(string));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
using Barotrauma.Items.Components;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionIsAiming : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
private enum WeaponType
|
||||||
|
{
|
||||||
|
Any = 0,
|
||||||
|
Melee = 1,
|
||||||
|
Ranged = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
private WeaponType weapontype;
|
||||||
|
public AbilityConditionIsAiming(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
{
|
||||||
|
switch (conditionElement.GetAttributeString("weapontype", ""))
|
||||||
|
{
|
||||||
|
case "melee":
|
||||||
|
weapontype = WeaponType.Melee;
|
||||||
|
break;
|
||||||
|
case "ranged":
|
||||||
|
weapontype = WeaponType.Ranged;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
bool aimingCorrectItem = false;
|
||||||
|
if (character.AnimController is HumanoidAnimController animController)
|
||||||
|
{
|
||||||
|
foreach (Item item in character.HeldItems)
|
||||||
|
{
|
||||||
|
switch (weapontype)
|
||||||
|
{
|
||||||
|
case WeaponType.Melee:
|
||||||
|
aimingCorrectItem |= item.GetComponent<MeleeWeapon>() != null && animController.IsAimingMelee;
|
||||||
|
break;
|
||||||
|
case WeaponType.Ranged:
|
||||||
|
aimingCorrectItem |= item.GetComponent<RangedWeapon>() != null && animController.IsAiming;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
aimingCorrectItem |= animController.IsAiming || animController.IsAimingMelee;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return aimingCorrectItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-3
@@ -22,10 +22,9 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
item = tempItem.Prefab;
|
item = tempItem.Prefab;
|
||||||
}
|
}
|
||||||
// this and other instances of this type of casting will be refactored
|
else if (abilityData is IAbilityItemPrefab abilityItemPrefab)
|
||||||
else if (abilityData is (ItemPrefab itemPrefab, object _))
|
|
||||||
{
|
{
|
||||||
item = itemPrefab;
|
item = abilityItemPrefab.ItemPrefab;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
|
|||||||
+4
-4
@@ -15,17 +15,17 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected override bool MatchesConditionSpecific(object abilityData)
|
protected override bool MatchesConditionSpecific(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is (Affliction affliction, float reduceAmount))
|
if (abilityData is IAbilityAffliction abilityAffliction)
|
||||||
{
|
{
|
||||||
if (allowedTypes.Find(c => c == affliction.Prefab.AfflictionType) == null) { return false; }
|
if (allowedTypes.Find(c => c == abilityAffliction.Affliction.Prefab.AfflictionType) == null) { return false; }
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(identifier) && affliction.Prefab.Identifier != identifier) { return false; }
|
if (!string.IsNullOrEmpty(identifier) && abilityAffliction.Affliction.Prefab.Identifier != identifier) { return false; }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogAbilityConditionError(abilityData, typeof((Affliction, float)));
|
LogAbilityConditionError(abilityData, typeof(IAbilityAffliction));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionSkill : AbilityConditionData
|
||||||
|
{
|
||||||
|
private readonly string skillIdentifier;
|
||||||
|
|
||||||
|
public AbilityConditionSkill(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
{
|
||||||
|
skillIdentifier = conditionElement.GetAttributeString("skillidentifier", "").ToLowerInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool MatchesConditionSpecific(string skillIdentifier)
|
||||||
|
{
|
||||||
|
return this.skillIdentifier == skillIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific(object abilityData)
|
||||||
|
{
|
||||||
|
if ((abilityData as string ?? (abilityData as IAbilityString)?.String) is string skillIdentifier)
|
||||||
|
{
|
||||||
|
return MatchesConditionSpecific(skillIdentifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogAbilityConditionError(abilityData, typeof(string));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-3
@@ -1,11 +1,10 @@
|
|||||||
using System.Linq;
|
using System.Xml.Linq;
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Abilities
|
namespace Barotrauma.Abilities
|
||||||
{
|
{
|
||||||
class AbilityConditionAboveVitality : AbilityConditionDataless
|
class AbilityConditionAboveVitality : AbilityConditionDataless
|
||||||
{
|
{
|
||||||
float vitalityPercentage;
|
private readonly float vitalityPercentage;
|
||||||
|
|
||||||
public AbilityConditionAboveVitality(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
public AbilityConditionAboveVitality(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
{
|
{
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionCoauthor : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
private readonly string jobIdentifier;
|
||||||
|
|
||||||
|
public AbilityConditionCoauthor(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
{
|
||||||
|
jobIdentifier = conditionElement.GetAttributeString("jobidentifier", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
if (character.SelectedCharacter is Character otherCharacter)
|
||||||
|
{
|
||||||
|
if (!otherCharacter.HasJob(jobIdentifier)) { return false; }
|
||||||
|
if (!(character.SelectedBy == otherCharacter)) { return false; }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-5
@@ -1,8 +1,4 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using System.Xml.Linq;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Abilities
|
namespace Barotrauma.Abilities
|
||||||
{
|
{
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionHasPermanentStat : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
private readonly StatTypes statType;
|
||||||
|
private readonly float min;
|
||||||
|
|
||||||
|
public AbilityConditionHasPermanentStat(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
{
|
||||||
|
statType = CharacterAbilityGroup.ParseStatType(conditionElement.GetAttributeString("stattype", ""), characterTalent.DebugIdentifier);
|
||||||
|
min = conditionElement.GetAttributeFloat("min", 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
// should consider decoupling this from stat values entirely
|
||||||
|
return character.Info.GetSavedStatValue(statType) >= min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionHasStatusTag : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
private readonly string tag;
|
||||||
|
|
||||||
|
|
||||||
|
public AbilityConditionHasStatusTag(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
{
|
||||||
|
tag = conditionElement.GetAttributeString("tag", "");
|
||||||
|
if (string.IsNullOrEmpty(tag))
|
||||||
|
{
|
||||||
|
DebugConsole.AddWarning($"Error in talent \"{characterTalent.Prefab.OriginalName}\" - tag not defined in AbilityConditionHasStatusTag.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(tag))
|
||||||
|
{
|
||||||
|
return
|
||||||
|
StatusEffect.DurationList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag)) ||
|
||||||
|
DelayedEffect.DelayList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionInFriendlySubmarine : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
public AbilityConditionInFriendlySubmarine(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { }
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
return character.Submarine?.TeamID == character.TeamID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionInHull : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
public AbilityConditionInHull(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { }
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
return character.CurrentHull != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class AbilityConditionLevelsBehindHighest : AbilityConditionDataless
|
||||||
|
{
|
||||||
|
private readonly int levelsBehind;
|
||||||
|
public AbilityConditionLevelsBehindHighest(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
{
|
||||||
|
levelsBehind = conditionElement.GetAttributeInt("levelsbehind", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool MatchesConditionSpecific()
|
||||||
|
{
|
||||||
|
return Character.GetFriendlyCrew(character).Where(c => c.Info != null && (c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind)).Any();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -24,13 +24,13 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected override bool MatchesConditionSpecific(object abilityData)
|
protected override bool MatchesConditionSpecific(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is (Mission mission, AbilityValue missionAbilityValue))
|
if (abilityData is IAbilityMission abilityMission)
|
||||||
{
|
{
|
||||||
return mission.Prefab.Type == missionType;
|
return abilityMission.Mission.Prefab.Type == missionType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogAbilityConditionError(abilityData, typeof((Mission, AbilityValue)));
|
LogAbilityConditionError(abilityData, typeof(IAbilityMission));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -1,14 +1,10 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using System.Xml.Linq;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma.Abilities
|
namespace Barotrauma.Abilities
|
||||||
{
|
{
|
||||||
class AbilityConditionServerRandom : AbilityConditionDataless
|
class AbilityConditionServerRandom : AbilityConditionDataless
|
||||||
{
|
{
|
||||||
private float randomChance = 0f;
|
private readonly float randomChance = 0f;
|
||||||
public override bool AllowClientSimulation => false;
|
public override bool AllowClientSimulation => false;
|
||||||
|
|
||||||
public AbilityConditionServerRandom(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
public AbilityConditionServerRandom(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement)
|
||||||
|
|||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
interface IAbilityItemPrefab
|
||||||
|
{
|
||||||
|
public ItemPrefab ItemPrefab { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAbilityValue
|
||||||
|
{
|
||||||
|
public float Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAbilityMission
|
||||||
|
{
|
||||||
|
public Mission Mission { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAbilityCharacter
|
||||||
|
{
|
||||||
|
public Character Character { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAbilityString
|
||||||
|
{
|
||||||
|
public string String { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAbilityAffliction
|
||||||
|
{
|
||||||
|
public Affliction Affliction { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
|
||||||
|
class AbilityValue : IAbilityValue
|
||||||
|
{
|
||||||
|
public AbilityValue(float value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
public float Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbilityValueItem : IAbilityValue, IAbilityItemPrefab
|
||||||
|
{
|
||||||
|
public AbilityValueItem(float value, ItemPrefab itemPrefab)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
ItemPrefab = itemPrefab;
|
||||||
|
}
|
||||||
|
public float Value { get; set; }
|
||||||
|
public ItemPrefab ItemPrefab { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbilityValueString : IAbilityValue, IAbilityString
|
||||||
|
{
|
||||||
|
public AbilityValueString(float value, string abilityString)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
String = abilityString;
|
||||||
|
}
|
||||||
|
public float Value { get; set; }
|
||||||
|
public string String { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbilityStringCharacter : IAbilityCharacter, IAbilityString
|
||||||
|
{
|
||||||
|
public AbilityStringCharacter(string abilityString, Character character)
|
||||||
|
{
|
||||||
|
String = abilityString;
|
||||||
|
Character = character;
|
||||||
|
}
|
||||||
|
public Character Character { get; set; }
|
||||||
|
public string String { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbilityValueAffliction : IAbilityValue, IAbilityAffliction
|
||||||
|
{
|
||||||
|
public AbilityValueAffliction(float value, Affliction affliction)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
Affliction = affliction;
|
||||||
|
}
|
||||||
|
public float Value { get; set; }
|
||||||
|
public Affliction Affliction { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbilityValueMission : IAbilityValue, IAbilityMission
|
||||||
|
{
|
||||||
|
public AbilityValueMission(float value, Mission mission)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
Mission = mission;
|
||||||
|
}
|
||||||
|
public float Value { get; set; }
|
||||||
|
public Mission Mission { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbilityAttackData : IAbilityCharacter
|
||||||
|
{
|
||||||
|
public float DamageMultiplier { get; set; } = 1f;
|
||||||
|
public float AddedPenetration { get; set; } = 0f;
|
||||||
|
public List<Affliction> Afflictions { get; set; }
|
||||||
|
public Attack SourceAttack { get; }
|
||||||
|
public Character Character { get; set; }
|
||||||
|
public Character Attacker { get; set; }
|
||||||
|
|
||||||
|
public AbilityAttackData(Attack sourceAttack, Character character)
|
||||||
|
{
|
||||||
|
SourceAttack = sourceAttack;
|
||||||
|
Character = character;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-7
@@ -12,12 +12,16 @@ namespace Barotrauma.Abilities
|
|||||||
public CharacterTalent CharacterTalent { get; }
|
public CharacterTalent CharacterTalent { get; }
|
||||||
public Character Character { get; }
|
public Character Character { get; }
|
||||||
|
|
||||||
public virtual bool RequiresAlive => true;
|
public bool RequiresAlive { get; }
|
||||||
|
|
||||||
public virtual bool AllowClientSimulation => false;
|
public virtual bool AllowClientSimulation => false;
|
||||||
public virtual bool AppliesEffectOnIntervalUpdate => false;
|
public virtual bool AppliesEffectOnIntervalUpdate => false;
|
||||||
|
|
||||||
private const float DefaultEffectTime = 1.0f;
|
private const float DefaultEffectTime = 1.0f;
|
||||||
|
|
||||||
|
// currently resets if the character dies. would need to be stored in a dictionary of sorts to maintain through death
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used primarily for StatusEffects. Default to constant outside interval abilities.
|
/// Used primarily for StatusEffects. Default to constant outside interval abilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -28,6 +32,7 @@ namespace Barotrauma.Abilities
|
|||||||
CharacterAbilityGroup = characterAbilityGroup;
|
CharacterAbilityGroup = characterAbilityGroup;
|
||||||
CharacterTalent = characterAbilityGroup.CharacterTalent;
|
CharacterTalent = characterAbilityGroup.CharacterTalent;
|
||||||
Character = CharacterTalent.Character;
|
Character = CharacterTalent.Character;
|
||||||
|
RequiresAlive = abilityElement.GetAttributeBool("requiresalive", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsViable()
|
public bool IsViable()
|
||||||
@@ -132,11 +137,5 @@ namespace Barotrauma.Abilities
|
|||||||
}
|
}
|
||||||
return flagType;
|
return flagType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float DistanceToSquaredDistance(float distance)
|
|
||||||
{
|
|
||||||
return distance * distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-4
@@ -10,16 +10,41 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected readonly List<StatusEffect> statusEffects;
|
protected readonly List<StatusEffect> statusEffects;
|
||||||
|
|
||||||
|
private readonly bool applyToSelected;
|
||||||
|
|
||||||
|
readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
|
||||||
|
|
||||||
public CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects"));
|
statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects"));
|
||||||
|
applyToSelected = abilityElement.GetAttributeBool("applytoselected", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ApplyEffectSpecific(Character targetCharacter)
|
protected void ApplyEffectSpecific(Character targetCharacter)
|
||||||
{
|
{
|
||||||
foreach (var statusEffect in statusEffects)
|
foreach (var statusEffect in statusEffects)
|
||||||
{
|
{
|
||||||
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter);
|
if (statusEffect.HasTargetType(StatusEffect.TargetType.UseTarget))
|
||||||
|
{
|
||||||
|
// currently used this to spawn items on the targeted character
|
||||||
|
statusEffect.SetUser(targetCharacter);
|
||||||
|
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targetCharacter);
|
||||||
|
}
|
||||||
|
else if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
|
||||||
|
{
|
||||||
|
targets.Clear();
|
||||||
|
targets.AddRange(statusEffect.GetNearbyTargets(targetCharacter.WorldPosition, targets));
|
||||||
|
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targets);
|
||||||
|
}
|
||||||
|
else if (statusEffect.HasTargetType(StatusEffect.TargetType.This))
|
||||||
|
{
|
||||||
|
statusEffect.SetUser(Character);
|
||||||
|
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, Character);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,13 +55,17 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected override void ApplyEffect(object abilityData)
|
protected override void ApplyEffect(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is Character targetCharacter)
|
if (applyToSelected && Character.SelectedCharacter is Character selectedCharacter)
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific(selectedCharacter);
|
||||||
|
}
|
||||||
|
else if ((abilityData as Character ?? (abilityData as IAbilityCharacter)?.Character) is Character targetCharacter)
|
||||||
{
|
{
|
||||||
ApplyEffectSpecific(targetCharacter);
|
ApplyEffectSpecific(targetCharacter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ApplyEffect();
|
ApplyEffect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
using Barotrauma.Extensions;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class CharacterAbilityApplyStatusEffectsToAllies : CharacterAbilityApplyStatusEffects
|
||||||
|
{
|
||||||
|
private readonly bool allowSelf;
|
||||||
|
|
||||||
|
public CharacterAbilityApplyStatusEffectsToAllies(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
|
{
|
||||||
|
allowSelf = abilityElement.GetAttributeBool("allowself", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void ApplyEffect()
|
||||||
|
{
|
||||||
|
IEnumerable<Character> chosenCharacters = Character.GetFriendlyCrew(Character).Where(c => allowSelf || c != Character);
|
||||||
|
|
||||||
|
foreach (Character character in chosenCharacters)
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific(character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class CharacterAbilityApplyStatusEffectsToAttacker : CharacterAbilityApplyStatusEffects
|
||||||
|
{
|
||||||
|
public CharacterAbilityApplyStatusEffectsToAttacker(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyEffect(object abilityData)
|
||||||
|
{
|
||||||
|
if ((abilityData as AbilityAttackData)?.Attacker is Character attacker)
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific(attacker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-4
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma.Abilities
|
namespace Barotrauma.Abilities
|
||||||
@@ -10,7 +9,7 @@ namespace Barotrauma.Abilities
|
|||||||
protected float squaredMaxDistance;
|
protected float squaredMaxDistance;
|
||||||
public CharacterAbilityApplyStatusEffectsToNearestAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityApplyStatusEffectsToNearestAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
squaredMaxDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue));
|
squaredMaxDistance = MathF.Pow(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyEffect()
|
protected override void ApplyEffect()
|
||||||
@@ -20,7 +19,7 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
foreach (Character crewCharacter in Character.GetFriendlyCrew(Character))
|
foreach (Character crewCharacter in Character.GetFriendlyCrew(Character))
|
||||||
{
|
{
|
||||||
if (crewCharacter != Character && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(crewCharacter)) is float tempDistance && tempDistance < closestDistance)
|
if (crewCharacter != Character && Vector2.DistanceSquared(Character.WorldPosition, crewCharacter.WorldPosition) is float tempDistance && tempDistance < closestDistance)
|
||||||
{
|
{
|
||||||
closestCharacter = crewCharacter;
|
closestCharacter = crewCharacter;
|
||||||
closestDistance = tempDistance;
|
closestDistance = tempDistance;
|
||||||
|
|||||||
+4
-3
@@ -1,5 +1,6 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
@@ -16,7 +17,7 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
public CharacterAbilityApplyStatusEffectsToRandomAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityApplyStatusEffectsToRandomAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
squaredMaxDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue));
|
squaredMaxDistance = MathF.Pow(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue), 2);
|
||||||
allowDifferentSub = abilityElement.GetAttributeBool("mustbeonsamesub", true);
|
allowDifferentSub = abilityElement.GetAttributeBool("mustbeonsamesub", true);
|
||||||
allowSelf = abilityElement.GetAttributeBool("allowself", true);
|
allowSelf = abilityElement.GetAttributeBool("allowself", true);
|
||||||
}
|
}
|
||||||
@@ -26,9 +27,9 @@ namespace Barotrauma.Abilities
|
|||||||
Character chosenCharacter = null;
|
Character chosenCharacter = null;
|
||||||
|
|
||||||
chosenCharacter = Character.GetFriendlyCrew(Character).Where(c =>
|
chosenCharacter = Character.GetFriendlyCrew(Character).Where(c =>
|
||||||
(allowSelf ||c != Character) &&
|
(allowSelf || c != Character) &&
|
||||||
(allowDifferentSub || c.Submarine == Character.Submarine) &&
|
(allowDifferentSub || c.Submarine == Character.Submarine) &&
|
||||||
Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(c)) is float tempDistance &&
|
Vector2.DistanceSquared(Character.WorldPosition, c.WorldPosition) is float tempDistance &&
|
||||||
tempDistance < squaredMaxDistance).GetRandom();
|
tempDistance < squaredMaxDistance).GetRandom();
|
||||||
|
|
||||||
if (chosenCharacter == null) { return; }
|
if (chosenCharacter == null) { return; }
|
||||||
|
|||||||
+27
-2
@@ -7,16 +7,41 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||||
|
|
||||||
private int amount;
|
private readonly int amount;
|
||||||
|
private StatTypes scalingStatType;
|
||||||
|
|
||||||
public CharacterAbilityGiveMoney(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityGiveMoney(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
amount = abilityElement.GetAttributeInt("amount", 0);
|
amount = abilityElement.GetAttributeInt("amount", 0);
|
||||||
|
scalingStatType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("scalingstattype", "None"), CharacterTalent.DebugIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyEffectSpecific(Character targetCharacter)
|
||||||
|
{
|
||||||
|
float multiplier = 1f;
|
||||||
|
if (scalingStatType != StatTypes.None)
|
||||||
|
{
|
||||||
|
multiplier = 0 + Character.Info.GetSavedStatValue(scalingStatType);
|
||||||
|
}
|
||||||
|
|
||||||
|
targetCharacter.GiveMoney((int)(multiplier * amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyEffect(object abilityData)
|
||||||
|
{
|
||||||
|
if ((abilityData as Character ?? (abilityData as IAbilityCharacter)?.Character) is Character targetCharacter)
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific(targetCharacter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific(Character);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyEffect()
|
protected override void ApplyEffect()
|
||||||
{
|
{
|
||||||
Character.GiveMoney(amount);
|
ApplyEffectSpecific(Character);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -8,8 +8,10 @@ namespace Barotrauma.Abilities
|
|||||||
private readonly string statIdentifier;
|
private readonly string statIdentifier;
|
||||||
private readonly StatTypes statType;
|
private readonly StatTypes statType;
|
||||||
private readonly float value;
|
private readonly float value;
|
||||||
|
private readonly float maxValue;
|
||||||
private readonly bool targetAllies;
|
private readonly bool targetAllies;
|
||||||
private readonly bool removeOnDeath;
|
private readonly bool removeOnDeath;
|
||||||
|
private readonly bool removeAfterRound;
|
||||||
//private readonly float maximumValue;
|
//private readonly float maximumValue;
|
||||||
|
|
||||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||||
@@ -19,8 +21,10 @@ namespace Barotrauma.Abilities
|
|||||||
statIdentifier = abilityElement.GetAttributeString("statidentifier", "").ToLowerInvariant();
|
statIdentifier = abilityElement.GetAttributeString("statidentifier", "").ToLowerInvariant();
|
||||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||||
value = abilityElement.GetAttributeFloat("value", 0f);
|
value = abilityElement.GetAttributeFloat("value", 0f);
|
||||||
|
maxValue = abilityElement.GetAttributeFloat("maxvalue", float.MaxValue);
|
||||||
targetAllies = abilityElement.GetAttributeBool("targetallies", false);
|
targetAllies = abilityElement.GetAttributeBool("targetallies", false);
|
||||||
removeOnDeath = abilityElement.GetAttributeBool("removeondeath", true);
|
removeOnDeath = abilityElement.GetAttributeBool("removeondeath", true);
|
||||||
|
removeAfterRound = abilityElement.GetAttributeBool("removeafterround", false);
|
||||||
//maximumValue = abilityElement.GetAttributeFloat("maximumvalue", float.MaxValue);
|
//maximumValue = abilityElement.GetAttributeFloat("maximumvalue", float.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,11 +42,11 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
if (targetAllies)
|
if (targetAllies)
|
||||||
{
|
{
|
||||||
Character.GetFriendlyCrew(Character).ForEach(c => c?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath));
|
Character.GetFriendlyCrew(Character).ForEach(c => c?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath, removeAfterRound, maxValue));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Character?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath);
|
Character?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath, removeAfterRound, maxValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -4,18 +4,23 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
class CharacterAbilityGiveResistance : CharacterAbility
|
class CharacterAbilityGiveResistance : CharacterAbility
|
||||||
{
|
{
|
||||||
private string resistanceId;
|
private readonly string resistanceId;
|
||||||
private float resistance;
|
private readonly float multiplier;
|
||||||
|
|
||||||
public CharacterAbilityGiveResistance(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityGiveResistance(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
resistanceId = abilityElement.GetAttributeString("resistanceid", "");
|
resistanceId = abilityElement.GetAttributeString("resistanceid", "");
|
||||||
resistance = abilityElement.GetAttributeFloat("resistance", 1f);
|
multiplier = abilityElement.GetAttributeFloat("multiplier", 1f);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(resistanceId))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in CharacterAbilityGiveResistance - resistance identifier not set.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitializeAbility(bool addingFirstTime)
|
public override void InitializeAbility(bool addingFirstTime)
|
||||||
{
|
{
|
||||||
Character.ChangeAbilityResistance(resistanceId, resistance);
|
Character.ChangeAbilityResistance(resistanceId, multiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -4,10 +4,9 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
class CharacterAbilityGiveStat : CharacterAbility
|
class CharacterAbilityGiveStat : CharacterAbility
|
||||||
{
|
{
|
||||||
private StatTypes statType;
|
private readonly StatTypes statType;
|
||||||
private float value;
|
private readonly float value;
|
||||||
|
|
||||||
// this and resistance giving should probably be moved directly to charactertalent attributes, as they don't need to interact with either ability group types
|
|
||||||
public CharacterAbilityGiveStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityGiveStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||||
|
|||||||
+12
-3
@@ -7,8 +7,9 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
private readonly List<Affliction> afflictions;
|
private readonly List<Affliction> afflictions;
|
||||||
|
|
||||||
float addedDamageMultiplier;
|
private readonly float addedDamageMultiplier;
|
||||||
float addedPenetration;
|
private readonly float addedPenetration;
|
||||||
|
private readonly bool implode;
|
||||||
|
|
||||||
public CharacterAbilityModifyAttackData(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityModifyAttackData(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
@@ -18,11 +19,12 @@ namespace Barotrauma.Abilities
|
|||||||
}
|
}
|
||||||
addedDamageMultiplier = abilityElement.GetAttributeFloat("addeddamagemultiplier", 0f);
|
addedDamageMultiplier = abilityElement.GetAttributeFloat("addeddamagemultiplier", 0f);
|
||||||
addedPenetration = abilityElement.GetAttributeFloat("addedpenetration", 0f);
|
addedPenetration = abilityElement.GetAttributeFloat("addedpenetration", 0f);
|
||||||
|
implode = abilityElement.GetAttributeBool("implode", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyEffect(object abilityData)
|
protected override void ApplyEffect(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is AttackData attackData)
|
if (abilityData is AbilityAttackData attackData)
|
||||||
{
|
{
|
||||||
if (attackData.Afflictions == null)
|
if (attackData.Afflictions == null)
|
||||||
{
|
{
|
||||||
@@ -34,6 +36,13 @@ namespace Barotrauma.Abilities
|
|||||||
}
|
}
|
||||||
attackData.DamageMultiplier += addedDamageMultiplier;
|
attackData.DamageMultiplier += addedDamageMultiplier;
|
||||||
attackData.AddedPenetration += addedPenetration;
|
attackData.AddedPenetration += addedPenetration;
|
||||||
|
|
||||||
|
if (implode)
|
||||||
|
{
|
||||||
|
// might have issues, as the method used to be private and only used for pressure death
|
||||||
|
attackData.Character?.Implode();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-2
@@ -4,8 +4,8 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
class CharacterAbilityModifyResistance : CharacterAbility
|
class CharacterAbilityModifyResistance : CharacterAbility
|
||||||
{
|
{
|
||||||
private string resistanceId;
|
private readonly string resistanceId;
|
||||||
private float resistance;
|
private readonly float resistance;
|
||||||
bool lastState;
|
bool lastState;
|
||||||
|
|
||||||
// should probably be split to different classes
|
// should probably be split to different classes
|
||||||
@@ -13,6 +13,11 @@ namespace Barotrauma.Abilities
|
|||||||
{
|
{
|
||||||
resistanceId = abilityElement.GetAttributeString("resistanceid", "");
|
resistanceId = abilityElement.GetAttributeString("resistanceid", "");
|
||||||
resistance = abilityElement.GetAttributeFloat("resistance", 1f);
|
resistance = abilityElement.GetAttributeFloat("resistance", 1f);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(resistanceId))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in CharacterAbilityModifyResistance - resistance identifier not set.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateCharacterAbility(bool conditionsMatched, float timeSinceLastUpdate)
|
public override void UpdateCharacterAbility(bool conditionsMatched, float timeSinceLastUpdate)
|
||||||
|
|||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class CharacterAbilityModifyStatToSkill : CharacterAbility
|
||||||
|
{
|
||||||
|
private readonly StatTypes statType;
|
||||||
|
private readonly float maxValue;
|
||||||
|
private readonly string skillIdentifier;
|
||||||
|
private readonly bool useAll;
|
||||||
|
private float lastValue = 0f;
|
||||||
|
|
||||||
|
public CharacterAbilityModifyStatToSkill(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
|
{
|
||||||
|
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||||
|
maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f);
|
||||||
|
skillIdentifier = abilityElement.GetAttributeString("skillidentifier", string.Empty);
|
||||||
|
useAll = skillIdentifier == "all";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate)
|
||||||
|
{
|
||||||
|
Character.ChangeStat(statType, -lastValue);
|
||||||
|
|
||||||
|
if (conditionsMatched)
|
||||||
|
{
|
||||||
|
float skillTotal = 0f;
|
||||||
|
|
||||||
|
if (useAll && Character.Info?.Job != null)
|
||||||
|
{
|
||||||
|
foreach (Skill skill in Character.Info.Job.Skills)
|
||||||
|
{
|
||||||
|
skillTotal += Character.GetSkillLevel(skill.Identifier);
|
||||||
|
}
|
||||||
|
skillTotal /= Character.Info.Job.Skills.Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skillTotal = Character.GetSkillLevel(skillIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastValue = skillTotal / 100f * maxValue;
|
||||||
|
Character.ChangeStat(statType, lastValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastValue = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-26
@@ -5,42 +5,21 @@ namespace Barotrauma.Abilities
|
|||||||
class CharacterAbilityModifyValue : CharacterAbility
|
class CharacterAbilityModifyValue : CharacterAbility
|
||||||
{
|
{
|
||||||
private float addedValue;
|
private float addedValue;
|
||||||
private float multiplierValue;
|
private float multiplyValue;
|
||||||
|
|
||||||
public CharacterAbilityModifyValue(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityModifyValue(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
addedValue = abilityElement.GetAttributeFloat("addedvalue", 0f);
|
addedValue = abilityElement.GetAttributeFloat("addedvalue", 0f);
|
||||||
multiplierValue = abilityElement.GetAttributeFloat("multipliervalue", 1f);
|
multiplyValue = abilityElement.GetAttributeFloat("multiplyvalue", 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyEffect(object abilityData)
|
protected override void ApplyEffect(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is AbilityValue abilityValue)
|
if (abilityData is IAbilityValue abilityValue)
|
||||||
{
|
{
|
||||||
ApplyEffectSpecific(abilityValue);
|
abilityValue.Value += addedValue;
|
||||||
|
abilityValue.Value *= multiplyValue;
|
||||||
}
|
}
|
||||||
else if (abilityData is (object _, AbilityValue tupleAbilityValue))
|
|
||||||
{
|
|
||||||
ApplyEffectSpecific(tupleAbilityValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyEffectSpecific(AbilityValue abilityValue)
|
|
||||||
{
|
|
||||||
abilityValue.Value += addedValue;
|
|
||||||
abilityValue.Value *= multiplierValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// this seems like a real silly way to have to pass values by reference into these same interfaces
|
|
||||||
// if more of these are required, maybe there should be an additional set of interfaces to easily pass values by reference instead
|
|
||||||
class AbilityValue
|
|
||||||
{
|
|
||||||
public float Value { get; set; }
|
|
||||||
public AbilityValue(float value)
|
|
||||||
{
|
|
||||||
Value = value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ namespace Barotrauma.Abilities
|
|||||||
class CharacterAbilityResetPermanentStat : CharacterAbility
|
class CharacterAbilityResetPermanentStat : CharacterAbility
|
||||||
{
|
{
|
||||||
private readonly string statIdentifier;
|
private readonly string statIdentifier;
|
||||||
public override bool RequiresAlive => false;
|
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||||
|
|
||||||
public CharacterAbilityResetPermanentStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityResetPermanentStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class CharacterAbilityRevive : CharacterAbility
|
||||||
|
{
|
||||||
|
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||||
|
|
||||||
|
public CharacterAbilityRevive(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyEffectSpecific()
|
||||||
|
{
|
||||||
|
Character.Revive();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyEffect()
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyEffect(object abilityData)
|
||||||
|
{
|
||||||
|
ApplyEffectSpecific();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class CharacterAbilityAlienHoarder : CharacterAbility
|
||||||
|
{
|
||||||
|
private readonly float addedDamageMultiplierPerItem;
|
||||||
|
private readonly int maxAmount;
|
||||||
|
private readonly string[] tags;
|
||||||
|
|
||||||
|
public CharacterAbilityAlienHoarder(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
|
{
|
||||||
|
addedDamageMultiplierPerItem = abilityElement.GetAttributeFloat("addeddamagemultiplierperitem", 0f);
|
||||||
|
maxAmount = abilityElement.GetAttributeInt("maxamount", 0);
|
||||||
|
tags = abilityElement.GetAttributeStringArray("tags", Array.Empty<string>(), convertToLowerInvariant: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyEffect(object abilityData)
|
||||||
|
{
|
||||||
|
if (abilityData is AbilityAttackData attackData)
|
||||||
|
{
|
||||||
|
float totalAddedDamageMultiplier = 0f;
|
||||||
|
foreach (Item item in Character.Inventory.AllItems)
|
||||||
|
{
|
||||||
|
if (tags.Any(t => item.Prefab.Tags.Any(p => t == p)))
|
||||||
|
{
|
||||||
|
totalAddedDamageMultiplier += addedDamageMultiplierPerItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attackData.DamageMultiplier += addedDamageMultiplierPerItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogAbilityDataMismatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -12,9 +12,9 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected override void ApplyEffect(object abilityData)
|
protected override void ApplyEffect(object abilityData)
|
||||||
{
|
{
|
||||||
if (abilityData is (string skillIdentifier, Character character) && character != Character)
|
if (abilityData is AbilityStringCharacter abilityStringCharacter && abilityStringCharacter.Character != Character)
|
||||||
{
|
{
|
||||||
character.Info?.IncreaseSkillLevel(skillIdentifier, 1.0f, character.Position + Vector2.UnitY * 175.0f);
|
Character.Info?.IncreaseSkillLevel(abilityStringCharacter.String, 1.0f, abilityStringCharacter.Character.Position + Vector2.UnitY * 175.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma.Abilities
|
||||||
|
{
|
||||||
|
class CharacterAbilityByTheBook : CharacterAbility
|
||||||
|
{
|
||||||
|
private int moneyAmount;
|
||||||
|
private int max;
|
||||||
|
|
||||||
|
public CharacterAbilityByTheBook(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
|
{
|
||||||
|
moneyAmount = abilityElement.GetAttributeInt("moneyamount", 0);
|
||||||
|
max = abilityElement.GetAttributeInt("max", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyEffect()
|
||||||
|
{
|
||||||
|
IEnumerable<Character> enemyCharacters = Character.CharacterList.Where(c => c.TeamID == CharacterTeamType.None);
|
||||||
|
|
||||||
|
int timesGiven = 0;
|
||||||
|
foreach (Character enemyCharacter in enemyCharacters)
|
||||||
|
{
|
||||||
|
if (!enemyCharacter.IsHuman) { continue; }
|
||||||
|
if (enemyCharacter.Submarine == null || enemyCharacter.Submarine != Submarine.MainSub) { continue; }
|
||||||
|
if (enemyCharacter.IsDead) { continue; }
|
||||||
|
if (!enemyCharacter.LockHands) { continue; }
|
||||||
|
if (timesGiven > max) { continue; }
|
||||||
|
Character.GiveMoney(moneyAmount);
|
||||||
|
timesGiven++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-27
@@ -9,45 +9,22 @@ namespace Barotrauma.Abilities
|
|||||||
class CharacterAbilityInsurancePolicy : CharacterAbility
|
class CharacterAbilityInsurancePolicy : CharacterAbility
|
||||||
{
|
{
|
||||||
public override bool AppliesEffectOnIntervalUpdate => true;
|
public override bool AppliesEffectOnIntervalUpdate => true;
|
||||||
public override bool RequiresAlive => false;
|
|
||||||
|
|
||||||
private readonly int moneyPerLevel;
|
private readonly int moneyPerMission;
|
||||||
private bool hasOccurred = false;
|
|
||||||
|
|
||||||
private static List<Client> clientsAlreadyUsed = new List<Client>();
|
private static List<Client> clientsAlreadyUsed = new List<Client>();
|
||||||
|
|
||||||
public CharacterAbilityInsurancePolicy(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityInsurancePolicy(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
moneyPerLevel = abilityElement.GetAttributeInt("moneyperlevel", 0);
|
moneyPerMission = abilityElement.GetAttributeInt("moneypermission", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyEffect()
|
protected override void ApplyEffect()
|
||||||
{
|
{
|
||||||
if (Character?.Info is CharacterInfo info && !hasOccurred)
|
if (Character?.Info is CharacterInfo info)
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
|
||||||
{
|
|
||||||
foreach (Client client in GameMain.NetworkMember.ConnectedClients)
|
|
||||||
{
|
|
||||||
if (client.Character == Character && clientsAlreadyUsed.Contains(client)) { return; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Character.GiveMoney(moneyPerLevel * info.GetCurrentLevel());
|
Character.GiveMoney(moneyPerMission * info.MissionsCompletedSinceDeath);
|
||||||
hasOccurred = true;
|
|
||||||
|
|
||||||
// this is an ugly way to do this, but this effect should not occur more than once per round for a client
|
|
||||||
// this seemed like the simplest way to do it since characters are instantiated from scratch each time
|
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
|
||||||
{
|
|
||||||
foreach (Client client in GameMain.NetworkMember.ConnectedClients)
|
|
||||||
{
|
|
||||||
if (client.Character == Character)
|
|
||||||
{
|
|
||||||
clientsAlreadyUsed.Add(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -5,14 +5,14 @@ namespace Barotrauma.Abilities
|
|||||||
class CharacterAbilityPsychoClown : CharacterAbility
|
class CharacterAbilityPsychoClown : CharacterAbility
|
||||||
{
|
{
|
||||||
private StatTypes statType;
|
private StatTypes statType;
|
||||||
private float value;
|
private float maxValue;
|
||||||
private string afflictionIdentifier;
|
private string afflictionIdentifier;
|
||||||
private float lastValue = 0f;
|
private float lastValue = 0f;
|
||||||
|
|
||||||
public CharacterAbilityPsychoClown(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
public CharacterAbilityPsychoClown(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||||
{
|
{
|
||||||
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier);
|
||||||
value = abilityElement.GetAttributeFloat("value", 0f);
|
maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f);
|
||||||
afflictionIdentifier = abilityElement.GetAttributeString("afflictionidentifier", "");
|
afflictionIdentifier = abilityElement.GetAttributeString("afflictionidentifier", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ namespace Barotrauma.Abilities
|
|||||||
afflictionStrength = affliction.Strength / affliction.Prefab.MaxStrength;
|
afflictionStrength = affliction.Strength / affliction.Prefab.MaxStrength;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastValue = afflictionStrength * value;
|
lastValue = afflictionStrength * maxValue;
|
||||||
Character.ChangeStat(statType, lastValue);
|
Character.ChangeStat(statType, lastValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user