Release 1.9.7.0 - Summer Update 2025
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -12,7 +10,11 @@ namespace Barotrauma
|
||||
{
|
||||
public readonly DelayedEffect Parent;
|
||||
public readonly Entity Entity;
|
||||
public readonly Vector2? WorldPosition;
|
||||
public Vector2? WorldPosition;
|
||||
/// <summary>
|
||||
/// Should the delayed effect attempt to determine the position of the effect based on the targets, or just use the position that was passed to the constructor.
|
||||
/// </summary>
|
||||
public bool GetPositionBasedOnTargets;
|
||||
public readonly Vector2? StartPosition;
|
||||
public readonly List<ISerializableEntity> Targets;
|
||||
public float Delay;
|
||||
@@ -62,7 +64,10 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (var existingEffect in DelayList)
|
||||
{
|
||||
if (existingEffect.Parent == this && existingEffect.Targets.FirstOrDefault() == target) { return; }
|
||||
if (existingEffect.Parent == this && existingEffect.Targets.FirstOrDefault() == target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IsValidTarget(target)) { return; }
|
||||
@@ -74,7 +79,11 @@ namespace Barotrauma
|
||||
switch (delayType)
|
||||
{
|
||||
case DelayTypes.Timer:
|
||||
DelayList.Add(new DelayedListElement(this, entity, currentTargets, delay, worldPosition ?? GetPosition(entity, currentTargets, worldPosition), startPosition: null));
|
||||
var newDelayListElement = new DelayedListElement(this, entity, currentTargets, delay, worldPosition ?? GetPosition(entity, currentTargets, worldPosition), startPosition: null)
|
||||
{
|
||||
GetPositionBasedOnTargets = worldPosition == null
|
||||
};
|
||||
DelayList.Add(newDelayListElement);
|
||||
break;
|
||||
case DelayTypes.ReachCursor:
|
||||
Projectile projectile = (entity as Item)?.GetComponent<Projectile>();
|
||||
@@ -171,7 +180,16 @@ namespace Barotrauma
|
||||
{
|
||||
case DelayTypes.Timer:
|
||||
element.Delay -= deltaTime;
|
||||
if (element.Delay > 0.0f) { continue; }
|
||||
if (element.Delay > 0.0f)
|
||||
{
|
||||
//if the delayed effect is supposed to get the position from the targets,
|
||||
//keep refreshing the position until the effect runs (so e.g. a delayed effect runs at the last known position of a monster before it despawned)
|
||||
if (element.GetPositionBasedOnTargets && element.Entity is { Removed: false })
|
||||
{
|
||||
element.WorldPosition = element.Parent.GetPosition(element.Entity, element.Parent.currentTargets);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case DelayTypes.ReachCursor:
|
||||
if (Vector2.Distance(element.Entity.WorldPosition, element.StartPosition.Value) < element.Delay) { continue; }
|
||||
|
||||
@@ -5,6 +5,7 @@ using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Steamworks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
@@ -639,6 +640,10 @@ namespace Barotrauma
|
||||
/// Should the sound(s) configured in the effect be played if the required items aren't found?
|
||||
/// </summary>
|
||||
private readonly bool playSoundOnRequiredItemFailure = false;
|
||||
|
||||
public readonly record struct SteamTimeLineEvent(string title, string description, string icon);
|
||||
private readonly SteamTimeLineEvent steamTimeLineEventToTrigger;
|
||||
|
||||
#endif
|
||||
|
||||
private readonly int useItemCount;
|
||||
@@ -716,6 +721,11 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
private readonly List<(Identifier eventIdentifier, Identifier tag)> eventTargetTags;
|
||||
|
||||
/// <summary>
|
||||
/// Can be used to make the effect unlock a fabrication recipe globally for the entire crew.
|
||||
/// </summary>
|
||||
public readonly Identifier UnlockRecipe;
|
||||
|
||||
private Character user;
|
||||
|
||||
public readonly float FireSize;
|
||||
@@ -926,6 +936,8 @@ namespace Barotrauma
|
||||
playSoundOnRequiredItemFailure = element.GetAttributeBool("playsoundonrequireditemfailure", false);
|
||||
#endif
|
||||
|
||||
UnlockRecipe = element.GetAttributeIdentifier(nameof(UnlockRecipe), Identifier.Empty);
|
||||
|
||||
List<XAttribute> propertyAttributes = new List<XAttribute>();
|
||||
propertyConditionals = new List<PropertyConditional>();
|
||||
foreach (XAttribute attribute in element.Attributes())
|
||||
@@ -1238,6 +1250,26 @@ namespace Barotrauma
|
||||
forceSayIdentifier = subElement.GetAttributeIdentifier("message", Identifier.Empty);
|
||||
forceSayInRadio = subElement.GetAttributeBool("sayinradio", false);
|
||||
break;
|
||||
#if CLIENT
|
||||
case "steamtimelineevent":
|
||||
steamTimeLineEventToTrigger = new SteamTimeLineEvent(
|
||||
subElement.GetAttributeString("title", string.Empty),
|
||||
subElement.GetAttributeString("description", string.Empty),
|
||||
subElement.GetAttributeString("icon", string.Empty));
|
||||
if (steamTimeLineEventToTrigger.title.IsNullOrWhiteSpace())
|
||||
{
|
||||
DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - steam timeline event has no title.", contentPackage: element.ContentPackage);
|
||||
}
|
||||
if (steamTimeLineEventToTrigger.description.IsNullOrWhiteSpace())
|
||||
{
|
||||
DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - steam timeline event has no description.", contentPackage: element.ContentPackage);
|
||||
}
|
||||
if (steamTimeLineEventToTrigger.icon.IsNullOrWhiteSpace())
|
||||
{
|
||||
DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - steam timeline event has no icon.", contentPackage: element.ContentPackage);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
InitProjSpecific(element, parentDebugName);
|
||||
@@ -2122,6 +2154,11 @@ namespace Barotrauma
|
||||
fire.Size = new Vector2(FireSize, fire.Size.Y);
|
||||
}
|
||||
|
||||
if (isNotClient && !UnlockRecipe.IsEmpty && GameMain.GameSession is { } gameSession)
|
||||
{
|
||||
gameSession.UnlockRecipe(UnlockRecipe, showNotifications: true);
|
||||
}
|
||||
|
||||
if (isNotClient && triggeredEvents != null && GameMain.GameSession?.EventManager is { } eventManager)
|
||||
{
|
||||
foreach (EventPrefab eventPrefab in triggeredEvents)
|
||||
@@ -2489,6 +2526,12 @@ namespace Barotrauma
|
||||
{
|
||||
rotation = parentItemBody.TransformRotation(chosenItemSpawnInfo.RotationRad);
|
||||
}
|
||||
else if (parentItem != null)
|
||||
{
|
||||
rotation = PhysicsBody.TransformRotation(
|
||||
-parentItem.RotationRad + chosenItemSpawnInfo.RotationRad,
|
||||
dir: parentItem.FlippedX ? -1.0f : 1.0f);
|
||||
}
|
||||
break;
|
||||
case ItemSpawnInfo.SpawnRotationType.Target:
|
||||
if (!entity.Removed)
|
||||
@@ -2556,11 +2599,17 @@ namespace Barotrauma
|
||||
projectile.Shoot(user, spawnPos, spawnPos, rotation, ignoredBodies: ignoredBodies, createNetworkEvent: true, damageMultiplier: damageMultiplier);
|
||||
projectile.Item.Submarine = projectile.LaunchSub = sourceEntity?.Submarine;
|
||||
}
|
||||
else if (newItem.body != null)
|
||||
else
|
||||
{
|
||||
newItem.body.SetTransform(newItem.SimPosition, rotation);
|
||||
Vector2 impulseDir = new Vector2(MathF.Cos(rotation), MathF.Sin(rotation));
|
||||
newItem.body.ApplyLinearImpulse(impulseDir * chosenItemSpawnInfo.Impulse);
|
||||
if (newItem.body != null)
|
||||
{
|
||||
//flipped on one axis = need to flip the rotation of the item (not if flipped on both, that's essentially double negation)
|
||||
bool flip = parentItem is { FlippedX: true } != parentItem is { FlippedY: true };
|
||||
newItem.body.Dir = flip ? -1 : 1;
|
||||
newItem.body.SetTransform(newItem.SimPosition, flip ? rotation - MathHelper.Pi : rotation);
|
||||
Vector2 impulseDir = new Vector2(MathF.Cos(rotation), MathF.Sin(rotation));
|
||||
newItem.body.ApplyLinearImpulse(impulseDir * chosenItemSpawnInfo.Impulse);
|
||||
}
|
||||
}
|
||||
}
|
||||
OnItemSpawned(newItem, chosenItemSpawnInfo);
|
||||
|
||||
Reference in New Issue
Block a user