Unstable v0.1300.0.0 (February 19th 2021)

This commit is contained in:
Joonas Rikkonen
2021-02-25 13:44:23 +02:00
parent b772654326
commit 24cbef485a
441 changed files with 21343 additions and 8562 deletions
@@ -11,6 +11,9 @@ namespace Barotrauma
{
if (!ShowAITargets) { return; }
var pos = new Vector2(WorldPosition.X, -WorldPosition.Y);
float thickness = 1 / Screen.Selected.Cam.Zoom;
float offset = MathUtils.VectorToAngle(new Vector2(sectorDir.X, -sectorDir.Y)) - (sectorRad / 2f);
if (soundRange > 0.0f)
{
Color color;
@@ -26,8 +29,16 @@ namespace Barotrauma
{
color = Color.OrangeRed;
}
ShapeExtensions.DrawCircle(spriteBatch, pos, SoundRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
ShapeExtensions.DrawCircle(spriteBatch, pos, 3, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
if (sectorRad < MathHelper.TwoPi)
{
spriteBatch.DrawSector(pos, SoundRange, sectorRad, 100, color, offset: offset, thickness: thickness);
}
else
{
spriteBatch.DrawCircle(pos, SoundRange, 100, color, thickness: thickness);
}
spriteBatch.DrawCircle(pos, 3, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
GUI.DrawLine(spriteBatch, pos, pos + Vector2.UnitY * SoundRange, color, width: (int)(1 / Screen.Selected.Cam.Zoom) + 1);
}
if (sightRange > 0.0f)
@@ -47,7 +58,14 @@ namespace Barotrauma
// disable the indicators for structures and hulls, because they clutter the debug view
return;
}
ShapeExtensions.DrawCircle(spriteBatch, pos, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
if (sectorRad < MathHelper.TwoPi)
{
spriteBatch.DrawSector(pos, SightRange, sectorRad, 100, color, offset: offset, thickness: thickness);
}
else
{
spriteBatch.DrawCircle(pos, SightRange, 100, color, thickness: thickness);
}
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
GUI.DrawLine(spriteBatch, pos, pos + Vector2.UnitY * SightRange, color, width: (int)(1 / Screen.Selected.Cam.Zoom) + 1);
}
@@ -1,22 +1,12 @@
using Microsoft.Xna.Framework;
using FarseerPhysics;
using System;
using System.Linq;
namespace Barotrauma
{
partial class HumanAIController : AIController
{
public static bool debugai;
partial void InitProjSpecific()
{
/*if (GameMain.GameSession != null && GameMain.GameSession.CrewManager != null)
{
CurrentOrder = Order.GetPrefab("dismissed");
objectiveManager.SetOrder(CurrentOrder, "", null);
GameMain.GameSession.CrewManager.SetCharacterOrder(Character, CurrentOrder, null, null);
}*/
}
public override void DebugDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
if (Character == Character.Controlled) { return; }
@@ -24,6 +14,7 @@ namespace Barotrauma
Vector2 pos = Character.WorldPosition;
pos.Y = -pos.Y;
Vector2 textOffset = new Vector2(-40, -160);
textOffset.Y -= Math.Max(ObjectiveManager.CurrentOrders.Count - 1, 0) * 20;
if (SelectedAiTarget?.Entity != null)
{
@@ -31,61 +22,57 @@ namespace Barotrauma
//GUI.DrawString(spriteBatch, pos + textOffset, $"AI TARGET: {SelectedAiTarget.Entity.ToString()}", Color.White, Color.Black);
}
GUI.DrawString(spriteBatch, pos + textOffset, Character.Name, Color.White, Color.Black);
Vector2 stringDrawPos = pos + textOffset;
GUI.DrawString(spriteBatch, stringDrawPos, Character.Name, Color.White, Color.Black);
if (ObjectiveManager != null)
var currentOrder = ObjectiveManager.CurrentOrder;
if (ObjectiveManager.CurrentOrders.Any())
{
var currentOrder = ObjectiveManager.CurrentOrder;
if (currentOrder != null)
var currentOrders = ObjectiveManager.CurrentOrders;
currentOrders.Sort((x, y) => y.ManualPriority.CompareTo(x.ManualPriority));
for (int i = 0; i < currentOrders.Count; i++)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"ORDER: {currentOrder.DebugTag} ({currentOrder.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
stringDrawPos += new Vector2(0, 20);
var order = currentOrders[i];
GUI.DrawString(spriteBatch, stringDrawPos, $"ORDER {i + 1}: {order.Objective.DebugTag} ({order.Objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
else if (ObjectiveManager.WaitTimer > 0)
}
else if (ObjectiveManager.WaitTimer > 0)
{
stringDrawPos += new Vector2(0, 20);
GUI.DrawString(spriteBatch, stringDrawPos - textOffset, $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
}
var currentObjective = ObjectiveManager.CurrentObjective;
if (currentObjective != null)
{
int offset = currentOrder != null ? 20 + ((ObjectiveManager.CurrentOrders.Count - 1) * 20) : 0;
if (currentOrder == null || currentOrder.Priority <= 0)
{
GUI.DrawString(spriteBatch, pos + new Vector2(0, 20), $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
stringDrawPos += new Vector2(0, 20);
GUI.DrawString(spriteBatch, stringDrawPos, $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
var currentObjective = ObjectiveManager.CurrentObjective;
if (currentObjective != null)
var subObjective = currentObjective.CurrentSubObjective;
if (subObjective != null)
{
int offset = currentOrder != null ? 20 : 0;
if (currentOrder == null || currentOrder.Priority <= 0)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20 + offset), $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
var subObjective = currentObjective.CurrentSubObjective;
if (subObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 40 + offset), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
var activeObjective = ObjectiveManager.GetActiveObjective();
if (activeObjective != null)
{
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 60 + offset), $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
stringDrawPos += new Vector2(0, 20);
GUI.DrawString(spriteBatch, stringDrawPos, $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
for (int i = 0; i < ObjectiveManager.Objectives.Count; i++)
var activeObjective = ObjectiveManager.GetActiveObjective();
if (activeObjective != null)
{
var objective = ObjectiveManager.Objectives[i];
int offsetMultiplier;
if (ObjectiveManager.CurrentOrder == null)
{
if (i == 0)
{
continue;
}
else
{
offsetMultiplier = i - 1;
}
}
else
{
offsetMultiplier = i + 1;
}
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(120, offsetMultiplier * 18 + 100), $"{objective.DebugTag} ({objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black * 0.5f);
stringDrawPos += new Vector2(0, 20);
GUI.DrawString(spriteBatch, stringDrawPos, $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
}
}
Vector2 objectiveStringDrawPos = stringDrawPos + new Vector2(120, 40);
for (int i = 0; i < ObjectiveManager.Objectives.Count; i++)
{
var objective = ObjectiveManager.Objectives[i];
GUI.DrawString(spriteBatch, objectiveStringDrawPos, $"{objective.DebugTag} ({objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black * 0.5f);
objectiveStringDrawPos += new Vector2(0, 18);
}
if (steeringManager is IndoorsSteeringManager pathSteering)
{
var path = pathSteering.CurrentPath;
@@ -111,13 +98,21 @@ namespace Barotrauma
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
Color.BlueViolet, 0, 3);
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 100), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
GUI.DrawString(spriteBatch, stringDrawPos + new Vector2(0, 40), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
}
}
}
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
if (Character.AnimController.InWater && objectiveManager.GetActiveObjective() is AIObjectiveGoTo gotoObjective && gotoObjective.TargetGap != null)
{
Vector2 gapPosition = gotoObjective.TargetGap.WorldPosition;
gapPosition.Y = -gapPosition.Y;
GUI.DrawRectangle(spriteBatch, gapPosition - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
GUI.DrawLine(spriteBatch, pos, gapPosition, Color.Orange * 0.5f, 0, 5);
}
//if (Character.IsKeyDown(InputType.Aim))
//{
// GUI.DrawLine(spriteBatch, pos, new Vector2(Character.CursorWorldPosition.X, -Character.CursorWorldPosition.Y), Color.Yellow, width: 4);
@@ -481,13 +481,13 @@ namespace Barotrauma
var controller = character.SelectedConstruction?.GetComponent<Controller>();
if (controller != null && controller.ControlCharacterPose && controller.User == character)
{
if (controller.Item.SpriteDepth > maxDepth)
if (controller.Item.SpriteDepth <= maxDepth || controller.DrawUserBehind)
{
depthOffset = Math.Max(controller.Item.SpriteDepth - 0.0001f - maxDepth, 0.0f);
depthOffset = Math.Max(controller.Item.GetDrawDepth() + 0.0001f - minDepth, -minDepth);
}
else
{
depthOffset = Math.Max(controller.Item.SpriteDepth + 0.0001f - minDepth, -minDepth);
depthOffset = Math.Max(controller.Item.GetDrawDepth() - 0.0001f - maxDepth, 0.0f);
}
}
}
@@ -46,7 +46,7 @@ namespace Barotrauma
if (sound != null)
{
SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range);
SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range, ignoreMuffling: sound.IgnoreMuffling);
}
}
}
@@ -457,7 +457,7 @@ namespace Barotrauma
if (draggingItemToWorld)
{
if (item.OwnInventory == null ||
!item.OwnInventory.CanBePut(CharacterInventory.draggingItem) ||
!item.OwnInventory.CanBePut(CharacterInventory.DraggingItems.First()) ||
!CanAccessInventory(item.OwnInventory))
{
continue;
@@ -520,7 +520,7 @@ namespace Barotrauma
foreach (Character c in CharacterList)
{
if (!CanInteractWith(c, checkVisibility: false)) continue;
if (!CanInteractWith(c, checkVisibility: false) || (c.AnimController?.SimplePhysicsEnabled ?? true)) { continue; }
float dist = Vector2.DistanceSquared(mouseSimPos, c.SimPosition);
if (dist < maxDist * maxDist && (closestCharacter == null || dist < closestDist))
@@ -561,7 +561,7 @@ namespace Barotrauma
{
if (InvisibleTimer > 0.0f)
{
if (Controlled == null || (Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
if (Controlled == null || Controlled == this || (Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
{
InvisibleTimer = 0.0f;
}
@@ -579,15 +579,15 @@ namespace Barotrauma
{
soundTimer -= deltaTime;
}
else if (AIController != null)
else if (AIController is EnemyAIController enemyAI)
{
switch (AIController.State)
switch (enemyAI.State)
{
case AIState.Attack:
PlaySound(CharacterSound.SoundType.Attack);
break;
default:
var petBehavior = (AIController as EnemyAIController)?.PetBehavior;
var petBehavior = enemyAI.PetBehavior;
if (petBehavior != null && petBehavior.Happiness < petBehavior.MaxHappiness * 0.25f)
{
PlaySound(CharacterSound.SoundType.Unhappy);
@@ -634,9 +634,9 @@ namespace Barotrauma
}
}
partial void SetOrderProjSpecific(Order order, string orderOption)
partial void SetOrderProjSpecific(Order order, string orderOption, int priority)
{
GameMain.GameSession?.CrewManager?.AddCurrentOrderIcon(this, order, orderOption);
GameMain.GameSession?.CrewManager?.AddCurrentOrderIcon(this, order, orderOption, priority);
}
public static void AddAllToGUIUpdateList()
@@ -686,7 +686,7 @@ namespace Barotrauma
public virtual void DrawFront(SpriteBatch spriteBatch, Camera cam)
{
if (!Enabled || InvisibleTimer > 0.0f) { return; }
if (!Enabled || InvisibleTimer > 0.0f || (AnimController?.SimplePhysicsEnabled ?? true)) { return; }
if (GameMain.DebugDraw)
{
@@ -741,7 +741,7 @@ namespace Barotrauma
if (speechBubbleTimer > 0.0f)
{
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 30,
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 5,
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
Math.Min(speechBubbleTimer, 1.0f));
}
@@ -803,7 +803,7 @@ namespace Barotrauma
Color nameColor = Color.White;
if (Controlled != null && TeamID != Controlled.TeamID)
{
nameColor = TeamID == TeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
nameColor = TeamID == CharacterTeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
}
if (CampaignInteractionType != CampaignMode.InteractionType.None && AllowCustomInteract)
{
@@ -815,7 +815,7 @@ namespace Barotrauma
iconPos.Y = -iconPos.Y;
nameColor = iconStyle.Color;
var icon = iconStyle.Sprites[GUIComponent.ComponentState.None].First();
float iconScale = 30.0f / icon.Sprite.size.X / cam.Zoom;
float iconScale = (30.0f / icon.Sprite.size.X / cam.Zoom) * GUI.Scale;
icon.Sprite.Draw(spriteBatch, iconPos + new Vector2(-35.0f, -25.0f), iconStyle.Color * hudInfoAlpha, scale: iconScale);
}
}
@@ -902,7 +902,7 @@ namespace Barotrauma
}
var selectedSound = matchingSounds.GetRandom();
if (selectedSound?.Sound == null) { return; }
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: CurrentHull);
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: CurrentHull, ignoreMuffling: selectedSound.IgnoreMuffling);
soundTimer = soundInterval;
}
@@ -1,4 +1,5 @@
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -57,7 +58,7 @@ namespace Barotrauma
!ConversationAction.FadeScreenToBlack;
}
private static string GetCachedHudText(string textTag, string keyBind)
public static string GetCachedHudText(string textTag, string keyBind)
{
if (cachedHudTexts.TryGetValue(textTag + keyBind, out string text))
{
@@ -76,10 +77,10 @@ namespace Barotrauma
{
if (character.Inventory != null)
{
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
for (int i = 0; i < character.Inventory.Capacity; i++)
{
var item = character.Inventory.Items[i];
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
var item = character.Inventory.GetItemAt(i);
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) { continue; }
foreach (ItemComponent ic in item.Components)
{
@@ -130,17 +131,6 @@ namespace Barotrauma
{
character.Inventory.ClearSubInventories();
}
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
{
var item = character.Inventory.Items[i];
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
foreach (ItemComponent ic in item.Components)
{
if (ic.DrawHudWhenEquipped) ic.UpdateHUD(character, deltaTime, cam);
}
}
}
if (character.IsHumanoid && character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null)
@@ -206,22 +196,31 @@ namespace Barotrauma
orderIndicatorCount.Clear();
foreach (Pair<Order, float?> activeOrder in GameMain.GameSession.CrewManager.ActiveOrders)
{
if (!DrawIcon(activeOrder.First)) { continue; }
if (activeOrder.Second.HasValue)
{
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First, iconAlpha: MathHelper.Clamp(activeOrder.Second.Value / 10.0f, 0.2f, 1.0f));
}
else
{
float iconAlpha = GetDistanceBasedIconAlpha(activeOrder.First.TargetSpatialEntity, maxDistance: 350.0f);
float iconAlpha = GetDistanceBasedIconAlpha(activeOrder.First.TargetSpatialEntity, maxDistance: 450.0f);
if (iconAlpha <= 0.0f) { continue; }
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First, iconAlpha: iconAlpha, createOffset: false, scaleMultiplier: 0.5f);
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First,
iconAlpha: iconAlpha, createOffset: false, scaleMultiplier: 0.5f, overrideAlpha: true);
}
}
if (character.CurrentOrder != null)
if (character.GetCurrentOrderWithTopPriority()?.Order is Order currentOrder && DrawIcon(currentOrder))
{
DrawOrderIndicator(spriteBatch, cam, character, character.CurrentOrder, 1.0f);
}
DrawOrderIndicator(spriteBatch, cam, character, currentOrder, 1.0f);
}
static bool DrawIcon(Order o) =>
o != null &&
(!(o.TargetEntity is Item i) ||
o.DrawIconWhenContained ||
i.GetRootInventoryOwner() == i);
}
foreach (Character.ObjectiveEntity objectiveEntity in character.ActiveObjectiveEntities)
@@ -231,7 +230,7 @@ namespace Barotrauma
foreach (Item brokenItem in brokenItems)
{
if (brokenItem.NonInteractable) { continue; }
if (!brokenItem.IsInteractable(character)) { continue; }
float alpha = GetDistanceBasedIconAlpha(brokenItem);
if (alpha <= 0.0f) continue;
GUI.DrawIndicator(spriteBatch, brokenItem.DrawPosition, cam, 100.0f, GUI.BrokenIcon,
@@ -244,7 +243,7 @@ namespace Barotrauma
return Math.Min((maxDistance - dist) / maxDistance * 2.0f, 1.0f);
}
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen && (!character.IsKeyDown(InputType.Aim) || character.SelectedItems.Any(it => it?.GetComponent<Sprayer>() == null)))
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen && (!character.IsKeyDown(InputType.Aim) || character.HeldItems.None(it => it?.GetComponent<Sprayer>() != null)))
{
if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
{
@@ -281,7 +280,7 @@ namespace Barotrauma
if (!GUI.DisableItemHighlights && !Inventory.DraggingItemToWorld)
{
bool shiftDown = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
if(shouldRecreateHudTexts || heldDownShiftWhenGotHudTexts != shiftDown)
if (shouldRecreateHudTexts || heldDownShiftWhenGotHudTexts != shiftDown)
{
shouldRecreateHudTexts = true;
heldDownShiftWhenGotHudTexts = shiftDown;
@@ -291,8 +290,8 @@ namespace Barotrauma
int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);
Vector2 textSize = GUI.Font.MeasureString(focusedItem.Name);
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusedItem.Name);
Vector2 textSize = GUI.Font.MeasureString(hudTexts.First().Text);
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(hudTexts.First().Text);
Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
startPos.Y -= (hudTexts.Count + 1) * textSize.Y;
@@ -307,11 +306,11 @@ namespace Barotrauma
float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);
GUI.DrawString(spriteBatch, textPos, focusedItem.Name, GUI.Style.TextColor * alpha, Color.Black * alpha * 0.7f, 2, font: GUI.SubHeadingFont);
GUI.DrawString(spriteBatch, textPos, hudTexts.First().Text, hudTexts.First().Color * alpha, Color.Black * alpha * 0.7f, 2, font: GUI.SubHeadingFont);
startPos.X += dir * 10.0f * GUI.Scale;
textPos.X += dir * 10.0f * GUI.Scale;
textPos.Y += largeTextSize.Y;
foreach (ColoredText coloredText in hudTexts)
foreach (ColoredText coloredText in hudTexts.Skip(1))
{
if (dir == -1) textPos.X = (int)(startPos.X - GUI.SmallFont.MeasureString(coloredText.Text).X);
GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUI.SmallFont);
@@ -341,9 +340,8 @@ namespace Barotrauma
}
if (Character.Controlled.Inventory != null)
{
foreach (Item item in Character.Controlled.Inventory.Items)
foreach (Item item in Character.Controlled.Inventory.AllItems)
{
if (item == null) { continue; }
if (Character.Controlled.HasEquippedItem(item))
{
item.DrawHUD(spriteBatch, cam, Character.Controlled);
@@ -355,10 +353,10 @@ namespace Barotrauma
if (character.Inventory != null)
{
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
for (int i = 0; i < character.Inventory.Capacity; i++)
{
var item = character.Inventory.Items[i];
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
var item = character.Inventory.GetItemAt(i);
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) { continue; }
foreach (ItemComponent ic in item.Components)
{
@@ -432,12 +430,16 @@ namespace Barotrauma
private static void DrawCharacterHoverTexts(SpriteBatch spriteBatch, Camera cam, Character character)
{
foreach (Item item in character.Inventory.Items)
var allItems = character.Inventory?.AllItems;
if (allItems != null)
{
var statusHUD = item?.GetComponent<StatusHUD>();
if (statusHUD != null && statusHUD.IsActive && statusHUD.VisibleCharacters.Contains(character.FocusedCharacter))
foreach (Item item in allItems)
{
return;
var statusHUD = item?.GetComponent<StatusHUD>();
if (statusHUD != null && statusHUD.IsActive && statusHUD.VisibleCharacters.Contains(character.FocusedCharacter))
{
return;
}
}
}
@@ -454,7 +456,7 @@ namespace Barotrauma
Color nameColor = GUI.Style.TextColor;
if (character.TeamID != character.FocusedCharacter.TeamID)
{
nameColor = character.FocusedCharacter.TeamID == Character.TeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
nameColor = character.FocusedCharacter.TeamID == CharacterTeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
}
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2, GUI.SubHeadingFont);
@@ -493,7 +495,9 @@ namespace Barotrauma
return character.ShouldLockHud();
}
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f, bool createOffset = true, float scaleMultiplier = 1.0f)
/// <param name="overrideAlpha">Override the distance-based alpha value with the iconAlpha parameter value</param>
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order,
float iconAlpha = 1.0f, bool createOffset = true, float scaleMultiplier = 1.0f, bool overrideAlpha = false)
{
if (order?.SymbolSprite == null) { return; }
if (order.IsReport && order.OrderGiver != character && !order.HasAppropriateJob(character)) { return; }
@@ -514,7 +518,8 @@ namespace Barotrauma
Vector2 drawPos = target is Entity ? (target as Entity).DrawPosition :
target.Submarine == null ? target.Position : target.Position + target.Submarine.DrawPosition;
drawPos += Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha, createOffset: createOffset, scaleMultiplier: scaleMultiplier);
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha,
createOffset: createOffset, scaleMultiplier: scaleMultiplier, overrideAlpha: overrideAlpha ? (float?)iconAlpha : null);
orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
}
@@ -152,48 +152,37 @@ namespace Barotrauma
partial void OnSkillChanged(string skillIdentifier, float prevLevel, float newLevel, Vector2 textPopupPos)
{
if (TeamID == Character.TeamType.FriendlyNPC) { return; }
if (TeamID == CharacterTeamType.FriendlyNPC) { return; }
if (Character.Controlled != null && Character.Controlled.TeamID != TeamID) { return; }
if (newLevel - prevLevel > 0.1f)
{
GUI.AddMessage(
"+" + ((int)((newLevel - prevLevel) * 100.0f)).ToString() + " XP",
GUI.Style.Green,
textPopupPos,
Vector2.UnitY * 10.0f,
playSound: false);
}
else if (prevLevel % 0.1f > 0.05f && newLevel % 0.1f < 0.05f)
{
GUI.AddMessage(
"+10 XP",
GUI.Style.Green,
textPopupPos,
Vector2.UnitY * 10.0f,
playSound: false);
}
if ((int)newLevel > (int)prevLevel)
{
int increase = Math.Max((int)newLevel - (int)prevLevel, 1);
GUI.AddMessage(
TextManager.GetWithVariables("SkillIncreased", new string[3] { "[name]", "[skillname]", "[newlevel]" },
new string[3] { Name, TextManager.Get("SkillName." + skillIdentifier), ((int)newLevel).ToString() },
new bool[3] { false, true, false }), GUI.Style.Green);
string.Format("+{0} {1}", increase, TextManager.Get("SkillName." + skillIdentifier)),
GUI.Style.Green,
textPopupPos,
Vector2.UnitY * 10.0f,
playSound: false,
subId: Character?.Submarine?.ID ?? -1);
}
}
private void GetDisguisedSprites(IdCard idCard)
{
if (idCard.Item.Tags == string.Empty) return;
if (idCard.StoredJobPrefab == null || idCard.StoredPortrait == null)
{
string[] readTags = idCard.Item.Tags.Split(',');
if (readTags.Length == 0) return;
if (idCard.StoredJobPrefab == null)
{
string jobIdTag = readTags.First(s => s.StartsWith("jobid:"));
string jobIdTag = readTags.FirstOrDefault(s => s.StartsWith("jobid:"));
if (jobIdTag != string.Empty && jobIdTag.Length > 6)
if (jobIdTag != null && jobIdTag.Length > 6)
{
string jobId = jobIdTag.Substring(6);
if (jobId != string.Empty)
@@ -292,7 +292,7 @@ namespace Barotrauma
break;
case ServerNetObject.ENTITY_EVENT:
int eventType = msg.ReadRangedInteger(0, 5);
int eventType = msg.ReadRangedInteger(0, 6);
switch (eventType)
{
case 0: //NetEntityEvent.Type.InventoryState
@@ -349,7 +349,7 @@ namespace Barotrauma
{
string skillIdentifier = msg.ReadString();
float skillLevel = msg.ReadSingle();
info?.SetSkillLevel(skillIdentifier, skillLevel, WorldPosition + Vector2.UnitY * 150.0f);
info?.SetSkillLevel(skillIdentifier, skillLevel, Position + Vector2.UnitY * 150.0f);
}
break;
case 4: //NetEntityEvent.Type.ExecuteAttack
@@ -390,6 +390,19 @@ namespace Barotrauma
byte campaignInteractionType = msg.ReadByte();
(GameMain.GameSession?.GameMode as CampaignMode)?.AssignNPCMenuInteraction(this, (CampaignMode.InteractionType)campaignInteractionType);
break;
case 6: //NetEntityEvent.Type.ObjectiveManagerOrderState
bool properData = msg.ReadBoolean();
if (!properData) { break; }
int orderIndex = msg.ReadRangedInteger(0, Order.PrefabList.Count);
var orderPrefab = Order.PrefabList[orderIndex];
string option = null;
if (orderPrefab.HasOptions)
{
int optionIndex = msg.ReadRangedInteger(0, orderPrefab.Options.Length);
option = orderPrefab.Options[optionIndex];
}
GameMain.GameSession.CrewManager.SetHighlightedOrderIcon(this, orderPrefab.Identifier, option);
break;
}
msg.ReadPadBits();
break;
@@ -434,20 +447,22 @@ namespace Barotrauma
CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);
character = Create(speciesName, position, seed, characterInfo: info, id: id, isRemotePlayer: ownerId > 0 && GameMain.Client.ID != ownerId, hasAi: hasAi);
character.TeamID = (TeamType)teamID;
character.TeamID = (CharacterTeamType)teamID;
character.CampaignInteractionType = (CampaignMode.InteractionType)inc.ReadByte();
if (character.CampaignInteractionType != CampaignMode.InteractionType.None)
{
(GameMain.GameSession.GameMode as CampaignMode)?.AssignNPCMenuInteraction(character, character.CampaignInteractionType);
}
// Check if the character has a current order
if (inc.ReadBoolean())
// Check if the character has current orders
int orderCount = inc.ReadByte();
for (int i = 0; i < orderCount; i++)
{
int orderPrefabIndex = inc.ReadByte();
Entity targetEntity = FindEntityByID(inc.ReadUInt16());
Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
int orderOptionIndex = inc.ReadByte();
int orderPriority = inc.ReadByte();
OrderTarget targetPosition = null;
if (inc.ReadBoolean())
{
@@ -468,7 +483,7 @@ namespace Barotrauma
new Order(orderPrefab, targetPosition, orderGiver: orderGiver);
character.SetOrder(order,
orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null,
orderGiver, speak: false);
orderPriority, orderGiver, speak: false);
}
else
{
@@ -487,7 +502,7 @@ namespace Barotrauma
character.ReadStatus(inc);
}
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead)
if (character.IsHuman && character.TeamID != CharacterTeamType.FriendlyNPC && character.TeamID != CharacterTeamType.None && !character.IsDead)
{
CharacterInfo duplicateCharacterInfo = GameMain.GameSession.CrewManager.GetCharacterInfos().FirstOrDefault(c => c.ID == info.ID);
GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo);
@@ -18,6 +18,11 @@ namespace Barotrauma
public float Range => roundSound == null ? 0.0f : roundSound.Range;
public Sound Sound => roundSound?.Sound;
public bool IgnoreMuffling
{
get { return roundSound?.IgnoreMuffling ?? false; }
}
public CharacterSound(CharacterParams.SoundParams soundParams)
{
Params = soundParams;
@@ -72,7 +72,7 @@ namespace Barotrauma
FadeTimer = 1.0f;
if (!string.IsNullOrEmpty(textTag))
{
textTag = textTag;
this.textTag = textTag;
Text = TextManager.Get(textTag);
}
}
@@ -10,6 +10,7 @@ namespace Barotrauma
{
partial void UpdateMessages()
{
if (Prefab is AfflictionPrefabHusk { SendMessages: false }) { return; }
switch (State)
{
case InfectionState.Dormant:
@@ -668,12 +668,17 @@ namespace Barotrauma
bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
if (bloodParticleTimer <= 0.0f)
{
var emitter = Character.BloodEmitters.FirstOrDefault();
float particleMinScale = emitter != null ? emitter.Prefab.ScaleMin : 0.5f;
float particleMaxScale = emitter != null ? emitter.Prefab.ScaleMax : 1;
float severity = Math.Min(affliction.Strength / affliction.Prefab.MaxStrength * Character.Params.BleedParticleMultiplier, 1);
float bloodParticleSize = MathHelper.Lerp(particleMinScale, particleMaxScale, severity);
bool inWater = Character.AnimController.InWater;
float bloodParticleSize = MathHelper.Lerp(0.5f, 1.0f, affliction.Strength / 100.0f);
if (!inWater)
{
bloodParticleSize *= 2.0f;
}
var blood = GameMain.ParticleManager.CreateParticle(
inWater ? Character.Params.BleedParticleWater : Character.Params.BleedParticleAir,
targetLimb.WorldPosition, Rand.Vector(affliction.Strength), 0.0f, Character.AnimController.CurrentHull);
@@ -682,7 +687,7 @@ namespace Barotrauma
{
blood.Size *= bloodParticleSize;
}
bloodParticleTimer = 1.0f;
bloodParticleTimer = MathHelper.Lerp(2, 0.5f, severity);
}
}
@@ -912,7 +917,7 @@ namespace Barotrauma
lowSkillIndicator.Color = new Color(lowSkillIndicator.Color, MathHelper.Lerp(0.5f, 1.0f, (float)(Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) / 2.0f));
if (Inventory.draggingItem != null)
if (Inventory.DraggingItems.Any())
{
if (highlightedLimbIndex > -1)
{
@@ -1632,8 +1637,8 @@ namespace Barotrauma
}
//can't apply treatment to dead characters
if (Character.IsDead) return true;
if (item == null || !item.UseInHealthInterface) return true;
if (Character.IsDead) { return true; }
if (item == null || !item.UseInHealthInterface) { return true; }
if (!ignoreMousePos)
{
if (highlightedLimbIndex > -1)
@@ -1652,33 +1657,25 @@ namespace Barotrauma
private List<Item> GetAvailableMedicalItems()
{
List<Item> allInventoryItems = new List<Item>();
allInventoryItems.AddRange(Character.Inventory.Items);
allInventoryItems.AddRange(Character.Inventory.AllItems);
if (Character.SelectedCharacter?.Inventory != null && Character.CanAccessInventory(Character.SelectedCharacter.Inventory))
{
allInventoryItems.AddRange(Character.SelectedCharacter.Inventory.Items);
allInventoryItems.AddRange(Character.SelectedCharacter.Inventory.AllItems);
}
if (Character.SelectedBy?.Inventory != null)
{
allInventoryItems.AddRange(Character.SelectedBy.Inventory.Items);
allInventoryItems.AddRange(Character.SelectedBy.Inventory.AllItems);
}
List<Item> medicalItems = new List<Item>();
foreach (Item item in allInventoryItems)
{
if (item == null) continue;
var containedItems = item.ContainedItems;
if (containedItems != null)
foreach (Item containedItem in item.ContainedItems)
{
foreach (Item containedItem in containedItems)
{
if (containedItem == null) continue;
if (!containedItem.HasTag("medical") && !containedItem.HasTag("chem")) continue;
medicalItems.Add(containedItem);
}
if (!containedItem.HasTag("medical") && !containedItem.HasTag("chem")) { continue; }
medicalItems.Add(containedItem);
}
if (!item.HasTag("medical") && !item.HasTag("chem")) continue;
if (!item.HasTag("medical") && !item.HasTag("chem")) { continue; }
medicalItems.Add(item);
}
@@ -1804,24 +1801,27 @@ namespace Barotrauma
spriteBatch.Begin(SpriteSortMode.Deferred, Lights.CustomBlendStates.Multiplicative);
float overlayScale = Math.Min(
drawArea.Width / (float)limbIndicatorOverlay.FrameSize.X,
drawArea.Height / (float)limbIndicatorOverlay.FrameSize.Y);
int frame = 0;
int frameCount = 17;
if (limbIndicatorOverlayAnimState >= frameCount * 2) limbIndicatorOverlayAnimState = 0.0f;
if (limbIndicatorOverlayAnimState < frameCount)
if (limbIndicatorOverlay != null)
{
frame = (int)limbIndicatorOverlayAnimState;
}
else
{
frame = frameCount - (int)(limbIndicatorOverlayAnimState - (frameCount - 1));
}
float overlayScale = Math.Min(
drawArea.Width / (float)limbIndicatorOverlay.FrameSize.X,
drawArea.Height / (float)limbIndicatorOverlay.FrameSize.Y);
limbIndicatorOverlay.Draw(spriteBatch, frame, drawArea.Center.ToVector2(), Color.Gray, origin: limbIndicatorOverlay.FrameSize.ToVector2() / 2, rotate: 0.0f,
scale: Vector2.One * overlayScale);
int frame = 0;
int frameCount = 17;
if (limbIndicatorOverlayAnimState >= frameCount * 2) limbIndicatorOverlayAnimState = 0.0f;
if (limbIndicatorOverlayAnimState < frameCount)
{
frame = (int)limbIndicatorOverlayAnimState;
}
else
{
frame = frameCount - (int)(limbIndicatorOverlayAnimState - (frameCount - 1));
}
limbIndicatorOverlay.Draw(spriteBatch, frame, drawArea.Center.ToVector2(), Color.Gray, origin: limbIndicatorOverlay.FrameSize.ToVector2() / 2, rotate: 0.0f,
scale: Vector2.One * overlayScale);
}
if (allowHighlight)
{
@@ -22,8 +22,8 @@ namespace Barotrauma
float strength = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(0, MathHelper.Pi, diff));
float jointAngle = JointAngle * strength;
JointBendDeformation limbADeformation = LimbA.Deformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
JointBendDeformation limbBDeformation = LimbB.Deformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
JointBendDeformation limbADeformation = LimbA.ActiveDeformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
JointBendDeformation limbBDeformation = LimbB.ActiveDeformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
if (limbADeformation != null && limbBDeformation != null)
{
@@ -114,7 +114,10 @@ namespace Barotrauma
/// Note that different limbs can share the same deformations.
/// Use ragdoll.SpriteDeformations for a collection that cannot have duplicates.
/// </summary>
public List<SpriteDeformation> Deformations { get; private set; } = new List<SpriteDeformation>();
private List<SpriteDeformation> Deformations { get; set; } = new List<SpriteDeformation>();
private List<SpriteDeformation> NonConditionalDeformations { get; set; } = new List<SpriteDeformation>();
private List<(ConditionalSprite, IEnumerable<SpriteDeformation>)> ConditionalDeformations { get; set; } = new List<(ConditionalSprite, IEnumerable<SpriteDeformation>)>();
public List<SpriteDeformation> ActiveDeformations { get; set; } = new List<SpriteDeformation>();
public Sprite Sprite { get; protected set; }
@@ -178,6 +181,9 @@ namespace Barotrauma
{
public float RotationState;
public float OffsetState;
public Vector2 RandomOffsetMultiplier = new Vector2(Rand.Range(-1.0f, 1.0f), Rand.Range(-1.0f, 1.0f));
public float RandomRotationFactor = Rand.Range(0.0f, 1.0f);
public float RandomScaleFactor = Rand.Range(0.0f, 1.0f);
public bool IsActive = true;
}
@@ -282,12 +288,16 @@ namespace Barotrauma
ConditionalSprites.Add(conditionalSprite);
if (conditionalSprite.DeformableSprite != null)
{
CreateDeformations(subElement.GetChildElement("deformablesprite"));
var conditionalDeformations = CreateDeformations(subElement.GetChildElement("deformablesprite"));
Deformations.AddRange(conditionalDeformations);
ConditionalDeformations.Add((conditionalSprite, conditionalDeformations));
}
break;
case "deformablesprite":
_deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
CreateDeformations(subElement);
var deformations = CreateDeformations(subElement);
Deformations.AddRange(deformations);
NonConditionalDeformations.AddRange(deformations);
break;
case "lightsource":
LightSource = new LightSource(subElement, GetConditionalTarget())
@@ -315,8 +325,9 @@ namespace Barotrauma
return targetEntity;
}
void CreateDeformations(XElement e)
IEnumerable<SpriteDeformation> CreateDeformations(XElement e)
{
List<SpriteDeformation> deformations = new List<SpriteDeformation>();
foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
{
int sync = animationElement.GetAttributeInt("sync", -1);
@@ -340,14 +351,39 @@ namespace Barotrauma
}
if (deformation != null)
{
Deformations.Add(deformation);
deformations.Add(deformation);
}
}
return deformations;
}
}
LightSource?.CheckConditionals();
}
private void RefreshDeformations()
{
if (_deformSprite == null) { return; }
if (ConditionalSprites.None())
{
ActiveDeformations = Deformations;
}
else
{
ActiveDeformations.Clear();
if (_deformSprite == DeformSprite)
{
ActiveDeformations.AddRange(NonConditionalDeformations);
}
foreach (var conditionalDeformation in ConditionalDeformations)
{
if (conditionalDeformation.Item1.IsActive)
{
ActiveDeformations.AddRange(conditionalDeformation.Item2);
}
}
}
}
public void RecreateSprites()
{
if (Sprite != null)
@@ -390,18 +426,24 @@ namespace Barotrauma
character.Info?.CalculateHeadPosition(sprite);
}
private string _texturePath;
private string GetSpritePath(XElement element, SpriteParams spriteParams)
{
if (spriteParams != null)
if (_texturePath == null)
{
return GetSpritePath(spriteParams.GetTexturePath());
}
else
{
string texturePath = element.GetAttributeString("texture", null);
texturePath = string.IsNullOrWhiteSpace(texturePath) ? ragdoll.RagdollParams.Texture : texturePath;
return GetSpritePath(texturePath);
if (spriteParams != null)
{
string texturePath = character.Params.VariantFile?.Root?.GetAttributeString("texture", null) ?? spriteParams.GetTexturePath();
_texturePath = GetSpritePath(texturePath);
}
else
{
string texturePath = element.GetAttributeString("texture", null);
texturePath = string.IsNullOrWhiteSpace(texturePath) ? ragdoll.RagdollParams.Texture : texturePath;
_texturePath = GetSpritePath(texturePath);
}
}
return _texturePath;
}
/// <summary>
@@ -537,7 +579,7 @@ namespace Barotrauma
else
{
var spriteParams = Params.GetSprite();
if (spriteParams.DeadColorTime > 0 && deadTimer < spriteParams.DeadColorTime)
if (spriteParams != null && spriteParams.DeadColorTime > 0 && deadTimer < spriteParams.DeadColorTime)
{
deadTimer += deltaTime;
}
@@ -587,6 +629,7 @@ namespace Barotrauma
}
UpdateSpriteStates(deltaTime);
RefreshDeformations();
}
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null)
@@ -637,13 +680,13 @@ namespace Barotrauma
var deformSprite = DeformSprite;
if (deformSprite != null)
{
if (Deformations != null && Deformations.Any())
if (ActiveDeformations.Any())
{
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
var deformation = SpriteDeformation.GetDeformation(ActiveDeformations, deformSprite.Size);
deformSprite.Deform(deformation);
if (LightSource != null && LightSource.DeformableLightSprite != null)
{
deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size, dir == Direction.Left);
deformation = SpriteDeformation.GetDeformation(ActiveDeformations, deformSprite.Size, dir == Direction.Left);
LightSource.DeformableLightSprite.Deform(deformation);
}
}
@@ -666,9 +709,9 @@ namespace Barotrauma
if (conditionalSprite.DeformableSprite != null)
{
var defSprite = conditionalSprite.DeformableSprite;
if (Deformations != null && Deformations.Any())
if (ActiveDeformations.Any())
{
var deformation = SpriteDeformation.GetDeformation(Deformations, defSprite.Size);
var deformation = SpriteDeformation.GetDeformation(ActiveDeformations, defSprite.Size);
defSprite.Deform(deformation);
}
else
@@ -705,13 +748,13 @@ namespace Barotrauma
c = Color.Lerp(c, spriteParams.DeadColor, MathUtils.InverseLerp(0, Params.GetSprite().DeadColorTime, deadTimer));
}
c = overrideColor ?? c;
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier) * Scale;
var ca = (float)Math.Cos(-body.Rotation);
var sa = (float)Math.Sin(-body.Rotation);
Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y);
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X + transformedOffset.X, -(body.DrawPosition.Y + transformedOffset.Y)), c,
-body.Rotation + rotation, decorativeSprite.Scale * Scale, spriteEffect,
-body.Rotation + rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, spriteEffect,
depth: decorativeSprite.Sprite.Depth);
}
float depthStep = 0.000001f;