(3dc4135ce) v0.9.5.1
This commit is contained in:
@@ -14,10 +14,27 @@ namespace Barotrauma
|
||||
Vector2 pos = Character.WorldPosition;
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
if (SelectedAiTarget?.Entity != null)
|
||||
if (State == AIState.Idle && PreviousState == AIState.Attack)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.5f, 0, 4);
|
||||
|
||||
var target = _selectedAiTarget ?? _lastAiTarget;
|
||||
if (target != null)
|
||||
{
|
||||
var memory = GetTargetMemory(target);
|
||||
Vector2 targetPos = memory.Location;
|
||||
targetPos.Y = -targetPos.Y;
|
||||
GUI.DrawLine(spriteBatch, pos, targetPos, Color.White * 0.5f, 0, 4);
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{target.Entity.ToString()} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
}
|
||||
else if (SelectedAiTarget?.Entity != null)
|
||||
{
|
||||
Vector2 targetPos = SelectedAiTarget.WorldPosition;
|
||||
if (State == AIState.Attack)
|
||||
{
|
||||
targetPos = attackWorldPos;
|
||||
}
|
||||
targetPos.Y = -targetPos.Y;
|
||||
GUI.DrawLine(spriteBatch, pos, targetPos, Color.Red * 0.5f, 0, 4);
|
||||
if (wallTarget != null)
|
||||
{
|
||||
Vector2 wallTargetPos = wallTarget.Position;
|
||||
@@ -26,7 +43,8 @@ namespace Barotrauma
|
||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
||||
}
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({GetTargetMemory(SelectedAiTarget).Priority.FormatZeroDecimal()})", Color.Red, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
|
||||
}
|
||||
|
||||
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, Color.Red);
|
||||
@@ -42,6 +60,9 @@ namespace Barotrauma
|
||||
case AIState.Escape:
|
||||
stateColor = Color.LightBlue;
|
||||
break;
|
||||
case AIState.Flee:
|
||||
stateColor = Color.White;
|
||||
break;
|
||||
case AIState.Eat:
|
||||
stateColor = Color.Brown;
|
||||
break;
|
||||
@@ -59,8 +80,8 @@ namespace Barotrauma
|
||||
|
||||
if (LatchOntoAI.WallAttachPos.HasValue)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos,
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.WallAttachPos.Value.X, -LatchOntoAI.WallAttachPos.Value.Y)), Color.Green, 0, 3);
|
||||
//GUI.DrawLine(spriteBatch, pos,
|
||||
// ConvertUnits.ToDisplayUnits(new Vector2(LatchOntoAI.WallAttachPos.Value.X, -LatchOntoAI.WallAttachPos.Value.Y)), Color.Green, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +114,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (steeringManager.AvoidDir.LengthSquared() > 0.0001f)
|
||||
{
|
||||
Vector2 hitPos = ConvertUnits.ToDisplayUnits(steeringManager.AvoidRayCastHitPosition);
|
||||
hitPos.Y = -hitPos.Y;
|
||||
|
||||
GUI.DrawLine(spriteBatch, hitPos, hitPos + new Vector2(steeringManager.AvoidDir.X, -steeringManager.AvoidDir.Y) * 100, Color.Red, width: 5);
|
||||
//GUI.DrawLine(spriteBatch, pos, ConvertUnits.ToDisplayUnits(steeringManager.AvoidLookAheadPos.X, -steeringManager.AvoidLookAheadPos.Y), Color.Orange, width: 4);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
||||
{
|
||||
Vector2 pos = Character.WorldPosition;
|
||||
pos.Y = -pos.Y;
|
||||
Vector2 textOffset = new Vector2(-40, -120);
|
||||
Vector2 textOffset = new Vector2(-40, -160);
|
||||
|
||||
if (SelectedAiTarget?.Entity != null)
|
||||
{
|
||||
@@ -33,26 +33,36 @@ 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);
|
||||
|
||||
if (ObjectiveManager != null)
|
||||
{
|
||||
var currentOrder = ObjectiveManager.CurrentOrder;
|
||||
if (currentOrder != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset, $"ORDER: {currentOrder.DebugTag} ({currentOrder.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"ORDER: {currentOrder.DebugTag} ({currentOrder.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
else if (ObjectiveManager.WaitTimer > 0)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset, $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos + new Vector2(0, 20), $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
|
||||
}
|
||||
var currentObjective = ObjectiveManager.CurrentObjective;
|
||||
if (currentObjective != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
if (currentOrder == null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var subObjective = currentObjective.SubObjectives.FirstOrDefault();
|
||||
if (subObjective != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 40), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var activeObjective = ObjectiveManager.GetActiveObjective();
|
||||
if (activeObjective != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 60), $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.GetPriority().FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +91,7 @@ namespace Barotrauma
|
||||
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
|
||||
Color.BlueViolet, 0, 3);
|
||||
|
||||
GUI.DrawString(spriteBatch, pos + textOffset - new Vector2(0, 20), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 80), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateNetPlayerPositionProjSpecific(float deltaTime, float lowestSubPos)
|
||||
{
|
||||
if (character != GameMain.Client.Character || !character.AllowInput)
|
||||
if (character != GameMain.Client.Character || !character.CanMove)
|
||||
{
|
||||
//remove states without a timestamp (there may still be ID-based states
|
||||
//in the list when the controlled character switches to timestamp-based interpolation)
|
||||
@@ -92,10 +92,10 @@ namespace Barotrauma
|
||||
Collider.AngularVelocity = newAngularVelocity;
|
||||
|
||||
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||
float errorTolerance = character.AllowInput ? 0.01f : 0.2f;
|
||||
float errorTolerance = character.CanMove ? 0.01f : 0.2f;
|
||||
if (distSqrd > errorTolerance)
|
||||
{
|
||||
if (distSqrd > 10.0f || !character.AllowInput)
|
||||
if (distSqrd > 10.0f || !character.CanMove)
|
||||
{
|
||||
Collider.TargetRotation = newRotation;
|
||||
SetPosition(newPosition, lerp: distSqrd < 5.0f, ignorePlatforms: false);
|
||||
@@ -108,9 +108,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
//unconscious/dead characters can't correct their position using AnimController movement
|
||||
//immobilized characters can't correct their position using AnimController movement
|
||||
// -> we need to correct it manually
|
||||
if (!character.AllowInput)
|
||||
if (!character.CanMove)
|
||||
{
|
||||
float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition);
|
||||
float mainLimbErrorTolerance = 0.1f;
|
||||
|
||||
@@ -343,7 +343,7 @@ namespace Barotrauma
|
||||
|
||||
partial void OnAttackedProjSpecific(Character attacker, AttackResult attackResult)
|
||||
{
|
||||
if (attackResult.Damage <= 1.0f) { return; }
|
||||
if (attackResult.Damage <= 1.0f || IsDead) { return; }
|
||||
if (soundTimer < soundInterval * 0.5f)
|
||||
{
|
||||
PlaySound(CharacterSound.SoundType.Damage);
|
||||
@@ -524,6 +524,8 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||
{
|
||||
if (!enabled) { return; }
|
||||
|
||||
if (!IsDead && !IsUnconscious)
|
||||
{
|
||||
if (soundTimer > 0)
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Barotrauma
|
||||
Job.Name, textColor: Job.Prefab.UIColor, font: font);
|
||||
}
|
||||
|
||||
if (personalityTrait != null && TextManager.Language == "English")
|
||||
if (personalityTrait != null)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), headerTextArea.RectTransform),
|
||||
TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), TextManager.Get("personalitytrait." + personalityTrait.Name.Replace(" ", ""))), font: font);
|
||||
@@ -125,7 +125,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
partial void LoadAttachmentSprites()
|
||||
partial void LoadAttachmentSprites(bool omitJob)
|
||||
{
|
||||
if (attachmentSprites == null)
|
||||
{
|
||||
@@ -139,7 +139,25 @@ namespace Barotrauma
|
||||
BeardElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Beard)));
|
||||
MoustacheElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Moustache)));
|
||||
HairElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.Hair)));
|
||||
Job?.Prefab.ClothingElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
||||
if (omitJob)
|
||||
{
|
||||
JobPrefab.NoJobElement?.Element("PortraitClothing")?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
||||
}
|
||||
else
|
||||
{
|
||||
Job?.Prefab.ClothingElement?.Elements("sprite").ForEach(s => attachmentSprites.Add(new WearableSprite(s, WearableType.JobIndicator)));
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't work if the head's source rect does not start at 0,0.
|
||||
public static Point CalculateOffset(Sprite sprite, Point offset) => sprite.SourceRect.Size * offset;
|
||||
|
||||
public void CalculateHeadPosition(Sprite sprite)
|
||||
{
|
||||
if (sprite == null) { return; }
|
||||
if (Head.SheetIndex == null) { return; }
|
||||
Point location = CalculateOffset(sprite, Head.SheetIndex.Value.ToPoint());
|
||||
sprite.SourceRect = new Rectangle(location, sprite.SourceRect.Size);
|
||||
}
|
||||
|
||||
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, float targetWidth)
|
||||
@@ -155,6 +173,10 @@ namespace Barotrauma
|
||||
// Scale down the head sprite 10%
|
||||
float scale = targetWidth * 0.9f / Portrait.size.X;
|
||||
Vector2 offset = Portrait.size * backgroundScale / 4;
|
||||
if (Head.SheetIndex.HasValue)
|
||||
{
|
||||
Portrait.SourceRect = new Rectangle(CalculateOffset(Portrait, Head.SheetIndex.Value.ToPoint()), Portrait.SourceRect.Size);
|
||||
}
|
||||
Portrait.Draw(spriteBatch, screenPos + offset, scale: scale, spriteEffect: SpriteEffects.FlipHorizontally);
|
||||
if (AttachmentSprites != null)
|
||||
{
|
||||
@@ -170,16 +192,21 @@ namespace Barotrauma
|
||||
|
||||
public void DrawIcon(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 targetAreaSize)
|
||||
{
|
||||
if (HeadSprite != null)
|
||||
var headSprite = HeadSprite;
|
||||
if (headSprite != null)
|
||||
{
|
||||
float scale = Math.Min(targetAreaSize.X / HeadSprite.size.X, targetAreaSize.Y / HeadSprite.size.Y);
|
||||
HeadSprite.Draw(spriteBatch, screenPos, scale: scale);
|
||||
float scale = Math.Min(targetAreaSize.X / headSprite.size.X, targetAreaSize.Y / headSprite.size.Y);
|
||||
if (Head.SheetIndex.HasValue)
|
||||
{
|
||||
headSprite.SourceRect = new Rectangle(CalculateOffset(headSprite, Head.SheetIndex.Value.ToPoint()), headSprite.SourceRect.Size);
|
||||
}
|
||||
headSprite.Draw(spriteBatch, screenPos, scale: scale);
|
||||
if (AttachmentSprites != null)
|
||||
{
|
||||
float depthStep = 0.000001f;
|
||||
foreach (var attachment in AttachmentSprites)
|
||||
{
|
||||
DrawAttachmentSprite(spriteBatch, attachment, HeadSprite, screenPos, scale, depthStep);
|
||||
DrawAttachmentSprite(spriteBatch, attachment, headSprite, screenPos, scale, depthStep);
|
||||
depthStep += depthStep;
|
||||
}
|
||||
}
|
||||
@@ -188,13 +215,15 @@ namespace Barotrauma
|
||||
|
||||
private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None)
|
||||
{
|
||||
var list = AttachmentSprites.ToList();
|
||||
if (attachment.InheritSourceRect)
|
||||
{
|
||||
if (attachment.SheetIndex.HasValue)
|
||||
{
|
||||
Point location = (head.SourceRect.Location + head.SourceRect.Size) * attachment.SheetIndex.Value;
|
||||
attachment.Sprite.SourceRect = new Rectangle(location, head.SourceRect.Size);
|
||||
attachment.Sprite.SourceRect = new Rectangle(CalculateOffset(head, attachment.SheetIndex.Value), head.SourceRect.Size);
|
||||
}
|
||||
else if (Head.SheetIndex.HasValue)
|
||||
{
|
||||
attachment.Sprite.SourceRect = new Rectangle(CalculateOffset(head, Head.SheetIndex.Value.ToPoint()), head.SourceRect.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -219,7 +248,6 @@ namespace Barotrauma
|
||||
attachment.Sprite.Draw(spriteBatch, drawPos, Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
|
||||
}
|
||||
|
||||
|
||||
public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
|
||||
{
|
||||
ushort infoID = inc.ReadUInt16();
|
||||
@@ -234,6 +262,8 @@ namespace Barotrauma
|
||||
string ragdollFile = inc.ReadString();
|
||||
|
||||
string jobIdentifier = inc.ReadString();
|
||||
int variant = inc.ReadByte();
|
||||
|
||||
JobPrefab jobPrefab = null;
|
||||
Dictionary<string, float> skillLevels = new Dictionary<string, float>();
|
||||
if (!string.IsNullOrEmpty(jobIdentifier))
|
||||
@@ -249,7 +279,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
// TODO: animations
|
||||
CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile)
|
||||
CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile, variant)
|
||||
{
|
||||
ID = infoID,
|
||||
};
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace Barotrauma
|
||||
msg.ReadPadBits();
|
||||
|
||||
int index = 0;
|
||||
if (GameMain.Client.Character == this && AllowInput)
|
||||
if (GameMain.Client.Character == this && CanMove)
|
||||
{
|
||||
var posInfo = new CharacterStateInfo(
|
||||
pos, rotation,
|
||||
@@ -309,7 +309,7 @@ namespace Barotrauma
|
||||
LastNetworkUpdateID = controlled.LastNetworkUpdateID;
|
||||
}
|
||||
|
||||
Controlled = this;
|
||||
if (!IsDead) { Controlled = this; }
|
||||
IsRemotePlayer = false;
|
||||
GameMain.Client.HasSpawned = true;
|
||||
GameMain.Client.Character = this;
|
||||
@@ -342,7 +342,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static Character ReadSpawnData(IReadMessage inc, bool spawn = true)
|
||||
public static Character ReadSpawnData(IReadMessage inc)
|
||||
{
|
||||
DebugConsole.Log("Reading character spawn data");
|
||||
|
||||
@@ -362,10 +362,9 @@ namespace Barotrauma
|
||||
Character character = null;
|
||||
if (noInfo)
|
||||
{
|
||||
if (!spawn) return null;
|
||||
|
||||
character = Create(speciesName, position, seed, null, true);
|
||||
character.ID = id;
|
||||
character.ReadStatus(inc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -375,15 +374,14 @@ namespace Barotrauma
|
||||
bool hasAi = inc.ReadBoolean();
|
||||
string infoSpeciesName = inc.ReadString();
|
||||
|
||||
if (!spawn) return null;
|
||||
|
||||
CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);
|
||||
|
||||
character = Create(infoSpeciesName, position, seed, info, GameMain.Client.ID != ownerId, hasAi);
|
||||
character = Create(speciesName, position, seed, info, GameMain.Client.ID != ownerId, hasAi);
|
||||
character.ID = id;
|
||||
character.TeamID = (TeamType)teamID;
|
||||
character.ReadStatus(inc);
|
||||
|
||||
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC)
|
||||
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead)
|
||||
{
|
||||
CharacterInfo duplicateCharacterInfo = GameMain.GameSession.CrewManager.GetCharacterInfos().FirstOrDefault(c => c.ID == info.ID);
|
||||
GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo);
|
||||
@@ -394,7 +392,7 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.Client.HasSpawned = true;
|
||||
GameMain.Client.Character = character;
|
||||
Controlled = character;
|
||||
if (!character.IsDead) { Controlled = character; }
|
||||
|
||||
GameMain.LightManager.LosEnabled = true;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Barotrauma
|
||||
{
|
||||
private static bool toggledThisFrame;
|
||||
|
||||
private static Sprite damageOverlay;
|
||||
public static Sprite DamageOverlay;
|
||||
|
||||
private static string[] strengthTexts;
|
||||
|
||||
@@ -153,12 +153,7 @@ namespace Barotrauma
|
||||
get { return healthBarPulsateTimer; }
|
||||
set { healthBarPulsateTimer = MathHelper.Clamp(value, 0.0f, 10.0f); }
|
||||
}
|
||||
|
||||
static CharacterHealth()
|
||||
{
|
||||
damageOverlay = new Sprite("Content/UI/damageOverlay.png", Vector2.Zero);
|
||||
}
|
||||
|
||||
|
||||
partial void InitProjSpecific(XElement element, Character character)
|
||||
{
|
||||
DisplayedVitality = MaxVitality;
|
||||
@@ -837,8 +832,8 @@ namespace Barotrauma
|
||||
|
||||
if (damageOverlayAlpha > 0.0f)
|
||||
{
|
||||
damageOverlay.Draw(spriteBatch, Vector2.Zero, Color.White * damageOverlayAlpha, Vector2.Zero, 0.0f,
|
||||
new Vector2(GameMain.GraphicsWidth / damageOverlay.size.X, GameMain.GraphicsHeight / damageOverlay.size.Y));
|
||||
DamageOverlay?.Draw(spriteBatch, Vector2.Zero, Color.White * damageOverlayAlpha, Vector2.Zero, 0.0f,
|
||||
new Vector2(GameMain.GraphicsWidth / DamageOverlay.size.X, GameMain.GraphicsHeight / DamageOverlay.size.Y));
|
||||
}
|
||||
|
||||
if (Character.Inventory != null)
|
||||
@@ -997,30 +992,7 @@ namespace Barotrauma
|
||||
//key = item identifier
|
||||
//float = suitability
|
||||
Dictionary<string, float> treatmentSuitability = new Dictionary<string, float>();
|
||||
float minSuitability = -10, maxSuitability = 10;
|
||||
foreach (Affliction affliction in afflictions)
|
||||
{
|
||||
foreach (KeyValuePair<string, float> treatment in affliction.Prefab.TreatmentSuitability)
|
||||
{
|
||||
if (!treatmentSuitability.ContainsKey(treatment.Key))
|
||||
{
|
||||
treatmentSuitability[treatment.Key] = treatment.Value * affliction.Strength;
|
||||
}
|
||||
else
|
||||
{
|
||||
treatmentSuitability[treatment.Key] += treatment.Value * affliction.Strength;
|
||||
}
|
||||
minSuitability = Math.Min(treatmentSuitability[treatment.Key], minSuitability);
|
||||
maxSuitability = Math.Max(treatmentSuitability[treatment.Key], maxSuitability);
|
||||
}
|
||||
}
|
||||
//normalize the suitabilities to a range of 0 to 1
|
||||
foreach (string treatment in treatmentSuitability.Keys.ToList())
|
||||
{
|
||||
treatmentSuitability[treatment] = (treatmentSuitability[treatment] - minSuitability) / (maxSuitability - minSuitability);
|
||||
//lerp towards a random value if the medical skill is low
|
||||
treatmentSuitability[treatment] = MathHelper.Lerp(treatmentSuitability[treatment], Rand.Range(0.0f, 1.0f), randomVariance);
|
||||
}
|
||||
GetSuitableTreatments(treatmentSuitability, normalize: true, randomization: randomVariance);
|
||||
|
||||
foreach (Affliction affliction in afflictions)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
partial class DamageModifier
|
||||
{
|
||||
[Serialize("", false)]
|
||||
[Serialize("", false), Editable]
|
||||
public string DamageSound
|
||||
{
|
||||
get;
|
||||
|
||||
@@ -119,7 +119,24 @@ namespace Barotrauma
|
||||
public List<SpriteDeformation> Deformations { get; private set; } = new List<SpriteDeformation>();
|
||||
|
||||
public Sprite Sprite { get; protected set; }
|
||||
public DeformableSprite DeformSprite { get; protected set; }
|
||||
|
||||
protected DeformableSprite _deformSprite;
|
||||
|
||||
public DeformableSprite DeformSprite
|
||||
{
|
||||
get
|
||||
{
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive && c.DeformableSprite != null);
|
||||
if (conditionalSprite != null)
|
||||
{
|
||||
return conditionalSprite.DeformableSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _deformSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<DecorativeSprite> DecorativeSprites { get; private set; } = new List<DecorativeSprite>();
|
||||
|
||||
@@ -127,15 +144,14 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: should we optimize this? No need to check all the conditionals each time the property is accessed.
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive);
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive && c.ActiveSprite != null);
|
||||
if (conditionalSprite != null)
|
||||
{
|
||||
return conditionalSprite;
|
||||
return conditionalSprite.ActiveSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DeformSprite != null ? DeformSprite.Sprite : Sprite;
|
||||
return _deformSprite != null ? _deformSprite.Sprite : Sprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,40 +231,53 @@ namespace Barotrauma
|
||||
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
|
||||
break;
|
||||
case "conditionalsprite":
|
||||
ConditionalSprites.Add(new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null)));
|
||||
var conditionalSprite = new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null));
|
||||
ConditionalSprites.Add(conditionalSprite);
|
||||
if (conditionalSprite.DeformableSprite != null)
|
||||
{
|
||||
CreateDeformations(subElement.GetChildElement("deformablesprite"));
|
||||
}
|
||||
break;
|
||||
case "deformablesprite":
|
||||
DeformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
|
||||
foreach (XElement animationElement in subElement.Elements())
|
||||
{
|
||||
int sync = animationElement.GetAttributeInt("sync", -1);
|
||||
SpriteDeformation deformation = null;
|
||||
if (sync > -1)
|
||||
{
|
||||
// if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already.
|
||||
string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant();
|
||||
deformation = ragdoll.Limbs
|
||||
.Where(l => l != null)
|
||||
.SelectMany(l => l.Deformations)
|
||||
.Where(d => d.TypeName == typeName && d.Sync == sync)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
if (deformation == null)
|
||||
{
|
||||
deformation = SpriteDeformation.Load(animationElement, character.SpeciesName);
|
||||
if (deformation != null)
|
||||
{
|
||||
ragdoll.SpriteDeformations.Add(deformation);
|
||||
}
|
||||
}
|
||||
if (deformation != null) Deformations.Add(deformation);
|
||||
}
|
||||
_deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
|
||||
CreateDeformations(subElement);
|
||||
break;
|
||||
case "lightsource":
|
||||
LightSource = new LightSource(subElement);
|
||||
InitialLightSourceColor = LightSource.Color;
|
||||
break;
|
||||
}
|
||||
|
||||
void CreateDeformations(XElement e)
|
||||
{
|
||||
foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
|
||||
{
|
||||
int sync = animationElement.GetAttributeInt("sync", -1);
|
||||
SpriteDeformation deformation = null;
|
||||
if (sync > -1)
|
||||
{
|
||||
// if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already.
|
||||
string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant();
|
||||
deformation = ragdoll.Limbs
|
||||
.Where(l => l != null)
|
||||
.SelectMany(l => l.Deformations)
|
||||
.Where(d => d.TypeName == typeName && d.Sync == sync)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
if (deformation == null)
|
||||
{
|
||||
deformation = SpriteDeformation.Load(animationElement, character.SpeciesName);
|
||||
if (deformation != null)
|
||||
{
|
||||
ragdoll.SpriteDeformations.Add(deformation);
|
||||
}
|
||||
}
|
||||
if (deformation != null)
|
||||
{
|
||||
Deformations.Add(deformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,11 +289,11 @@ namespace Barotrauma
|
||||
var source = Sprite.SourceElement;
|
||||
Sprite = new Sprite(source, file: GetSpritePath(source, Params.normalSpriteParams));
|
||||
}
|
||||
if (DeformSprite != null)
|
||||
if (_deformSprite != null)
|
||||
{
|
||||
DeformSprite.Remove();
|
||||
var source = DeformSprite.Sprite.SourceElement;
|
||||
DeformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams));
|
||||
_deformSprite.Remove();
|
||||
var source = _deformSprite.Sprite.SourceElement;
|
||||
_deformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams));
|
||||
}
|
||||
if (DamagedSprite != null)
|
||||
{
|
||||
@@ -275,9 +304,8 @@ namespace Barotrauma
|
||||
for (int i = 0; i < ConditionalSprites.Count; i++)
|
||||
{
|
||||
var conditionalSprite = ConditionalSprites[i];
|
||||
var source = conditionalSprite.ActiveSprite.SourceElement;
|
||||
conditionalSprite.Remove();
|
||||
var source = conditionalSprite.SourceElement;
|
||||
// TODO: lazy load?
|
||||
ConditionalSprites[i] = new ConditionalSprite(source, character, file: GetSpritePath(source, null));
|
||||
}
|
||||
for (int i = 0; i < DecorativeSprites.Count; i++)
|
||||
@@ -289,6 +317,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateHeadPosition(Sprite sprite)
|
||||
{
|
||||
if (type != LimbType.Head) { return; }
|
||||
character.Info?.CalculateHeadPosition(sprite);
|
||||
}
|
||||
|
||||
private string GetSpritePath(XElement element, SpriteParams spriteParams)
|
||||
{
|
||||
string texturePath = element.GetAttributeString("texture", null);
|
||||
@@ -330,7 +364,7 @@ namespace Barotrauma
|
||||
bool isFlipped = dir == Direction.Left;
|
||||
Sprite?.LoadParams(Params.normalSpriteParams, isFlipped);
|
||||
DamagedSprite?.LoadParams(Params.damagedSpriteParams, isFlipped);
|
||||
DeformSprite?.Sprite.LoadParams(Params.deformSpriteParams, isFlipped);
|
||||
_deformSprite?.Sprite.LoadParams(Params.deformSpriteParams, isFlipped);
|
||||
for (int i = 0; i < DecorativeSprites.Count; i++)
|
||||
{
|
||||
DecorativeSprites[i].Sprite?.LoadParams(Params.decorativeSpriteParams[i], isFlipped);
|
||||
@@ -461,24 +495,31 @@ namespace Barotrauma
|
||||
enableHuskSprite && HuskSprite != null && HuskSprite.HideLimb ||
|
||||
OtherWearables.Any(w => w.HideLimb) ||
|
||||
wearingItems.Any(w => w != null && w.HideLimb);
|
||||
|
||||
var activeSprite = ActiveSprite;
|
||||
if (type == LimbType.Head)
|
||||
{
|
||||
CalculateHeadPosition(activeSprite);
|
||||
}
|
||||
|
||||
// TODO: there's now two calls to this, because body.Draw() method calls this too -> is this an issue?
|
||||
body.UpdateDrawPosition();
|
||||
|
||||
if (!hideLimb)
|
||||
{
|
||||
var activeSprite = ActiveSprite;
|
||||
if (DeformSprite != null && activeSprite == DeformSprite.Sprite)
|
||||
var deformSprite = DeformSprite;
|
||||
if (deformSprite != null)
|
||||
{
|
||||
if (Deformations != null && Deformations.Any())
|
||||
{
|
||||
var deformation = SpriteDeformation.GetDeformation(Deformations, DeformSprite.Size);
|
||||
DeformSprite.Deform(deformation);
|
||||
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
|
||||
deformSprite.Deform(deformation);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeformSprite.Reset();
|
||||
deformSprite.Reset();
|
||||
}
|
||||
body.Draw(DeformSprite, cam, Vector2.One * Scale * TextureScale, color, Params.MirrorHorizontally);
|
||||
body.Draw(deformSprite, cam, Vector2.One * Scale * TextureScale, color, Params.MirrorHorizontally);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -489,15 +530,16 @@ namespace Barotrauma
|
||||
if (LightSource != null)
|
||||
{
|
||||
LightSource.Position = body.DrawPosition;
|
||||
if (LightSource.ParentSub != null) { LightSource.Position -= LightSource.ParentSub.DrawPosition; }
|
||||
LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically;
|
||||
}
|
||||
if (damageOverlayStrength > 0.0f && DamagedSprite != null && !hideLimb)
|
||||
{
|
||||
DamagedSprite.Draw(spriteBatch,
|
||||
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
|
||||
color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin,
|
||||
color * Math.Min(damageOverlayStrength, 1.0f), activeSprite.Origin,
|
||||
-body.DrawRotation,
|
||||
Scale, spriteEffect, ActiveSprite.Depth - 0.0000015f);
|
||||
Scale, spriteEffect, activeSprite.Depth - 0.0000015f);
|
||||
}
|
||||
foreach (var decorativeSprite in DecorativeSprites)
|
||||
{
|
||||
@@ -636,48 +678,58 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (var modifier in damageModifiers)
|
||||
{
|
||||
float rotation = -body.TransformedRotation + GetArmorSectorRotationOffset(modifier.ArmorSectorInRadians) * Dir;
|
||||
Vector2 forward = VectorExtensions.Forward(rotation);
|
||||
//Vector2 up = VectorExtensions.Backward(-body.TransformedRotation + Params.GetSpriteOrientation() * Dir);
|
||||
//int width = 4;
|
||||
//if (!isScreenSpace)
|
||||
//{
|
||||
// width = (int)Math.Round(width / cam.Zoom);
|
||||
//}
|
||||
//GUI.DrawLine(spriteBatch, startPos, startPos + Vector2.Normalize(up) * size, Color.Red, width: width);
|
||||
Color color = modifier.DamageMultiplier > 1 ? Color.Red : Color.GreenYellow;
|
||||
float size = ConvertUnits.ToDisplayUnits(body.GetSize().Length() / 2);
|
||||
if (isScreenSpace)
|
||||
{
|
||||
size *= cam.Zoom;
|
||||
}
|
||||
Color color = modifier.DamageMultiplier > 1 ? Color.Red : Color.GreenYellow;
|
||||
int width = 4;
|
||||
if (!isScreenSpace)
|
||||
{
|
||||
width = (int)Math.Round(width / cam.Zoom);
|
||||
}
|
||||
GUI.DrawLine(spriteBatch, startPos, startPos + Vector2.Normalize(forward) * size, color, width: width);
|
||||
int thickness = 2;
|
||||
if (!isScreenSpace)
|
||||
{
|
||||
thickness = (int)Math.Round(thickness / cam.Zoom);
|
||||
}
|
||||
ShapeExtensions.DrawSector(spriteBatch, startPos, size, GetArmorSectorSize(modifier.ArmorSectorInRadians) * Dir, 40, color, rotation + MathHelper.Pi, thickness);
|
||||
float bodyRotation = -body.Rotation;
|
||||
float constantOffset = -MathHelper.PiOver2;
|
||||
Vector2 armorSector = modifier.ArmorSectorInRadians;
|
||||
float armorSectorSize = Math.Abs(armorSector.X - armorSector.Y);
|
||||
float radians = armorSectorSize * Dir;
|
||||
float armorSectorOffset = armorSector.X * Dir;
|
||||
float finalOffset = bodyRotation + constantOffset + armorSectorOffset;
|
||||
ShapeExtensions.DrawSector(spriteBatch, startPos, size, radians, 40, color, finalOffset, thickness);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWearable(WearableSprite wearable, float depthStep, SpriteBatch spriteBatch, Color color, SpriteEffects spriteEffect)
|
||||
{
|
||||
var sprite = ActiveSprite;
|
||||
if (wearable.InheritSourceRect)
|
||||
{
|
||||
if (wearable.SheetIndex.HasValue)
|
||||
{
|
||||
Point location = (ActiveSprite.SourceRect.Location + ActiveSprite.SourceRect.Size) * wearable.SheetIndex.Value;
|
||||
wearable.Sprite.SourceRect = new Rectangle(location, ActiveSprite.SourceRect.Size);
|
||||
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, wearable.SheetIndex.Value), sprite.SourceRect.Size);
|
||||
}
|
||||
else if (type == LimbType.Head && character.Info != null && character.Info.Head.SheetIndex.HasValue)
|
||||
{
|
||||
wearable.Sprite.SourceRect = new Rectangle(CharacterInfo.CalculateOffset(sprite, character.Info.Head.SheetIndex.Value.ToPoint()), sprite.SourceRect.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
wearable.Sprite.SourceRect = ActiveSprite.SourceRect;
|
||||
wearable.Sprite.SourceRect = sprite.SourceRect;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 origin = wearable.Sprite.Origin;
|
||||
if (wearable.InheritOrigin)
|
||||
{
|
||||
origin = ActiveSprite.Origin;
|
||||
origin = sprite.Origin;
|
||||
wearable.Sprite.Origin = origin;
|
||||
}
|
||||
else
|
||||
@@ -694,7 +746,7 @@ namespace Barotrauma
|
||||
|
||||
if (wearable.InheritLimbDepth)
|
||||
{
|
||||
depth = ActiveSprite.Depth - depthStep;
|
||||
depth = sprite.Depth - depthStep;
|
||||
Limb depthLimb = (wearable.DepthLimb == LimbType.None) ? this : character.AnimController.GetLimb(wearable.DepthLimb);
|
||||
if (depthLimb != null)
|
||||
{
|
||||
@@ -728,11 +780,11 @@ namespace Barotrauma
|
||||
XElement element;
|
||||
if (random)
|
||||
{
|
||||
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.FirstOrDefault();
|
||||
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.GetRandom(Rand.RandSync.ClientOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.GetRandom(Rand.RandSync.ClientOnly);
|
||||
element = info.FilterByTypeAndHeadID(character.Info.FilterElementsByGenderAndRace(character.Info.Wearables), type)?.FirstOrDefault();
|
||||
}
|
||||
if (element != null)
|
||||
{
|
||||
@@ -749,8 +801,8 @@ namespace Barotrauma
|
||||
DamagedSprite?.Remove();
|
||||
DamagedSprite = null;
|
||||
|
||||
DeformSprite?.Sprite?.Remove();
|
||||
DeformSprite = null;
|
||||
_deformSprite?.Sprite?.Remove();
|
||||
_deformSprite = null;
|
||||
|
||||
DecorativeSprites.ForEach(s => s.Remove());
|
||||
ConditionalSprites.Clear();
|
||||
|
||||
Reference in New Issue
Block a user