Unstable 0.1300.0.7

This commit is contained in:
Markus Isberg
2021-04-07 15:24:22 +03:00
parent 96b2184811
commit 538c3dbfc3
47 changed files with 246 additions and 103 deletions

View File

@@ -55,6 +55,10 @@ namespace Barotrauma
};
TopContainer.Visible = SideContainer.Visible = false;
TopContainer.CanBeFocused = false;
TopContainer.Children.ForEach(c => c.CanBeFocused = false);
SideContainer.CanBeFocused = false;
SideContainer.Children.ForEach(c => c.CanBeFocused = false);
}
}

View File

@@ -465,7 +465,7 @@ namespace Barotrauma
if (currentRichTextData != null && currentRichTextData.StartIndex + lineNum <= i + rtdOffset && i + rtdOffset <= currentRichTextData.EndIndex + lineNum)
{
currentTextColor = currentRichTextData.Color ?? color;
currentTextColor = currentRichTextData.Color * currentRichTextData.Alpha ?? color;
if (!string.IsNullOrEmpty(currentRichTextData.Metadata))
{
currentTextColor = Color.Lerp(currentTextColor, Color.White, 0.5f);

View File

@@ -584,6 +584,7 @@ namespace Barotrauma
if (ToggleOpen)
{
GUIFrame.CanBeFocused = true;
openState += deltaTime * 5.0f;
//delete all popup messages when the chatbox is open
foreach (var popupMsg in popupMessages)
@@ -594,6 +595,7 @@ namespace Barotrauma
}
else
{
GUIFrame.CanBeFocused = false;
openState -= deltaTime * 5.0f;
int yOffset = 0;

View File

@@ -263,6 +263,8 @@ namespace Barotrauma
public bool HasColorHighlight => RichTextData != null;
public bool OverrideRichTextDataAlpha = true;
public struct ClickableArea
{
public RichTextData Data;
@@ -645,10 +647,13 @@ namespace Barotrauma
}
Font.DrawString(spriteBatch, textToShow, pos, colorToShow, 0.0f, origin, TextScale, SpriteEffects.None, textDepth);
}
else
{
if (OverrideRichTextDataAlpha)
{
RichTextData.ForEach(rt => rt.Alpha = currentTextColor.A / 255.0f);
}
Font.DrawStringWithColors(spriteBatch, Censor ? censoredText : (Wrap ? wrappedText : text), pos,
currentTextColor * (currentTextColor.A / 255.0f), 0.0f, origin, TextScale, SpriteEffects.None, textDepth, RichTextData);
}

View File

@@ -626,6 +626,9 @@ namespace Barotrauma
{
if (Text == null) Text = "";
// Prevent alt gr from triggering any of these as that combination is often needed for special characters
if (PlayerInput.IsAltDown()) return;
switch (command)
{
case '\b' when !Readonly: //backspace
@@ -667,7 +670,10 @@ namespace Barotrauma
}
break;
case (char)0x1: // ctrl-a
SelectAll();
if (PlayerInput.IsCtrlDown())
{
SelectAll();
}
break;
case (char)0x1A when !Readonly && !SubEditorScreen.IsSubEditor(): // ctrl-z
text = memento.Undo();

View File

@@ -917,6 +917,13 @@ namespace Barotrauma
var orderInfo = (OrderInfo)userData;
SetCharacterOrder(character, orderInfo.Order, orderInfo.OrderOption, CharacterInfo.HighestManualOrderPriority, Character.Controlled);
return true;
},
OnSecondaryClicked = (button, userData) =>
{
if (previousOrderIconGroup == null) { return false; }
previousOrderIconGroup.RemoveChild(button);
previousOrderIconGroup.Recalculate();
return true;
}
};
prevOrderFrame.RectTransform.IsFixedSize = true;

View File

@@ -695,6 +695,7 @@ namespace Barotrauma
if (firstItem != null && !DraggingItems.Contains(firstItem) && Character.Controlled?.Inventory == this &&
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(visualSlots[i].InventoryKeyIndex))
{
if (SubEditorScreen.IsSubEditor() && SubEditorScreen.SkipInventorySlotUpdate) { continue; }
#if LINUX
// some window managers on Linux use windows key + number to change workspaces or perform other actions
if (PlayerInput.KeyDown(Keys.RightWindows) || PlayerInput.KeyDown(Keys.LeftWindows)) { continue; }

View File

@@ -587,7 +587,7 @@ namespace Barotrauma.Items.Components
//ID ushort.MaxValue = launched without a projectile
if (projectileID == ushort.MaxValue)
{
Launch(null);
Launch(null, user);
}
else
{
@@ -596,7 +596,7 @@ namespace Barotrauma.Items.Components
DebugConsole.ThrowError("Failed to launch a projectile - item with the ID \"" + projectileID + " not found");
return;
}
Launch(projectile, launchRotation: newTargetRotation);
Launch(projectile, user, launchRotation: newTargetRotation);
}
}
}

View File

@@ -134,6 +134,7 @@ namespace Barotrauma.Networking
HasPassword = incMsg.ReadBoolean();
IsPublic = incMsg.ReadBoolean();
GameMain.NetLobbyScreen.SetPublic(IsPublic);
AllowFileTransfers = incMsg.ReadBoolean();
incMsg.ReadPadBits();
TickRate = incMsg.ReadRangedInteger(1, 60);
GameMain.NetworkMember.TickRate = TickRate;

View File

@@ -27,7 +27,8 @@ namespace Barotrauma.Particles
private float angularVelocity;
private Vector2 dragVec = Vector2.Zero;
private int dragWait = 0;
private float dragWait = 0;
private float collisionIgnoreTimer = 0;
private Vector2 size;
private Vector2 sizeChange;
@@ -103,7 +104,7 @@ namespace Barotrauma.Particles
return debugName;
}
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false)
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f)
{
this.prefab = prefab;
debugName = $"Particle ({prefab.Name})";
@@ -174,14 +175,22 @@ namespace Barotrauma.Particles
}
DrawOnTop = drawOnTop;
this.collisionIgnoreTimer = collisionIgnoreTimer;
}
public bool Update(float deltaTime)
public enum UpdateResult
{
Normal,
Delete
}
public UpdateResult Update(float deltaTime)
{
if (startDelay > 0.0f)
{
startDelay -= deltaTime;
return true;
return UpdateResult.Normal;
}
prevPosition = position;
@@ -251,7 +260,7 @@ namespace Barotrauma.Particles
}
lifeTime -= deltaTime;
if (lifeTime <= 0.0f || color.A <= 0 || size.X <= 0.0f || size.Y <= 0.0f) { return false; }
if (lifeTime <= 0.0f || color.A <= 0 || size.X <= 0.0f || size.Y <= 0.0f) { return UpdateResult.Delete; }
if (hasSubEmitters)
{
@@ -261,7 +270,13 @@ namespace Barotrauma.Particles
}
}
if (!prefab.UseCollision) { return true; }
if (collisionIgnoreTimer > 0f)
{
collisionIgnoreTimer -= deltaTime;
if (collisionIgnoreTimer <= 0f) { currentHull ??= Hull.FindHull(position); }
return UpdateResult.Normal;
}
if (!prefab.UseCollision) { return UpdateResult.Normal; }
if (HighQualityCollisionDetection)
{
@@ -278,17 +293,17 @@ namespace Barotrauma.Particles
}
}
return true;
return UpdateResult.Normal;
}
private bool CollisionUpdate()
private UpdateResult CollisionUpdate()
{
if (currentHull == null)
{
Hull collidedHull = Hull.FindHull(position);
if (collidedHull != null)
{
if (prefab.DeleteOnCollision) return false;
if (prefab.DeleteOnCollision) return UpdateResult.Delete;
OnWallCollisionOutside(collidedHull);
}
}
@@ -298,12 +313,12 @@ namespace Barotrauma.Particles
Vector2 collisionNormal = Vector2.Zero;
if (velocity.Y < 0.0f && position.Y - prefab.CollisionRadius * size.Y < hullRect.Y - hullRect.Height)
{
if (prefab.DeleteOnCollision) { return false; }
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
collisionNormal = new Vector2(0.0f, 1.0f);
}
else if (velocity.Y > 0.0f && position.Y + prefab.CollisionRadius * size.Y > hullRect.Y)
{
if (prefab.DeleteOnCollision) { return false; }
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
collisionNormal = new Vector2(0.0f, -1.0f);
}
@@ -328,12 +343,12 @@ namespace Barotrauma.Particles
if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < hullRect.X)
{
if (prefab.DeleteOnCollision) { return false; }
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
collisionNormal = new Vector2(1.0f, 0.0f);
}
else if (velocity.X > 0.0f && position.X + prefab.CollisionRadius * size.X > hullRect.Right)
{
if (prefab.DeleteOnCollision) { return false; }
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
collisionNormal = new Vector2(-1.0f, 0.0f);
}
@@ -374,7 +389,7 @@ namespace Barotrauma.Particles
}
}
return true;
return UpdateResult.Normal;
}
private void ApplyDrag(float dragCoefficient, float deltaTime)
@@ -389,10 +404,10 @@ namespace Barotrauma.Particles
//TODO: some better way to handle particle drag
//this doesn't work that well because the drag vector is only updated every 0.5 seconds, allowing the particle to accelerate way more than it should
//(e.g. a falling particle can freely accelerate for 0.5 seconds before the drag takes effect)
dragWait--;
if (dragWait <= 0)
dragWait-=deltaTime;
if (dragWait <= 0f)
{
dragWait = 30;
dragWait = 0.5f;
float speed = velocity.Length();

View File

@@ -115,12 +115,12 @@ namespace Barotrauma.Particles
Prefabs.RemoveByFile(configFile);
}
public Particle CreateParticle(string prefabName, Vector2 position, float angle, float speed, Hull hullGuess = null)
public Particle CreateParticle(string prefabName, Vector2 position, float angle, float speed, Hull hullGuess = null, float collisionIgnoreTimer = 0f)
{
return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess);
return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess, collisionIgnoreTimer);
}
public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null)
public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, float collisionIgnoreTimer = 0f)
{
ParticlePrefab prefab = FindPrefab(prefabName);
@@ -130,10 +130,10 @@ namespace Barotrauma.Particles
return null;
}
return CreateParticle(prefab, position, velocity, rotation, hullGuess);
return CreateParticle(prefab, position, velocity, rotation, hullGuess, collisionIgnoreTimer: collisionIgnoreTimer);
}
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false)
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false, float collisionIgnoreTimer = 0f)
{
if (particleCount >= MaxParticles || prefab == null || prefab.Sprites.Count == 0) { return null; }
@@ -149,7 +149,7 @@ namespace Barotrauma.Particles
if (particles[particleCount] == null) particles[particleCount] = new Particle();
particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess, drawOnTop);
particles[particleCount].Init(prefab, position, velocity, rotation, hullGuess, drawOnTop, collisionIgnoreTimer);
particleCount++;
@@ -181,10 +181,10 @@ namespace Barotrauma.Particles
for (int i = 0; i < particleCount; i++)
{
bool remove = false;
bool remove;
try
{
remove = !particles[i].Update(deltaTime);
remove = particles[i].Update(deltaTime) == Particle.UpdateResult.Delete;
}
catch (Exception e)
{

View File

@@ -476,6 +476,11 @@ namespace Barotrauma
#endif
}
public static bool IsAltDown()
{
return KeyDown(Keys.LeftAlt) || KeyDown(Keys.RightAlt);
}
public static void Update(double deltaTime)
{
timeSinceClick += deltaTime;

View File

@@ -111,6 +111,8 @@ namespace Barotrauma
public static bool TransparentWiringMode = true;
public static bool SkipInventorySlotUpdate;
private static object bulkItemBufferinUse;
public static object BulkItemBufferInUse
@@ -4109,6 +4111,7 @@ namespace Barotrauma
/// </summary>
public override void Update(double deltaTime)
{
SkipInventorySlotUpdate = false;
ImageManager.Update((float) deltaTime);
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y)
@@ -4222,11 +4225,15 @@ namespace Barotrauma
}
List<Keys> numberKeys = PlayerInput.NumberKeys;
if (numberKeys.Find(PlayerInput.KeyHit) is { } key)
if (numberKeys.Find(PlayerInput.KeyHit) is { } key && key != Keys.None)
{
// treat 0 as the last key instead of first
int index = key == Keys.D0 ? numberKeys.Count : numberKeys.IndexOf(key) - 1;
listBox.Select(index, force: false, autoScroll: true, takeKeyBoardFocus: false);
if (index > -1 && index < listBox.Content.CountChildren)
{
listBox.Select(index, force: false, autoScroll: true, takeKeyBoardFocus: false);
SkipInventorySlotUpdate = true;
}
}
}
}

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.5</Version>
<Version>0.1300.0.7</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.5</Version>
<Version>0.1300.0.7</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.5</Version>
<Version>0.1300.0.7</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.5</Version>
<Version>0.1300.0.7</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.5</Version>
<Version>0.1300.0.7</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -111,7 +111,7 @@ namespace Barotrauma
// -> correct the position and the state of the Holdable component (in case the item was deattached client-side)
item.PositionUpdateInterval = 0.0f;
var holdable = item.GetComponent<Items.Components.Holdable>();
holdable.Item?.CreateServerEvent(holdable);
holdable?.Item?.CreateServerEvent(holdable);
}
}
else if (closestEntity is Character character)

View File

@@ -2177,6 +2177,11 @@ namespace Barotrauma.Networking
{
respawnManager = new RespawnManager(this, serverSettings.UseRespawnShuttle && !isOutpost ? selectedShuttle : null);
}
if (campaign != null)
{
campaign.CargoManager.CreatePurchasedItems();
campaign.SendCrewState(null, default, null);
}
Level.Loaded?.SpawnNPCs();
Level.Loaded?.SpawnCorpses();

View File

@@ -49,6 +49,7 @@ namespace Barotrauma.Networking
outMsg.Write((byte)MaxPlayers);
outMsg.Write(HasPassword);
outMsg.Write(IsPublic);
outMsg.Write(AllowFileTransfers);
outMsg.WritePadBits();
outMsg.WriteRangedInteger(TickRate, 1, 60);

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.5</Version>
<Version>0.1300.0.7</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -100,6 +100,7 @@
<Character file="Content/Characters/Spineling/Spineling.xml" />
<Character file="Content/Characters/Variants/Swarmcrawler.xml" />
<Character file="Content/Characters/Variants/Moloch_m.xml" />
<Character file="Content/Characters/Variants/Molochblack_m.xml" />
<Character file="Content/Characters/Variants/Hammerhead_m.xml" />
<Character file="Content/Characters/Variants/Hammerheadgold_m.xml" />
<Character file="Content/Characters/Variants/Crawler_hatchling/Crawler_hatchling.xml" />

View File

@@ -765,7 +765,7 @@ namespace Barotrauma
{
var location = memory.Location;
float dist = Vector2.DistanceSquared(WorldPosition, location);
if (dist < 50 * 50)
if (dist < 50 * 50 || !IsPositionInsideAllowedZone(WorldPosition, out _))
{
// Target is gone
ResetAITarget();

View File

@@ -1848,49 +1848,68 @@ namespace Barotrauma
public static bool IsItemOperatedByAnother(Character character, ItemComponent target, out Character operatingCharacter)
{
operatingCharacter = null;
if (character == null) { return false; }
if (target?.Item == null) { return false; }
bool isOrder = IsOrderedToOperateThis(character.AIController);
foreach (var c in Character.CharacterList)
{
if (character == null) { continue; }
if (c == character) { continue; }
if (c.IsDead || c.IsIncapacitated) { continue; }
if (!IsFriendly(character, c, onlySameTeam: true)) { continue; }
operatingCharacter = c;
if (c.AIController is HumanAIController controllingHumanAi)
if (c.IsPlayer)
{
Item otherTarget = controllingHumanAi.objectiveManager.GetActiveObjective<AIObjectiveOperateItem>()?.Component.Item ?? c.SelectedConstruction;
if (otherTarget != target.Item) { continue; }
// If the other character is player, don't try to operate
if (c.IsPlayer) { return true; }
// If the other character is ordered to operate the item, let him do it
if (controllingHumanAi.ObjectiveManager.IsCurrentOrder<AIObjectiveOperateItem>())
if (c.SelectedConstruction == target.Item)
{
// If the other character is player, don't try to operate
return true;
}
}
else if (c.AIController is HumanAIController operatingAI)
{
if (operatingAI.ObjectiveManager.Objectives.None(o => o is AIObjectiveOperateItem operateObjective && operateObjective.Component.Item == target.Item))
{
// Not targeting the same item.
continue;
}
bool isTargetOrdered = IsOrderedToOperateThis(c.AIController);
if (!isOrder && isTargetOrdered)
{
// If the other bot is ordered to operate the item, let him do it, unless we are ordered too
return true;
}
else
{
if (character == null)
if (isOrder && !isTargetOrdered)
{
return true;
}
else if (target is Steering)
{
// Steering is hard-coded -> cannot use the required skills collection defined in the xml
return character.GetSkillLevel("helm") <= c.GetSkillLevel("helm");
// We are ordered and the target is not -> allow to operate
continue;
}
else
{
return target.DegreeOfSuccess(character) <= target.DegreeOfSuccess(c);
if (!isTargetOrdered && operatingAI.ObjectiveManager.CurrentOrder == operatingAI.ObjectiveManager.CurrentObjective)
{
// The other bot is ordered to do something else
continue;
}
if (target is Steering)
{
// Steering is hard-coded -> cannot use the required skills collection defined in the xml
if (character.GetSkillLevel("helm") <= c.GetSkillLevel("helm"))
{
return true;
}
}
else if (target.DegreeOfSuccess(character) <= target.DegreeOfSuccess(c))
{
return true;
}
}
}
}
else
{
return c.SelectedConstruction == target.Item;
}
}
return false;
bool IsOrderedToOperateThis(AIController ai) => ai is HumanAIController humanAI && humanAI.ObjectiveManager.CurrentOrder is AIObjectiveOperateItem operateObjective && operateObjective.Component.Item == target.Item;
}
#region Wrappers

View File

@@ -415,7 +415,7 @@ namespace Barotrauma
#if DEBUG
DebugConsole.NewMessage($"{character.Name}: Get item failed to reach {moveToTarget}", Color.Yellow);
#endif
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder != null)
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder == objectiveManager.CurrentObjective)
{
string TargetName = (moveToTarget as MapEntity)?.Name ?? (moveToTarget as Character)?.Name ?? moveToTarget.ToString();
string msg = TargetName == null ? TextManager.Get("dialogcannotreachtarget", true) : TextManager.GetWithVariable("dialogcannotreachtarget", "[name]", TargetName, formatCapitals: !(moveToTarget is Character));

View File

@@ -147,7 +147,7 @@ namespace Barotrauma
#if DEBUG
DebugConsole.NewMessage($"{character.Name}: Cannot reach the target: {Target}", Color.Yellow);
#endif
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder != null && DialogueIdentifier != null && SpeakIfFails)
if (character.IsOnPlayerTeam && objectiveManager.CurrentOrder == objectiveManager.CurrentObjective && DialogueIdentifier != null && SpeakIfFails)
{
string msg = TargetName == null ? TextManager.Get(DialogueIdentifier, true) : TextManager.GetWithVariable(DialogueIdentifier, "[name]", TargetName, formatCapitals: !(Target is Character));
if (msg != null)

View File

@@ -132,7 +132,13 @@ namespace Barotrauma
}
var order = new Order(orderPrefab, item ?? character.CurrentHull as Entity, orderPrefab.GetTargetItemComponent(item), orderGiver: character);
if (order == null) { continue; }
if (autonomousObjective.ignoreAtOutpost && Level.IsLoadedOutpost && character.TeamID != CharacterTeamType.FriendlyNPC) { continue; }
if (autonomousObjective.ignoreAtOutpost && Level.IsLoadedOutpost && character.TeamID != CharacterTeamType.FriendlyNPC)
{
if (Submarine.MainSub != null && Submarine.MainSub.DockedTo.None(s => s.TeamID != CharacterTeamType.FriendlyNPC && s.TeamID != character.TeamID))
{
continue;
}
}
var objective = CreateObjective(order, autonomousObjective.option, character, isAutonomous: true, autonomousObjective.priorityModifier);
if (objective != null && objective.CanBeCompleted)
{

View File

@@ -121,7 +121,7 @@ namespace Barotrauma
{
float value = CumulatedDevotion + (AIObjectiveManager.LowestOrderPriority * PriorityModifier);
float max = AIObjectiveManager.LowestOrderPriority - 1;
if (reactor != null && reactor.PowerOn && Option == "powerup")
if (reactor != null && reactor.PowerOn && reactor.FissionRate > 1 && Option == "powerup")
{
// Decrease the priority when targeting a reactor that is already on.
value /= 2;

View File

@@ -1343,6 +1343,22 @@ namespace Barotrauma
/// </summary>
public float SpeedMultiplier { get; private set; } = 1;
private double propulsionSpeedMultiplierLastSet;
private float propulsionSpeedMultiplier;
/// <summary>
/// Can be used to modify the speed at which Propulsion ItemComponents move the character via StatusEffects (e.g. heavy suit can slow down underwater scooters)
/// </summary>
public float PropulsionSpeedMultiplier
{
get { return propulsionSpeedMultiplier; }
set
{
propulsionSpeedMultiplier = value;
propulsionSpeedMultiplierLastSet = Timing.TotalTime;
}
}
public void StackSpeedMultiplier(float val)
{
if (val < 1f)
@@ -1365,6 +1381,10 @@ namespace Barotrauma
{
greatestPositiveSpeedMultiplier = 1f;
greatestNegativeSpeedMultiplier = 1f;
if (Timing.TotalTime > propulsionSpeedMultiplierLastSet + 0.1)
{
propulsionSpeedMultiplier = 1.0f;
}
}
private float greatestNegativeHealthMultiplier = 1f;
@@ -3420,6 +3440,7 @@ namespace Barotrauma
if (statusEffect.type != actionType) { continue; }
if (statusEffect.type == ActionType.OnDamaged)
{
if (LastDamage.Afflictions == null || LastDamage.Afflictions.None(a => a.Prefab.AfflictionType == "damage")) { continue; }
if (statusEffect.OnlyPlayerTriggered)
{
if (LastAttacker == null || !LastAttacker.IsPlayer)

View File

@@ -1127,6 +1127,7 @@ namespace Barotrauma
if (statusEffect.type != actionType) { continue; }
if (statusEffect.type == ActionType.OnDamaged)
{
if (character.LastDamage.Afflictions == null || character.LastDamage.Afflictions.None(a => a.Prefab.AfflictionType == "damage")) { continue; }
if (statusEffect.OnlyPlayerTriggered)
{
if (character.LastAttacker == null || !character.LastAttacker.IsPlayer)

View File

@@ -26,7 +26,6 @@ namespace Barotrauma
public override void Update(float deltaTime)
{
if (isFinished) { return; }
GameMain.GameSession?.Map?.CurrentLocation?.Connections.ForEach(c => c.Locked = false);
if (GameMain.GameSession?.Map?.CurrentLocation?.Connections != null)
{
foreach (LocationConnection connection in GameMain.GameSession?.Map?.CurrentLocation?.Connections)

View File

@@ -418,6 +418,7 @@ namespace Barotrauma
List<Pair<EventPrefab, float>> unusedEvents = new List<Pair<EventPrefab, float>>(suitablePrefabs);
for (int j = 0; j < eventSet.EventCount; j++)
{
if (unusedEvents.All(e => CalculateCommonness(e) <= 0.0f)) { break; }
var eventPrefab = ToolBox.SelectWeightedRandom(unusedEvents, unusedEvents.Select(e => CalculateCommonness(e)).ToList(), rand);
if (eventPrefab != null)
{

View File

@@ -100,7 +100,7 @@ namespace Barotrauma
{
spawnPos = new Vector2(
MathHelper.Clamp(wp.WorldPosition.X + Rand.Range(-200, 200), wp.CurrentHull.WorldRect.X, wp.CurrentHull.WorldRect.Right),
wp.CurrentHull.WorldRect.Y - wp.CurrentHull.Rect.Height + 10.0f);
wp.CurrentHull.WorldRect.Y - wp.CurrentHull.Rect.Height + 16.0f);
}
var item = new Item(itemPrefab, spawnPos, null);
items.Add(item);

View File

@@ -478,13 +478,6 @@ namespace Barotrauma
}
if (GameMode is MultiPlayerCampaign mpCampaign)
{
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
{
mpCampaign.CargoManager.CreatePurchasedItems();
#if SERVER
mpCampaign.SendCrewState(null, default, null);
#endif
}
mpCampaign.UpgradeManager.ApplyUpgrades();
mpCampaign.UpgradeManager.SanityCheckUpgrades(Submarine);
}

View File

@@ -41,25 +41,25 @@ namespace Barotrauma.Items.Components
public override bool Use(float deltaTime, Character character = null)
{
if (character == null || character.Removed) return false;
if (!character.IsKeyDown(InputType.Aim) || character.Stun > 0.0f) return false;
if (!character.IsKeyDown(InputType.Aim) || character.Stun > 0.0f) { return false; }
IsActive = true;
useState = 0.1f;
if (character.AnimController.InWater)
{
if (UsableIn == UseEnvironment.Air) return true;
if (UsableIn == UseEnvironment.Air) { return true; }
}
else
{
if (UsableIn == UseEnvironment.Water) return true;
if (UsableIn == UseEnvironment.Water) { return true; }
}
Vector2 dir = Vector2.Normalize(character.CursorPosition - character.Position);
//move upwards if the cursor is at the position of the character
if (!MathUtils.IsValid(dir)) dir = Vector2.UnitY;
Vector2 propulsion = dir * Force;
Vector2 propulsion = dir * Force * character.PropulsionSpeedMultiplier;
if (character.AnimController.InWater) character.AnimController.TargetMovement = dir;

View File

@@ -333,7 +333,7 @@ namespace Barotrauma.Items.Components
if (item.CurrentHull != null)
{
var aiTarget = item.CurrentHull.AiTarget;
if (aiTarget != null)
if (aiTarget != null && MaxPowerOutput > 0)
{
float range = Math.Abs(currPowerConsumption) / MaxPowerOutput;
float noise = MathHelper.Lerp(aiTarget.MinSoundRange, aiTarget.MaxSoundRange, range);
@@ -341,7 +341,7 @@ namespace Barotrauma.Items.Components
}
}
if (item.AiTarget != null)
if (item.AiTarget != null && MaxPowerOutput > 0)
{
var aiTarget = item.AiTarget;
float range = Math.Abs(currPowerConsumption) / MaxPowerOutput;

View File

@@ -711,7 +711,7 @@ namespace Barotrauma.Items.Components
steeringAdjustSpeed = DefaultSteeringAdjustSpeed;
steeringInput = XMLExtensions.ParseVector2(signal.value, errorMessages: false);
steeringInput.X = MathHelper.Clamp(steeringInput.X, -100.0f, 100.0f);
steeringInput.Y = MathHelper.Clamp(steeringInput.Y, -100.0f, 100.0f);
steeringInput.Y = MathHelper.Clamp(-steeringInput.Y, -100.0f, 100.0f);
}
else
{

View File

@@ -1,13 +1,10 @@
using FarseerPhysics;
using Barotrauma.IO;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Xml.Linq;
using System.Linq;
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
using Voronoi2;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -1077,7 +1074,10 @@ namespace Barotrauma
priceInfo = null;
if (location?.Type == null) { return false; }
priceInfo = GetPriceInfo(location);
return priceInfo != null && priceInfo.CanBeBought;
return
priceInfo != null &&
priceInfo.CanBeBought &&
(location.LevelData?.Difficulty ?? 0) >= priceInfo.MinLevelDifficulty;
}
public static ItemPrefab Find(string name, string identifier)

View File

@@ -419,7 +419,7 @@ namespace Barotrauma
int zone1 = GetZoneIndex(Connections[i].Locations[0].MapPosition.X);
int zone2 = GetZoneIndex(Connections[i].Locations[1].MapPosition.X);
if (zone1 == zone2) { continue; }
if (zone2 == generationParams.DifficultyZones) { continue; }
if (zone1 == generationParams.DifficultyZones || zone2 == generationParams.DifficultyZones) { continue; }
if (!connectionsBetweenZones.Contains(Connections[i]))
{
@@ -464,7 +464,10 @@ namespace Barotrauma
foreach (Location location in Locations)
{
location.LevelData = new LevelData(location);
location.LevelData = new LevelData(location)
{
Difficulty = MathHelper.Clamp(location.MapPosition.X / Width * 100, 0.0f, 100.0f)
};
if (location.Type.MissionIdentifiers.Any())
{
location.UnlockMissionByIdentifier(location.Type.MissionIdentifiers.GetRandom());

View File

@@ -20,15 +20,20 @@ namespace Barotrauma
/// Can the item be a Daily Special or a Requested Good
/// </summary>
public readonly bool CanBeSpecial;
/// <summary>
/// The item isn't available in stores unless the level's difficulty is above this value
/// </summary>
public readonly int MinLevelDifficulty;
/// <summary>
/// Support for the old style of determining item prices
/// when there were individual Price elements for each location type
/// where the item was for sale.
/// </summary>
public PriceInfo (XElement element)
public PriceInfo(XElement element)
{
Price = element.GetAttributeInt("buyprice", 0);
MinLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0);
CanBeBought = true;
var minAmount = GetMinAmount(element);
MinAvailableAmount = Math.Min(minAmount, CargoManager.MaxQuantity);
@@ -37,13 +42,14 @@ namespace Barotrauma
MaxAvailableAmount = Math.Max(maxAmount, MinAvailableAmount);
}
public PriceInfo(int price, bool canBeBought, int minAmount = 0, int maxAmount = 0, bool canBeSpecial = true)
public PriceInfo(int price, bool canBeBought, int minAmount = 0, int maxAmount = 0, bool canBeSpecial = true, int minLevelDifficulty = 0)
{
Price = price;
CanBeBought = canBeBought;
MinAvailableAmount = Math.Min(minAmount, CargoManager.MaxQuantity);
maxAmount = Math.Min(maxAmount, CargoManager.MaxQuantity);
MaxAvailableAmount = Math.Max(maxAmount, minAmount);
MinLevelDifficulty = minLevelDifficulty;
CanBeSpecial = canBeSpecial;
}
@@ -54,6 +60,7 @@ namespace Barotrauma
var soldByDefault = element.GetAttributeBool("soldbydefault", true);
var minAmount = GetMinAmount(element);
var maxAmount = GetMaxAmount(element);
var minLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0);
var canBeSpecial = element.GetAttributeBool("canbespecial", true);
var priceInfos = new List<Tuple<string, PriceInfo>>();
@@ -65,14 +72,16 @@ namespace Barotrauma
new PriceInfo(price: (int)(priceMultiplier * basePrice), canBeBought: sold,
minAmount: sold ? GetMinAmount(childElement, minAmount) : 0,
maxAmount: sold ? GetMaxAmount(childElement, maxAmount) : 0,
canBeSpecial: canBeSpecial)));
canBeSpecial,
childElement.GetAttributeInt("minleveldifficulty", minLevelDifficulty))));
}
var canBeBoughtAtOtherLocations = soldByDefault && element.GetAttributeBool("soldeverywhere", true);
defaultPrice = new PriceInfo(basePrice, canBeBoughtAtOtherLocations,
minAmount: canBeBoughtAtOtherLocations ? minAmount : 0,
maxAmount: canBeBoughtAtOtherLocations ? maxAmount : 0,
canBeSpecial: canBeSpecial);
canBeSpecial,
minLevelDifficulty);
return priceInfos;
}

View File

@@ -819,16 +819,12 @@ namespace Barotrauma
}
for (int i = 1; i <= particleAmount; i++)
{
var worldRect = section.WorldRect;
Vector2 particlePos = new Vector2(
Rand.Range(section.rect.X, section.rect.Right),
Rand.Range(section.rect.Y - section.rect.Height, section.rect.Y));
Rand.Range(worldRect.X, worldRect.Right),
Rand.Range(worldRect.Y - worldRect.Height, worldRect.Y));
if (Submarine != null)
{
particlePos += Submarine.DrawPosition;
}
var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)));
var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)), collisionIgnoreTimer: 1f);
if (particle == null) break;
}
}

View File

@@ -9,6 +9,8 @@ namespace Barotrauma
public Color? Color;
public string Metadata;
public float Alpha = 1.0f;
private const char definitionIndicator = '‖';
private const char attributeSeparator = ';';
private const char keyValueSeparator = ':';

View File

@@ -1,10 +1,43 @@
---------------------------------------------------------------------------------------------------------
v0.1300.0.7 (unstable)
---------------------------------------------------------------------------------------------------------
Changes:
- Bandit outfits aren't sold at outposts.
- Charybdis: Increased the attack cooldown from 3 to 4. Tweaked the texture. Adjusted the ragdoll and the animations. More tentacles.
- Molochs: Boosted the structural damage slightly. Increased the attack and damage ranges slightly to help the attacks to hit the target.
- Added black moloch mission variants.
- Icons for previous orders can now be removed from crew list by right-clicking on them.
- Diving suits have an effect on underwater scooter speed (slower movement when wearing an abyss suit, faster when wearing a combat suit).
- Abyss/combat diving suits aren't sold in outpost for the first quarter of the campaign.
- Nerfed nuclear shell's EMP effect.
Fixes:
- Fixed entity IDs getting messed up when purchasing items in the MP campaign, which lead to disconnects with an "entity not found" error message. Happened because the server created the purchased items before loading the respawn shuttle, while the clients did it the other way around.
- Fixed clients not getting the prompt to download a custom sub they don't have unless they have permissions to edit server settings.
- Fixed edge of the chatbox stealing cursor focus when the chatbox is hidden (preventing firing turrets when the cursor is in the bottom-left corner of the screen).
- Fixed inconsistency in the way vertical velocity in/out signals are handled by the nav terminals. Previously "velocity_in" would interpret positive y as upwards, even though "velocity_y_out" outputs a negative value when going up. Now positive is always down (= corresponds with the "descent velocity" value displayed on the terminal).
- Fixed non-repeatable outpost events starting to repeat once all of them have been triggered.
- Fixed gate outpost still sometimes generating before the last level/biome.
- Reduced the amount of clown gear in the "Praise the Honkmother" mission to fit everything in the crate.
- Fixed boss health bars not appearing in multiplayer when damaging a boss monster with a turret.
- Fixed clients not getting notified when a path between biomes is unlocked, preventing them from proceeding without saving and reloading the campaign.
- Fixed crashing on startup with the error message "unable to load shared library 'freetype6' or one of its dependencies" on some Linux systems.
- Fixed monsters trying to follow the last target while in the idle state even when the target is outside of the allowed area (only unstable).
- Fixed multiple issues regarding bots targeting the reactor.
- Fixed OnDamaged status effect triggering from burns, poisons etc. Only afflictions of type "damage" can now trigger it. Fixes Moloch spawning a lot of particles after being hit with a nuclear shell (#5412).
- Fixed black moloch doing only 62.5% of the structure damage compared to the regular moloch.
- Fixes to R-29: fixed top docking port's control circuit, adjustments to pre-placed supplies, adjusted discharge coil power consumption, minor visual fixes.
- Fixed wall damage particles sometimes spawning at an incorrect position.
---------------------------------------------------------------------------------------------------------
v0.1300.0.6 (unstable)
---------------------------------------------------------------------------------------------------------
Fixes:
- Fixed bots trying to clean up items that have changed place and shouldn't be allowed to clean up anymore. Fixes #5400
- Fixed "attempted to set SoundRange to NaN" error when a reactor's maximum power output is 0.
- Fixed nullref exception when forcing an item position correction upon interaction failure.
---------------------------------------------------------------------------------------------------------
v0.1300.0.5 (unstable)