diff --git a/Barotrauma/BarotraumaClient/Launch_Barotrauma b/Barotrauma/BarotraumaClient/Launch_Barotrauma
index 4e95158fd..8792fad24 100644
--- a/Barotrauma/BarotraumaClient/Launch_Barotrauma
+++ b/Barotrauma/BarotraumaClient/Launch_Barotrauma
@@ -1,3 +1,3 @@
#!/bin/sh
-./Barotrauma
+exec mono "./Barotrauma.exe" MONO_LOG_LEVEL=debug "$@"
diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj
index c74cd30c3..411dec235 100644
--- a/Barotrauma/BarotraumaClient/LinuxClient.csproj
+++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj
@@ -186,9 +186,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs
index 2e11c7af2..667d29d62 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs
@@ -98,7 +98,7 @@ namespace Barotrauma
if (distSqrd > 10.0f || !character.AllowInput)
{
Collider.TargetRotation = newRotation;
- SetPosition(newPosition, lerp: distSqrd < 5.0f, ignorePlatforms: false);
+ SetPosition(newPosition, lerp: distSqrd < 5.0f);
}
else
{
@@ -238,16 +238,20 @@ namespace Barotrauma
}
float errorMagnitude = positionError.Length();
- if (errorMagnitude > 0.5f)
- {
- character.MemLocalState.Clear();
- SetPosition(serverPos.Position, lerp: true, ignorePlatforms: false);
- }
- else if (errorMagnitude > 0.01f)
+ if (errorMagnitude > 0.01f)
{
Collider.TargetPosition = Collider.SimPosition + positionError;
Collider.TargetRotation = Collider.Rotation + rotationError;
Collider.MoveToTargetPosition(lerp: true);
+ if (errorMagnitude > 0.5f)
+ {
+ character.MemLocalState.Clear();
+ foreach (Limb limb in Limbs)
+ {
+ limb.body.TargetPosition = limb.body.SimPosition + positionError;
+ limb.body.MoveToTargetPosition(lerp: true);
+ }
+ }
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
index b4e831e77..2eff39aa6 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
@@ -46,7 +46,8 @@ namespace Barotrauma
if (controlled == value) return;
controlled = value;
if (controlled != null) controlled.Enabled = true;
- CharacterHealth.OpenHealthWindow = null;
+ CharacterHealth.OpenHealthWindow = null;
+
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs
index e180f44e6..441ae6a6e 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs
@@ -85,8 +85,7 @@ namespace Barotrauma
{
if (character.Inventory != null)
{
- if (!character.LockHands && character.Stun < 0.1f &&
- (character.SelectedConstruction == null || character.SelectedConstruction.GetComponent() == null))
+ if (!character.LockHands && character.Stun < 0.1f)
{
character.Inventory.Update(deltaTime, cam);
}
@@ -321,7 +320,6 @@ namespace Barotrauma
}
if (character.Inventory != null && !character.LockHands)
{
- character.Inventory.Locked = (character.SelectedConstruction != null && character.SelectedConstruction.GetComponent() != null);
character.Inventory.DrawOwn(spriteBatch);
character.Inventory.CurrentLayout = CharacterHealth.OpenHealthWindow == null && character.SelectedCharacter == null ?
CharacterInventory.Layout.Default :
diff --git a/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs b/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs
index 0ea60b4a5..71b3d07d0 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/CharacterInventory.cs
@@ -793,7 +793,7 @@ namespace Barotrauma
base.Draw(spriteBatch);
- if (hideButton != null && hideButton.Visible && !Locked)
+ if (hideButton != null && hideButton.Visible)
{
hideButton.DrawManually(spriteBatch, alsoChildren: true);
}
@@ -835,7 +835,6 @@ namespace Barotrauma
color = Color.White;
highlightedQuickUseSlot = slots[i];
}
- if (Locked) { color *= 0.3f; }
var quickUseIndicator = Items[i].AllowedSlots.Any(a => a == InvSlotType.Any) ?
EquipIndicator : DropIndicator;
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs
index e3c4ea985..8fb30030a 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs
@@ -820,9 +820,8 @@ namespace Barotrauma
else
{
Sprite slotSprite = slot.SlotSprite ?? slotSpriteSmall;
- Color slotColor = slot.IsHighlighted ? Color.White : Color.White * 0.8f;
- if (inventory != null && inventory.Locked) { slotColor = Color.Gray * 0.5f; }
- spriteBatch.Draw(slotSprite.Texture, rect, slotSprite.SourceRect, slotColor);
+
+ spriteBatch.Draw(slotSprite.Texture, rect, slotSprite.SourceRect, slot.IsHighlighted ? Color.White : Color.White * 0.8f);
if (item != null && drawItem)
{
@@ -874,17 +873,14 @@ namespace Barotrauma
}
indicatorSprite.Draw(spriteBatch, containedIndicatorArea.Center.ToVector2(),
- (inventory != null && inventory.Locked) ? Color.DarkGray * 0.5f : Color.DarkGray * 0.9f,
+ Color.DarkGray * 0.9f,
origin: indicatorSprite.size / 2,
rotate: 0.0f,
scale: indicatorScale);
-
- Color indicatorColor = ToolBox.GradientLerp(containedState, Color.Red, Color.Orange, Color.Green);
- if (inventory != null && inventory.Locked) { indicatorColor *= 0.5f; }
-
+
spriteBatch.Draw(indicatorSprite.Texture, containedIndicatorArea.Center.ToVector2(),
sourceRectangle: new Rectangle(indicatorSprite.SourceRect.Location, new Point((int)(indicatorSprite.SourceRect.Width * containedState), indicatorSprite.SourceRect.Height)),
- color: indicatorColor,
+ color: ToolBox.GradientLerp(containedState, Color.Red, Color.Orange, Color.Green),
rotation: 0.0f,
origin: indicatorSprite.size / 2,
scale: indicatorScale,
@@ -924,7 +920,6 @@ namespace Barotrauma
}
Color spriteColor = sprite == item.Sprite ? item.GetSpriteColor() : item.GetInventoryIconColor();
- if (inventory != null && inventory.Locked) { spriteColor *= 0.5f; }
if (CharacterHealth.OpenHealthWindow != null && !item.UseInHealthInterface)
{
spriteColor = Color.Lerp(spriteColor, Color.TransparentBlack, 0.5f);
@@ -936,10 +931,7 @@ namespace Barotrauma
sprite.Draw(spriteBatch, itemPos, spriteColor, rotation, scale);
}
- if (inventory != null &&
- !inventory.Locked &&
- Character.Controlled?.Inventory == inventory &&
- slot.QuickUseKey != Keys.None)
+ if (inventory != null && Character.Controlled?.Inventory == inventory && slot.QuickUseKey != Keys.None)
{
GUI.DrawString(spriteBatch, rect.Location.ToVector2(),
slot.QuickUseKey.ToString().Substring(1, 1),
diff --git a/Barotrauma/BarotraumaClient/Source/Map/Structure.cs b/Barotrauma/BarotraumaClient/Source/Map/Structure.cs
index 99b7bbedd..08a9b5ae0 100644
--- a/Barotrauma/BarotraumaClient/Source/Map/Structure.cs
+++ b/Barotrauma/BarotraumaClient/Source/Map/Structure.cs
@@ -1,9 +1,6 @@
using Barotrauma.Extensions;
using Barotrauma.Lights;
using Barotrauma.Networking;
-using FarseerPhysics;
-using FarseerPhysics.Dynamics;
-using FarseerPhysics.Dynamics.Contacts;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -168,20 +165,6 @@ namespace Barotrauma
{
Vector2 pos = ConvertUnits.ToDisplayUnits(f2.Body.Position);
- int section = FindSectionIndex(pos);
- if (section > -1)
- {
- Vector2 normal = contact.Manifold.LocalNormal;
-
- float impact = Vector2.Dot(f2.Body.LinearVelocity, -normal) * f2.Body.Mass * 0.1f;
- if (impact > 10.0f)
- {
- SoundPlayer.PlayDamageSound("StructureBlunt", impact, SectionPosition(section, true), tags: Tags);
- }
- }
- }
- }
-
public override bool IsVisible(Rectangle worldView)
{
Rectangle worldRect = WorldRect;
diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs b/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs
index 515bc987a..3c1705000 100644
--- a/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs
+++ b/Barotrauma/BarotraumaClient/Source/Sounds/SoundPlayer.cs
@@ -238,7 +238,7 @@ namespace Barotrauma
}
float ambienceVolume = 0.8f;
- if (Character.Controlled != null && !Character.Controlled.Removed)
+ if (Character.Controlled != null)
{
AnimController animController = Character.Controlled.AnimController;
if (animController.HeadInWater)
diff --git a/Barotrauma/BarotraumaServer/Server.csproj b/Barotrauma/BarotraumaServer/Server.csproj
index bc97ad59e..3647a5b6d 100644
--- a/Barotrauma/BarotraumaServer/Server.csproj
+++ b/Barotrauma/BarotraumaServer/Server.csproj
@@ -216,7 +216,7 @@
-
+
PreserveNewest
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs
index eac638a27..3c5e54192 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/EnemyAIController.cs
@@ -320,8 +320,9 @@ namespace Barotrauma
{
State = AIState.Idle;
}
- else if (Character.Health < fleeHealthThreshold)
+ else if (Character.Health < fleeHealthThreshold && SwarmBehavior == null)
{
+ // Don't flee from damage if in a swarm.
State = AIState.Escape;
}
else if (targetingPriority != null)
@@ -493,7 +494,7 @@ namespace Barotrauma
}
else
{
- if (!IsProperlyLatchedOnSub)
+ if (!IsLatchedOnSub)
{
UpdateWallTarget();
}
@@ -552,7 +553,7 @@ namespace Barotrauma
{
WallSection section = wallTarget.Structure.GetSection(wallTarget.SectionIndex);
Vector2 targetPos = wallTarget.Structure.SectionPosition(wallTarget.SectionIndex, true);
- if (section?.gap != null && section.gap.IsRoomToRoom && SteerThroughGap(wallTarget.Structure, section, targetPos, deltaTime))
+ if (section?.gap != null && SteerThroughGap(wallTarget.Structure, section, targetPos, deltaTime))
{
return;
}
@@ -791,7 +792,6 @@ namespace Barotrauma
{
UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance);
}
- return false;
}
private bool SteerThroughGap(Structure wall, WallSection section, Vector2 targetWorldPos, float deltaTime)
@@ -1048,35 +1048,38 @@ namespace Barotrauma
#region Targeting
private bool IsLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub;
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
- private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
-
//goes through all the AItargets, evaluates how preferable it is to attack the target,
//whether the Character can see/hear the target and chooses the most preferable target within
//sight/hearing range
public AITarget UpdateTargets(Character character, out TargetingPriority priority)
{
- if (IsProperlyLatchedOnSub)
+ if (IsLatchedOnSub)
{
- // If attached to a valid target, just keep the target.
- // Priority not used in this case.
- priority = null;
- return SelectedAiTarget;
+ var wall = SelectedAiTarget.Entity as Structure;
+ // The target is not a wall or it's not the same as we are attached to -> release
+ bool releaseTarget = wall == null || !wall.Bodies.Contains(LatchOntoAI.AttachJoints[0].BodyB);
+ if (!releaseTarget)
+ {
+ for (int i = 0; i < wall.Sections.Length; i++)
+ {
+ if (CanPassThroughHole(wall, i))
+ {
+ releaseTarget = true;
+ }
+ }
+ }
+ if (releaseTarget)
+ {
+ SelectedAiTarget = null;
+ LatchOntoAI.DeattachFromBody();
+ }
+ else if (SelectedAiTarget.Entity == wallTarget?.Structure)
+ {
+ // If attached to a valid target, just keep the target.
+ // Priority not used in this case.
+ priority = null;
+ return SelectedAiTarget;
+ }
}
AITarget newTarget = null;
priority = null;
@@ -1159,7 +1162,7 @@ namespace Barotrauma
else if (target.Entity != null)
{
//skip the target if it's a room and the character is already inside a sub
- if (character.CurrentHull != null && target.Entity is Hull) continue;
+ if (character.CurrentHull != null && target.Entity is Hull) { continue; }
Door door = null;
if (target.Entity is Item item)
@@ -1188,6 +1191,13 @@ namespace Barotrauma
// Ignore structures that doesn't have a body (not walls)
continue;
}
+ if (s.IsPlatform)
+ {
+ continue;
+ }
+ float wallMaxHealth = 400; // Anything more than this is ignored -> 200 = 1
+ // Prefer weaker targets.
+ valueModifier = MathHelper.Lerp(2, 0, MathHelper.Clamp(s.Health / wallMaxHealth, 0, 1));
// Ignore walls when inside.
valueModifier = character.CurrentHull == null ? 1 : 0;
if (aggressiveBoarding)
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs
index 3530df734..5de8c9140 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/HumanoidAnimController.cs
@@ -560,8 +560,7 @@ namespace Barotrauma
//TODO: take into account that the feet aren't necessarily in CurrentHull
//full slowdown (1.5f) when water is up to the torso
surfaceY = ConvertUnits.ToSimUnits(currentHull.Surface);
- float bottomPos = Math.Max(colliderPos.Y, currentHull.Rect.Y - currentHull.Rect.Height);
- slowdownAmount = MathHelper.Clamp((surfaceY - bottomPos) / TorsoPosition.Value, 0.0f, 1.0f) * 1.5f;
+ slowdownAmount = MathHelper.Clamp((surfaceY - colliderPos.Y) / TorsoPosition.Value, 0.0f, 1.0f) * 1.5f;
}
float maxSpeed = Math.Max(TargetMovement.Length() - slowdownAmount, 1.0f);
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs
index d3dcbc16b..435f0fd7d 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs
@@ -2555,9 +2555,11 @@ namespace Barotrauma
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
- CharacterList.Remove(this);
+#if CLIENT
+ GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
+#endif
- if (Controlled == this) { Controlled = null; }
+ CharacterList.Remove(this);
if (Inventory != null)
{
diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs
index 01905d2cf..6e8445416 100644
--- a/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs
+++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/MonsterMission.cs
@@ -34,14 +34,33 @@ namespace Barotrauma
{
Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos);
- bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient;
+ //bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient;
+ //for (int i = 0; i < monsterCount; i++)
+ //{
+ // monsters.Add(Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false));
+ //}
+ //monsters.ForEach(m => m.Enabled = false);
+ //SwarmBehavior.CreateSwarm(monsters.Cast());
+ //sonarPositions.Add(spawnPos);
+
+ float offsetAmount = 500;
for (int i = 0; i < monsterCount; i++)
{
- monsters.Add(Character.Create(monsterFile, spawnPos, ToolBox.RandomSeed(8), null, isClient, true, false));
+ CoroutineManager.InvokeAfter(() =>
+ {
+ bool isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient;
+ var monster = Character.Create(monsterFile, spawnPos + Rand.Vector(offsetAmount, Rand.RandSync.Server), i.ToString(), null, isClient, true, true);
+ monster.Enabled = false;
+ monsters.Add(monster);
+ if (monsters.Count == monsterCount)
+ {
+ //this will do nothing if the monsters have no swarm behavior defined,
+ //otherwise it'll make the spawned characters act as a swarm
+ SwarmBehavior.CreateSwarm(monsters.Cast());
+ sonarPositions.Add(spawnPos);
+ }
+ }, Rand.Range(0f, monsterCount / 2, Rand.RandSync.Server));
}
- monsters.ForEach(m => m.Enabled = false);
- SwarmBehavior.CreateSwarm(monsters.Cast());
- sonarPositions.Add(spawnPos);
}
public override void Update(float deltaTime)
diff --git a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs
index 38dcb8a64..59d65255f 100644
--- a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs
+++ b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs
@@ -635,6 +635,24 @@ namespace Barotrauma
var character = ((Limb)f2.Body.UserData).character;
if (character.DisableImpactDamageTimer > 0.0f || ((Limb)f2.Body.UserData).Mass < 100.0f) return true;
}
+
+ if (!Prefab.Platform && Prefab.StairDirection == Direction.None)
+ {
+ Vector2 pos = ConvertUnits.ToDisplayUnits(f2.Body.Position);
+
+ int section = FindSectionIndex(pos);
+ if (section > -1)
+ {
+ Vector2 normal = contact.Manifold.LocalNormal;
+
+ float impact = Vector2.Dot(f2.Body.LinearVelocity, -normal) * f2.Body.Mass * 0.1f;
+ if (impact < 10.0f) return true;
+#if CLIENT
+ SoundPlayer.PlayDamageSound("StructureBlunt", impact, SectionPosition(section, true), tags: Tags);
+#endif
+ AddDamage(section, impact);
+ }
+ }
OnImpactProjSpecific(f1, f2, contact);
diff --git a/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs b/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs
index e89da30e1..c2cd7710d 100644
--- a/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs
+++ b/Barotrauma/BarotraumaShared/Source/Networking/EntitySpawner.cs
@@ -102,7 +102,7 @@ namespace Barotrauma
{
string errorMsg = "Attempted to add a null item to entity spawn queue.\n" + Environment.StackTrace;
DebugConsole.ThrowError(errorMsg);
- GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue1:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
+ GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue3:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return;
}
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, worldPosition, condition));
@@ -115,7 +115,7 @@ namespace Barotrauma
{
string errorMsg = "Attempted to add a null item to entity spawn queue.\n" + Environment.StackTrace;
DebugConsole.ThrowError(errorMsg);
- GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue2:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
+ GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue3:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
return;
}
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub, condition));