(6eeea9b7c) v0.9.10.0.0
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -37,5 +37,8 @@ Libraries/webm_mem_playback/opus_x64_linux/
|
||||
# Mac
|
||||
*.DS_Store
|
||||
|
||||
# Win
|
||||
desktop.ini
|
||||
|
||||
#Merge script
|
||||
temp.txt
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace Barotrauma
|
||||
worldView = new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
viewMatrix = Matrix.CreateTranslation(new Vector3(GameMain.GraphicsWidth / 2.0f, GameMain.GraphicsHeight / 2.0f, 0));
|
||||
|
||||
globalZoomScale = (float)Math.Pow(new Vector2(resolution.X, resolution.Y).Length() / new Vector2(1920, 1080).Length(), 2);
|
||||
globalZoomScale = (float)Math.Pow(new Vector2(GUI.UIWidth, resolution.Y).Length() / GUI.ReferenceResolution.Length(), 2);
|
||||
}
|
||||
|
||||
public void UpdateTransform(bool interpolate = true)
|
||||
|
||||
@@ -19,11 +19,14 @@ namespace Barotrauma
|
||||
var target = _selectedAiTarget ?? _lastAiTarget;
|
||||
if (target != null && target.Entity != 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);
|
||||
var memory = GetTargetMemory(target, false);
|
||||
if (memory != null)
|
||||
{
|
||||
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} ({memory.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SelectedAiTarget?.Entity != null)
|
||||
@@ -35,7 +38,7 @@ namespace Barotrauma
|
||||
}
|
||||
targetPos.Y = -targetPos.Y;
|
||||
GUI.DrawLine(spriteBatch, pos, targetPos, GUI.Style.Red * 0.5f, 0, 4);
|
||||
if (wallTarget != null)
|
||||
if (wallTarget != null && (State == AIState.Attack || State == AIState.Aggressive || State == AIState.PassiveAggressive))
|
||||
{
|
||||
Vector2 wallTargetPos = wallTarget.Position;
|
||||
if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.Position; }
|
||||
@@ -43,7 +46,7 @@ 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()} ({GetTargetMemory(SelectedAiTarget).Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity} ({GetTargetMemory(SelectedAiTarget, false)?.Priority.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 40.0f, $"({targetValue.FormatZeroDecimal()})", GUI.Style.Red, Color.Black);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,19 +44,20 @@ namespace Barotrauma
|
||||
var currentObjective = ObjectiveManager.CurrentObjective;
|
||||
if (currentObjective != null)
|
||||
{
|
||||
if (currentOrder == null)
|
||||
int offset = currentOrder != null ? 20 : 0;
|
||||
if (currentOrder == null || currentOrder.Priority <= 0)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
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), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
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), $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 60 + offset), $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +87,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, 80), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 100), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
if (limb == null || limb.IsSevered || limb.ActiveSprite == null) continue;
|
||||
if (limb == null || limb.IsSevered || limb.ActiveSprite == null) { continue; }
|
||||
|
||||
Vector2 spriteOrigin = limb.ActiveSprite.Origin;
|
||||
spriteOrigin.X = limb.ActiveSprite.SourceRect.Width - spriteOrigin.X;
|
||||
@@ -404,8 +404,8 @@ namespace Barotrauma
|
||||
float gibParticleAmount = MathHelper.Clamp(limb.Mass / character.AnimController.Mass, 0.1f, 1.0f);
|
||||
foreach (ParticleEmitter emitter in character.GibEmitters)
|
||||
{
|
||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) continue;
|
||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) continue;
|
||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
|
||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
|
||||
|
||||
emitter.Emit(1.0f, limb.WorldPosition, character.CurrentHull, amountMultiplier: gibParticleAmount);
|
||||
}
|
||||
@@ -418,7 +418,8 @@ namespace Barotrauma
|
||||
|
||||
if (playSound)
|
||||
{
|
||||
SoundPlayer.PlayDamageSound("Gore", 1.0f, limbJoint.LimbA.body);
|
||||
var damageSound = character.GetSound(s => s.Type == CharacterSound.SoundType.Damage);
|
||||
SoundPlayer.PlayDamageSound(limbJoint.Params.BreakSound, 1.0f, limbJoint.LimbA.body.DrawPosition, range: damageSound != null ? damageSound.Range : 800);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,9 +447,10 @@ namespace Barotrauma
|
||||
float depthOffset = GetDepthOffset();
|
||||
for (int i = 0; i < limbs.Length; i++)
|
||||
{
|
||||
if (depthOffset != 0.0f) { inversedLimbDrawOrder[i].ActiveSprite.Depth += depthOffset; }
|
||||
inversedLimbDrawOrder[i].Draw(spriteBatch, cam, color);
|
||||
if (depthOffset != 0.0f) { inversedLimbDrawOrder[i].ActiveSprite.Depth -= depthOffset; }
|
||||
var limb = inversedLimbDrawOrder[i];
|
||||
if (depthOffset != 0.0f) { limb.ActiveSprite.Depth += depthOffset; }
|
||||
limb.Draw(spriteBatch, cam, color);
|
||||
if (depthOffset != 0.0f) { limb.ActiveSprite.Depth -= depthOffset; }
|
||||
}
|
||||
LimbJoints.ForEach(j => j.Draw(spriteBatch));
|
||||
}
|
||||
@@ -489,8 +491,8 @@ namespace Barotrauma
|
||||
|
||||
public void DebugDraw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!GameMain.DebugDraw || !character.Enabled) return;
|
||||
if (simplePhysicsEnabled) return;
|
||||
if (!GameMain.DebugDraw || !character.Enabled) { return; }
|
||||
if (simplePhysicsEnabled) { return; }
|
||||
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
@@ -508,7 +510,7 @@ namespace Barotrauma
|
||||
Collider.DebugDraw(spriteBatch, frozen ? GUI.Style.Red : (inWater ? Color.SkyBlue : Color.Gray));
|
||||
GUI.Font.DrawString(spriteBatch, Collider.LinearVelocity.X.FormatSingleDecimal(), new Vector2(Collider.DrawPosition.X, -Collider.DrawPosition.Y), Color.Orange);
|
||||
|
||||
foreach (RevoluteJoint joint in LimbJoints)
|
||||
foreach (var joint in LimbJoints)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(joint.WorldAnchorA);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.White, true);
|
||||
@@ -522,7 +524,10 @@ namespace Barotrauma
|
||||
if (limb.body.TargetPosition != null)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits((Vector2)limb.body.TargetPosition);
|
||||
if (currentHull?.Submarine != null) pos += currentHull.Submarine.DrawPosition;
|
||||
if (currentHull?.Submarine != null)
|
||||
{
|
||||
pos += currentHull.Submarine.DrawPosition;
|
||||
}
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X - 10, (int)pos.Y - 10, 20, 20), Color.Cyan, false, 0.01f);
|
||||
@@ -541,13 +546,19 @@ namespace Barotrauma
|
||||
if (character.MemState.Count > 1)
|
||||
{
|
||||
Vector2 prevPos = ConvertUnits.ToDisplayUnits(character.MemState[0].Position);
|
||||
if (currentHull?.Submarine != null) prevPos += currentHull.Submarine.DrawPosition;
|
||||
if (currentHull?.Submarine != null)
|
||||
{
|
||||
prevPos += currentHull.Submarine.DrawPosition;
|
||||
}
|
||||
prevPos.Y = -prevPos.Y;
|
||||
|
||||
for (int i = 1; i < character.MemState.Count; i++)
|
||||
{
|
||||
Vector2 currPos = ConvertUnits.ToDisplayUnits(character.MemState[i].Position);
|
||||
if (currentHull?.Submarine != null) currPos += currentHull.Submarine.DrawPosition;
|
||||
if (currentHull?.Submarine != null)
|
||||
{
|
||||
currPos += currentHull.Submarine.DrawPosition;
|
||||
}
|
||||
currPos.Y = -currPos.Y;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)currPos.X - 3, (int)currPos.Y - 3, 6, 6), Color.Cyan * 0.6f, true, 0.01f);
|
||||
|
||||
@@ -10,6 +10,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -357,7 +358,16 @@ namespace Barotrauma
|
||||
|
||||
partial void OnAttackedProjSpecific(Character attacker, AttackResult attackResult, float stun)
|
||||
{
|
||||
if (attackResult.Damage <= 1.0f || IsDead) { return; }
|
||||
if (IsDead) { return; }
|
||||
if (attacker != null)
|
||||
{
|
||||
if (attackResult.Damage <= 0.01f) { return; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (attackResult.Damage <= 1.0f) { return; }
|
||||
}
|
||||
|
||||
if (soundTimer < soundInterval * 0.5f)
|
||||
{
|
||||
PlaySound(CharacterSound.SoundType.Damage);
|
||||
@@ -813,20 +823,22 @@ namespace Barotrauma
|
||||
return progressBar;
|
||||
}
|
||||
|
||||
private readonly List<CharacterSound> matchingSounds = new List<CharacterSound>();
|
||||
private SoundChannel soundChannel;
|
||||
public void PlaySound(CharacterSound.SoundType soundType)
|
||||
{
|
||||
if (sounds == null || sounds.Count == 0) { return; }
|
||||
if (soundChannel != null && soundChannel.IsPlaying) { return; }
|
||||
if (GameMain.SoundManager?.Disabled ?? true) { return; }
|
||||
|
||||
var matchingSounds = sounds.Where(s =>
|
||||
s.Type == soundType &&
|
||||
(s.Gender == Gender.None || (info != null && info.Gender == s.Gender)));
|
||||
if (!matchingSounds.Any()) { return; }
|
||||
|
||||
var matchingSoundsList = matchingSounds.ToList();
|
||||
var selectedSound = matchingSoundsList[Rand.Int(matchingSoundsList.Count)];
|
||||
matchingSounds.Clear();
|
||||
foreach (var s in sounds)
|
||||
{
|
||||
if (s.Type == soundType && (s.Gender == Gender.None || (info != null && info.Gender == s.Gender)))
|
||||
{
|
||||
matchingSounds.Add(s);
|
||||
}
|
||||
}
|
||||
var selectedSound = matchingSounds.GetRandom();
|
||||
if (selectedSound?.Sound == null) { return; }
|
||||
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, CurrentHull);
|
||||
soundTimer = soundInterval;
|
||||
@@ -846,6 +858,11 @@ namespace Barotrauma
|
||||
activeObjectiveEntities.Remove(found);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Note that when a predicate is provided, the random option uses Linq.Where() extension method, which creates a new collection.
|
||||
/// </summary>
|
||||
public CharacterSound GetSound(Func<CharacterSound, bool> predicate = null, bool random = false) => random ? sounds.GetRandom(predicate) : sounds.FirstOrDefault(predicate);
|
||||
|
||||
partial void ImplodeFX()
|
||||
{
|
||||
Vector2 centerOfMass = AnimController.GetCenterOfMass();
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (hudFrame == null)
|
||||
{
|
||||
hudFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null)
|
||||
hudFrame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -163,7 +163,7 @@ namespace Barotrauma
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine == null || item.Submarine.TeamID != character.TeamID || item.Submarine.Info.IsWreck) { continue; }
|
||||
if (!item.Repairables.Any(r => item.ConditionPercentage <= r.AIRepairThreshold)) { continue; }
|
||||
if (!item.Repairables.Any(r => item.ConditionPercentage <= r.RepairThreshold)) { continue; }
|
||||
if (Submarine.VisibleEntities != null && !Submarine.VisibleEntities.Contains(item)) { continue; }
|
||||
|
||||
Vector2 diff = item.WorldPosition - character.WorldPosition;
|
||||
@@ -202,6 +202,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (Item brokenItem in brokenItems)
|
||||
{
|
||||
if (brokenItem.NonInteractable) { continue; }
|
||||
float dist = Vector2.Distance(character.WorldPosition, brokenItem.WorldPosition);
|
||||
Vector2 drawPos = brokenItem.DrawPosition;
|
||||
float alpha = Math.Min((1000.0f - dist) / 1000.0f * 2.0f, 1.0f);
|
||||
@@ -373,7 +374,7 @@ namespace Barotrauma
|
||||
{
|
||||
GUIComponent.DrawToolTip(
|
||||
spriteBatch,
|
||||
character.Info?.Job == null ? character.DisplayName : character.Name + " (" + character.Info.Job.Name + ")",
|
||||
character.Info?.Job == null ? character.DisplayName : character.DisplayName + " (" + character.Info.Job.Name + ")",
|
||||
HUDLayoutSettings.PortraitArea);
|
||||
}
|
||||
}
|
||||
@@ -393,10 +394,6 @@ namespace Barotrauma
|
||||
startPos = cam.WorldToScreen(startPos);
|
||||
|
||||
string focusName = character.FocusedCharacter.DisplayName;
|
||||
if (character.FocusedCharacter.Info != null)
|
||||
{
|
||||
focusName = character.FocusedCharacter.Info.DisplayName;
|
||||
}
|
||||
Vector2 textPos = startPos;
|
||||
Vector2 textSize = GUI.Font.MeasureString(focusName);
|
||||
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusName);
|
||||
|
||||
@@ -146,7 +146,8 @@ namespace Barotrauma
|
||||
"+" + ((int)((newLevel - prevLevel) * 100.0f)).ToString() + " XP",
|
||||
GUI.Style.Green,
|
||||
textPopupPos,
|
||||
Vector2.UnitY * 10.0f);
|
||||
Vector2.UnitY * 10.0f,
|
||||
playSound: Character.Controlled?.Info == this);
|
||||
}
|
||||
else if (prevLevel % 0.1f > 0.05f && newLevel % 0.1f < 0.05f)
|
||||
{
|
||||
@@ -154,7 +155,8 @@ namespace Barotrauma
|
||||
"+10 XP",
|
||||
GUI.Style.Green,
|
||||
textPopupPos,
|
||||
Vector2.UnitY * 10.0f);
|
||||
Vector2.UnitY * 10.0f,
|
||||
playSound: Character.Controlled?.Info == this);
|
||||
}
|
||||
|
||||
if ((int)newLevel > (int)prevLevel)
|
||||
|
||||
@@ -502,11 +502,9 @@ namespace Barotrauma
|
||||
causeOfDeathAffliction = AfflictionPrefab.Prefabs[afflictionName];
|
||||
}
|
||||
}
|
||||
|
||||
byte severedLimbCount = msg.ReadByte();
|
||||
if (!IsDead)
|
||||
{
|
||||
if (causeOfDeathType == CauseOfDeathType.Pressure)
|
||||
if (causeOfDeathType == CauseOfDeathType.Pressure || causeOfDeathAffliction == AfflictionPrefab.Pressure)
|
||||
{
|
||||
Implode(true);
|
||||
}
|
||||
@@ -515,26 +513,26 @@ namespace Barotrauma
|
||||
Kill(causeOfDeathType, causeOfDeathAffliction?.Instantiate(1.0f), true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < severedLimbCount; i++)
|
||||
{
|
||||
int severedJointIndex = msg.ReadByte();
|
||||
if (severedJointIndex < 0 || severedJointIndex >= AnimController.LimbJoints.Length)
|
||||
{
|
||||
string errorMsg = $"Error in CharacterNetworking.ReadStatus: severed joint index out of bounds (index: {severedJointIndex}, joint count: {AnimController.LimbJoints.Length})";
|
||||
GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ReadStatus:JointIndexOutOfBounts", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimController.SeverLimbJoint(AnimController.LimbJoints[severedJointIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsDead) { Revive(); }
|
||||
CharacterHealth.ClientRead(msg);
|
||||
}
|
||||
byte severedLimbCount = msg.ReadByte();
|
||||
for (int i = 0; i < severedLimbCount; i++)
|
||||
{
|
||||
int severedJointIndex = msg.ReadByte();
|
||||
if (severedJointIndex < 0 || severedJointIndex >= AnimController.LimbJoints.Length)
|
||||
{
|
||||
string errorMsg = $"Error in CharacterNetworking.ReadStatus: severed joint index out of bounds (index: {severedJointIndex}, joint count: {AnimController.LimbJoints.Length})";
|
||||
GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ReadStatus:JointIndexOutOfBounts", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimController.SeverLimbJoint(AnimController.LimbJoints[severedJointIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -20,9 +21,9 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
const int MaxFakeFireSources = 10;
|
||||
private float minFakeFireSourceInterval = 10.0f, maxFakeFireSourceInterval = 200.0f;
|
||||
const float MinFakeFireSourceInterval = 30.0f, MaxFakeFireSourceInterval = 240.0f;
|
||||
private float createFireSourceTimer;
|
||||
private List<FakeFireSource> fakeFireSources = new List<FakeFireSource>();
|
||||
private readonly List<FakeFireSource> fakeFireSources = new List<FakeFireSource>();
|
||||
|
||||
enum FloodType
|
||||
{
|
||||
@@ -31,26 +32,30 @@ namespace Barotrauma
|
||||
HideFlooding
|
||||
}
|
||||
|
||||
private float minSoundInterval = 10.0f, maxSoundInterval = 60.0f;
|
||||
const float MinSoundInterval = 10.0f, MaxSoundInterval = 180.0f;
|
||||
private FloodType currentFloodType;
|
||||
private float soundTimer;
|
||||
|
||||
private float minFloodInterval = 30.0f, maxFloodInterval = 180.0f;
|
||||
const float MinFloodInterval = 60.0f, MaxFloodInterval = 240.0f;
|
||||
private float createFloodTimer;
|
||||
private float currentFloodState;
|
||||
private float currentFloodDuration;
|
||||
|
||||
private float fakeBrokenInterval = 30.0f;
|
||||
private float fakeBrokenTimer = 0.0f;
|
||||
|
||||
partial void UpdateProjSpecific(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
|
||||
{
|
||||
if (Character.Controlled != characterHealth.Character) return;
|
||||
UpdateFloods(deltaTime);
|
||||
UpdateSounds(characterHealth.Character, deltaTime);
|
||||
UpdateFires(characterHealth.Character, deltaTime);
|
||||
UpdateFires(characterHealth.Character, deltaTime);
|
||||
UpdateFakeBroken(deltaTime);
|
||||
}
|
||||
|
||||
private void UpdateSounds(Character character, float deltaTime)
|
||||
{
|
||||
if (soundTimer < MathHelper.Lerp(maxSoundInterval, minSoundInterval, Strength / 100.0f))
|
||||
if (soundTimer < MathHelper.Lerp(MaxSoundInterval, MinSoundInterval, Strength / 100.0f))
|
||||
{
|
||||
soundTimer += deltaTime;
|
||||
return;
|
||||
@@ -97,7 +102,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (createFloodTimer < MathHelper.Lerp(maxFloodInterval, minFloodInterval, Strength / 100.0f))
|
||||
if (createFloodTimer < MathHelper.Lerp(MaxFloodInterval, MinFloodInterval, Strength / 100.0f))
|
||||
{
|
||||
createFloodTimer += deltaTime;
|
||||
return;
|
||||
@@ -124,7 +129,7 @@ namespace Barotrauma
|
||||
createFireSourceTimer += deltaTime;
|
||||
if (fakeFireSources.Count < MaxFakeFireSources &&
|
||||
character.Submarine != null &&
|
||||
createFireSourceTimer > MathHelper.Lerp(maxFakeFireSourceInterval, minFakeFireSourceInterval, Strength / 100.0f))
|
||||
createFireSourceTimer > MathHelper.Lerp(MaxFakeFireSourceInterval, MinFakeFireSourceInterval, Strength / 100.0f))
|
||||
{
|
||||
Hull fireHull = Hull.hullList.GetRandom(h => h.Submarine == character.Submarine);
|
||||
|
||||
@@ -140,9 +145,9 @@ namespace Barotrauma
|
||||
|
||||
foreach (FakeFireSource fakeFireSource in fakeFireSources)
|
||||
{
|
||||
if (fakeFireSource.Hull.Surface > fakeFireSource.Hull.Rect.Y - fakeFireSource.Hull.Rect.Height + fakeFireSource.Position.Y)
|
||||
if (fakeFireSource.Hull.DrawSurface > fakeFireSource.Hull.Rect.Y - fakeFireSource.Hull.Rect.Height + fakeFireSource.Position.Y)
|
||||
{
|
||||
fakeFireSource.LifeTime -= deltaTime * 10.0f;
|
||||
fakeFireSource.LifeTime -= deltaTime * 100.0f;
|
||||
}
|
||||
|
||||
fakeFireSource.LifeTime -= deltaTime;
|
||||
@@ -162,5 +167,28 @@ namespace Barotrauma
|
||||
|
||||
fakeFireSources.RemoveAll(fs => fs.LifeTime <= 0.0f);
|
||||
}
|
||||
|
||||
private void UpdateFakeBroken(float deltaTime)
|
||||
{
|
||||
fakeBrokenTimer -= deltaTime;
|
||||
if (fakeBrokenTimer > 0.0f) { return; }
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
var repairable = item.GetComponent<Repairable>();
|
||||
if (repairable == null) { continue; }
|
||||
if (ShouldFakeBrokenItem(item))
|
||||
{
|
||||
repairable.FakeBrokenTimer = 60.0f;
|
||||
}
|
||||
}
|
||||
|
||||
fakeBrokenTimer = fakeBrokenInterval;
|
||||
}
|
||||
|
||||
private bool ShouldFakeBrokenItem(Item item)
|
||||
{
|
||||
return Rand.Range(0.0f, 1000.0f) < Strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,8 +251,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
// 0.38775510204f = percentage of offset before reaching the healthbar portion of the graphic going from bottom upwards
|
||||
return new Point(2, (int)(HUDLayoutSettings.HealthBarArea.Size.Y * 0.38775510204f));
|
||||
return new Point(Math.Max(2, GUI.IntScaleCeiling(1.5f)), Math.Min(GUI.IntScaleFloor(18f), 19));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +259,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Point((int)Math.Ceiling(HUDLayoutSettings.HealthBarArea.Size.X - 45 * GUI.Scale), (int)(healthBarHolder.Rect.Height - Math.Min(23 * GUI.Scale, 25)) / 2);
|
||||
return new Point(healthBarHolder.Rect.Width - Math.Min(GUI.IntScale(45f), 47), GUI.IntScale(15f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,12 +596,14 @@ namespace Barotrauma
|
||||
switch (alignment)
|
||||
{
|
||||
case Alignment.Left:
|
||||
healthInterfaceFrame.RectTransform.SetPosition(Anchor.CenterLeft);
|
||||
healthInterfaceFrame.RectTransform.SetPosition(Anchor.BottomLeft);
|
||||
break;
|
||||
case Alignment.Right:
|
||||
healthInterfaceFrame.RectTransform.SetPosition(Anchor.CenterRight);
|
||||
healthInterfaceFrame.RectTransform.SetPosition(Anchor.BottomRight);
|
||||
break;
|
||||
}
|
||||
|
||||
healthInterfaceFrame.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.Padding, screenResolution.Y - HUDLayoutSettings.ChatBoxArea.Y + HUDLayoutSettings.Padding);
|
||||
healthInterfaceFrame.RectTransform.RecalculateChildren(false);
|
||||
}
|
||||
|
||||
@@ -1107,7 +1108,7 @@ namespace Barotrauma
|
||||
float currHealth = healthBar.BarSize;
|
||||
Color prevColor = healthBar.Color;
|
||||
healthBarShadow.BarSize = healthShadowSize;
|
||||
healthBarShadow.Color = GUI.Style.Red;
|
||||
healthBarShadow.Color = Color.Lerp(GUI.Style.Red, Color.Black, 0.5f);
|
||||
healthBarShadow.Visible = true;
|
||||
healthBar.BarSize = currHealth;
|
||||
healthBar.Color = prevColor;
|
||||
@@ -1822,7 +1823,7 @@ namespace Barotrauma
|
||||
Vector2 iconPos = highlightArea.Center.ToVector2();
|
||||
|
||||
//Affliction mostSevereAffliction = thisAfflictions.FirstOrDefault(a => !a.Prefab.IsBuff && !thisAfflictions.Any(a2 => !a2.Prefab.IsBuff && a2.Strength > a.Strength)) ?? thisAfflictions.FirstOrDefault();
|
||||
Affliction mostSevereAffliction = SortAfflictionsBySeverity(thisAfflictions).FirstOrDefault();
|
||||
Affliction mostSevereAffliction = SortAfflictionsBySeverity(thisAfflictions, excludeBuffs: false).FirstOrDefault();
|
||||
if (mostSevereAffliction != null) { DrawLimbAfflictionIcon(spriteBatch, mostSevereAffliction, iconScale, ref iconPos); }
|
||||
|
||||
if (thisAfflictions.Count() > 1)
|
||||
|
||||
@@ -8,12 +8,14 @@ namespace Barotrauma
|
||||
{
|
||||
partial class JobPrefab : IPrefab, IDisposable
|
||||
{
|
||||
public GUIButton CreateInfoFrame(int variant)
|
||||
public GUIButton CreateInfoFrame(out GUIComponent buttonContainer)
|
||||
{
|
||||
int width = 500, height = 400;
|
||||
|
||||
GUIButton backFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, height), backFrame.RectTransform, Anchor.Center));
|
||||
GUIButton frameHolder = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, frameHolder.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, height), frameHolder.RectTransform, Anchor.Center));
|
||||
GUIFrame paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), Name, font: GUI.LargeFont);
|
||||
@@ -32,6 +34,8 @@ namespace Barotrauma
|
||||
font: GUI.SmallFont);
|
||||
}
|
||||
|
||||
buttonContainer = paddedFrame;
|
||||
|
||||
/*if (!ItemIdentifiers.TryGetValue(variant, out var itemIdentifiers)) { return backFrame; }
|
||||
var itemContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 0.5f), paddedFrame.RectTransform, Anchor.TopRight)
|
||||
{ RelativeOffset = new Vector2(0.0f, 0.2f + descriptionBlock.RectTransform.RelativeSize.Y) })
|
||||
@@ -49,7 +53,7 @@ namespace Barotrauma
|
||||
font: GUI.SmallFont);
|
||||
}*/
|
||||
|
||||
return backFrame;
|
||||
return frameHolder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,25 +3,24 @@ using Barotrauma.Particles;
|
||||
using Barotrauma.SpriteDeformations;
|
||||
using Barotrauma.Extensions;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics.Joints;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using SpriteParams = Barotrauma.RagdollParams.SpriteParams;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LimbJoint : RevoluteJoint
|
||||
partial class LimbJoint
|
||||
{
|
||||
public void UpdateDeformations(float deltaTime)
|
||||
{
|
||||
float diff = Math.Abs(UpperLimit - LowerLimit);
|
||||
float strength = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(0, MathHelper.Pi, diff));
|
||||
float jointAngle = this.JointAngle * strength;
|
||||
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;
|
||||
@@ -70,7 +69,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
@@ -126,7 +124,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive && c.DeformableSprite != null);
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.Exclusive && c.IsActive && c.DeformableSprite != null);
|
||||
if (conditionalSprite != null)
|
||||
{
|
||||
return conditionalSprite.DeformableSprite;
|
||||
@@ -144,7 +142,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive && c.ActiveSprite != null);
|
||||
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.Exclusive && c.IsActive && c.ActiveSprite != null);
|
||||
if (conditionalSprite != null)
|
||||
{
|
||||
return conditionalSprite.ActiveSprite;
|
||||
@@ -166,6 +164,12 @@ namespace Barotrauma
|
||||
|
||||
public Sprite DamagedSprite { get; private set; }
|
||||
|
||||
public bool Hide
|
||||
{
|
||||
get => Params.Hide;
|
||||
set => Params.Hide = value;
|
||||
}
|
||||
|
||||
public List<ConditionalSprite> ConditionalSprites { get; private set; } = new List<ConditionalSprite>();
|
||||
private Dictionary<DecorativeSprite, SpriteState> spriteAnimState = new Dictionary<DecorativeSprite, SpriteState>();
|
||||
private Dictionary<int, List<DecorativeSprite>> DecorativeSpriteGroups = new Dictionary<int, List<DecorativeSprite>>();
|
||||
@@ -274,7 +278,17 @@ namespace Barotrauma
|
||||
DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
|
||||
break;
|
||||
case "conditionalsprite":
|
||||
var conditionalSprite = new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null));
|
||||
ISerializableEntity targetEntity;
|
||||
string target = subElement.GetAttributeString("target", null);
|
||||
if (string.Equals(target, "character", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
targetEntity = character;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetEntity = this;
|
||||
}
|
||||
var conditionalSprite = new ConditionalSprite(subElement, targetEntity, file: GetSpritePath(subElement, null));
|
||||
ConditionalSprites.Add(conditionalSprite);
|
||||
if (conditionalSprite.DeformableSprite != null)
|
||||
{
|
||||
@@ -373,12 +387,16 @@ namespace Barotrauma
|
||||
|
||||
private string GetSpritePath(XElement element, SpriteParams spriteParams)
|
||||
{
|
||||
string texturePath = element.GetAttributeString("texture", null);
|
||||
if (string.IsNullOrWhiteSpace(texturePath) && spriteParams != null)
|
||||
if (spriteParams != null)
|
||||
{
|
||||
texturePath = spriteParams.Ragdoll.Texture;
|
||||
return GetSpritePath(spriteParams.GetTexturePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
string texturePath = element.GetAttributeString("texture", null);
|
||||
texturePath = string.IsNullOrWhiteSpace(texturePath) ? ragdoll.RagdollParams.Texture : texturePath;
|
||||
return GetSpritePath(texturePath);
|
||||
}
|
||||
return GetSpritePath(texturePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -419,12 +437,29 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
partial void AddDamageProjSpecific(IEnumerable<Affliction> afflictions, bool playSound, IEnumerable<DamageModifier> appliedDamageModifiers)
|
||||
partial void AddDamageProjSpecific(bool playSound, AttackResult result)
|
||||
{
|
||||
float bleedingDamage = character.CharacterHealth.DoesBleed ? afflictions.Where(a => a is AfflictionBleeding).Sum(a => a.GetVitalityDecrease(character.CharacterHealth)) : 0;
|
||||
float damage = afflictions.Where(a => a.Prefab.AfflictionType == "damage").Sum(a => a.GetVitalityDecrease(character.CharacterHealth));
|
||||
float bleedingDamage = 0;
|
||||
if (character.CharacterHealth.DoesBleed)
|
||||
{
|
||||
foreach (var affliction in result.Afflictions)
|
||||
{
|
||||
if (affliction is AfflictionBleeding)
|
||||
{
|
||||
bleedingDamage += affliction.GetVitalityDecrease(character.CharacterHealth);
|
||||
}
|
||||
}
|
||||
}
|
||||
float damage = 0;
|
||||
foreach (var affliction in result.Afflictions)
|
||||
{
|
||||
if (affliction.Prefab.AfflictionType == "damage")
|
||||
{
|
||||
damage += affliction.GetVitalityDecrease(character.CharacterHealth);
|
||||
}
|
||||
}
|
||||
float damageMultiplier = 1;
|
||||
foreach (DamageModifier damageModifier in appliedDamageModifiers)
|
||||
foreach (DamageModifier damageModifier in result.AppliedDamageModifiers)
|
||||
{
|
||||
foreach (var afflictionPrefab in AfflictionPrefab.List)
|
||||
{
|
||||
@@ -433,6 +468,7 @@ namespace Barotrauma
|
||||
if (afflictionPrefab.Effects.Any(e => e.MaxVitalityDecrease > 0))
|
||||
{
|
||||
damageMultiplier *= damageModifier.DamageMultiplier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,7 +476,7 @@ namespace Barotrauma
|
||||
if (playSound)
|
||||
{
|
||||
string damageSoundType = (bleedingDamage > damage) ? "LimbSlash" : "LimbBlunt";
|
||||
foreach (DamageModifier damageModifier in appliedDamageModifiers)
|
||||
foreach (DamageModifier damageModifier in result.AppliedDamageModifiers)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(damageModifier.DamageSound))
|
||||
{
|
||||
@@ -457,9 +493,8 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (ParticleEmitter emitter in character.DamageEmitters)
|
||||
{
|
||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) continue;
|
||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) continue;
|
||||
|
||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
|
||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
|
||||
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, amountMultiplier: damageParticleAmount);
|
||||
}
|
||||
}
|
||||
@@ -471,9 +506,8 @@ namespace Barotrauma
|
||||
|
||||
foreach (ParticleEmitter emitter in character.BloodEmitters)
|
||||
{
|
||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) continue;
|
||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) continue;
|
||||
|
||||
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) { continue; }
|
||||
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) { continue; }
|
||||
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, sizeMultiplier: bloodParticleSize, amountMultiplier: bloodParticleAmount);
|
||||
}
|
||||
|
||||
@@ -481,15 +515,14 @@ namespace Barotrauma
|
||||
{
|
||||
character.CurrentHull.AddDecal(character.BloodDecalName, WorldPosition, MathHelper.Clamp(bloodParticleSize, 0.5f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
if (!body.Enabled) { return; }
|
||||
|
||||
if (!character.IsDead)
|
||||
if (!IsDead)
|
||||
{
|
||||
DamageOverlayStrength -= deltaTime;
|
||||
BurnOverlayStrength -= deltaTime;
|
||||
@@ -534,6 +567,10 @@ namespace Barotrauma
|
||||
{
|
||||
LightSource.LightSprite.Depth = ActiveSprite.Depth;
|
||||
}
|
||||
if (LightSource.DeformableLightSprite != null)
|
||||
{
|
||||
LightSource.DeformableLightSprite.Sprite.Depth = ActiveSprite.Depth;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSpriteStates(deltaTime);
|
||||
@@ -543,6 +580,8 @@ namespace Barotrauma
|
||||
{
|
||||
float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f;
|
||||
var spriteParams = Params.GetSprite();
|
||||
if (spriteParams == null) { return; }
|
||||
|
||||
Color color = new Color(spriteParams.Color.R / 255f * brightness, spriteParams.Color.G / 255f * brightness, spriteParams.Color.B / 255f * brightness, spriteParams.Color.A / 255f);
|
||||
if (deadTimer > 0)
|
||||
{
|
||||
@@ -568,7 +607,7 @@ namespace Barotrauma
|
||||
|
||||
float herpesStrength = character.CharacterHealth.GetAfflictionStrength("spaceherpes");
|
||||
|
||||
bool hideLimb = Params.Hide ||
|
||||
bool hideLimb = Hide ||
|
||||
OtherWearables.Any(w => w.HideLimb) ||
|
||||
wearingItems.Any(w => w != null && w.HideLimb);
|
||||
|
||||
@@ -589,6 +628,11 @@ namespace Barotrauma
|
||||
{
|
||||
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
|
||||
deformSprite.Deform(deformation);
|
||||
if (LightSource != null && LightSource.DeformableLightSprite != null)
|
||||
{
|
||||
deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size, dir == Direction.Left);
|
||||
LightSource.DeformableLightSprite.Deform(deformation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -600,6 +644,31 @@ namespace Barotrauma
|
||||
{
|
||||
body.Draw(spriteBatch, activeSprite, color, null, Scale * TextureScale, Params.MirrorHorizontally, Params.MirrorVertically);
|
||||
}
|
||||
// Handle non-exlusive, i.e. additional conditional sprites
|
||||
foreach (var conditionalSprite in ConditionalSprites)
|
||||
{
|
||||
// Exclusive conditional sprites are handled in the Properties
|
||||
if (conditionalSprite.Exclusive) { continue; }
|
||||
if (!conditionalSprite.IsActive) { continue; }
|
||||
if (conditionalSprite.DeformableSprite != null)
|
||||
{
|
||||
var defSprite = conditionalSprite.DeformableSprite;
|
||||
if (Deformations != null && Deformations.Any())
|
||||
{
|
||||
var deformation = SpriteDeformation.GetDeformation(Deformations, defSprite.Size);
|
||||
defSprite.Deform(deformation);
|
||||
}
|
||||
else
|
||||
{
|
||||
defSprite.Reset();
|
||||
}
|
||||
body.Draw(defSprite, cam, Vector2.One * Scale * TextureScale, color, Params.MirrorHorizontally);
|
||||
}
|
||||
else
|
||||
{
|
||||
body.Draw(spriteBatch, conditionalSprite.Sprite, color, null, Scale * TextureScale, Params.MirrorHorizontally, Params.MirrorVertically);
|
||||
}
|
||||
}
|
||||
}
|
||||
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
|
||||
if (LightSource != null)
|
||||
|
||||
@@ -5,7 +5,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
@@ -456,18 +456,6 @@ namespace Barotrauma
|
||||
GameMain.CharacterEditorScreen.Select();
|
||||
}));
|
||||
|
||||
commands.Add(new Command("money", "", args =>
|
||||
{
|
||||
if (args.Length == 0) { return; }
|
||||
if (GameMain.GameSession.GameMode is CampaignMode campaign)
|
||||
{
|
||||
if (int.TryParse(args[0], out int money))
|
||||
{
|
||||
campaign.Money += money;
|
||||
}
|
||||
}
|
||||
}, isCheat: true));
|
||||
|
||||
commands.Add(new Command("steamnetdebug", "steamnetdebug: Toggles Steamworks debug logging.", (string[] args) =>
|
||||
{
|
||||
SteamManager.NetworkingDebugLog = !SteamManager.NetworkingDebugLog;
|
||||
@@ -504,6 +492,7 @@ namespace Barotrauma
|
||||
AssignRelayToServer("setpassword", true);
|
||||
commands.Add(new Command("traitorlist", "", (string[] args) => { }));
|
||||
AssignRelayToServer("traitorlist", true);
|
||||
AssignRelayToServer("money", true);
|
||||
|
||||
AssignOnExecute("control", (string[] args) =>
|
||||
{
|
||||
@@ -669,6 +658,44 @@ namespace Barotrauma
|
||||
}
|
||||
}, isCheat: true));
|
||||
|
||||
commands.Add(new Command("listcloudfiles", "Lists all of your files on the Steam Cloud.", args =>
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var file in Steamworks.SteamRemoteStorage.Files)
|
||||
{
|
||||
NewMessage($"* {i}: {file.Filename}, {file.Size} bytes", Color.Orange);
|
||||
i++;
|
||||
}
|
||||
NewMessage($"Bytes remaining: {Steamworks.SteamRemoteStorage.QuotaRemainingBytes}/{Steamworks.SteamRemoteStorage.QuotaBytes}", Color.Yellow);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("removefromcloud", "Removes a file from Steam Cloud.", args =>
|
||||
{
|
||||
if (args.Length < 1) { return; }
|
||||
var files = Steamworks.SteamRemoteStorage.Files;
|
||||
Steamworks.SteamRemoteStorage.RemoteFile file;
|
||||
if (int.TryParse(args[0], out int index) && index>=0 && index<files.Count)
|
||||
{
|
||||
file = files[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
file = files.Find(f => f.Filename.Equals(args[0], StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(file.Filename))
|
||||
{
|
||||
if (file.Delete())
|
||||
{
|
||||
NewMessage($"Deleting {file.Filename}", Color.Orange);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowError($"Failed to delete {file.Filename}");
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
commands.Add(new Command("resetall", "Reset all items and structures to prefabs. Only applicable in the subeditor.", args =>
|
||||
{
|
||||
if (Screen.Selected == GameMain.SubEditorScreen)
|
||||
@@ -846,7 +873,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (Submarine.MainSub.SaveAs(System.IO.Path.Combine(SubmarineInfo.SavePath, fileName + ".sub")))
|
||||
if (Submarine.MainSub.SaveAs(Barotrauma.IO.Path.Combine(SubmarineInfo.SavePath, fileName + ".sub")))
|
||||
{
|
||||
NewMessage("Sub saved", Color.Green);
|
||||
}
|
||||
@@ -1038,8 +1065,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (var deconstructItem in itemPrefab.DeconstructItems)
|
||||
{
|
||||
var targetItem = MapEntityPrefab.Find(null, deconstructItem.ItemIdentifier, showErrorMessages: false) as ItemPrefab;
|
||||
if (targetItem == null)
|
||||
if (!(MapEntityPrefab.Find(null, deconstructItem.ItemIdentifier, showErrorMessages: false) is ItemPrefab targetItem))
|
||||
{
|
||||
ThrowError("Error in item \"" + itemPrefab.Name + "\" - could not find deconstruct item \"" + deconstructItem.ItemIdentifier + "\"!");
|
||||
continue;
|
||||
@@ -1054,9 +1080,14 @@ namespace Barotrauma
|
||||
|
||||
if (fabricationRecipe != null)
|
||||
{
|
||||
if (!fabricationRecipe.RequiredItems.Any(r => r.ItemPrefab == targetItem))
|
||||
var ingredient = fabricationRecipe.RequiredItems.Find(r => r.ItemPrefab == targetItem);
|
||||
if (ingredient == null)
|
||||
{
|
||||
NewMessage("Deconstructing \"" + itemPrefab.Name + "\" produces \"" + deconstructItem.ItemIdentifier + "\", which isn't required in the fabrication recipe of the item.", Color.Orange);
|
||||
NewMessage("Deconstructing \"" + itemPrefab.Name + "\" produces \"" + deconstructItem.ItemIdentifier + "\", which isn't required in the fabrication recipe of the item.", Color.Red);
|
||||
}
|
||||
else if (ingredient.UseCondition && ingredient.MinCondition < deconstructItem.OutCondition)
|
||||
{
|
||||
NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {ingredient.ItemPrefab.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(deconstructItem.OutCondition * 100)}%)", Color.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1267,6 +1298,13 @@ namespace Barotrauma
|
||||
TextManager.Language = "English";
|
||||
}));
|
||||
|
||||
commands.Add(new Command("eventstats", "", (string[] args) =>
|
||||
{
|
||||
var debugLines = ScriptedEventSet.GetDebugStatistics();
|
||||
string filePath = "eventstats.txt";
|
||||
File.WriteAllLines(filePath, debugLines);
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
}));
|
||||
#if DEBUG
|
||||
commands.Add(new Command("printreceivertransfers", "", (string[] args) =>
|
||||
{
|
||||
@@ -1440,7 +1478,7 @@ namespace Barotrauma
|
||||
element.Value = lines[i];
|
||||
i++;
|
||||
}
|
||||
doc.Save(destinationPath);
|
||||
doc.SaveSafe(destinationPath);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
@@ -1475,7 +1513,7 @@ namespace Barotrauma
|
||||
while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode;
|
||||
destinationElement = nextNode as XElement;
|
||||
}
|
||||
destinationDoc.Save(destinationPath);
|
||||
destinationDoc.SaveSafe(destinationPath);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
@@ -1730,69 +1768,69 @@ namespace Barotrauma
|
||||
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);
|
||||
var saveFiles = Barotrauma.IO.Directory.GetFiles(SaveUtil.SaveFolder);
|
||||
|
||||
foreach (string saveFile in saveFiles)
|
||||
{
|
||||
System.IO.File.Delete(saveFile);
|
||||
Barotrauma.IO.File.Delete(saveFile);
|
||||
NewMessage("Deleted " + saveFile, Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
|
||||
if (Barotrauma.IO.Directory.Exists(Barotrauma.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
|
||||
{
|
||||
System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
|
||||
Barotrauma.IO.Directory.Delete(Barotrauma.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
|
||||
NewMessage("Deleted temp save folder", Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.Directory.Exists(ServerLog.SavePath))
|
||||
if (Barotrauma.IO.Directory.Exists(ServerLog.SavePath))
|
||||
{
|
||||
var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath);
|
||||
var logFiles = Barotrauma.IO.Directory.GetFiles(ServerLog.SavePath);
|
||||
|
||||
foreach (string logFile in logFiles)
|
||||
{
|
||||
System.IO.File.Delete(logFile);
|
||||
Barotrauma.IO.File.Delete(logFile);
|
||||
NewMessage("Deleted " + logFile, Color.Green);
|
||||
}
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists("filelist.xml"))
|
||||
if (Barotrauma.IO.File.Exists("filelist.xml"))
|
||||
{
|
||||
System.IO.File.Delete("filelist.xml");
|
||||
Barotrauma.IO.File.Delete("filelist.xml");
|
||||
NewMessage("Deleted filelist", Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists("Data/bannedplayers.txt"))
|
||||
if (Barotrauma.IO.File.Exists("Data/bannedplayers.txt"))
|
||||
{
|
||||
System.IO.File.Delete("Data/bannedplayers.txt");
|
||||
Barotrauma.IO.File.Delete("Data/bannedplayers.txt");
|
||||
NewMessage("Deleted bannedplayers.txt", Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
|
||||
if (Barotrauma.IO.File.Exists("Submarines/TutorialSub.sub"))
|
||||
{
|
||||
System.IO.File.Delete("Submarines/TutorialSub.sub");
|
||||
Barotrauma.IO.File.Delete("Submarines/TutorialSub.sub");
|
||||
|
||||
NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
|
||||
}
|
||||
|
||||
/*if (System.IO.File.Exists(GameServer.SettingsFile))
|
||||
/*if (Barotrauma.IO.File.Exists(GameServer.SettingsFile))
|
||||
{
|
||||
System.IO.File.Delete(GameServer.SettingsFile);
|
||||
Barotrauma.IO.File.Delete(GameServer.SettingsFile);
|
||||
NewMessage("Deleted server settings", Color.Green);
|
||||
}
|
||||
|
||||
if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
|
||||
if (Barotrauma.IO.File.Exists(GameServer.ClientPermissionsFile))
|
||||
{
|
||||
System.IO.File.Delete(GameServer.ClientPermissionsFile);
|
||||
Barotrauma.IO.File.Delete(GameServer.ClientPermissionsFile);
|
||||
NewMessage("Deleted client permission file", Color.Green);
|
||||
}*/
|
||||
|
||||
if (System.IO.File.Exists("crashreport.log"))
|
||||
if (Barotrauma.IO.File.Exists("crashreport.log"))
|
||||
{
|
||||
System.IO.File.Delete("crashreport.log");
|
||||
Barotrauma.IO.File.Delete("crashreport.log");
|
||||
NewMessage("Deleted crashreport.log", Color.Green);
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists("Content/Map/TutorialSub.sub"))
|
||||
if (!Barotrauma.IO.File.Exists("Content/Map/TutorialSub.sub"))
|
||||
{
|
||||
ThrowError("TutorialSub.sub not found!");
|
||||
}
|
||||
@@ -1841,7 +1879,7 @@ namespace Barotrauma
|
||||
"giveperm",
|
||||
(string[] args) =>
|
||||
{
|
||||
if (args.Length < 1) return;
|
||||
if (args.Length < 1) { return; }
|
||||
|
||||
NewMessage("Valid permissions are:", Color.White);
|
||||
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
|
||||
@@ -1898,7 +1936,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (args.Length < 1) return;
|
||||
|
||||
ShowQuestionPrompt("Console command permissions to grant to client " + args[0] + "? You may enter multiple commands separated with a space.", (commandNames) =>
|
||||
ShowQuestionPrompt("Console command permissions to grant to client " + args[0] + "? You may enter multiple commands separated with a space or use \"all\" to give the permission to use all console commands.", (commandNames) =>
|
||||
{
|
||||
GameMain.Client?.SendConsoleCommand("givecommandperm " + args[0] + " " + commandNames);
|
||||
}, args, 1);
|
||||
@@ -1911,7 +1949,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (args.Length < 1) return;
|
||||
|
||||
ShowQuestionPrompt("Console command permissions to revoke from client " + args[0] + "? You may enter multiple commands separated with a space.", (commandNames) =>
|
||||
ShowQuestionPrompt("Console command permissions to revoke from client " + args[0] + "? You may enter multiple commands separated with a space or use \"all\" to revoke the permission to use any console commands.", (commandNames) =>
|
||||
{
|
||||
GameMain.Client?.SendConsoleCommand("revokecommandperm " + args[0] + " " + commandNames);
|
||||
}, args, 1);
|
||||
@@ -2206,7 +2244,7 @@ namespace Barotrauma
|
||||
ThrowError("Cannot use the flipx command while playing online.");
|
||||
return;
|
||||
}
|
||||
Submarine.MainSub?.FlipX();
|
||||
if (Submarine.MainSub.SubBody != null) { Submarine.MainSub?.FlipX(); }
|
||||
}, isCheat: true));
|
||||
|
||||
commands.Add(new Command("gender", "Set the gender of the controlled character. Allowed parameters: Male, Female, None.", args =>
|
||||
@@ -2328,9 +2366,16 @@ namespace Barotrauma
|
||||
}
|
||||
try
|
||||
{
|
||||
SubmarineInfo subInfo = new SubmarineInfo(args[0]);
|
||||
Submarine spawnedSub = Submarine.Load(subInfo, false);
|
||||
spawnedSub.SetPosition(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition));
|
||||
var subInfo = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.DisplayName.Equals(args[0], StringComparison.OrdinalIgnoreCase));
|
||||
if (subInfo == null)
|
||||
{
|
||||
ThrowError($"Could not find a submarine with the name \"{args[0]}\".");
|
||||
}
|
||||
else
|
||||
{
|
||||
Submarine spawnedSub = Submarine.Load(subInfo, false);
|
||||
spawnedSub.SetPosition(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -2338,7 +2383,15 @@ namespace Barotrauma
|
||||
ThrowError(errorMsg, e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("DebugConsole.SpawnSubmarine:Error", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + '\n' + e.Message + '\n' + e.StackTrace);
|
||||
}
|
||||
}, isCheat: true));
|
||||
},
|
||||
() =>
|
||||
{
|
||||
return new string[][]
|
||||
{
|
||||
SubmarineInfo.SavedSubmarines.Select(s => s.DisplayName).ToArray()
|
||||
};
|
||||
},
|
||||
isCheat: true));
|
||||
|
||||
commands.Add(new Command("pause", "Toggles the pause state when playing offline", (string[] args) =>
|
||||
{
|
||||
|
||||
@@ -83,10 +83,6 @@ namespace Barotrauma
|
||||
}
|
||||
foreach (ScriptedEventSet eventSet in pendingEventSets)
|
||||
{
|
||||
float distanceTraveled = MathHelper.Clamp(
|
||||
(Submarine.MainSub.WorldPosition.X - level.StartPosition.X) / (level.EndPosition.X - level.StartPosition.X),
|
||||
0.0f, 1.0f);
|
||||
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace Barotrauma
|
||||
{
|
||||
public override void ClientReadInitial(IReadMessage msg)
|
||||
{
|
||||
items.Clear();
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
@@ -17,7 +18,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (items.Count != itemCount)
|
||||
{
|
||||
throw new System.Exception("Error in CargoMission.ClientReadInitial: item count does not match the server count (" + itemCount + " != " + items.Count + "mission: " + Prefab.Identifier + ")");
|
||||
throw new System.Exception("Error in CargoMission.ClientReadInitial: item count does not match the server count (" + itemCount + " != " + items.Count + ", mission: " + Prefab.Identifier + ")");
|
||||
}
|
||||
if (requiredDeliveryAmount == 0) { requiredDeliveryAmount = items.Count; }
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Barotrauma
|
||||
};
|
||||
chatSendButton.RectTransform.AbsoluteOffset = new Point((int)(InputBox.Rect.Height * 0.15f), 0);
|
||||
InputBox.TextBlock.RectTransform.MaxSize
|
||||
= new Point((int)(InputBox.Rect.Width - chatSendButton.Rect.Width * 1.25f - InputBox.TextBlock.Padding.Z), int.MaxValue);
|
||||
= new Point((int)(InputBox.Rect.Width - chatSendButton.Rect.Width * 1.25f - InputBox.TextBlock.Padding.X - chatSendButton.RectTransform.AbsoluteOffset.X), int.MaxValue);
|
||||
|
||||
showNewMessagesButton = new GUIButton(new RectTransform(new Vector2(1f, 0.075f), GUIFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, 0.125f) }, TextManager.Get("chat.shownewmessages"));
|
||||
showNewMessagesButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
@@ -384,17 +384,6 @@ namespace Barotrauma
|
||||
prevUIScale = GUI.Scale;
|
||||
}
|
||||
|
||||
//hide chatbox when accessing the inventory of another character to prevent overlaps
|
||||
if (Character.Controlled?.SelectedCharacter?.Inventory != null &&
|
||||
Character.Controlled.SelectedCharacter.CanInventoryBeAccessed)
|
||||
{
|
||||
SetVisibility(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVisibility(true);
|
||||
}
|
||||
|
||||
if (showNewMessagesButton.Visible && chatBox.ScrollBar.BarScroll == 1f)
|
||||
{
|
||||
showNewMessagesButton.Visible = false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Barotrauma
|
||||
private static GUIDropDown fileTypeDropdown;
|
||||
private static GUIButton openButton;
|
||||
|
||||
private static FileSystemWatcher fileSystemWatcher;
|
||||
private static System.IO.FileSystemWatcher fileSystemWatcher;
|
||||
|
||||
private static string currentFileTypePattern;
|
||||
|
||||
@@ -78,10 +78,10 @@ namespace Barotrauma
|
||||
currentDirectory += "/";
|
||||
}
|
||||
fileSystemWatcher?.Dispose();
|
||||
fileSystemWatcher = new FileSystemWatcher(currentDirectory)
|
||||
fileSystemWatcher = new System.IO.FileSystemWatcher(currentDirectory)
|
||||
{
|
||||
Filter = "*",
|
||||
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName
|
||||
NotifyFilter = System.IO.NotifyFilters.LastWrite | System.IO.NotifyFilters.FileName | System.IO.NotifyFilters.DirectoryName
|
||||
};
|
||||
fileSystemWatcher.Created += OnFileSystemChanges;
|
||||
fileSystemWatcher.Deleted += OnFileSystemChanges;
|
||||
@@ -97,11 +97,11 @@ namespace Barotrauma
|
||||
set;
|
||||
}
|
||||
|
||||
private static void OnFileSystemChanges(object sender, FileSystemEventArgs e)
|
||||
private static void OnFileSystemChanges(object sender, System.IO.FileSystemEventArgs e)
|
||||
{
|
||||
switch (e.ChangeType)
|
||||
{
|
||||
case WatcherChangeTypes.Created:
|
||||
case System.IO.WatcherChangeTypes.Created:
|
||||
{
|
||||
var itemFrame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), fileList.Content.RectTransform), e.Name)
|
||||
{
|
||||
@@ -114,15 +114,15 @@ namespace Barotrauma
|
||||
fileList.Content.RectTransform.SortChildren(SortFiles);
|
||||
}
|
||||
break;
|
||||
case WatcherChangeTypes.Deleted:
|
||||
case System.IO.WatcherChangeTypes.Deleted:
|
||||
{
|
||||
var itemFrame = fileList.Content.FindChild(c => (c is GUITextBlock tb) && (tb.Text == e.Name || tb.Text == e.Name + "/"));
|
||||
if (itemFrame != null) { fileList.RemoveChild(itemFrame); }
|
||||
}
|
||||
break;
|
||||
case WatcherChangeTypes.Renamed:
|
||||
case System.IO.WatcherChangeTypes.Renamed:
|
||||
{
|
||||
RenamedEventArgs renameArgs = e as RenamedEventArgs;
|
||||
System.IO.RenamedEventArgs renameArgs = e as System.IO.RenamedEventArgs;
|
||||
var itemFrame = fileList.Content.FindChild(c => (c is GUITextBlock tb) && (tb.Text == renameArgs.OldName || tb.Text == renameArgs.OldName + "/")) as GUITextBlock;
|
||||
itemFrame.UserData = (bool?)Directory.Exists(e.FullPath);
|
||||
itemFrame.Text = renameArgs.Name;
|
||||
@@ -156,7 +156,7 @@ namespace Barotrauma
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
backgroundFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null)
|
||||
backgroundFrame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
|
||||
{
|
||||
Color = Color.Black * 0.5f,
|
||||
HoverColor = Color.Black * 0.5f,
|
||||
@@ -169,10 +169,10 @@ namespace Barotrauma
|
||||
var horizontalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, window.RectTransform, Anchor.Center), true);
|
||||
sidebar = new GUIListBox(new RectTransform(new Vector2(0.29f, 1.0f), horizontalLayout.RectTransform));
|
||||
|
||||
var drives = DriveInfo.GetDrives();
|
||||
var drives = System.IO.DriveInfo.GetDrives();
|
||||
foreach (var drive in drives)
|
||||
{
|
||||
if (drive.DriveType == DriveType.Ram) { continue; }
|
||||
if (drive.DriveType == System.IO.DriveType.Ram) { continue; }
|
||||
if (ignoredDrivePrefixes.Any(p => drive.Name.StartsWith(p))) { continue; }
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), sidebar.Content.RectTransform), drive.Name.Replace('\\','/'));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.CharacterEditor;
|
||||
@@ -80,8 +80,8 @@ namespace Barotrauma
|
||||
public static readonly string[] colorComponentLabels = { "R", "G", "B", "A" };
|
||||
|
||||
public static Vector2 ReferenceResolution => new Vector2(1920f, 1080f);
|
||||
public static float Scale => (GameMain.GraphicsWidth / ReferenceResolution.X + GameMain.GraphicsHeight / ReferenceResolution.Y) / 2.0f * GameSettings.HUDScale;
|
||||
public static float xScale => GameMain.GraphicsWidth / ReferenceResolution.X * GameSettings.HUDScale;
|
||||
public static float Scale => (UIWidth / ReferenceResolution.X + GameMain.GraphicsHeight / ReferenceResolution.Y) / 2.0f * GameSettings.HUDScale;
|
||||
public static float xScale => UIWidth / ReferenceResolution.X * GameSettings.HUDScale;
|
||||
public static float yScale => GameMain.GraphicsHeight / ReferenceResolution.Y * GameSettings.HUDScale;
|
||||
public static int IntScale(float f) => (int)(f * Scale);
|
||||
public static int IntScaleFloor(float f) => (int)Math.Floor(f * Scale);
|
||||
@@ -90,6 +90,23 @@ namespace Barotrauma
|
||||
public static float VerticalAspectRatio => GameMain.GraphicsHeight / (float)GameMain.GraphicsWidth;
|
||||
public static float RelativeHorizontalAspectRatio => HorizontalAspectRatio / (ReferenceResolution.X / ReferenceResolution.Y);
|
||||
public static float RelativeVerticalAspectRatio => VerticalAspectRatio / (ReferenceResolution.Y / ReferenceResolution.X);
|
||||
public static bool IsUltrawide => HorizontalAspectRatio > 2.0f;
|
||||
|
||||
public static int UIWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
// Ultrawide
|
||||
if (IsUltrawide)
|
||||
{
|
||||
return (int)(GameMain.GraphicsHeight * ReferenceResolution.X / ReferenceResolution.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GameMain.GraphicsWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float SlicedSpriteScale
|
||||
{
|
||||
@@ -521,6 +538,37 @@ namespace Barotrauma
|
||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)anchorPivotStringSize.X - padding, yPos), anchorPivotString, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||
yPos += (int)anchorPivotStringSize.Y + padding / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
string guiScaleString = $"GUI.Scale: {Scale}";
|
||||
string guixScaleString = $"GUI.xScale: {xScale}";
|
||||
string guiyScaleString = $"GUI.yScale: {yScale}";
|
||||
string relativeHorizontalAspectRatioString = $"RelativeHorizontalAspectRatio: {RelativeHorizontalAspectRatio}";
|
||||
string relativeVerticalAspectRatioString = $"RelativeVerticalAspectRatio: {RelativeVerticalAspectRatio}";
|
||||
Vector2 guiScaleStringSize = SmallFont.MeasureString(guiScaleString);
|
||||
Vector2 guixScaleStringSize = SmallFont.MeasureString(guixScaleString);
|
||||
Vector2 guiyScaleStringSize = SmallFont.MeasureString(guiyScaleString);
|
||||
Vector2 relativeHorizontalAspectRatioStringSize = SmallFont.MeasureString(relativeHorizontalAspectRatioString);
|
||||
Vector2 relativeVerticalAspectRatioStringSize = SmallFont.MeasureString(relativeVerticalAspectRatioString);
|
||||
|
||||
int padding = IntScale(10);
|
||||
int yPos = padding;
|
||||
|
||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guiScaleStringSize.X - padding, yPos), guiScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||
yPos += (int)guiScaleStringSize.Y + padding / 2;
|
||||
|
||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guixScaleStringSize.X - padding, yPos), guixScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||
yPos += (int)guixScaleStringSize.Y + padding / 2;
|
||||
|
||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)guiyScaleStringSize.X - padding, yPos), guiyScaleString, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||
yPos += (int)guiyScaleStringSize.Y + padding / 2;
|
||||
|
||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)relativeHorizontalAspectRatioStringSize.X - padding, yPos), relativeHorizontalAspectRatioString, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||
yPos += (int)relativeHorizontalAspectRatioStringSize.Y + padding / 2;
|
||||
|
||||
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)relativeVerticalAspectRatioStringSize.X - padding, yPos), relativeVerticalAspectRatioString, Color.LightGreen, Color.Black, 0, SmallFont);
|
||||
yPos += (int)relativeVerticalAspectRatioStringSize.Y + padding / 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (HUDLayoutSettings.DebugDraw) HUDLayoutSettings.Draw(spriteBatch);
|
||||
@@ -1917,8 +1965,9 @@ namespace Barotrauma
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingInventory = null;
|
||||
|
||||
PauseMenu = new GUIFrame(new RectTransform(Vector2.One, Canvas), style: null, color: Color.Black * 0.5f);
|
||||
|
||||
PauseMenu = new GUIFrame(new RectTransform(Vector2.One, Canvas, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, PauseMenu.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.3f), PauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(250, 300) });
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.6f), pauseMenuInner.RectTransform, Anchor.Center))
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Barotrauma
|
||||
{
|
||||
public class GUICanvas : RectTransform
|
||||
{
|
||||
protected GUICanvas() : base(Vector2.One, parent: null) { }
|
||||
protected GUICanvas() : base(size, parent: null) { }
|
||||
|
||||
private static GUICanvas _instance;
|
||||
public static GUICanvas Instance
|
||||
@@ -22,15 +22,63 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.Instance.OnResolutionChanged += RecalculateSize;
|
||||
}
|
||||
_instance.ItemComponentHolder = new GUIFrame(new RectTransform(Vector2.One, _instance, Anchor.Center)).RectTransform;
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public RectTransform ItemComponentHolder;
|
||||
|
||||
private static Vector2 size => new Vector2(GameMain.GraphicsWidth / (float)GUI.UIWidth, 1f);
|
||||
|
||||
protected override Rectangle NonScaledUIRect => UIRect;
|
||||
|
||||
private enum ResizeAxis { Both = 0, X = 1, Y = 2 }
|
||||
|
||||
// Turn public, if there is a need to call this manually.
|
||||
private static void RecalculateSize()
|
||||
{
|
||||
Instance.Resize(Vector2.One, resizeChildren: true);
|
||||
Vector2 recalculatedSize = size;
|
||||
|
||||
// Scale children that are supposed to encompass the whole screen so that they are properly scaled on ultrawide as well
|
||||
for (int i = 0; i < Instance.Children.Count(); i++)
|
||||
{
|
||||
RectTransform target = Instance.GetChild(i);
|
||||
if (target == null || target.RelativeSize.X < 1 && target.RelativeSize.Y < 1) continue;
|
||||
|
||||
ResizeAxis axis;
|
||||
|
||||
if (target.RelativeSize.X >= 1 && target.RelativeSize.Y >= 1)
|
||||
{
|
||||
axis = ResizeAxis.Both;
|
||||
}
|
||||
else if (target.RelativeSize.X >= 1)
|
||||
{
|
||||
axis = ResizeAxis.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
axis = ResizeAxis.Y;
|
||||
}
|
||||
|
||||
switch (axis)
|
||||
{
|
||||
case ResizeAxis.Both:
|
||||
target.RelativeSize = recalculatedSize;
|
||||
break;
|
||||
|
||||
case ResizeAxis.X:
|
||||
target.RelativeSize = new Vector2(recalculatedSize.X, target.RelativeSize.Y);
|
||||
break;
|
||||
|
||||
case ResizeAxis.Y:
|
||||
target.RelativeSize = new Vector2(target.RelativeSize.X, recalculatedSize.Y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Instance.Resize(size, resizeChildren: true);
|
||||
Instance.GetAllChildren().Select(c => c.GUIComponent as GUITextBlock).ForEach(t => t?.SetTextPos());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using RestSharp;
|
||||
using System.Net;
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ namespace Barotrauma
|
||||
|
||||
if (Dropped)
|
||||
{
|
||||
listBox.AddToGUIUpdateList(false, UpdateOrder);
|
||||
listBox.AddToGUIUpdateList(false, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,17 @@ namespace Barotrauma
|
||||
public class GUIImage : GUIComponent
|
||||
{
|
||||
//paths of the textures that are being loaded asynchronously
|
||||
private static readonly HashSet<string> activeTextureLoads = new HashSet<string>();
|
||||
private static readonly List<string> activeTextureLoads = new List<string>();
|
||||
|
||||
private static bool loadingTextures;
|
||||
|
||||
public static bool LoadingTextures
|
||||
{
|
||||
get
|
||||
{
|
||||
return loadingTextures;
|
||||
}
|
||||
}
|
||||
|
||||
public float Rotation;
|
||||
|
||||
@@ -25,7 +35,7 @@ namespace Barotrauma
|
||||
private bool lazyLoaded, loading;
|
||||
|
||||
public bool LoadAsynchronously;
|
||||
|
||||
|
||||
public bool Crop
|
||||
{
|
||||
get
|
||||
@@ -122,6 +132,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (LoadAsynchronously)
|
||||
{
|
||||
loadingTextures = true;
|
||||
loading = true;
|
||||
TaskPool.Add(LoadTextureAsync(), (Task) =>
|
||||
{
|
||||
@@ -223,6 +234,7 @@ namespace Barotrauma
|
||||
lock (activeTextureLoads)
|
||||
{
|
||||
activeTextureLoads.Remove(Sprite.FullPath);
|
||||
loadingTextures = activeTextureLoads.Count > 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -76,19 +76,7 @@ namespace Barotrauma
|
||||
|
||||
public GUILayoutGroup(RectTransform rectT, bool isHorizontal = false, Anchor childAnchor = Anchor.TopLeft) : base(null, rectT)
|
||||
{
|
||||
#if DEBUG
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
CanBeFocused = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
CanBeFocused = false;
|
||||
#if DEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
CanBeFocused = false;
|
||||
this.isHorizontal = isHorizontal;
|
||||
this.childAnchor = childAnchor;
|
||||
rectT.ChildrenChanged += (child) => needsToRecalculate = true;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Barotrauma
|
||||
public static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
|
||||
private static int DefaultWidth
|
||||
{
|
||||
get { return Math.Max(400, 400 * (GameMain.GraphicsWidth / 1920)); }
|
||||
get { return Math.Max(400, (int)(400 * (GameMain.GraphicsWidth / GUI.ReferenceResolution.X))); }
|
||||
}
|
||||
|
||||
private float inGameCloseTimer = 0.0f;
|
||||
@@ -63,7 +63,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null)
|
||||
: base(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
|
||||
: base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
|
||||
{
|
||||
int width = (int)(DefaultWidth * (type == Type.Default ? 1.0f : 1.5f)), height = 0;
|
||||
if (relativeSize.HasValue)
|
||||
|
||||
@@ -510,6 +510,8 @@ namespace Barotrauma
|
||||
|
||||
var currPosition = positions[0];
|
||||
|
||||
float topY = positions.Min(p => p.Item1.Y);
|
||||
|
||||
for (int i = 1; i < positions.Count; i++)
|
||||
{
|
||||
var p1 = positions[i];
|
||||
@@ -527,7 +529,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
diffY = Math.Abs(p1.Item1.Y - pos.Y);
|
||||
if (diffY < halfHeight)
|
||||
if (diffY < halfHeight || (p1.Item1.Y == topY && pos.Y < topY))
|
||||
{
|
||||
//we are on this line, select the nearest character
|
||||
float diffX = Math.Abs(p1.Item1.X - pos.X) - Math.Abs(p2.Item1.X - pos.X);
|
||||
|
||||
@@ -67,6 +67,8 @@ namespace Barotrauma
|
||||
private Vector2 selectionEndPos;
|
||||
private Vector2 selectionRectSize;
|
||||
|
||||
private bool mouseHeldInside;
|
||||
|
||||
private readonly Memento<string> memento = new Memento<string>();
|
||||
|
||||
// Skip one update cycle, fixes Enter key instantly deselecting the chatbox
|
||||
@@ -414,6 +416,7 @@ namespace Barotrauma
|
||||
State = ComponentState.Hover;
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
mouseHeldInside = true;
|
||||
Select();
|
||||
}
|
||||
else
|
||||
@@ -436,7 +439,11 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((PlayerInput.LeftButtonClicked() || PlayerInput.RightButtonClicked()) && selected) Deselect();
|
||||
if ((PlayerInput.LeftButtonClicked() || PlayerInput.RightButtonClicked()) && selected)
|
||||
{
|
||||
if (!mouseHeldInside) { Deselect(); }
|
||||
mouseHeldInside = false;
|
||||
}
|
||||
isSelecting = false;
|
||||
State = ComponentState.None;
|
||||
}
|
||||
|
||||
@@ -50,10 +50,6 @@ namespace Barotrauma
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/*public static Rectangle HealthBarAreaRight
|
||||
{
|
||||
get; private set;
|
||||
}*/
|
||||
public static Rectangle HealthBarArea
|
||||
{
|
||||
get; private set;
|
||||
@@ -120,17 +116,11 @@ namespace Barotrauma
|
||||
|
||||
//horizontal slices at the corners of the screen for health bar and affliction icons
|
||||
int afflictionAreaHeight = (int)(50 * GUI.Scale);
|
||||
int healthBarWidth = BottomRightInfoArea.Width + CharacterInventory.SlotSize.X + CharacterInventory.Spacing * 2 + CharacterInventory.HideButtonWidth;
|
||||
int healthBarWidth = (int)(BottomRightInfoArea.Width * 1.58f);
|
||||
int healthBarHeight = (int)(50f * GUI.Scale);
|
||||
HealthBarArea = new Rectangle(BottomRightInfoArea.X - (healthBarWidth - BottomRightInfoArea.Width) + (int)(2 * GUI.Scale), BottomRightInfoArea.Y - healthBarHeight + (int)(10 * GUI.Scale), healthBarWidth, healthBarHeight);
|
||||
AfflictionAreaLeft = new Rectangle(HealthBarArea.X, HealthBarArea.Y - Padding - afflictionAreaHeight, HealthBarArea.Width, afflictionAreaHeight);
|
||||
|
||||
//HealthBarAreaRight = new Rectangle(Padding, GameMain.GraphicsHeight - healthBarHeight - Padding, healthBarWidth, healthBarHeight);
|
||||
/*if (HealthBarAreaRight.Y + healthBarHeight * 0.75f < PortraitArea.Y)
|
||||
{
|
||||
HealthBarAreaRight = new Rectangle(GameMain.GraphicsWidth - Padding - healthBarWidth, HealthBarAreaRight.Y, HealthBarAreaRight.Width, HealthBarAreaRight.Height);
|
||||
}*/
|
||||
//AfflictionAreaRight = new Rectangle(HealthBarAreaRight.X, HealthBarAreaRight.Y + healthBarHeight + Padding, healthBarWidth, afflictionAreaHeight);
|
||||
HealthBarArea = new Rectangle(BottomRightInfoArea.Right - healthBarWidth + (int)Math.Floor(1 / GUI.Scale), BottomRightInfoArea.Y - healthBarHeight + GUI.IntScale(10), healthBarWidth, healthBarHeight);
|
||||
AfflictionAreaLeft = new Rectangle(HealthBarArea.X, HealthBarArea.Y - Padding - afflictionAreaHeight, HealthBarArea.Width, afflictionAreaHeight);
|
||||
|
||||
|
||||
int messageAreaWidth = GameMain.GraphicsWidth / 3;
|
||||
MessageAreaTop = new Rectangle((GameMain.GraphicsWidth - messageAreaWidth) / 2, ButtonAreaTop.Bottom, messageAreaWidth, ButtonAreaTop.Height);
|
||||
@@ -146,7 +136,7 @@ namespace Barotrauma
|
||||
|
||||
CrewArea = new Rectangle(Padding, Padding, (int)Math.Max(400 * GUI.Scale, 220), ObjectiveAnchor.Top - Padding * 2);
|
||||
|
||||
InventoryAreaLower = new Rectangle(Padding, inventoryTopY, GameMain.GraphicsWidth - Padding * 2, GameMain.GraphicsHeight - inventoryTopY);
|
||||
InventoryAreaLower = new Rectangle(ChatBoxArea.Right + Padding * 7, inventoryTopY, GameMain.GraphicsWidth - Padding * 9 - ChatBoxArea.Width, GameMain.GraphicsHeight - inventoryTopY);
|
||||
|
||||
int healthWindowWidth = (int)(GameMain.GraphicsWidth * 0.5f);
|
||||
int healthWindowHeight = (int)(GameMain.GraphicsWidth * 0.5f * 0.65f);
|
||||
|
||||
@@ -253,11 +253,12 @@ namespace Barotrauma
|
||||
return _rect;
|
||||
}
|
||||
}
|
||||
public Rectangle ParentRect => Parent != null ? Parent.Rect : ScreenRect;
|
||||
|
||||
public Rectangle ParentRect => Parent != null ? Parent.Rect : UIRect;
|
||||
protected Rectangle NonScaledRect => new Rectangle(NonScaledTopLeft, NonScaledSize);
|
||||
protected Rectangle NonScaledParentRect => parent != null ? Parent.NonScaledRect : ScreenRect;
|
||||
protected Rectangle ScreenRect => new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
protected virtual Rectangle NonScaledUIRect => NonScaledRect;
|
||||
protected Rectangle NonScaledParentRect => parent != null ? Parent.NonScaledRect : UIRect;
|
||||
protected Rectangle NonScaledParentUIRect => parent != null ? Parent.NonScaledUIRect : UIRect;
|
||||
protected Rectangle UIRect => new Rectangle(0, 0, GUI.UIWidth, GameMain.GraphicsHeight);
|
||||
|
||||
private Pivot pivot;
|
||||
/// <summary>
|
||||
@@ -444,14 +445,14 @@ namespace Barotrauma
|
||||
|
||||
protected void RecalculateRelativeSize()
|
||||
{
|
||||
relativeSize = new Vector2(NonScaledSize.X, NonScaledSize.Y) / new Vector2(NonScaledParentRect.Width, NonScaledParentRect.Height);
|
||||
relativeSize = new Vector2(NonScaledSize.X, NonScaledSize.Y) / new Vector2(NonScaledParentUIRect.Width, NonScaledParentUIRect.Height);
|
||||
recalculateRect = true;
|
||||
SizeChanged?.Invoke();
|
||||
}
|
||||
|
||||
protected void RecalculateAbsoluteSize()
|
||||
{
|
||||
Point size = NonScaledParentRect.Size;
|
||||
Point size = NonScaledParentUIRect.Size;
|
||||
switch (ScaleBasis)
|
||||
{
|
||||
case ScaleBasis.BothWidth:
|
||||
|
||||
@@ -177,7 +177,8 @@ namespace Barotrauma
|
||||
{
|
||||
tabButtons.Clear();
|
||||
|
||||
infoFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
|
||||
infoFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, infoFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
switch (selectedTab)
|
||||
{
|
||||
@@ -488,6 +489,12 @@ namespace Barotrauma
|
||||
Color = (GameMain.NetworkMember != null && GameMain.Client.Character == character) ? ownCharacterBGColor : Color.Transparent
|
||||
};
|
||||
|
||||
frame.OnSecondaryClicked += (component, data) =>
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.CreateModerationContextMenu(PlayerInput.MousePosition.ToPoint(), client);
|
||||
return true;
|
||||
};
|
||||
|
||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), frame.RectTransform, Anchor.Center), isHorizontal: true)
|
||||
{
|
||||
AbsoluteSpacing = 2
|
||||
@@ -593,6 +600,8 @@ namespace Barotrauma
|
||||
{
|
||||
GUITextBlock characterNameBlock;
|
||||
Sprite permissionIcon = GetPermissionIcon(client);
|
||||
JobPrefab prefab = client.Character?.Info?.Job?.Prefab;
|
||||
Color nameColor = prefab != null ? prefab.UIColor : Color.White;
|
||||
|
||||
if (permissionIcon != null)
|
||||
{
|
||||
@@ -600,7 +609,7 @@ namespace Barotrauma
|
||||
float characterNameWidthAdjustment = (iconSize.X + paddedFrame.AbsoluteSpacing) / characterColumnWidth;
|
||||
|
||||
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||
ToolBox.LimitString(client.Name, GUI.Font, (int)(characterColumnWidth - paddedFrame.Rect.Width * characterNameWidthAdjustment)), textAlignment: Alignment.Center, textColor: client.Character != null ? client.Character.Info.Job.Prefab.UIColor : Color.White);
|
||||
ToolBox.LimitString(client.Name, GUI.Font, (int)(characterColumnWidth - paddedFrame.Rect.Width * characterNameWidthAdjustment)), textAlignment: Alignment.Center, textColor: nameColor);
|
||||
|
||||
float iconWidth = iconSize.X / (float)characterColumnWidth;
|
||||
int xOffset = (int)(jobColumnWidth + characterNameBlock.TextPos.X - GUI.Font.MeasureString(characterNameBlock.Text).X / 2f - paddedFrame.AbsoluteSpacing - iconWidth * paddedFrame.Rect.Width);
|
||||
@@ -609,7 +618,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||
ToolBox.LimitString(client.Name, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: client.Character != null ? client.Character.Info.Job.Prefab.UIColor : Color.White);
|
||||
ToolBox.LimitString(client.Name, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: nameColor);
|
||||
}
|
||||
|
||||
if (client.Character != null && client.Character.IsDead)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Media;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -56,7 +56,7 @@ namespace Barotrauma
|
||||
|
||||
public VideoPlayer() // GUI elements with size set to Point.Zero are resized based on content
|
||||
{
|
||||
int screenWidth = (int)(GameMain.GraphicsWidth * 0.55f);
|
||||
int screenWidth = (int)(GameMain.GraphicsWidth * 0.65f);
|
||||
scaledVideoResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f));
|
||||
|
||||
int width = scaledVideoResolution.X;
|
||||
@@ -178,6 +178,7 @@ namespace Barotrauma
|
||||
|
||||
videoFrame.RectTransform.NonScaledSize = scaledVideoResolution + new Point(scaledBorderSize, scaledBorderSize);
|
||||
videoView.RectTransform.NonScaledSize = scaledVideoResolution;
|
||||
videoFrame.RectTransform.AbsoluteOffset = new Point(0, videoFrame.RectTransform.NonScaledSize.Y);
|
||||
|
||||
title.RectTransform.NonScaledSize = new Point(scaledTextWidth, scaledTitleHeight);
|
||||
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
|
||||
@@ -247,7 +248,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
videoFrame.RectTransform.AbsoluteOffset = new Point(0, (int)(100 * GUI.Scale));
|
||||
videoFrame.RectTransform.AbsoluteOffset = new Point(0, 0);
|
||||
|
||||
okButton = new GUIButton(new RectTransform(scaledButtonSize, videoFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("Back"))
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using GameAnalyticsSDK.Net;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Threading;
|
||||
using Barotrauma.Tutorials;
|
||||
using Barotrauma.Media;
|
||||
@@ -532,6 +532,8 @@ namespace Barotrauma
|
||||
ScriptedEventSet.LoadPrefabs();
|
||||
AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
|
||||
SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings));
|
||||
Order.Init();
|
||||
EventManagerSettings.Init();
|
||||
TitleScreen.LoadState = 50.0f;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
@@ -860,7 +862,7 @@ namespace Barotrauma
|
||||
//TODO: do we need to check Inventory.SelectedSlot?
|
||||
&& Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null
|
||||
&& !CrewManager.IsCommandInterfaceOpen
|
||||
&& !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled.SelectedConstruction != null))
|
||||
&& !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled?.SelectedConstruction != null))
|
||||
{
|
||||
// Otherwise toggle pausing, unless another window/interface is open.
|
||||
GUI.TogglePauseMenu();
|
||||
|
||||
@@ -1264,7 +1264,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateCommandUI(HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition) ? Character.Controlled : GUI.MouseOn?.UserData as Character);
|
||||
CreateCommandUI(HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) ? Character.Controlled : GUI.MouseOn?.UserData as Character);
|
||||
}
|
||||
GUI.PlayUISound(GUISoundType.PopupMenu);
|
||||
clicklessSelectionActive = isOpeningClick = true;
|
||||
@@ -1288,18 +1288,9 @@ namespace Barotrauma
|
||||
else if (PlayerInput.SecondaryMouseButtonClicked() && characterContext == null &&
|
||||
(optionNodes.Any(n => GUI.IsMouseOn(n.Item1)) || shortcutNodes.Any(n => GUI.IsMouseOn(n))))
|
||||
{
|
||||
var node = optionNodes.Find(n => GUI.IsMouseOn(n.Item1))?.Item1;
|
||||
if (node == null)
|
||||
{
|
||||
node = shortcutNodes.Find(n => GUI.IsMouseOn(n));
|
||||
}
|
||||
// Make sure the node is for an option-less order...
|
||||
if (node.UserData is Order order && !order.HasOptions)
|
||||
{
|
||||
CreateAssignmentNodes(node);
|
||||
}
|
||||
// ...or an order option
|
||||
else if (node.UserData is Tuple<Order, string>)
|
||||
var node = optionNodes.Find(n => GUI.IsMouseOn(n.Item1))?.Item1 ?? shortcutNodes.Find(n => GUI.IsMouseOn(n));
|
||||
// Make sure the node is for an option-less order or an order option
|
||||
if ((node.UserData is Order order && !order.HasOptions && (!order.MustSetTarget || itemContext != null)) || node.UserData is Tuple<Order, string>)
|
||||
{
|
||||
CreateAssignmentNodes(node);
|
||||
}
|
||||
@@ -1543,31 +1534,31 @@ namespace Barotrauma
|
||||
}
|
||||
private GUIFrame commandFrame, targetFrame;
|
||||
private GUIButton centerNode, returnNode, expandNode, shortcutCenterNode;
|
||||
private List<Tuple<GUIComponent, Keys>> optionNodes = new List<Tuple<GUIComponent, Keys>>();
|
||||
private readonly List<Tuple<GUIComponent, Keys>> optionNodes = new List<Tuple<GUIComponent, Keys>>();
|
||||
private Keys returnNodeHotkey = Keys.None, expandNodeHotkey = Keys.None;
|
||||
private List<GUIComponent> shortcutNodes = new List<GUIComponent>();
|
||||
private List<GUIComponent> extraOptionNodes = new List<GUIComponent>();
|
||||
private readonly List<GUIComponent> shortcutNodes = new List<GUIComponent>();
|
||||
private readonly List<GUIComponent> extraOptionNodes = new List<GUIComponent>();
|
||||
private GUICustomComponent nodeConnectors;
|
||||
private GUIImage background;
|
||||
|
||||
private GUIButton selectedNode;
|
||||
private float selectionTime = 0.75f, timeSelected = 0.0f;
|
||||
private readonly float selectionTime = 0.75f;
|
||||
private float timeSelected = 0.0f;
|
||||
private bool clicklessSelectionActive, isOpeningClick, isSelectionHighlighted;
|
||||
|
||||
private Point centerNodeSize, nodeSize, shortcutCenterNodeSize, shortcutNodeSize, returnNodeSize;
|
||||
private Point centerNodeSize, nodeSize, shortcutCenterNodeSize, shortcutNodeSize, returnNodeSize, assignmentNodeSize;
|
||||
private float centerNodeMargin, optionNodeMargin, shortcutCenterNodeMargin, shortcutNodeMargin, returnNodeMargin;
|
||||
|
||||
private List<OrderCategory> availableCategories;
|
||||
private Stack<GUIButton> historyNodes = new Stack<GUIButton>();
|
||||
private List<Character> extraOptionCharacters = new List<Character>();
|
||||
private readonly List<Character> extraOptionCharacters = new List<Character>();
|
||||
|
||||
/// <summary>
|
||||
/// node.Color = node.HighlightColor * nodeColorMultiplier
|
||||
/// </summary>
|
||||
private const float nodeColorMultiplier = 0.75f;
|
||||
private const int assignmentNodeMaxCount = 8;
|
||||
private int nodeDistance = (int)(GUI.Scale * 250);
|
||||
private float returnNodeDistanceModifier = 0.65f;
|
||||
private const float returnNodeDistanceModifier = 0.65f;
|
||||
private Order dismissedOrderPrefab;
|
||||
private Character characterContext;
|
||||
private Item itemContext;
|
||||
@@ -1576,6 +1567,7 @@ namespace Barotrauma
|
||||
private readonly List<Order> contextualOrders = new List<Order>();
|
||||
private Point shorcutCenterNodeOffset;
|
||||
private const int maxShorcutNodeCount = 4;
|
||||
|
||||
private bool WasCommandInterfaceDisabledThisUpdate { get; set; }
|
||||
private bool CanIssueOrders
|
||||
{
|
||||
@@ -1584,7 +1576,7 @@ namespace Barotrauma
|
||||
#if DEBUG
|
||||
return Character.Controlled == null || Character.Controlled.Info != null && Character.Controlled.SpeechImpediment < 100.0f;
|
||||
#else
|
||||
return Character.Controlled != null && Character.Controlled.SpeechImpediment < 100.0f;
|
||||
return Character.Controlled?.Info != null && Character.Controlled.SpeechImpediment < 100.0f;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1743,16 +1735,21 @@ namespace Barotrauma
|
||||
|
||||
private void ScaleCommandUI()
|
||||
{
|
||||
centerNodeSize = new Point((int)(100 * GUI.Scale));
|
||||
// Node sizes
|
||||
nodeSize = new Point((int)(100 * GUI.Scale));
|
||||
shortcutCenterNodeSize = new Point((int)(48 * GUI.Scale));
|
||||
shortcutNodeSize = new Point((int)(64 * GUI.Scale));
|
||||
centerNodeSize = nodeSize;
|
||||
returnNodeSize = new Point((int)(48 * GUI.Scale));
|
||||
assignmentNodeSize = new Point((int)(64 * GUI.Scale));
|
||||
shortcutCenterNodeSize = returnNodeSize;
|
||||
shortcutNodeSize = assignmentNodeSize;
|
||||
|
||||
// Node margins (used in drawing the connecting lines)
|
||||
centerNodeMargin = centerNodeSize.X * 0.5f;
|
||||
optionNodeMargin = nodeSize.X * 0.5f;
|
||||
shortcutCenterNodeMargin = shortcutCenterNodeSize.X * 0.45f;
|
||||
shortcutNodeMargin = shortcutNodeSize.X * 0.5f;
|
||||
returnNodeMargin = returnNodeSize.X * 0.5f;
|
||||
|
||||
nodeDistance = (int)(150 * GUI.Scale);
|
||||
shorcutCenterNodeOffset = new Point(0, (int)(1.25f * nodeDistance));
|
||||
}
|
||||
@@ -1783,12 +1780,12 @@ namespace Barotrauma
|
||||
{
|
||||
if (centerNode == null || optionNodes == null) { return; }
|
||||
var startNodePos = centerNode.Rect.Center.ToVector2();
|
||||
if (targetFrame == null || !targetFrame.Visible)
|
||||
// Don't draw connectors for mini map options or assignment nodes
|
||||
if ((targetFrame == null || !targetFrame.Visible) && !(optionNodes.FirstOrDefault()?.Item1.UserData is Character))
|
||||
{
|
||||
optionNodes.ForEach(n => DrawNodeConnector(startNodePos, centerNodeMargin, n.Item1, optionNodeMargin, spriteBatch));
|
||||
}
|
||||
DrawNodeConnector(startNodePos, centerNodeMargin, returnNode, returnNodeMargin, spriteBatch);
|
||||
DrawNodeConnector(startNodePos, centerNodeMargin, expandNode, optionNodeMargin, spriteBatch);
|
||||
if (shortcutCenterNode == null || !shortcutCenterNode.Visible) { return; }
|
||||
DrawNodeConnector(startNodePos, centerNodeMargin, shortcutCenterNode, shortcutCenterNodeMargin, spriteBatch);
|
||||
startNodePos = shortcutCenterNode.Rect.Center.ToVector2();
|
||||
@@ -1850,6 +1847,7 @@ namespace Barotrauma
|
||||
shortcutNodes.Remove(node);
|
||||
};
|
||||
RemoveOptionNodes();
|
||||
|
||||
if (returnNode != null)
|
||||
{
|
||||
returnNode.RemoveChild(returnNode.GetChildByUserData("hotkey"));
|
||||
@@ -1857,15 +1855,20 @@ namespace Barotrauma
|
||||
returnNode.Visible = false;
|
||||
historyNodes.Push(returnNode);
|
||||
}
|
||||
SetReturnNode(centerNode, new Point(
|
||||
(int)(node.RectTransform.AbsoluteOffset.X * -returnNodeDistanceModifier),
|
||||
(int)(node.RectTransform.AbsoluteOffset.Y * -returnNodeDistanceModifier)));
|
||||
|
||||
// When the mini map is shown, always position the return node on the bottom
|
||||
var offset = node?.UserData is Order order && order.GetMatchingItems(true).Count > 1 ?
|
||||
new Point(0, (int)(returnNodeDistanceModifier * nodeDistance)) :
|
||||
node.RectTransform.AbsoluteOffset.Multiply(-returnNodeDistanceModifier);
|
||||
SetReturnNode(centerNode, offset);
|
||||
|
||||
SetCenterNode(node);
|
||||
if (shortcutCenterNode != null)
|
||||
{
|
||||
commandFrame.RemoveChild(shortcutCenterNode);
|
||||
shortcutCenterNode = null;
|
||||
}
|
||||
|
||||
CreateNodes(userData);
|
||||
CreateReturnNodeHotkey();
|
||||
return true;
|
||||
@@ -1914,9 +1917,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCenterNode(GUIButton node)
|
||||
private void SetCenterNode(GUIButton node, bool resetAnchor = false)
|
||||
{
|
||||
node.RectTransform.Parent = commandFrame.RectTransform;
|
||||
if (resetAnchor)
|
||||
{
|
||||
node.RectTransform.SetPosition(Anchor.Center);
|
||||
}
|
||||
node.RectTransform.SetPosition(Anchor.Center);
|
||||
node.RectTransform.MoveOverTime(Point.Zero, CommandNodeAnimDuration);
|
||||
node.RectTransform.ScaleOverTime(centerNodeSize, CommandNodeAnimDuration);
|
||||
node.RemoveChild(node.GetChildByUserData("hotkey"));
|
||||
@@ -2021,14 +2029,13 @@ namespace Barotrauma
|
||||
|
||||
private void CreateShortcutNodes()
|
||||
{
|
||||
var sub = Character.Controlled != null && Character.Controlled.TeamID == Character.TeamType.Team2 && Submarine.MainSubs.Length > 1 ?
|
||||
Submarine.MainSubs[1] : Submarine.MainSub;
|
||||
Submarine sub = GetTargetSubmarine();
|
||||
|
||||
if (sub == null) { return; }
|
||||
|
||||
shortcutNodes.Clear();
|
||||
|
||||
if (shortcutNodes.Count < maxShorcutNodeCount && sub.GetItems(false).Find(i => i.HasTag("reactor"))?.GetComponent<Reactor>() is Reactor reactor)
|
||||
if (shortcutNodes.Count < maxShorcutNodeCount && sub.GetItems(false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||
{
|
||||
var reactorOutput = -reactor.CurrPowerConsumption;
|
||||
// If player is not an engineer AND the reactor is not powered up AND nobody is using the reactor
|
||||
@@ -2037,8 +2044,9 @@ namespace Barotrauma
|
||||
reactorOutput < float.Epsilon && characters.None(c => c.SelectedConstruction == reactor.Item))
|
||||
{
|
||||
var order = new Order(Order.GetPrefab("operatereactor"), reactor.Item, reactor, Character.Controlled);
|
||||
var option = order.Prefab.Options[0];
|
||||
shortcutNodes.Add(
|
||||
CreateOrderOptionNode(shortcutNodeSize, null, Point.Zero, order, order.Prefab.Options[0], order.Prefab.OptionNames[0], -1));
|
||||
CreateOrderOptionNode(shortcutNodeSize, null, Point.Zero, order, option, order.Prefab.GetOptionName(option), -1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2046,7 +2054,7 @@ namespace Barotrauma
|
||||
// If player is not a captain AND nobody is using the nav terminal AND the nav terminal is powered up
|
||||
// --> Create shortcut node for Steer order
|
||||
if (shortcutNodes.Count < maxShorcutNodeCount && (Character.Controlled == null || Character.Controlled.Info.Job.Prefab != JobPrefab.Get("captain")) &&
|
||||
sub.GetItems(false).Find(i => i.HasTag("navterminal")) is Item nav && characters.None(c => c.SelectedConstruction == nav) &&
|
||||
sub.GetItems(false).Find(i => i.HasTag("navterminal") && !i.NonInteractable) is Item nav && characters.None(c => c.SelectedConstruction == nav) &&
|
||||
nav.GetComponent<Steering>() is Steering steering && steering.Voltage > steering.MinVoltage)
|
||||
{
|
||||
shortcutNodes.Add(
|
||||
@@ -2097,7 +2105,10 @@ namespace Barotrauma
|
||||
(n.UserData is Tuple<Order, string> orderWithOption && orderWithOption.Item1.Identifier == orderIdentifier)) &&
|
||||
!orderPrefab.TargetAllCharacters && orderPrefab.Category != null)
|
||||
{
|
||||
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, orderPrefab, -1));
|
||||
if (!orderPrefab.MustSetTarget || orderPrefab.GetMatchingItems(sub, true).Any())
|
||||
{
|
||||
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, orderPrefab, -1));
|
||||
}
|
||||
if (shortcutNodes.Count >= maxShorcutNodeCount) { break; }
|
||||
}
|
||||
}
|
||||
@@ -2129,16 +2140,19 @@ namespace Barotrauma
|
||||
|
||||
private void CreateOrderNodes(OrderCategory orderCategory)
|
||||
{
|
||||
// TODO: Save the available orders for each category so we don't have to check them again during the same game?
|
||||
var orders = Order.PrefabList.FindAll(o => o.Category == orderCategory && !o.TargetAllCharacters);
|
||||
orders.RemoveAll(o => (o.ItemComponentType != null || o.ItemIdentifiers.Length > 0) && o.MustSetTarget && o.GetMatchingItems(true).None());
|
||||
Order order;
|
||||
bool disableNode;
|
||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance,
|
||||
GetCircumferencePointCount(orders.Count), GetFirstNodeAngle(orders.Count));
|
||||
for (int i = 0; i < orders.Count; i++)
|
||||
{
|
||||
order = orders[i];
|
||||
disableNode = !CanSomeoneHearCharacter() ||
|
||||
(order.MustSetTarget && (order.ItemComponentType != null || order.ItemIdentifiers.Length > 0) && order.GetMatchingItems(true).None());
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), orders[i], (i + 1) % 10),
|
||||
CanSomeoneHearCharacter() ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), order, (i + 1) % 10, disableNode: disableNode, checkIfOrderCanBeHeard: false),
|
||||
!disableNode ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2150,7 +2164,7 @@ namespace Barotrauma
|
||||
if (contextualOrders.None())
|
||||
{
|
||||
// Check if targeting an item or a hull
|
||||
if (itemContext != null)
|
||||
if (itemContext != null && !itemContext.NonInteractable)
|
||||
{
|
||||
foreach (Order p in Order.PrefabList)
|
||||
{
|
||||
@@ -2165,11 +2179,11 @@ namespace Barotrauma
|
||||
// If targeting a periscope connected to a turret, show the 'operateweapons' order
|
||||
var orderIdentifier = "operateweapons";
|
||||
var operateWeaponsPrefab = Order.GetPrefab(orderIdentifier);
|
||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && itemContext.Components.Any(c => c is Controller) &&
|
||||
(itemContext.GetConnectedComponents<Turret>().Any(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier)) ||
|
||||
itemContext.GetConnectedComponents<Turret>(recursive: true).Any(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier))))
|
||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && itemContext.Components.Any(c => c is Controller))
|
||||
{
|
||||
contextualOrders.Add(operateWeaponsPrefab);
|
||||
var turret = itemContext.GetConnectedComponents<Turret>().FirstOrDefault(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier)) ??
|
||||
itemContext.GetConnectedComponents<Turret>(recursive: true).FirstOrDefault(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier));
|
||||
if (turret != null) { contextualOrders.Add(new Order(operateWeaponsPrefab, turret.Item, turret, Character.Controlled)); }
|
||||
}
|
||||
|
||||
// If targeting a repairable item, show the 'repairsystems' order
|
||||
@@ -2193,6 +2207,14 @@ namespace Barotrauma
|
||||
{
|
||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), itemContext, null, Character.Controlled));
|
||||
}
|
||||
|
||||
// Remove the 'pumpwater' order if the target pump is auto-controlled (as it will immediately overwrite the work done by the bot)
|
||||
orderIdentifier = "pumpwater";
|
||||
if (contextualOrders.FirstOrDefault(o => o.Identifier.Equals(orderIdentifier)) is Order o &&
|
||||
itemContext.Components.FirstOrDefault(c => c.GetType() == o.ItemComponentType) is Pump pump)
|
||||
{
|
||||
if (pump.IsAutoControlled) { contextualOrders.Remove(o); }
|
||||
}
|
||||
}
|
||||
else if(hullContext != null)
|
||||
{
|
||||
@@ -2218,11 +2240,12 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count));
|
||||
bool disableNode = !CanSomeoneHearCharacter();
|
||||
for (int i = 0; i < contextualOrders.Count; i++)
|
||||
{
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), contextualOrders[i], (i + 1) % 10),
|
||||
CanSomeoneHearCharacter() ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), contextualOrders[i], (i + 1) % 10, disableNode: disableNode, checkIfOrderCanBeHeard: false),
|
||||
!disableNode ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2239,7 +2262,7 @@ namespace Barotrauma
|
||||
item.GetConnectedComponents<Turret>(recursive: true).Any(c => operateWeaponsPrefab.ItemIdentifiers.Contains(c.Item.Prefab.Identifier)));
|
||||
}
|
||||
|
||||
private GUIButton CreateOrderNode(Point size, RectTransform parent, Point offset, Order order, int hotkey)
|
||||
private GUIButton CreateOrderNode(Point size, RectTransform parent, Point offset, Order order, int hotkey, bool disableNode = false, bool checkIfOrderCanBeHeard = true)
|
||||
{
|
||||
var node = new GUIButton(
|
||||
new RectTransform(size, parent: parent, anchor: Anchor.Center), style: null)
|
||||
@@ -2249,16 +2272,17 @@ namespace Barotrauma
|
||||
|
||||
node.RectTransform.MoveOverTime(offset, CommandNodeAnimDuration);
|
||||
|
||||
var canSomeoneHearCharacter = CanSomeoneHearCharacter();
|
||||
if (checkIfOrderCanBeHeard && !disableNode) { disableNode = !CanSomeoneHearCharacter(); }
|
||||
var mustSetOptionOrTarget = order.HasOptions || (order.MustSetTarget && itemContext == null);
|
||||
node.OnClicked = (button, userData) =>
|
||||
{
|
||||
if (!canSomeoneHearCharacter || !CanIssueOrders) { return false; }
|
||||
if (disableNode || !CanIssueOrders) { return false; }
|
||||
var o = userData as Order;
|
||||
if (o.MustManuallyAssign && characterContext == null)
|
||||
{
|
||||
CreateAssignmentNodes(node);
|
||||
}
|
||||
else if (o.HasOptions)
|
||||
else if (mustSetOptionOrTarget)
|
||||
{
|
||||
NavigateForward(button, userData);
|
||||
}
|
||||
@@ -2270,11 +2294,11 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
var icon = CreateNodeIcon(node.RectTransform, order.SymbolSprite, order.Color,
|
||||
tooltip: order.HasOptions || characterContext != null ? order.Name : order.Name +
|
||||
tooltip: mustSetOptionOrTarget || characterContext != null ? order.Name : order.Name +
|
||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") +
|
||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip"));
|
||||
|
||||
if (!canSomeoneHearCharacter)
|
||||
|
||||
if (disableNode)
|
||||
{
|
||||
node.CanBeFocused = icon.CanBeFocused = false;
|
||||
CreateBlockIcon(node.RectTransform);
|
||||
@@ -2288,11 +2312,7 @@ namespace Barotrauma
|
||||
|
||||
private void CreateOrderOptions(Order order)
|
||||
{
|
||||
// This is largely based on the CreateOrderTargetFrame() method
|
||||
|
||||
Submarine submarine = Character.Controlled != null && Character.Controlled.TeamID == Character.TeamType.Team2 && Submarine.MainSubs.Length > 1 ?
|
||||
Submarine.MainSubs[1] :
|
||||
Submarine.MainSub;
|
||||
Submarine submarine = GetTargetSubmarine();
|
||||
var matchingItems = (itemContext == null && order.MustSetTarget) ? order.GetMatchingItems(submarine, true) : new List<Item>();
|
||||
|
||||
//more than one target item -> create a minimap-like selection with a pic of the sub
|
||||
@@ -2332,7 +2352,7 @@ namespace Barotrauma
|
||||
UserData = submarine
|
||||
};
|
||||
|
||||
List<GUIComponent> optionFrames = new List<GUIComponent>();
|
||||
List<GUIComponent> optionElements = new List<GUIComponent>();
|
||||
foreach (Item item in matchingItems)
|
||||
{
|
||||
var itemTargetFrame = targetFrame.Children.First().FindChild(item);
|
||||
@@ -2353,52 +2373,87 @@ namespace Barotrauma
|
||||
anchor = Anchor.TopRight;
|
||||
}
|
||||
|
||||
var optionFrame = new GUIFrame(
|
||||
new RectTransform(
|
||||
new Point((int)(250 * GUI.Scale), (int)((40 + order.Options.Length * 40) * GUI.Scale)),
|
||||
parent: itemTargetFrame.RectTransform,
|
||||
anchor: anchor),
|
||||
style: "InnerFrame");
|
||||
|
||||
new GUIFrame(
|
||||
new RectTransform(Vector2.One, optionFrame.RectTransform, anchor: Anchor.Center),
|
||||
style: "OuterGlow",
|
||||
color: Color.Black * 0.7f);
|
||||
|
||||
var optionContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f), optionFrame.RectTransform, anchor: Anchor.Center))
|
||||
GUIComponent optionElement;
|
||||
if (order.Options.Length > 1)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
optionElement = new GUIFrame(
|
||||
new RectTransform(
|
||||
new Point((int)(250 * GUI.Scale), (int)((40 + order.Options.Length * 40) * GUI.Scale)),
|
||||
parent: itemTargetFrame.RectTransform,
|
||||
anchor: anchor),
|
||||
style: "InnerFrame");
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), optionContainer.RectTransform), item != null ? item.Name : order.Name);
|
||||
new GUIFrame(
|
||||
new RectTransform(Vector2.One, optionElement.RectTransform, anchor: Anchor.Center),
|
||||
style: "OuterGlow",
|
||||
color: Color.Black * 0.7f);
|
||||
|
||||
for (int i = 0; i < order.Options.Length; i++)
|
||||
{
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
new GUIButton(
|
||||
new RectTransform(new Vector2(1.0f, 0.2f), optionContainer.RectTransform),
|
||||
text: order.OptionNames[i],
|
||||
style: "GUITextBox")
|
||||
{
|
||||
UserData = new Tuple<Order, string>(
|
||||
item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
|
||||
order.Options[i]),
|
||||
Font = GUI.SmallFont,
|
||||
OnClicked = (_, userData) =>
|
||||
var optionContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f), optionElement.RectTransform, anchor: Anchor.Center))
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), optionContainer.RectTransform), item != null ? item.Name : order.Name);
|
||||
|
||||
for (int i = 0; i < order.Options.Length; i++)
|
||||
{
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
new GUIButton(
|
||||
new RectTransform(new Vector2(1.0f, 0.2f), optionContainer.RectTransform),
|
||||
text: order.GetOptionName(i),
|
||||
style: "GUITextBox")
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
var o = userData as Tuple<Order, string>;
|
||||
SetCharacterOrder(characterContext ?? GetCharacterForQuickAssignment(o.Item1), o.Item1, o.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
Keys.None));
|
||||
UserData = new Tuple<Order, string>(
|
||||
item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
|
||||
order.Options[i]),
|
||||
Font = GUI.SmallFont,
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
var o = userData as Tuple<Order, string>;
|
||||
SetCharacterOrder(characterContext ?? GetCharacterForQuickAssignment(o.Item1), o.Item1, o.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
Keys.None));
|
||||
}
|
||||
}
|
||||
optionFrames.Add(optionFrame);
|
||||
else
|
||||
{
|
||||
var userData = new Tuple<Order, string>(item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)), "");
|
||||
optionElement = new GUIButton(
|
||||
new RectTransform(
|
||||
new Point((int)(50 * GUI.Scale)),
|
||||
parent: itemTargetFrame.RectTransform,
|
||||
anchor: anchor),
|
||||
style: null)
|
||||
{
|
||||
UserData = userData,
|
||||
Font = GUI.SmallFont,
|
||||
ToolTip = item?.Name ?? order.Name,
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
var o = userData as Tuple<Order, string>;
|
||||
SetCharacterOrder(characterContext ?? GetCharacterForQuickAssignment(o.Item1), o.Item1, o.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Sprite icon = null;
|
||||
order.MinimapIcons?.TryGetValue(item.Prefab.Identifier, out icon);
|
||||
var colorMultiplier = characters.Any(c => c.CurrentOrder != null &&
|
||||
c.CurrentOrder.Identifier == userData.Item1.Identifier &&
|
||||
c.CurrentOrder.TargetEntity == userData.Item1.TargetEntity) ? 0.5f : 1f;
|
||||
CreateNodeIcon(optionElement.RectTransform, icon ?? order.SymbolSprite, order.Color * colorMultiplier);
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(optionElement, Keys.None));
|
||||
}
|
||||
optionElements.Add(optionElement);
|
||||
}
|
||||
GUI.PreventElementOverlap(optionFrames, clampArea: new Rectangle(10, 10, GameMain.GraphicsWidth - 20, GameMain.GraphicsHeight - 20));
|
||||
GUI.PreventElementOverlap(optionElements, clampArea: new Rectangle(10, 10, GameMain.GraphicsWidth - 20, GameMain.GraphicsHeight - 20));
|
||||
|
||||
var shadow = new GUIFrame(
|
||||
new RectTransform(targetFrame.Rect.Size + new Point((int)(200 * GUI.Scale)), targetFrame.RectTransform, anchor: Anchor.Center),
|
||||
@@ -2420,7 +2475,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i < order.Options.Length; i++)
|
||||
{
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
CreateOrderOptionNode(nodeSize, commandFrame.RectTransform, offsets[offsetIndex++].ToPoint(), o, order.Options[i], order.OptionNames[i], (i + 1) % 10),
|
||||
CreateOrderOptionNode(nodeSize, commandFrame.RectTransform, offsets[offsetIndex++].ToPoint(), o, order.Options[i], order.GetOptionName(i), (i + 1) % 10),
|
||||
Keys.D0 + (i + 1) % 10));
|
||||
}
|
||||
}
|
||||
@@ -2428,12 +2483,7 @@ namespace Barotrauma
|
||||
|
||||
private GUIButton CreateOrderOptionNode(Point size, RectTransform parent, Point offset, Order order, string option, string optionName, int hotkey)
|
||||
{
|
||||
var node = new GUIButton(
|
||||
new RectTransform(size, parent: parent, anchor: Anchor.Center)
|
||||
{
|
||||
AbsoluteOffset = offset
|
||||
},
|
||||
style: null)
|
||||
var node = new GUIButton(new RectTransform(size, parent: parent, anchor: Anchor.Center), style: null)
|
||||
{
|
||||
UserData = new Tuple<Order, string>(order, option),
|
||||
OnClicked = (_, userData) =>
|
||||
@@ -2445,6 +2495,8 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
};
|
||||
node.RectTransform.MoveOverTime(offset, CommandNodeAnimDuration);
|
||||
|
||||
GUIImage icon = null;
|
||||
if (order.Prefab.OptionSprites.TryGetValue(option, out Sprite sprite))
|
||||
{
|
||||
@@ -2472,40 +2524,47 @@ namespace Barotrauma
|
||||
new Tuple<Order, string>(node.UserData as Order, null) :
|
||||
node.UserData as Tuple<Order, string>;
|
||||
var characters = GetCharactersForManualAssignment(order.Item1);
|
||||
if (characters.Count < 1) { return; }
|
||||
if (characters.None()) { return; }
|
||||
|
||||
if (!(optionNodes.Find(n => n.Item1 == node) is Tuple<GUIComponent, Keys> optionNode) || !optionNodes.Remove(optionNode))
|
||||
{
|
||||
shortcutNodes.Remove(node);
|
||||
};
|
||||
RemoveOptionNodes();
|
||||
|
||||
if (returnNode != null)
|
||||
{
|
||||
returnNode.Children.ForEach(child => child.Visible = false);
|
||||
returnNode.Visible = false;
|
||||
historyNodes.Push(returnNode);
|
||||
}
|
||||
SetReturnNode(centerNode, new Point(
|
||||
(int)(node.RectTransform.AbsoluteOffset.X * -returnNodeDistanceModifier),
|
||||
(int)(node.RectTransform.AbsoluteOffset.Y * -returnNodeDistanceModifier)));
|
||||
SetReturnNode(centerNode, new Point(0, (int)(returnNodeDistanceModifier * nodeDistance)));
|
||||
|
||||
if (targetFrame == null || !targetFrame.Visible)
|
||||
{
|
||||
SetCenterNode(node as GUIButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
var clickedOptionNode = new GUIButton(
|
||||
if (string.IsNullOrEmpty(order.Item2))
|
||||
{
|
||||
SetCenterNode(node as GUIButton, resetAnchor: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var clickedOptionNode = new GUIButton(
|
||||
new RectTransform(centerNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center),
|
||||
style: null)
|
||||
{
|
||||
UserData = node.UserData
|
||||
};
|
||||
if (order.Item1.Prefab.OptionSprites.TryGetValue(order.Item2, out Sprite sprite))
|
||||
{
|
||||
CreateNodeIcon(clickedOptionNode.RectTransform, sprite, order.Item1.Color, tooltip: order.Item2);
|
||||
{
|
||||
UserData = node.UserData
|
||||
};
|
||||
if (order.Item1.Prefab.OptionSprites.TryGetValue(order.Item2, out Sprite sprite))
|
||||
{
|
||||
CreateNodeIcon(clickedOptionNode.RectTransform, sprite, order.Item1.Color, tooltip: order.Item2);
|
||||
}
|
||||
SetCenterNode(clickedOptionNode);
|
||||
node = null;
|
||||
}
|
||||
SetCenterNode(clickedOptionNode);
|
||||
node = null;
|
||||
targetFrame.Visible = false;
|
||||
}
|
||||
if (shortcutCenterNode != null)
|
||||
@@ -2514,21 +2573,36 @@ namespace Barotrauma
|
||||
shortcutCenterNode = null;
|
||||
}
|
||||
|
||||
var needToExpand = characters.Count > assignmentNodeMaxCount + 1;
|
||||
var nodeCount = needToExpand ? assignmentNodeMaxCount + 1 : characters.Count;
|
||||
var extraNodeDistance = Math.Max(nodeCount - 6, 0) * (GUI.Scale * 30);
|
||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance + extraNodeDistance,
|
||||
GetCircumferencePointCount(nodeCount),
|
||||
GetFirstNodeAngle(nodeCount));
|
||||
|
||||
var i = 0;
|
||||
var assignmentNodeCount = (needToExpand ? nodeCount - 1 : nodeCount);
|
||||
for (; i < assignmentNodeCount; i++)
|
||||
var characterCount = characters.Count;
|
||||
int hotkey = 1;
|
||||
Vector2[] offsets;
|
||||
var needToExpand = characterCount > 10;
|
||||
if (characterCount > 5)
|
||||
{
|
||||
CreateAssignmentNode(order, characters[i], offsets[i].ToPoint(), (i + 1) % 10);
|
||||
// First ring
|
||||
var charactersOnFirstRing = needToExpand ? 5 : (int)Math.Floor(characterCount / 2f);
|
||||
offsets = GetAssignmentNodeOffsets(charactersOnFirstRing);
|
||||
for (int i = 0; i < charactersOnFirstRing; i++)
|
||||
{
|
||||
CreateAssignmentNode(order, characters[i], offsets[i].ToPoint(), hotkey++ % 10);
|
||||
}
|
||||
// Second ring
|
||||
var charactersOnSecondRing = needToExpand ? 4 : characterCount - charactersOnFirstRing;
|
||||
offsets = GetAssignmentNodeOffsets(needToExpand ? 5 : charactersOnSecondRing, false);
|
||||
for (int i = 0; i < charactersOnSecondRing; i++)
|
||||
{
|
||||
CreateAssignmentNode(order, characters[charactersOnFirstRing + i], offsets[i].ToPoint(), hotkey++ % 10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets = GetAssignmentNodeOffsets(characterCount);
|
||||
for (int i = 0; i < characterCount; i++)
|
||||
{
|
||||
CreateAssignmentNode(order, characters[i], offsets[i].ToPoint(), hotkey++ % 10);
|
||||
}
|
||||
}
|
||||
|
||||
int hotkey;
|
||||
if (!needToExpand)
|
||||
{
|
||||
hotkey = optionNodes.Count + 1;
|
||||
@@ -2539,12 +2613,14 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
extraOptionCharacters.Clear();
|
||||
extraOptionCharacters.AddRange(characters.GetRange(i, characters.Count - i));
|
||||
// Sort expanded assignment nodes by characters' jobs and then by their names
|
||||
extraOptionCharacters.AddRange(characters.GetRange(hotkey - 1, characterCount - (hotkey - 1))
|
||||
.OrderBy(c => c?.Info?.Job?.Name).ThenBy(c => c?.Info?.DisplayName));
|
||||
|
||||
expandNode = new GUIButton(
|
||||
new RectTransform(nodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center)
|
||||
new RectTransform(assignmentNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center)
|
||||
{
|
||||
AbsoluteOffset = offsets[i].ToPoint()
|
||||
AbsoluteOffset = offsets.Last().ToPoint()
|
||||
},
|
||||
style: null)
|
||||
{
|
||||
@@ -2560,6 +2636,22 @@ namespace Barotrauma
|
||||
returnNodeHotkey = Keys.D0 + hotkey % 10;
|
||||
}
|
||||
|
||||
private Vector2[] GetAssignmentNodeOffsets(int characters, bool firstRing = true)
|
||||
{
|
||||
var nodeDistance = 1.8f * this.nodeDistance;
|
||||
var nodePositionsOnEachSide = characters % 2 > 0 ? 7 : 6;
|
||||
var nodeCountForCalculation = 2 * nodePositionsOnEachSide + 2;
|
||||
var offsets = MathUtils.GetPointsOnCircumference(firstRing ? new Vector2(0f, 0.5f * nodeDistance) : Vector2.Zero,
|
||||
nodeDistance, nodeCountForCalculation, MathHelper.ToRadians(180f + 360f / nodeCountForCalculation));
|
||||
var emptySpacesPerSide = (nodePositionsOnEachSide - characters) / 2;
|
||||
var offsetsInUse = new Vector2[nodePositionsOnEachSide - 2 * emptySpacesPerSide];
|
||||
for (int i = 0; i < offsetsInUse.Length; i++)
|
||||
{
|
||||
offsetsInUse[i] = offsets[i + emptySpacesPerSide];
|
||||
}
|
||||
return offsetsInUse;
|
||||
}
|
||||
|
||||
private bool ExpandAssignmentNodes(GUIButton node, object userData)
|
||||
{
|
||||
node.OnClicked = (button, _) =>
|
||||
@@ -2569,60 +2661,86 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
|
||||
var order = userData as Tuple<Order, string>;
|
||||
// TODO: The value 100 should be determined by how large the inner circle is
|
||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, (nodeDistance + GUI.Scale * 100) * 1.55f,
|
||||
GetCircumferencePointCount(extraOptionCharacters.Count),
|
||||
GetFirstNodeAngle(extraOptionCharacters.Count));
|
||||
var availableNodePositions = 20;
|
||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, 2.7f * this.nodeDistance, availableNodePositions,
|
||||
firstAngle: MathHelper.ToRadians(-90f - ((extraOptionCharacters.Count - 1) * 0.5f * (360f / availableNodePositions))));
|
||||
for (int i = 0; i < extraOptionCharacters.Count; i++)
|
||||
{
|
||||
CreateAssignmentNode(order, extraOptionCharacters[i], offsets[i].ToPoint(), -1);
|
||||
CreateAssignmentNode(userData as Tuple<Order, string>, extraOptionCharacters[i], offsets[i].ToPoint(), -1, nameLabelScale: 1.15f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CreateAssignmentNode(Tuple<Order, string> order, Character character, Point offset, int hotkey)
|
||||
private void CreateAssignmentNode(Tuple<Order, string> order, Character character, Point offset, int hotkey, float nameLabelScale = 1f)
|
||||
{
|
||||
// Button
|
||||
var node = new GUIButton(
|
||||
new RectTransform(nodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center),
|
||||
new RectTransform(assignmentNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center),
|
||||
style: null)
|
||||
{
|
||||
OnClicked = (button, userData) =>
|
||||
UserData = character,
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
SetCharacterOrder(character, order.Item1, order.Item2, Character.Controlled);
|
||||
SetCharacterOrder(userData as Character, order.Item1, order.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
node.RectTransform.MoveOverTime(offset, CommandNodeAnimDuration);
|
||||
// Container
|
||||
var icon = new GUIImage(
|
||||
new RectTransform(new Vector2(1.2f), node.RectTransform, anchor: Anchor.Center),
|
||||
"CommandNodeContainer",
|
||||
scaleToFit: true)
|
||||
{
|
||||
Color = character.Info.Job.Prefab.UIColor * nodeColorMultiplier,
|
||||
HoverColor = character.Info.Job.Prefab.UIColor,
|
||||
PressedColor = character.Info.Job.Prefab.UIColor,
|
||||
SelectedColor = character.Info.Job.Prefab.UIColor,
|
||||
UserData = "colorsource"
|
||||
};
|
||||
// Character icon
|
||||
new GUICustomComponent(
|
||||
new RectTransform(Vector2.One, node.RectTransform),
|
||||
(spriteBatch, _) =>
|
||||
{
|
||||
character.Info.DrawJobIcon(spriteBatch,
|
||||
new Rectangle((int)(node.Rect.X + node.Rect.Width * 0.5f), (int)(node.Rect.Y + node.Rect.Height * 0.1f), (int)(node.Rect.Width * 0.6f), (int)(node.Rect.Height * 0.8f)));
|
||||
character.Info.DrawIcon(spriteBatch, new Vector2(node.Rect.X + node.Rect.Width * 0.35f, node.Center.Y), node.Rect.Size.ToVector2() * 0.7f);
|
||||
|
||||
})
|
||||
var jobColor = character.Info?.Job?.Prefab?.UIColor ?? Color.White;
|
||||
|
||||
// Order icon
|
||||
GUIImage orderIcon;
|
||||
if (character.CurrentOrder != null && !character.CurrentOrder.Identifier.Equals("dismissed"))
|
||||
{
|
||||
ToolTip = character.Info.DisplayName + " (" + character.Info.Job.Name + ")"
|
||||
orderIcon = new GUIImage(new RectTransform(new Vector2(1.2f), node.RectTransform, anchor: Anchor.Center), character.CurrentOrder.SymbolSprite, scaleToFit: true);
|
||||
var tooltip = character.CurrentOrder.Name;
|
||||
if (!string.IsNullOrWhiteSpace(character.CurrentOrderOption)) { tooltip += " (" + character.CurrentOrder.GetOptionName(character.CurrentOrderOption) + ")"; };
|
||||
orderIcon.ToolTip = tooltip;
|
||||
}
|
||||
else
|
||||
{
|
||||
orderIcon = new GUIImage(new RectTransform(new Vector2(1.2f), node.RectTransform, anchor: Anchor.Center), "CommandIdleNode", scaleToFit: true);
|
||||
}
|
||||
orderIcon.Color = jobColor * nodeColorMultiplier;
|
||||
orderIcon.HoverColor = jobColor;
|
||||
orderIcon.PressedColor = jobColor;
|
||||
orderIcon.SelectedColor = jobColor;
|
||||
orderIcon.UserData = "colorsource";
|
||||
|
||||
// Name label
|
||||
var width = (int)(nameLabelScale * nodeSize.X);
|
||||
var font = GUI.SmallFont;
|
||||
var nameLabel = new GUITextBlock(
|
||||
new RectTransform(new Point(width, 0), parent: node.RectTransform, anchor: Anchor.TopCenter, pivot: Pivot.BottomCenter)
|
||||
{
|
||||
RelativeOffset = new Vector2(0f, -0.25f)
|
||||
},
|
||||
ToolBox.LimitString(character.Info?.DisplayName, font, width), textColor: jobColor * nodeColorMultiplier, font: font, textAlignment: Alignment.Center, style: null)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
ForceUpperCase = true,
|
||||
HoverTextColor = jobColor
|
||||
};
|
||||
|
||||
if (character.Info?.Job?.Prefab?.IconSmall is Sprite smallJobIcon)
|
||||
{
|
||||
// Job icon
|
||||
new GUIImage(
|
||||
new RectTransform(new Vector2(0.4f), node.RectTransform, anchor: Anchor.TopCenter, pivot: Pivot.Center)
|
||||
{
|
||||
RelativeOffset = new Vector2(0.0f, -((orderIcon.RectTransform.RelativeSize.Y - 1) / 2))
|
||||
},
|
||||
smallJobIcon, scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Color = jobColor,
|
||||
HoverColor = jobColor
|
||||
};
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
bool canHear = true;
|
||||
#else
|
||||
@@ -2630,7 +2748,7 @@ namespace Barotrauma
|
||||
#endif
|
||||
if (!canHear)
|
||||
{
|
||||
node.CanBeFocused = icon.CanBeFocused = false;
|
||||
node.CanBeFocused = orderIcon.CanBeFocused = false;
|
||||
CreateBlockIcon(node.RectTransform);
|
||||
}
|
||||
if (hotkey >= 0)
|
||||
@@ -2705,8 +2823,9 @@ namespace Barotrauma
|
||||
|
||||
private void CreateBlockIcon(RectTransform parent)
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, parent, anchor: Anchor.Center), cancelIcon, scaleToFit: true)
|
||||
new GUIImage(new RectTransform(new Vector2(0.9f), parent, anchor: Anchor.Center), cancelIcon, scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Color = GUI.Style.Red * nodeColorMultiplier,
|
||||
HoverColor = GUI.Style.Red
|
||||
};
|
||||
@@ -2749,6 +2868,7 @@ namespace Barotrauma
|
||||
private bool TryGetBreachedHullAtHoveredWall(out Hull breachedHull)
|
||||
{
|
||||
breachedHull = null;
|
||||
// Based on the IsValidTarget() method of AIObjectiveFixLeaks class
|
||||
List<Gap> leaks = Gap.GapList.FindAll(g =>
|
||||
g != null && g.ConnectedWall != null && g.ConnectedDoor == null && g.Open > 0 && g.linkedTo.Any(l => l != null) &&
|
||||
g.Submarine != null && (Character.Controlled != null && g.Submarine.TeamID == Character.Controlled.TeamID && g.Submarine.Info.IsPlayer));
|
||||
@@ -2765,6 +2885,25 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
private Submarine GetTargetSubmarine()
|
||||
{
|
||||
var sub = Submarine.MainSub;
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
// Pick the second main sub when we have two teams (in combat mission)
|
||||
if (Character.Controlled.TeamID == Character.TeamType.Team2 && Submarine.MainSubs.Length > 1)
|
||||
{
|
||||
sub = Submarine.MainSubs[1];
|
||||
}
|
||||
// Target current submarine (likely a shuttle) when undocked from the main sub
|
||||
if (Character.Controlled.Submarine is Submarine currentSub && currentSub != sub && currentSub.TeamID == Character.Controlled.TeamID && !currentSub.IsConnectedTo(sub))
|
||||
{
|
||||
sub = currentSub;
|
||||
}
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
|
||||
#region Crew Member Assignment Logic
|
||||
|
||||
private Character GetCharacterForQuickAssignment(Order order)
|
||||
@@ -2776,7 +2915,7 @@ namespace Barotrauma
|
||||
{
|
||||
return operatingCharacter;
|
||||
}
|
||||
return GetCharactersSortedForOrder(order, false).FirstOrDefault();
|
||||
return GetCharactersSortedForOrder(order, false).FirstOrDefault() ?? Character.Controlled;
|
||||
}
|
||||
|
||||
private List<Character> GetCharactersForManualAssignment(Order order)
|
||||
@@ -2784,6 +2923,11 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (Character.Controlled == null) { return new List<Character>(); }
|
||||
#endif
|
||||
if (order.Identifier == dismissedOrderPrefab.Identifier)
|
||||
{
|
||||
return characters.FindAll(c => c.CurrentOrder != null && c.CurrentOrder.Identifier != dismissedOrderPrefab.Identifier)
|
||||
.OrderBy(c => c.Info.DisplayName).ToList();
|
||||
}
|
||||
return GetCharactersSortedForOrder(order, order.Identifier != "follow").ToList();
|
||||
}
|
||||
|
||||
@@ -2822,10 +2966,7 @@ namespace Barotrauma
|
||||
|
||||
if (canIssueOrders)
|
||||
{
|
||||
//report buttons are hidden when accessing another character's inventory
|
||||
ReportButtonFrame.Visible = !Character.Controlled.ShouldLockHud() &&
|
||||
(Character.Controlled?.SelectedCharacter?.Inventory == null ||
|
||||
!Character.Controlled.SelectedCharacter.CanInventoryBeAccessed);
|
||||
ReportButtonFrame.Visible = !Character.Controlled.ShouldLockHud();
|
||||
if (!ReportButtonFrame.Visible) { return; }
|
||||
|
||||
var reportButtonParent = ChatBox ?? GameMain.Client?.ChatBox;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
||||
: base(preset, param)
|
||||
{
|
||||
int buttonHeight = (int)(HUDLayoutSettings.ButtonAreaTop.Height * 0.7f);
|
||||
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(HUDLayoutSettings.ButtonAreaTop.Right - 200, HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonHeight / 2, 200, buttonHeight), GUICanvas.Instance),
|
||||
endRoundButton = new GUIButton(HUDLayoutSettings.ToRectTransform(new Rectangle(HUDLayoutSettings.ButtonAreaTop.Right - GUI.IntScale(200), HUDLayoutSettings.ButtonAreaTop.Center.Y - buttonHeight / 2, GUI.IntScale(200), buttonHeight), GUICanvas.Instance),
|
||||
TextManager.Get("EndRound"), textAlignment: Alignment.Center)
|
||||
{
|
||||
Font = GUI.SmallFont,
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace Barotrauma.Tutorials
|
||||
// GameMain.GameSession.CrewManager.HighlightOrderButton(captain_security, "operateweapons", highlightColor, new Vector2(5, 5));
|
||||
HighlightOrderOption("fireatwill");
|
||||
}
|
||||
while (!HasOrder(captain_security, "operateweapons", "fireatwill"));
|
||||
while (!HasOrder(captain_security, "operateweapons"));
|
||||
RemoveCompletedObjective(segments[2]);
|
||||
yield return new WaitForSeconds(4f, false);
|
||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Command));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
@@ -315,6 +315,7 @@ namespace Barotrauma.Tutorials
|
||||
yield return new WaitForSeconds(2f, false);
|
||||
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
||||
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
||||
((EnemyAIController)officer_hammerhead.AIController).StayInsideLevel = false;
|
||||
officer_hammerhead.AIController.SelectTarget(officer.AiTarget);
|
||||
SetHighlight(officer_coilgunPeriscope, true);
|
||||
float originalDistance = Vector2.Distance(officer_coilgunPeriscope.WorldPosition, officer_hammerheadSpawnPos);
|
||||
@@ -329,7 +330,13 @@ namespace Barotrauma.Tutorials
|
||||
if (distance > originalDistance)
|
||||
{
|
||||
// Ensure that the Hammerhead targets the player
|
||||
officer.AiTarget.SoundRange = float.MaxValue;
|
||||
officer.AiTarget.SightRange = float.MaxValue;
|
||||
officer_hammerhead.AIController.SelectTarget(officer.AiTarget);
|
||||
if ((officer_hammerhead.AIController as EnemyAIController)?.SelectedTargetingParams != null)
|
||||
{
|
||||
((EnemyAIController)officer_hammerhead.AIController).SelectedTargetingParams.ReactDistance = 5000.0f;
|
||||
}
|
||||
/*var ai = officer_hammerhead.AIController as EnemyAIController;
|
||||
ai.sight = 2.0f;*/
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
@@ -515,7 +515,7 @@ namespace Barotrauma.Tutorials
|
||||
height += (int)GUI.Font.MeasureString(title).Y + (int)(150 * GUI.Scale);
|
||||
}
|
||||
|
||||
var background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), style: null, Color.Black * 0.5f);
|
||||
var background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
var infoBlock = new GUIFrame(new RectTransform(new Point(width, height), background.RectTransform, anchor));
|
||||
infoBlock.Flash(GUI.Style.Green);
|
||||
|
||||
@@ -32,7 +32,9 @@ namespace Barotrauma
|
||||
SoundPlayer.OverrideMusicDuration = 18.0f;
|
||||
}
|
||||
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker")
|
||||
GUIFrame background = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(Vector2.One, background.RectTransform, Anchor.Center), style: null)
|
||||
{
|
||||
UserData = "roundsummary"
|
||||
};
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private const int inventoryHotkeyCount = 10;
|
||||
|
||||
public void SetDefaultBindings(XDocument doc = null, bool legacy = false)
|
||||
{
|
||||
keyMapping = new KeyOrMouse[Enum.GetNames(typeof(InputType)).Length];
|
||||
@@ -100,6 +102,13 @@ namespace Barotrauma
|
||||
keyMapping[(int)InputType.Select] = new KeyOrMouse(MouseButton.PrimaryMouse);
|
||||
// shoot and deselect are handled in CheckBindings() so that we don't override the legacy settings.
|
||||
}
|
||||
|
||||
inventoryKeyMapping = new KeyOrMouse[inventoryHotkeyCount];
|
||||
for (int i = 0; i < inventoryKeyMapping.Length; i++)
|
||||
{
|
||||
inventoryKeyMapping[i] = new KeyOrMouse(Keys.D0 + (i + 1) % 10);
|
||||
}
|
||||
|
||||
if (doc != null)
|
||||
{
|
||||
LoadControls(doc);
|
||||
@@ -179,6 +188,26 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadInventoryKeybinds(XElement element)
|
||||
{
|
||||
for (int i = 0; i < inventoryKeyMapping.Length; i++)
|
||||
{
|
||||
XAttribute attribute = element.Attributes().ElementAt(i);
|
||||
if (int.TryParse(attribute.Value.ToString(), out int mouseButtonInt))
|
||||
{
|
||||
inventoryKeyMapping[i] = new KeyOrMouse((MouseButton)mouseButtonInt);
|
||||
}
|
||||
else if (Enum.TryParse(attribute.Value.ToString(), true, out MouseButton mouseButton))
|
||||
{
|
||||
inventoryKeyMapping[i] = new KeyOrMouse(mouseButton);
|
||||
}
|
||||
else if (Enum.TryParse(attribute.Value.ToString(), true, out Keys key))
|
||||
{
|
||||
inventoryKeyMapping[i] = new KeyOrMouse(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadControls(XDocument doc)
|
||||
{
|
||||
XElement keyMapping = doc.Root.Element("keymapping");
|
||||
@@ -186,6 +215,12 @@ namespace Barotrauma
|
||||
{
|
||||
LoadKeyBinds(keyMapping);
|
||||
}
|
||||
|
||||
XElement inventoryKeyMapping = doc.Root.Element("inventorykeymapping");
|
||||
if (inventoryKeyMapping != null)
|
||||
{
|
||||
LoadInventoryKeybinds(inventoryKeyMapping);
|
||||
}
|
||||
}
|
||||
|
||||
public KeyOrMouse KeyBind(InputType inputType)
|
||||
@@ -195,25 +230,14 @@ namespace Barotrauma
|
||||
|
||||
public string KeyBindText(InputType inputType)
|
||||
{
|
||||
KeyOrMouse bind = keyMapping[(int)inputType];
|
||||
|
||||
if (bind.MouseButton != MouseButton.None)
|
||||
{
|
||||
switch (bind.MouseButton)
|
||||
{
|
||||
case MouseButton.PrimaryMouse:
|
||||
return PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse");
|
||||
case MouseButton.SecondaryMouse:
|
||||
return PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse");
|
||||
default:
|
||||
return TextManager.Get("input." + bind.MouseButton.ToString().ToLowerInvariant());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return bind.ToString();
|
||||
return keyMapping[(int)inputType].Name;
|
||||
}
|
||||
|
||||
|
||||
public KeyOrMouse InventoryKeyBind(int index)
|
||||
{
|
||||
return inventoryKeyMapping[index];
|
||||
}
|
||||
|
||||
private GUIListBox contentPackageList;
|
||||
|
||||
private bool ChangeSliderText(GUIScrollBar scrollBar, float barScroll)
|
||||
@@ -259,7 +283,8 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f);
|
||||
settingsFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, settingsFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
var settingsFrameContent = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.8f), settingsFrame.RectTransform, Anchor.Center));
|
||||
settingsHolder = settingsFrameContent.RectTransform;
|
||||
}
|
||||
@@ -292,6 +317,25 @@ namespace Barotrauma
|
||||
ButtonEnabled = ContentPackage.List.Count(cp => cp.CorePackage) > 1
|
||||
};
|
||||
|
||||
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftPanel.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("serverlog.filter"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
|
||||
var searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font, createClearButton: true);
|
||||
filterContainer.RectTransform.MinSize = searchBox.RectTransform.MinSize;
|
||||
searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
|
||||
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
|
||||
searchBox.OnTextChanged += (textBox, text) =>
|
||||
{
|
||||
foreach (GUIComponent child in contentPackageList.Content.Children)
|
||||
{
|
||||
if (!(child.UserData is ContentPackage cp)) { continue; }
|
||||
child.Visible = string.IsNullOrEmpty(text) ? true : cp.Name.ToLower().Contains(text.ToLower());
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.70f), leftPanel.RectTransform))
|
||||
{
|
||||
OnSelected = (gc, obj) => false,
|
||||
@@ -551,6 +595,37 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
|
||||
GUITickBox textureCompressionTickBox = new GUITickBox(new RectTransform(tickBoxScale, leftColumn.RectTransform), TextManager.Get("EnableTextureCompression"))
|
||||
{
|
||||
ToolTip = TextManager.Get("EnableTextureCompressionToolTip"),
|
||||
OnSelected = (GUITickBox box) =>
|
||||
{
|
||||
if (box.Selected == TextureCompressionEnabled) { return true; }
|
||||
bool prevTextureCompressionEnabled = TextureCompressionEnabled;
|
||||
TextureCompressionEnabled = box.Selected;
|
||||
|
||||
var msgBox = new GUIMessageBox(
|
||||
TextManager.Get("RestartRequiredLabel"),
|
||||
TextManager.Get("RestartRequiredGeneric"),
|
||||
buttons: new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") });
|
||||
msgBox.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
ApplySettings();
|
||||
GameMain.Instance.Exit();
|
||||
return true;
|
||||
}; msgBox.Buttons[1].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
TextureCompressionEnabled = prevTextureCompressionEnabled;
|
||||
box.Selected = prevTextureCompressionEnabled;
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
|
||||
return true;
|
||||
},
|
||||
Selected = TextureCompressionEnabled
|
||||
};
|
||||
|
||||
GUITickBox pauseOnFocusLostBox = new GUITickBox(new RectTransform(tickBoxScale, leftColumn.RectTransform),
|
||||
TextManager.Get("PauseOnFocusLost"))
|
||||
{
|
||||
@@ -612,7 +687,8 @@ namespace Barotrauma
|
||||
{
|
||||
ChangeSliderText(scrollBar, barScroll);
|
||||
LightMapScale = MathHelper.Lerp(0.2f, 1.0f, barScroll);
|
||||
UnsavedSettings = true; return true;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
},
|
||||
Step = 0.25f
|
||||
};
|
||||
@@ -1113,6 +1189,24 @@ namespace Barotrauma
|
||||
keyBox.SelectedColor = Color.Gold * 0.3f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventoryHotkeyCount; i++)
|
||||
{
|
||||
var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f), ((i + 1) <= inventoryHotkeyCount / 2 ? inputColumnLeft : inputColumnRight).RectTransform))
|
||||
{ Stretch = true, IsHorizontal = true, RelativeSpacing = 0.01f, Color = new Color(12, 14, 15, 215) };
|
||||
var inputName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), inputContainer.RectTransform, Anchor.TopLeft) { MinSize = new Point(100, 0) },
|
||||
TextManager.GetWithVariable("inventoryslotkeybind", "[slotnumber]", (i + 1).ToString()), font: GUI.SmallFont)
|
||||
{ ForceUpperCase = true };
|
||||
inputNameBlocks.Add(inputName);
|
||||
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), inputContainer.RectTransform),
|
||||
text: inventoryKeyMapping[i].Name, font: GUI.SmallFont, style: "GUITextBoxNoIcon")
|
||||
{
|
||||
UserData = i
|
||||
};
|
||||
keyBox.Text = ToolBox.LimitString(keyBox.Text, keyBox.Font, (int)(keyBox.Rect.Width - keyBox.Padding.X - keyBox.Padding.Z));
|
||||
keyBox.OnSelected += InventoryKeyBoxSelected;
|
||||
keyBox.SelectedColor = Color.Gold * 0.3f;
|
||||
}
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(inputNameBlocks);
|
||||
|
||||
var resetControlsArea = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.07f), controlsLayoutGroup.RectTransform), style: null);
|
||||
@@ -1380,7 +1474,13 @@ namespace Barotrauma
|
||||
private void KeyBoxSelected(GUITextBox textBox, Keys key)
|
||||
{
|
||||
textBox.Text = "";
|
||||
CoroutineManager.StartCoroutine(WaitForKeyPress(textBox));
|
||||
CoroutineManager.StartCoroutine(WaitForKeyPress(textBox, keyMapping));
|
||||
}
|
||||
|
||||
private void InventoryKeyBoxSelected(GUITextBox textBox, Keys key)
|
||||
{
|
||||
textBox.Text = "";
|
||||
CoroutineManager.StartCoroutine(WaitForKeyPress(textBox, inventoryKeyMapping));
|
||||
}
|
||||
|
||||
private void ResetControls(bool legacy)
|
||||
@@ -1476,7 +1576,7 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitForKeyPress(GUITextBox keyBox)
|
||||
private IEnumerable<object> WaitForKeyPress(GUITextBox keyBox, KeyOrMouse[] keyArray)
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
@@ -1500,42 +1600,43 @@ namespace Barotrauma
|
||||
|
||||
if (PlayerInput.LeftButtonClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.LeftMouse);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.LeftMouse);
|
||||
}
|
||||
else if (PlayerInput.RightButtonClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.RightMouse);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.RightMouse);
|
||||
}
|
||||
else if (PlayerInput.MidButtonClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.MiddleMouse);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.MiddleMouse);
|
||||
}
|
||||
else if (PlayerInput.Mouse4ButtonClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.MouseButton4);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.MouseButton4);
|
||||
}
|
||||
else if (PlayerInput.Mouse5ButtonClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.MouseButton5);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.MouseButton5);
|
||||
}
|
||||
else if (PlayerInput.MouseWheelUpClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.MouseWheelUp);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.MouseWheelUp);
|
||||
}
|
||||
else if (PlayerInput.MouseWheelDownClicked())
|
||||
{
|
||||
keyMapping[keyIndex] = new KeyOrMouse(MouseButton.MouseWheelDown);
|
||||
keyArray[keyIndex] = new KeyOrMouse(MouseButton.MouseWheelDown);
|
||||
}
|
||||
else if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0)
|
||||
{
|
||||
Keys key = PlayerInput.GetKeyboardState.GetPressedKeys()[0];
|
||||
keyMapping[keyIndex] = new KeyOrMouse(key);
|
||||
keyArray[keyIndex] = new KeyOrMouse(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
keyBox.Text = KeyBindText((InputType)keyIndex);
|
||||
|
||||
keyBox.Text = keyArray[keyIndex].Name;
|
||||
keyBox.Text = ToolBox.LimitString(keyBox.Text, keyBox.Font, keyBox.Rect.Width);
|
||||
|
||||
keyBox.Deselect();
|
||||
|
||||
@@ -354,7 +354,6 @@ namespace Barotrauma
|
||||
break;
|
||||
case Layout.Right:
|
||||
{
|
||||
int extraOffset = 0;
|
||||
int x = HUDLayoutSettings.InventoryAreaLower.Right;
|
||||
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing;
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
@@ -371,17 +370,18 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
int lowerX = x;
|
||||
int personalSlotY = GameMain.GraphicsHeight - bottomOffset * 2 - Spacing * 2 - (int)(!GUI.IsFourByThree() ? UnequippedIndicator.size.Y * UIScale * IndicatorScaleAdjustment : UnequippedIndicator.size.Y * UIScale * IndicatorScaleAdjustment * 2f);
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - extraOffset - Spacing * 2);
|
||||
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
|
||||
personalSlotX -= slots[i].Rect.Width + Spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset);
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
x += slots[i].Rect.Width + Spacing;
|
||||
}
|
||||
}
|
||||
@@ -391,7 +391,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!HideSlot(i)) continue;
|
||||
x -= slots[i].Rect.Width + Spacing;
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset);
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -399,12 +399,14 @@ namespace Barotrauma
|
||||
{
|
||||
int x = HUDLayoutSettings.InventoryAreaLower.X;
|
||||
int personalSlotX = x;
|
||||
int personalSlotY = GameMain.GraphicsHeight - bottomOffset * 2 - Spacing * 2 - (int)(!GUI.IsFourByThree() ? UnequippedIndicator.size.Y * UIScale * IndicatorScaleAdjustment : UnequippedIndicator.size.Y * UIScale * IndicatorScaleAdjustment * 2f);
|
||||
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - Spacing * 2);
|
||||
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
|
||||
personalSlotX += slots[i].Rect.Width + Spacing;
|
||||
}
|
||||
else
|
||||
@@ -523,8 +525,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (Items[i] != null && Items[i] != draggingItem && Character.Controlled?.Inventory == this &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen &&
|
||||
slots[i].QuickUseKey != Keys.None && PlayerInput.KeyHit(slots[i].QuickUseKey))
|
||||
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(slots[i].InventoryKeyIndex))
|
||||
{
|
||||
QuickUseItem(Items[i], true, false, true);
|
||||
}
|
||||
@@ -782,21 +783,16 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void AssignQuickUseNumKeys()
|
||||
public void AssignQuickUseNumKeys()
|
||||
{
|
||||
int num = 1;
|
||||
int keyBindIndex = 0;
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
{
|
||||
if (HideSlot(i))
|
||||
{
|
||||
slots[i].QuickUseKey = Keys.None;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HideSlot(i)) continue;
|
||||
if (SlotTypes[i] == InvSlotType.Any)
|
||||
{
|
||||
slots[i].QuickUseKey = Keys.D0 + num % 10;
|
||||
num++;
|
||||
slots[i].InventoryKeyIndex = keyBindIndex;
|
||||
keyBindIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -819,16 +815,21 @@ namespace Barotrauma
|
||||
{
|
||||
if (item.Container == null || character.Inventory.FindIndex(item.Container) == -1) // Not a subinventory in the character's inventory
|
||||
{
|
||||
return item.ParentInventory is CharacterInventory ?
|
||||
QuickUseAction.TakeFromCharacter : QuickUseAction.TakeFromContainer;
|
||||
if (character.SelectedItems.Any(i => i?.OwnInventory != null && i.OwnInventory.CanBePut(item)))
|
||||
{
|
||||
return QuickUseAction.PutToEquippedItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
return item.ParentInventory is CharacterInventory ? QuickUseAction.TakeFromCharacter : QuickUseAction.TakeFromContainer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var selectedContainer = character.SelectedConstruction?.GetComponent<ItemContainer>();
|
||||
if (selectedContainer != null &&
|
||||
selectedContainer.Inventory != null &&
|
||||
!selectedContainer.Inventory.Locked &&
|
||||
allowInventorySwap)
|
||||
!selectedContainer.Inventory.Locked)
|
||||
{
|
||||
// Move the item from the subinventory to the selected container
|
||||
return QuickUseAction.PutToContainer;
|
||||
@@ -928,24 +929,24 @@ namespace Barotrauma
|
||||
//attempt to put in a free slot first
|
||||
for (int i = capacity - 1; i >= 0; i--)
|
||||
{
|
||||
if (Items[i] != null) continue;
|
||||
if (SlotTypes[i] == InvSlotType.Any || !item.AllowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) continue;
|
||||
if (Items[i] != null) { continue; }
|
||||
if (SlotTypes[i] == InvSlotType.Any || !item.AllowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { continue; }
|
||||
success = TryPutItem(item, i, true, false, Character.Controlled, true);
|
||||
if (success) break;
|
||||
if (success) { break; }
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
for (int i = capacity - 1; i >= 0; i--)
|
||||
{
|
||||
if (SlotTypes[i] == InvSlotType.Any || !item.AllowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) continue;
|
||||
//something else already equipped in the slot, attempt to unequip it
|
||||
if (Items[i] != null && Items[i].AllowedSlots.Contains(InvSlotType.Any))
|
||||
if (SlotTypes[i] == InvSlotType.Any || !item.AllowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { continue; }
|
||||
// something else already equipped in a hand slot, attempt to unequip it so items aren't unnecessarily swapped to it
|
||||
if (Items[i] != null && Items[i].AllowedSlots.Contains(InvSlotType.Any) && (SlotTypes[i] == InvSlotType.LeftHand || SlotTypes[i] == InvSlotType.RightHand))
|
||||
{
|
||||
TryPutItem(Items[i], Character.Controlled, new List<InvSlotType>() { InvSlotType.Any }, true);
|
||||
}
|
||||
success = TryPutItem(item, i, true, false, Character.Controlled, true);
|
||||
if (success) break;
|
||||
if (success) { break; }
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1041,6 +1042,7 @@ namespace Barotrauma
|
||||
prevUIScale != UIScale ||
|
||||
prevHUDScale != GUI.Scale)
|
||||
{
|
||||
CreateSlots();
|
||||
SetSlotPositions(layout);
|
||||
prevUIScale = UIScale;
|
||||
prevHUDScale = GUI.Scale;
|
||||
|
||||
@@ -237,6 +237,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
StopPicking(null);
|
||||
PlaySound(forcedOpen ? ActionType.OnPicked : ActionType.OnUse);
|
||||
if (isOpen) { stuck = MathHelper.Clamp(stuck - StuckReductionOnOpen, 0.0f, 100.0f); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,7 +246,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
base.ClientRead(type, msg, sendingTime);
|
||||
|
||||
bool open = msg.ReadBoolean();
|
||||
bool open = msg.ReadBoolean();
|
||||
bool broken = msg.ReadBoolean();
|
||||
bool forcedOpen = msg.ReadBoolean();
|
||||
SetState(open, isNetworkMessage: true, sendNetworkMessage: false, forcedOpen: forcedOpen);
|
||||
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
@@ -258,6 +260,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
if (isStuck) { OpenState = 0.0f; }
|
||||
IsBroken = broken;
|
||||
PredictedState = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
|
||||
@@ -52,5 +53,13 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
CurrPowerConsumption = powerConsumption;
|
||||
charging = true;
|
||||
timer = Duration;
|
||||
IsActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
if (!IsActive || picker == null || !CanBeAttached() || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled) { return; }
|
||||
if (!IsActive || picker == null || !CanBeAttached(picker) || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled) { return; }
|
||||
|
||||
Vector2 gridPos = picker.Position;
|
||||
Vector2 roundedGridPos = new Vector2(
|
||||
@@ -71,6 +71,8 @@ namespace Barotrauma.Items.Components
|
||||
base.ClientRead(type, msg, sendingTime);
|
||||
bool shouldBeAttached = msg.ReadBoolean();
|
||||
Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle());
|
||||
UInt16 submarineID = msg.ReadUInt16();
|
||||
Submarine sub = Entity.FindEntityByID(submarineID) as Submarine;
|
||||
|
||||
if (!attachable)
|
||||
{
|
||||
@@ -84,6 +86,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Drop(false, null);
|
||||
item.SetTransform(simPosition, 0.0f);
|
||||
item.Submarine = sub;
|
||||
AttachToWall();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
@@ -436,8 +436,7 @@ namespace Barotrauma.Items.Components
|
||||
if (subElement.Attribute("color") != null) color = subElement.GetAttributeColor("color", Color.White);
|
||||
string style = subElement.Attribute("style") == null ?
|
||||
null : subElement.GetAttributeString("style", "");
|
||||
|
||||
GuiFrame = new GUIFrame(RectTransform.Load(subElement, GUI.Canvas, Anchor.Center), style, color);
|
||||
GuiFrame = new GUIFrame(RectTransform.Load(subElement, GUI.Canvas.ItemComponentHolder, Anchor.Center), style, color);
|
||||
DefaultLayout = GUILayoutSettings.Load(subElement);
|
||||
break;
|
||||
case "alternativelayout":
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
private string text;
|
||||
[Serialize("", true, translationTextTag: "Label.", description: "The text displayed in the label."), Editable(100)]
|
||||
[Serialize("", true, translationTextTag: "Label.", description: "The text displayed in the label.", alwaysUseInstanceValues: true), Editable(100)]
|
||||
public string Text
|
||||
{
|
||||
get { return text; }
|
||||
@@ -58,7 +58,7 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
}
|
||||
|
||||
[Editable, Serialize("0,0,0,255", true, description: "The color of the text displayed on the label (R,G,B,A).")]
|
||||
[Editable, Serialize("0,0,0,255", true, description: "The color of the text displayed on the label (R,G,B,A).", alwaysUseInstanceValues: true)]
|
||||
public Color TextColor
|
||||
{
|
||||
get { return textColor; }
|
||||
@@ -69,7 +69,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(0.0f, 10.0f), Serialize(1.0f, true, description: "The scale of the text displayed on the label.")]
|
||||
[Editable(0.0f, 10.0f), Serialize(1.0f, true, description: "The scale of the text displayed on the label.", alwaysUseInstanceValues: true)]
|
||||
public float TextScale
|
||||
{
|
||||
get { return textBlock == null ? 1.0f : textBlock.TextScale; }
|
||||
|
||||
@@ -48,7 +48,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f && IsOn)
|
||||
{
|
||||
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, 0.0f, item.Scale, SpriteEffects.None, item.SpriteDepth - 0.0001f);
|
||||
Vector2 origin = light.LightSprite.Origin;
|
||||
if (light.LightSpriteEffect == SpriteEffects.FlipHorizontally) { origin.X = light.LightSprite.SourceRect.Width - origin.X; }
|
||||
if (light.LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = light.LightSprite.SourceRect.Height - origin.Y; }
|
||||
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, origin, -light.Rotation, item.Scale, light.LightSpriteEffect, item.SpriteDepth - 0.0001f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
state = msg.ReadBoolean();
|
||||
State = msg.ReadBoolean();
|
||||
ushort userID = msg.ReadUInt16();
|
||||
if (userID == 0)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,10 @@ namespace Barotrauma.Items.Components
|
||||
private GUIScrollBar forceSlider;
|
||||
private GUITickBox autoControlIndicator;
|
||||
|
||||
private int particlesPerSec = 60;
|
||||
private float particleTimer;
|
||||
|
||||
|
||||
public float AnimSpeed
|
||||
{
|
||||
get;
|
||||
|
||||
@@ -318,10 +318,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (item.ParentInventory.slots[availableSlotIndex].HighlightTimer <= 0.0f)
|
||||
{
|
||||
item.ParentInventory.slots[availableSlotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f);
|
||||
item.ParentInventory.slots[availableSlotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||
if (slotIndex < inputContainer.Capacity)
|
||||
{
|
||||
inputContainer.Inventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f);
|
||||
inputContainer.Inventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,10 +337,22 @@ namespace Barotrauma.Items.Components
|
||||
slotRect.Center.ToVector2(),
|
||||
color: requiredItem.ItemPrefab.InventoryIconColor * 0.3f,
|
||||
scale: Math.Min(slotRect.Width / itemIcon.size.X, slotRect.Height / itemIcon.size.Y));
|
||||
|
||||
|
||||
if (requiredItem.UseCondition && requiredItem.MinCondition < 1.0f)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(slotRect.X, slotRect.Bottom - 8, slotRect.Width, 8), Color.Black * 0.8f, true);
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(slotRect.X, slotRect.Bottom - 8, (int)(slotRect.Width * requiredItem.MinCondition), 8),
|
||||
GUI.Style.Green * 0.8f, true);
|
||||
}
|
||||
|
||||
if (slotRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
string toolTipText = requiredItem.ItemPrefab.Name;
|
||||
if (requiredItem.UseCondition && requiredItem.MinCondition < 1.0f)
|
||||
{
|
||||
toolTipText += " " + (int)Math.Round(requiredItem.MinCondition * 100) + "%";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(requiredItem.ItemPrefab.Description))
|
||||
{
|
||||
toolTipText += '\n' + requiredItem.ItemPrefab.Description;
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
pumpSpeedLockTimer -= deltaTime;
|
||||
isActiveLockTimer -= deltaTime;
|
||||
autoControlIndicator.Selected = pumpSpeedLockTimer > 0.0f || isActiveLockTimer > 0.0f;
|
||||
autoControlIndicator.Selected = IsAutoControlled;
|
||||
PowerButton.Enabled = isActiveLockTimer <= 0.0f;
|
||||
if (HasPower)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace Barotrauma.Items.Components
|
||||
Disruption
|
||||
}
|
||||
|
||||
private PathFinder pathFinder;
|
||||
|
||||
private bool dynamicDockingIndicator = true;
|
||||
|
||||
private bool unsentChanges;
|
||||
@@ -45,7 +47,7 @@ namespace Barotrauma.Items.Components
|
||||
private Sprite sonarBlip;
|
||||
private Sprite lineSprite;
|
||||
|
||||
private Dictionary<string, Sprite> targetIcons = new Dictionary<string, Sprite>();
|
||||
private readonly Dictionary<string, Sprite> targetIcons = new Dictionary<string, Sprite>();
|
||||
|
||||
private float displayBorderSize;
|
||||
|
||||
@@ -65,7 +67,24 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
//Vector2 = vector from the ping source to the position of the disruption
|
||||
//float = strength of the disruption, between 0-1
|
||||
List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
|
||||
private readonly List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
|
||||
|
||||
class CachedDistance
|
||||
{
|
||||
public readonly Vector2 TransducerWorldPos;
|
||||
public readonly Vector2 WorldPos;
|
||||
public readonly float Distance;
|
||||
public double RecalculationTime;
|
||||
|
||||
public CachedDistance(Vector2 transducerWorldPos, Vector2 worldPos, float dist)
|
||||
{
|
||||
TransducerWorldPos = transducerWorldPos;
|
||||
WorldPos = worldPos;
|
||||
Distance = dist;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<object, CachedDistance> markerDistances = new Dictionary<object, CachedDistance>();
|
||||
|
||||
private readonly Color positiveColor = Color.Green;
|
||||
private readonly Color warningColor = Color.Orange;
|
||||
@@ -74,7 +93,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public static readonly Vector2 controlBoxSize = new Vector2(0.33f, 0.32f);
|
||||
public static readonly Vector2 controlBoxOffset = new Vector2(0.025f, 0);
|
||||
public static readonly float sonarAreaSize = 1.09f;
|
||||
private static readonly float sonarAreaSize = 1.09f;
|
||||
|
||||
private static readonly Dictionary<BlipType, Color[]> blipColorGradient = new Dictionary<BlipType, Color[]>()
|
||||
{
|
||||
@@ -94,6 +113,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public float DisplayRadius { get; private set; }
|
||||
|
||||
public static Vector2 GUISizeCalculation => Vector2.One * Math.Min(GUI.RelativeHorizontalAspectRatio, 1f) * sonarAreaSize;
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(Enum.GetValues(typeof(BlipType)).Cast<BlipType>().All(t => blipColorGradient.ContainsKey(t)));
|
||||
@@ -254,7 +275,7 @@ namespace Barotrauma.Items.Components
|
||||
controlContainer.RectTransform.SetPosition(Anchor.TopLeft);
|
||||
sonarView.RectTransform.ScaleBasis = ScaleBasis.Smallest;
|
||||
sonarView.RectTransform.SetPosition(Anchor.CenterRight);
|
||||
sonarView.RectTransform.Resize(Vector2.One * GUI.RelativeHorizontalAspectRatio * sonarAreaSize);
|
||||
sonarView.RectTransform.Resize(GUISizeCalculation);
|
||||
GUITextBlock.AutoScaleAndNormalize(passiveTickBox.TextBlock, activeTickBox.TextBlock, zoomText, directionalModeSwitchText);
|
||||
}
|
||||
}
|
||||
@@ -653,12 +674,16 @@ namespace Barotrauma.Items.Components
|
||||
DrawMarker(spriteBatch,
|
||||
GameMain.GameSession.StartLocation.Name,
|
||||
"outpost",
|
||||
(Level.Loaded.StartPosition - transducerCenter), displayScale, center, DisplayRadius);
|
||||
GameMain.GameSession.StartLocation.Name,
|
||||
Level.Loaded.StartPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius);
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
GameMain.GameSession.EndLocation.Name,
|
||||
"outpost",
|
||||
(Level.Loaded.EndPosition - transducerCenter), displayScale, center, DisplayRadius);
|
||||
GameMain.GameSession.EndLocation.Name,
|
||||
Level.Loaded.EndPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius);
|
||||
|
||||
foreach (AITarget aiTarget in AITarget.List)
|
||||
{
|
||||
@@ -670,7 +695,9 @@ namespace Barotrauma.Items.Components
|
||||
DrawMarker(spriteBatch,
|
||||
aiTarget.SonarLabel,
|
||||
aiTarget.SonarIconIdentifier,
|
||||
aiTarget.WorldPosition - transducerCenter, displayScale, center, DisplayRadius * 0.975f);
|
||||
aiTarget,
|
||||
aiTarget.WorldPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.975f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,7 +712,9 @@ namespace Barotrauma.Items.Components
|
||||
DrawMarker(spriteBatch,
|
||||
mission.SonarLabel,
|
||||
mission.SonarIconIdentifier,
|
||||
sonarPosition - transducerCenter, displayScale, center, DisplayRadius * 0.95f);
|
||||
mission,
|
||||
sonarPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.95f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -704,7 +733,8 @@ namespace Barotrauma.Items.Components
|
||||
DrawMarker(spriteBatch,
|
||||
sub.Info.DisplayName,
|
||||
sub.Info.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
|
||||
sub.WorldPosition - transducerCenter,
|
||||
sub,
|
||||
sub.WorldPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.95f);
|
||||
}
|
||||
|
||||
@@ -951,14 +981,13 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
foreach (AITarget aiTarget in AITarget.List)
|
||||
{
|
||||
if (aiTarget.SonarDisruption <= 0.0f || !aiTarget.Enabled) { continue; }
|
||||
float disruption = aiTarget.Entity is Character c ? c.Params.SonarDisruption : aiTarget.SonarDisruption;
|
||||
if (disruption <= 0.0f || !aiTarget.Enabled) { continue; }
|
||||
float distSqr = Vector2.DistanceSquared(aiTarget.WorldPosition, pingSource);
|
||||
if (distSqr > worldPingRadiusSqr) { continue; }
|
||||
|
||||
float disruptionDist = (float)Math.Sqrt(distSqr);
|
||||
disruptedDirections.Add(new Pair<Vector2, float>((aiTarget.WorldPosition - pingSource) / disruptionDist, aiTarget.SonarDisruption));
|
||||
|
||||
CreateBlipsForDisruption(aiTarget.WorldPosition, aiTarget.SonarDisruption);
|
||||
CreateBlipsForDisruption(aiTarget.WorldPosition, disruption);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1303,9 +1332,48 @@ namespace Barotrauma.Items.Components
|
||||
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f, sonarBlip.Origin, 0, scale * 0.08f, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
private void DrawMarker(SpriteBatch spriteBatch, string label, string iconIdentifier, Vector2 position, float scale, Vector2 center, float radius)
|
||||
private void DrawMarker(SpriteBatch spriteBatch, string label, string iconIdentifier, object targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, float scale, Vector2 center, float radius)
|
||||
{
|
||||
float dist = position.Length();
|
||||
float linearDist = Vector2.Distance(worldPosition, transducerPosition);
|
||||
float dist = linearDist;
|
||||
if (linearDist > Range)
|
||||
{
|
||||
if (markerDistances.TryGetValue(targetIdentifier, out CachedDistance cachedDistance))
|
||||
{
|
||||
if (Timing.TotalTime > cachedDistance.RecalculationTime &&
|
||||
(Vector2.DistanceSquared(cachedDistance.TransducerWorldPos, transducerPosition) > 500 * 500 ||
|
||||
Vector2.DistanceSquared(cachedDistance.WorldPos, worldPosition) > 500 * 500))
|
||||
{
|
||||
markerDistances.Remove(targetIdentifier);
|
||||
CalculateDistance();
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = Math.Max(cachedDistance.Distance, linearDist);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CalculateDistance();
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateDistance()
|
||||
{
|
||||
pathFinder ??= new PathFinder(WayPoint.WayPointList, indoorsSteering: false);
|
||||
var path = pathFinder.FindPath(ConvertUnits.ToSimUnits(transducerPosition), ConvertUnits.ToSimUnits(worldPosition));
|
||||
if (!path.Unreachable)
|
||||
{
|
||||
var cachedDistance = new CachedDistance(transducerPosition, worldPosition, path.TotalLength)
|
||||
{
|
||||
RecalculationTime = Timing.TotalTime + Rand.Range(1.0f, 5.0f)
|
||||
};
|
||||
markerDistances.Add(targetIdentifier, cachedDistance);
|
||||
dist = path.TotalLength;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 position = worldPosition - transducerPosition;
|
||||
|
||||
position *= zoom;
|
||||
position *= scale;
|
||||
@@ -1314,16 +1382,16 @@ namespace Barotrauma.Items.Components
|
||||
float textAlpha = MathHelper.Clamp(1.5f - dist / 50000.0f, 0.5f, 1.0f);
|
||||
|
||||
Vector2 dir = Vector2.Normalize(position);
|
||||
Vector2 markerPos = (dist * zoom * scale > radius) ? dir * radius : position;
|
||||
Vector2 markerPos = (linearDist * zoom * scale > radius) ? dir * radius : position;
|
||||
markerPos += center;
|
||||
|
||||
markerPos.X = (int)markerPos.X;
|
||||
markerPos.Y = (int)markerPos.Y;
|
||||
|
||||
float alpha = 1.0f;
|
||||
if (dist * scale < radius)
|
||||
if (linearDist * scale < radius)
|
||||
{
|
||||
float normalizedDist = dist * scale / radius;
|
||||
float normalizedDist = linearDist * scale / radius;
|
||||
alpha = Math.Max(normalizedDist - 0.4f, 0.0f);
|
||||
|
||||
float mouseDist = Vector2.Distance(PlayerInput.MousePosition, markerPos);
|
||||
@@ -1334,14 +1402,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (!GuiFrame.Children.First().Rect.Contains(markerPos))
|
||||
{
|
||||
if (MathUtils.GetLineRectangleIntersection(center, markerPos, GuiFrame.Children.First().Rect, out Vector2 intersection))
|
||||
{
|
||||
markerPos = intersection;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(iconIdentifier) || !targetIcons.ContainsKey(iconIdentifier))
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)markerPos.X - 3, (int)markerPos.Y - 3, 6, 6), markerColor, thickness: 2);
|
||||
|
||||
@@ -390,7 +390,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
|
||||
// Sonar area
|
||||
steerArea = new GUICustomComponent(new RectTransform(Vector2.One * GUI.RelativeHorizontalAspectRatio * Sonar.sonarAreaSize, GuiFrame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest),
|
||||
steerArea = new GUICustomComponent(new RectTransform(Sonar.GUISizeCalculation, GuiFrame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest),
|
||||
(spriteBatch, guiCustomComponent) => { DrawHUD(spriteBatch, guiCustomComponent.Rect); }, null);
|
||||
steerRadius = steerArea.Rect.Width / 2;
|
||||
|
||||
@@ -438,11 +438,8 @@ namespace Barotrauma.Items.Components
|
||||
if (Voltage < MinVoltage) { return; }
|
||||
|
||||
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
|
||||
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
||||
displaySubPos.Y = -displaySubPos.Y;
|
||||
displaySubPos = displaySubPos.ClampLength(velRect.Width / 2);
|
||||
displaySubPos = steerArea.Rect.Center.ToVector2() + displaySubPos;
|
||||
|
||||
Vector2 steeringOrigin = steerArea.Rect.Center.ToVector2();
|
||||
|
||||
if (!AutoPilot)
|
||||
{
|
||||
Vector2 unitSteeringInput = steeringInput / 100.0f;
|
||||
@@ -450,18 +447,18 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 steeringInputPos = new Vector2(
|
||||
steeringInput.X * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.Y * unitSteeringInput.Y),
|
||||
-steeringInput.Y * (float)Math.Sqrt(1.0f - 0.5f * unitSteeringInput.X * unitSteeringInput.X));
|
||||
steeringInputPos += displaySubPos;
|
||||
steeringInputPos += steeringOrigin;
|
||||
|
||||
if (steeringIndicator != null)
|
||||
{
|
||||
Vector2 dir = steeringInputPos - displaySubPos;
|
||||
Vector2 dir = steeringInputPos - steeringOrigin;
|
||||
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
||||
steeringIndicator.Draw(spriteBatch, displaySubPos, Color.White, origin: steeringIndicator.Origin, rotate: angle,
|
||||
steeringIndicator.Draw(spriteBatch, steeringOrigin, Color.White, origin: steeringIndicator.Origin, rotate: angle,
|
||||
scale: new Vector2(dir.Length() / steeringIndicator.size.X, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, displaySubPos, steeringInputPos, Color.LightGray);
|
||||
GUI.DrawLine(spriteBatch, steeringOrigin, steeringInputPos, Color.LightGray);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringInputPos.X - 5, (int)steeringInputPos.Y - 5, 10, 10), Color.White);
|
||||
}
|
||||
|
||||
@@ -475,7 +472,7 @@ namespace Barotrauma.Items.Components
|
||||
Sonar sonar = item.GetComponent<Sonar>();
|
||||
if (sonar != null && controlledSub != null)
|
||||
{
|
||||
Vector2 displayPosToMaintain = ((posToMaintain.Value - sonar.DisplayOffset * sonar.Zoom - controlledSub.WorldPosition)) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
||||
Vector2 displayPosToMaintain = ((posToMaintain.Value - controlledSub.WorldPosition)) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
||||
displayPosToMaintain.Y = -displayPosToMaintain.Y;
|
||||
displayPosToMaintain = displayPosToMaintain.ClampLength(velRect.Width / 2);
|
||||
displayPosToMaintain = steerArea.Rect.Center.ToVector2() + displayPosToMaintain;
|
||||
@@ -494,11 +491,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (maintainPosOriginIndicator != null)
|
||||
{
|
||||
maintainPosOriginIndicator.Draw(spriteBatch, displaySubPos, GUI.Style.Orange, scale: 0.5f * sonar.Zoom);
|
||||
maintainPosOriginIndicator.Draw(spriteBatch, steeringOrigin, GUI.Style.Orange, scale: 0.5f * sonar.Zoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)displaySubPos.X - 5, (int)displaySubPos.Y - 5, 10, 10), GUI.Style.Orange);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)steeringOrigin.X - 5, (int)steeringOrigin.Y - 5, 10, 10), GUI.Style.Orange);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -508,20 +505,19 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 steeringPos = new Vector2(
|
||||
targetVelocity.X * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.Y * unitTargetVel.Y),
|
||||
-targetVelocity.Y * 0.9f * (float)Math.Sqrt(1.0f - 0.5f * unitTargetVel.X * unitTargetVel.X));
|
||||
steeringPos += displaySubPos;
|
||||
|
||||
steeringPos += steeringOrigin;
|
||||
|
||||
if (steeringIndicator != null)
|
||||
{
|
||||
Vector2 dir = steeringPos - displaySubPos;
|
||||
Vector2 dir = steeringPos - steeringOrigin;
|
||||
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
||||
steeringIndicator.Draw(spriteBatch, displaySubPos, Color.Gray, origin: steeringIndicator.Origin, rotate: angle,
|
||||
steeringIndicator.Draw(spriteBatch, steeringOrigin, Color.Gray, origin: steeringIndicator.Origin, rotate: angle,
|
||||
scale: new Vector2(dir.Length() / steeringIndicator.size.X, 0.7f));
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
displaySubPos,
|
||||
steeringOrigin,
|
||||
steeringPos,
|
||||
Color.CadetBlue, 0, 2);
|
||||
}
|
||||
@@ -669,11 +665,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen)
|
||||
{
|
||||
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
||||
displaySubPos.Y = -displaySubPos.Y;
|
||||
displaySubPos = steerArea.Rect.Center.ToVector2() + displaySubPos;
|
||||
|
||||
Vector2 inputPos = PlayerInput.MousePosition - displaySubPos;
|
||||
Vector2 inputPos = PlayerInput.MousePosition - steerArea.Rect.Center.ToVector2();
|
||||
inputPos.Y = -inputPos.Y;
|
||||
if (AutoPilot && !LevelStartSelected && !LevelEndSelected)
|
||||
{
|
||||
@@ -848,7 +840,6 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 newSteeringInput = steeringInput;
|
||||
Vector2 newTargetVelocity = targetVelocity;
|
||||
float newSteeringAdjustSpeed = steeringAdjustSpeed;
|
||||
bool maintainPos = false;
|
||||
Vector2? newPosToMaintain = null;
|
||||
bool headingToStart = false;
|
||||
|
||||
@@ -859,8 +850,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (autoPilot)
|
||||
{
|
||||
maintainPos = msg.ReadBoolean();
|
||||
if (maintainPos)
|
||||
if (msg.ReadBoolean())
|
||||
{
|
||||
newPosToMaintain = new Vector2(
|
||||
msg.ReadSingle(),
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private FixActions requestStartFixAction;
|
||||
|
||||
public float FakeBrokenTimer;
|
||||
|
||||
[Serialize("", false, description: "An optional description of the needed repairs displayed in the repair interface.")]
|
||||
public string Description
|
||||
{
|
||||
@@ -43,7 +45,7 @@ namespace Barotrauma.Items.Components
|
||||
public override bool ShouldDrawHUD(Character character)
|
||||
{
|
||||
if (!HasRequiredItems(character, false) || character.SelectedConstruction != item) return false;
|
||||
return !item.IsFullCondition || character.IsTraitor && item.ConditionPercentage > MinSabotageCondition || (CurrentFixer == character && (!item.IsFullCondition || (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition)));
|
||||
return item.ConditionPercentage < RepairThreshold || character.IsTraitor && item.ConditionPercentage > MinSabotageCondition || (CurrentFixer == character && (!item.IsFullCondition || (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition)));
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
@@ -136,6 +138,17 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
if (Character.Controlled == null || (Character.Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
|
||||
{
|
||||
FakeBrokenTimer = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
FakeBrokenTimer -= deltaTime;
|
||||
}
|
||||
|
||||
item.FakeBroken = FakeBrokenTimer > 0.0f;
|
||||
|
||||
if (!GameMain.IsMultiplayer)
|
||||
{
|
||||
switch (requestStartFixAction)
|
||||
@@ -150,10 +163,10 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < particleEmitters.Count; i++)
|
||||
{
|
||||
if (item.ConditionPercentage >= particleEmitterConditionRanges[i].X && item.ConditionPercentage <= particleEmitterConditionRanges[i].Y)
|
||||
if ((item.ConditionPercentage >= particleEmitterConditionRanges[i].X && item.ConditionPercentage <= particleEmitterConditionRanges[i].Y) || FakeBrokenTimer > 0.0f)
|
||||
{
|
||||
particleEmitters[i].Emit(deltaTime, item.WorldPosition, item.CurrentHull);
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ namespace Barotrauma.Items.Components
|
||||
ConnectionPanel.HighlightedWire = wire;
|
||||
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring;
|
||||
if (allowRewiring && !wire.Locked && (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
if (allowRewiring && (!wire.Locked && !panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
{
|
||||
//start dragging the wire
|
||||
if (PlayerInput.PrimaryMouseButtonHeld()) { DraggingConnected = wire; }
|
||||
|
||||
@@ -285,6 +285,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public static void UpdateEditing(List<Wire> wires)
|
||||
{
|
||||
var doubleClicked = PlayerInput.DoubleClicked();
|
||||
|
||||
Wire equippedWire =
|
||||
Character.Controlled?.SelectedItems[0]?.GetComponent<Wire>() ??
|
||||
Character.Controlled?.SelectedItems[1]?.GetComponent<Wire>();
|
||||
@@ -298,7 +300,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
//dragging a node of some wire
|
||||
if (draggingWire != null)
|
||||
if (draggingWire != null && !doubleClicked)
|
||||
{
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
@@ -329,15 +331,18 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (selectedNodeIndex.HasValue)
|
||||
{
|
||||
nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f);
|
||||
nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
|
||||
if (!PlayerInput.IsShiftDown())
|
||||
{
|
||||
nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f);
|
||||
nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
|
||||
}
|
||||
|
||||
draggingWire.nodes[(int)selectedNodeIndex] = nodeWorldPos;
|
||||
draggingWire.UpdateSections();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Vector2.DistanceSquared(nodeWorldPos, draggingWire.nodes[(int)highlightedNodeIndex]) > Submarine.GridSize.X * Submarine.GridSize.X)
|
||||
if (Vector2.DistanceSquared(nodeWorldPos, draggingWire.nodes[(int)highlightedNodeIndex]) > Submarine.GridSize.X * Submarine.GridSize.X || PlayerInput.IsShiftDown())
|
||||
{
|
||||
selectedNodeIndex = highlightedNodeIndex;
|
||||
}
|
||||
@@ -350,6 +355,8 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
bool updateHighlight = true;
|
||||
|
||||
//a wire has been selected -> check if we should start dragging one of the nodes
|
||||
float nodeSelectDist = 10, sectionSelectDist = 5;
|
||||
highlightedNodeIndex = null;
|
||||
@@ -405,6 +412,37 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
selectedWire.nodes.RemoveAt(closestIndex);
|
||||
selectedWire.UpdateSections();
|
||||
}
|
||||
// if only one end of the wire is disconnect pick it back up with double click
|
||||
else if (doubleClicked && equippedWire == null && Character.Controlled != null && selectedWire.connections.Any(conn => conn != null))
|
||||
{
|
||||
if (selectedWire.connections[0] == null && closestIndex == 0 || selectedWire.connections[1] == null && closestIndex == selectedWire.nodes.Count - 1)
|
||||
{
|
||||
selectedWire.IsActive = true;
|
||||
selectedWire.nodes.RemoveAt(closestIndex);
|
||||
selectedWire.UpdateSections();
|
||||
|
||||
// flip the wire
|
||||
if (closestIndex == 0)
|
||||
{
|
||||
selectedWire.nodes.Reverse();
|
||||
selectedWire.connections[0] = selectedWire.connections[1];
|
||||
selectedWire.connections[1] = null;
|
||||
}
|
||||
|
||||
selectedWire.shouldClearConnections = false;
|
||||
Character.Controlled.Inventory.TryPutItem(selectedWire.item, Character.Controlled, new List<InvSlotType> { InvSlotType.LeftHand, InvSlotType.RightHand });
|
||||
foreach (var entity in MapEntity.mapEntityList)
|
||||
{
|
||||
if (entity is Item item)
|
||||
{
|
||||
item.GetComponent<ConnectionPanel>()?.DisconnectedWires.Remove(selectedWire);
|
||||
}
|
||||
}
|
||||
MapEntity.SelectedList.Clear();
|
||||
selectedWire.shouldClearConnections = true;
|
||||
updateHighlight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,7 +484,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (highlighted != null)
|
||||
if (highlighted != null && updateHighlight)
|
||||
{
|
||||
highlighted.item.IsHighlighted = true;
|
||||
if (PlayerInput.PrimaryMouseButtonClicked())
|
||||
|
||||
@@ -5,7 +5,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Barotrauma
|
||||
|
||||
public Sprite SlotSprite;
|
||||
|
||||
public Keys QuickUseKey;
|
||||
public int InventoryKeyIndex = -1;
|
||||
|
||||
public int SubInventoryDir = -1;
|
||||
|
||||
@@ -709,12 +709,15 @@ namespace Barotrauma
|
||||
/// Is the mouse on any inventory element (slot, equip button, subinventory...)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsMouseOnInventory()
|
||||
public static bool IsMouseOnInventory(bool ignoreDraggedItem = false)
|
||||
{
|
||||
var isSubEditor = Screen.Selected is SubEditorScreen editor && !editor.WiringMode;
|
||||
if (Character.Controlled == null) return false;
|
||||
if (Character.Controlled == null) { return false; }
|
||||
|
||||
if (draggingItem != null || DraggingInventory != null) return true;
|
||||
if (!ignoreDraggedItem)
|
||||
{
|
||||
if (draggingItem != null || DraggingInventory != null) { return true; }
|
||||
}
|
||||
|
||||
if (Character.Controlled.Inventory != null && !isSubEditor)
|
||||
{
|
||||
@@ -966,7 +969,8 @@ namespace Barotrauma
|
||||
{
|
||||
Character.Controlled.ClearInputs();
|
||||
|
||||
if (CharacterHealth.OpenHealthWindow != null &&
|
||||
if (!IsMouseOnInventory(ignoreDraggedItem: true) &&
|
||||
CharacterHealth.OpenHealthWindow != null &&
|
||||
CharacterHealth.OpenHealthWindow.OnItemDropped(draggingItem, false))
|
||||
{
|
||||
draggingItem = null;
|
||||
@@ -1078,7 +1082,7 @@ namespace Barotrauma
|
||||
protected static Rectangle GetSubInventoryHoverArea(SlotReference subSlot)
|
||||
{
|
||||
Rectangle hoverArea;
|
||||
if (!subSlot.Inventory.Movable())
|
||||
if (!subSlot.Inventory.Movable() || Character.Controlled?.Inventory == subSlot.ParentInventory && !Character.Controlled.HasEquippedItem(subSlot.Item))
|
||||
{
|
||||
hoverArea = subSlot.Slot.Rect;
|
||||
hoverArea.Location += subSlot.Slot.DrawOffset.ToPoint();
|
||||
@@ -1251,7 +1255,7 @@ namespace Barotrauma
|
||||
|
||||
if (item != null && drawItem)
|
||||
{
|
||||
if (!item.IsFullCondition && (itemContainer == null || !itemContainer.ShowConditionInContainedStateIndicator))
|
||||
if (!item.IsFullCondition && !item.Prefab.HideConditionBar && (itemContainer == null || !itemContainer.ShowConditionInContainedStateIndicator))
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Bottom - 8, rect.Width, 8), Color.Black * 0.8f, true);
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
@@ -1378,10 +1382,10 @@ namespace Barotrauma
|
||||
if (inventory != null &&
|
||||
!inventory.Locked &&
|
||||
Character.Controlled?.Inventory == inventory &&
|
||||
slot.QuickUseKey != Keys.None)
|
||||
slot.InventoryKeyIndex != -1)
|
||||
{
|
||||
spriteBatch.Draw(slotHotkeySprite.Texture, rect.ScaleSize(1.15f), slotHotkeySprite.SourceRect, slotColor);
|
||||
GUI.DrawString(spriteBatch, rect.Location.ToVector2() + new Vector2((int)(4.25f * UIScale), (int)Math.Ceiling(-1.5f * UIScale)), slot.QuickUseKey.ToString().Substring(1, 1), Color.Black, font: GUI.HotkeyFont);
|
||||
GUI.DrawString(spriteBatch, rect.Location.ToVector2() + new Vector2((int)(4.25f * UIScale), (int)Math.Ceiling(-1.5f * UIScale)), GameMain.Config.InventoryKeyBind(slot.InventoryKeyIndex).Name, Color.Black, font: GUI.HotkeyFont);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,20 @@ namespace Barotrauma
|
||||
|
||||
private readonly Dictionary<DecorativeSprite, DecorativeSprite.State> spriteAnimState = new Dictionary<DecorativeSprite, DecorativeSprite.State>();
|
||||
|
||||
private bool fakeBroken;
|
||||
public bool FakeBroken
|
||||
{
|
||||
get { return fakeBroken; }
|
||||
set
|
||||
{
|
||||
if (value != fakeBroken)
|
||||
{
|
||||
fakeBroken = value;
|
||||
SetActiveSprite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Sprite activeSprite;
|
||||
public override Sprite Sprite
|
||||
{
|
||||
@@ -71,6 +85,10 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!GameMain.SubEditorScreen.ShowThalamus && prefab.Category.HasFlag(MapEntityCategory.Thalamus))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return parentInventory == null && (body == null || body.Enabled) && ShowItems;
|
||||
}
|
||||
}
|
||||
@@ -139,11 +157,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
float displayCondition = FakeBroken ? 0.0f : condition;
|
||||
for (int i = 0; i < Prefab.BrokenSprites.Count;i++)
|
||||
{
|
||||
if (Prefab.BrokenSprites[i].FadeIn) { continue; }
|
||||
float minCondition = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f;
|
||||
if (condition <= minCondition ||
|
||||
condition <= Prefab.BrokenSprites[i].MaxCondition && !Prefab.BrokenSprites[i].FadeIn)
|
||||
if (displayCondition <= minCondition || displayCondition <= Prefab.BrokenSprites[i].MaxCondition)
|
||||
{
|
||||
activeSprite = Prefab.BrokenSprites[i].Sprite;
|
||||
break;
|
||||
@@ -225,7 +244,9 @@ namespace Barotrauma
|
||||
|
||||
BrokenItemSprite fadeInBrokenSprite = null;
|
||||
float fadeInBrokenSpriteAlpha = 0.0f;
|
||||
if (condition < Prefab.Health)
|
||||
float displayCondition = FakeBroken ? 0.0f : condition;
|
||||
Vector2 drawOffset = Vector2.Zero;
|
||||
if (displayCondition < Prefab.Health)
|
||||
{
|
||||
for (int i = 0; i < Prefab.BrokenSprites.Count; i++)
|
||||
{
|
||||
@@ -233,16 +254,17 @@ namespace Barotrauma
|
||||
{
|
||||
float min = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f;
|
||||
float max = Prefab.BrokenSprites[i].MaxCondition;
|
||||
fadeInBrokenSpriteAlpha = 1.0f - ((condition - min) / (max - min));
|
||||
if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha < 1.0f)
|
||||
fadeInBrokenSpriteAlpha = 1.0f - ((displayCondition - min) / (max - min));
|
||||
if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha <= 1.0f)
|
||||
{
|
||||
fadeInBrokenSprite = Prefab.BrokenSprites[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (condition <= Prefab.BrokenSprites[i].MaxCondition)
|
||||
if (displayCondition <= Prefab.BrokenSprites[i].MaxCondition)
|
||||
{
|
||||
activeSprite = Prefab.BrokenSprites[i].Sprite;
|
||||
drawOffset = Prefab.BrokenSprites[i].Offset.ToVector2() * Scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -264,9 +286,13 @@ namespace Barotrauma
|
||||
{
|
||||
if (prefab.ResizeHorizontal || prefab.ResizeVertical)
|
||||
{
|
||||
activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color,
|
||||
Vector2 size = new Vector2(rect.Width, rect.Height);
|
||||
activeSprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + drawOffset,
|
||||
size, color: color,
|
||||
textureScale: Vector2.One * Scale,
|
||||
depth: depth);
|
||||
fadeInBrokenSprite?.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)), new Vector2(rect.Width, rect.Height), color: color * fadeInBrokenSpriteAlpha,
|
||||
fadeInBrokenSprite?.Sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X - rect.Width / 2, -(DrawPosition.Y + rect.Height / 2)) + fadeInBrokenSprite.Offset.ToVector2() * Scale, size, color: color * fadeInBrokenSpriteAlpha,
|
||||
textureScale: Vector2.One * Scale,
|
||||
depth: depth - 0.000001f);
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
@@ -280,8 +306,8 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, SpriteRotation, Scale, activeSprite.effects, depth);
|
||||
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f);
|
||||
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, SpriteRotation, Scale, activeSprite.effects, depth);
|
||||
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f);
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
@@ -302,19 +328,25 @@ namespace Barotrauma
|
||||
if (holdable.Picker.SelectedItems[0] == this)
|
||||
{
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.RightHand);
|
||||
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() + depthStep * 2;
|
||||
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
|
||||
if (holdLimb != null)
|
||||
{
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null) { depth = Math.Max(wearableSprite.Sprite.Depth + depthStep, depth); }
|
||||
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() + depthStep * 2;
|
||||
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
|
||||
{
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null) { depth = Math.Max(wearableSprite.Sprite.Depth + depthStep, depth); }
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (holdable.Picker.SelectedItems[1] == this)
|
||||
{
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.LeftHand);
|
||||
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() - depthStep * 2;
|
||||
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
|
||||
if (holdLimb != null)
|
||||
{
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null) { depth = Math.Min(wearableSprite.Sprite.Depth - depthStep, depth); }
|
||||
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() - depthStep * 2;
|
||||
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
|
||||
{
|
||||
if (!wearableSprite.InheritLimbDepth && wearableSprite.Sprite != null) { depth = Math.Min(wearableSprite.Sprite.Depth - depthStep, depth); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1263,6 +1295,14 @@ namespace Barotrauma
|
||||
inventory = container.Inventory;
|
||||
}
|
||||
}
|
||||
else if (inventoryOwner == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to spawn item \"{(itemIdentifier ?? "null")}\" in the inventory of an entity with the ID {inventoryId} (entity not found)");
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to spawn item \"{(itemIdentifier ?? "null")}\" in the inventory of \"{inventoryOwner} ({inventoryOwner.ID})\" (invalid entity, should be an item or a character)");
|
||||
}
|
||||
}
|
||||
|
||||
var item = new Item(itemPrefab, pos, sub)
|
||||
|
||||
@@ -14,12 +14,14 @@ namespace Barotrauma
|
||||
public readonly float MaxCondition;
|
||||
public readonly Sprite Sprite;
|
||||
public readonly bool FadeIn;
|
||||
public readonly Point Offset;
|
||||
|
||||
public BrokenItemSprite(Sprite sprite, float maxCondition, bool fadeIn)
|
||||
public BrokenItemSprite(Sprite sprite, float maxCondition, bool fadeIn, Point offset)
|
||||
{
|
||||
Sprite = sprite;
|
||||
MaxCondition = MathHelper.Clamp(maxCondition, 0.0f, 100.0f);
|
||||
FadeIn = fadeIn;
|
||||
Offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,10 +60,10 @@ namespace Barotrauma
|
||||
var particle = GameMain.ParticleManager.CreateParticle("flame",
|
||||
particlePos, particleVel, 0.0f, hull);
|
||||
|
||||
if (particle == null) continue;
|
||||
if (particle == null) { continue; }
|
||||
|
||||
//make some of the particles create another firesource when they enter another hull
|
||||
if (Rand.Int(20) == 1) particle.OnChangeHull = onChangeHull;
|
||||
if (Rand.Int(20) == 1) { particle.OnChangeHull = onChangeHull; }
|
||||
|
||||
particle.Size *= MathHelper.Clamp(size.X / 60.0f * Math.Max(hull.Oxygen / hull.Volume, 0.4f), 0.5f, 1.0f);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -24,7 +25,7 @@ namespace Barotrauma
|
||||
|
||||
public override void Draw(SpriteBatch sb, bool editing, bool back = true)
|
||||
{
|
||||
if (!GameMain.DebugDraw && Screen.Selected.Cam.Zoom > 0.1f)
|
||||
if (GameMain.DebugDraw && Screen.Selected.Cam.Zoom > 0.1f)
|
||||
{
|
||||
Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height / 2.0f));
|
||||
GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y) / 10.0f, GUI.Style.Red);
|
||||
@@ -121,24 +122,36 @@ namespace Barotrauma
|
||||
|
||||
partial void EmitParticles(float deltaTime)
|
||||
{
|
||||
if (flowTargetHull == null) return;
|
||||
|
||||
if (flowTargetHull == null) { return; }
|
||||
|
||||
if (linkedTo.Count == 2 && linkedTo[0] is Hull hull1 && linkedTo[1] is Hull hull2)
|
||||
{
|
||||
//no flow particles between linked hulls (= rooms consisting of multiple hulls)
|
||||
if (hull1.linkedTo.Contains(hull2)) { return; }
|
||||
if (hull1.linkedTo.Any(h => h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2))) { return; }
|
||||
if (hull2.linkedTo.Any(h => h.linkedTo.Contains(hull1) && h.linkedTo.Contains(hull2))) { return; }
|
||||
}
|
||||
|
||||
Vector2 pos = Position;
|
||||
if (IsHorizontal)
|
||||
{
|
||||
pos.X += Math.Sign(flowForce.X);
|
||||
pos.Y = MathHelper.Clamp((higherSurface + lowerSurface) / 2.0f, rect.Y - rect.Height, rect.Y) + 10;
|
||||
pos.Y = MathHelper.Clamp(Rand.Range(higherSurface, lowerSurface), rect.Y - rect.Height, rect.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.Y += Math.Sign(flowForce.Y) * rect.Height / 2.0f;
|
||||
}
|
||||
|
||||
//spawn less particles when there's already a large number of them
|
||||
float particleAmountMultiplier = 1.0f - GameMain.ParticleManager.ParticleCount / (float)GameMain.ParticleManager.MaxParticles;
|
||||
particleAmountMultiplier *= particleAmountMultiplier;
|
||||
|
||||
//light dripping
|
||||
if (open < 0.2f && LerpedFlowForce.LengthSquared() > 100.0f)
|
||||
{
|
||||
particleTimer += deltaTime;
|
||||
float particlesPerSec = open * 100.0f;
|
||||
float particlesPerSec = open * 100.0f * particleAmountMultiplier;
|
||||
float emitInterval = 1.0f / particlesPerSec;
|
||||
while (particleTimer > emitInterval)
|
||||
{
|
||||
@@ -174,12 +187,13 @@ namespace Barotrauma
|
||||
particleTimer += deltaTime;
|
||||
if (IsHorizontal)
|
||||
{
|
||||
float particlesPerSec = open * rect.Height * 0.1f;
|
||||
float particlesPerSec = open * rect.Height * 0.1f * particleAmountMultiplier;
|
||||
if (openedTimer > 0.0f) { particlesPerSec *= 1.0f + openedTimer * 10.0f; }
|
||||
float emitInterval = 1.0f / particlesPerSec;
|
||||
while (particleTimer > emitInterval)
|
||||
{
|
||||
Vector2 velocity = new Vector2(
|
||||
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
|
||||
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f),
|
||||
flowForce.Y * Rand.Range(0.5f, 0.7f));
|
||||
|
||||
if (flowTargetHull.WaterVolume < flowTargetHull.Volume * 0.95f)
|
||||
@@ -191,11 +205,11 @@ namespace Barotrauma
|
||||
|
||||
if (particle != null)
|
||||
{
|
||||
particle.Size = particle.Size * Math.Min(Math.Abs(flowForce.X / 1000.0f), 5.0f);
|
||||
particle.Size *= Math.Min(Math.Abs(flowForce.X / 500.0f), 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.Abs(flowForce.X) > 300.0f)
|
||||
if (Math.Abs(flowForce.X) > 300.0f && flowTargetHull.WaterVolume > flowTargetHull.Volume * 0.1f)
|
||||
{
|
||||
pos.X += Math.Sign(flowForce.X) * 10.0f;
|
||||
if (rect.Height < 32)
|
||||
@@ -211,7 +225,7 @@ namespace Barotrauma
|
||||
GameMain.ParticleManager.CreateParticle(
|
||||
"bubbles",
|
||||
Submarine == null ? pos : pos + Submarine.Position,
|
||||
flowForce / 10.0f, 0, flowTargetHull);
|
||||
velocity, 0, flowTargetHull);
|
||||
}
|
||||
particleTimer -= emitInterval;
|
||||
}
|
||||
@@ -220,7 +234,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (Math.Sign(flowTargetHull.Rect.Y - rect.Y) != Math.Sign(lerpedFlowForce.Y)) return;
|
||||
|
||||
float particlesPerSec = open * rect.Width * 0.3f;
|
||||
float particlesPerSec = open * rect.Width * 0.3f * particleAmountMultiplier;
|
||||
float emitInterval = 1.0f / particlesPerSec;
|
||||
while (particleTimer > emitInterval)
|
||||
{
|
||||
@@ -237,7 +251,7 @@ namespace Barotrauma
|
||||
velocity, 0, FlowTargetHull);
|
||||
if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f);
|
||||
}
|
||||
if (Math.Abs(flowForce.Y) > 190.0f && Rand.Range(0.0f, 1.0f) < 0.3f)
|
||||
if (Math.Abs(flowForce.Y) > 190.0f && Rand.Range(0.0f, 1.0f) < 0.3f && flowTargetHull.WaterVolume > flowTargetHull.Volume * 0.1f)
|
||||
{
|
||||
GameMain.ParticleManager.CreateParticle(
|
||||
"bubbles",
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Barotrauma
|
||||
{
|
||||
public const int MaxDecalsPerHull = 10;
|
||||
|
||||
private List<Decal> decals = new List<Decal>();
|
||||
private readonly List<Decal> decals = new List<Decal>();
|
||||
|
||||
private float serverUpdateDelay;
|
||||
private float remoteWaterVolume, remoteOxygenPercentage;
|
||||
@@ -23,6 +23,8 @@ namespace Barotrauma
|
||||
private bool networkUpdatePending;
|
||||
private float networkUpdateTimer;
|
||||
|
||||
private double lastAmbientLightEditTime;
|
||||
|
||||
public override bool SelectableInEditor
|
||||
{
|
||||
get
|
||||
@@ -232,33 +234,36 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
/*if (!Visible)
|
||||
if (!ShowHulls && !GameMain.DebugDraw) { return; }
|
||||
|
||||
if (!editing && (!GameMain.DebugDraw || Screen.Selected.Cam.Zoom < 0.1f)) { return; }
|
||||
|
||||
float alpha = 1.0f;
|
||||
float hideTimeAfterEdit = 3.0f;
|
||||
if (lastAmbientLightEditTime > Timing.TotalTime - hideTimeAfterEdit * 2.0f)
|
||||
{
|
||||
drawRect =
|
||||
Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(drawRect.X, -drawRect.Y),
|
||||
new Vector2(rect.Width, rect.Height),
|
||||
Color.Black, true,
|
||||
0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
|
||||
}*/
|
||||
|
||||
if (!ShowHulls && !GameMain.DebugDraw) return;
|
||||
|
||||
if (!editing && (!GameMain.DebugDraw || Screen.Selected.Cam.Zoom < 0.1f)) return;
|
||||
alpha = Math.Min((float)(Timing.TotalTime - lastAmbientLightEditTime) / hideTimeAfterEdit - 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
Rectangle drawRect =
|
||||
Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
|
||||
|
||||
if ((IsSelected || IsHighlighted) && editing)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(drawRect.X, -drawRect.Y),
|
||||
new Vector2(rect.Width, rect.Height),
|
||||
(IsHighlighted ? Color.LightBlue * 0.8f : GUI.Style.Red * 0.5f) * alpha, false, 0, (int)Math.Max(5.0f / Screen.Selected.Cam.Zoom, 1.0f));
|
||||
}
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(drawRect.X, -drawRect.Y),
|
||||
new Vector2(rect.Width, rect.Height),
|
||||
Color.Blue, false, (ID % 255) * 0.000001f, (int)Math.Max((1.5f / Screen.Selected.Cam.Zoom), 1.0f));
|
||||
Color.Blue * alpha, false, (ID % 255) * 0.000001f, (int)Math.Max(1.5f / Screen.Selected.Cam.Zoom, 1.0f));
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height),
|
||||
GUI.Style.Red * ((100.0f - OxygenPercentage) / 400.0f), true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
|
||||
GUI.Style.Red * ((100.0f - OxygenPercentage) / 400.0f) * alpha, true, 0, (int)Math.Max(1.5f / Screen.Selected.Cam.Zoom, 1.0f));
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
@@ -277,10 +282,12 @@ namespace Barotrauma
|
||||
foreach (FireSource fs in FireSources)
|
||||
{
|
||||
Rectangle fireSourceRect = new Rectangle((int)fs.WorldPosition.X, -(int)fs.WorldPosition.Y, (int)fs.Size.X, (int)fs.Size.Y);
|
||||
GUI.DrawRectangle(spriteBatch, fireSourceRect, GUI.Style.Orange, false, 0, 5);
|
||||
GUI.DrawRectangle(spriteBatch, fireSourceRect, GUI.Style.Red, false, 0, 5);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUI.Style.Orange, false, 0, 5);
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
||||
}
|
||||
|
||||
|
||||
/*GUI.DrawLine(spriteBatch, new Vector2(drawRect.X, -WorldSurface), new Vector2(drawRect.Right, -WorldSurface), Color.Cyan * 0.5f);
|
||||
for (int i = 0; i < waveY.Length - 1; i++)
|
||||
{
|
||||
@@ -290,24 +297,15 @@ namespace Barotrauma
|
||||
}*/
|
||||
}
|
||||
|
||||
if ((IsSelected || IsHighlighted) && editing)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(drawRect.X + 5, -drawRect.Y + 5),
|
||||
new Vector2(rect.Width - 10, rect.Height - 10),
|
||||
IsHighlighted ? Color.LightBlue * 0.5f : GUI.Style.Red * 0.5f, true, 0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
|
||||
}
|
||||
|
||||
foreach (MapEntity e in linkedTo)
|
||||
{
|
||||
if (e is Hull)
|
||||
if (e is Hull linkedHull)
|
||||
{
|
||||
Hull linkedHull = (Hull)e;
|
||||
Rectangle connectedHullRect = e.Submarine == null ?
|
||||
linkedHull.rect :
|
||||
Rectangle connectedHullRect = e.Submarine == null ?
|
||||
linkedHull.rect :
|
||||
new Rectangle(
|
||||
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
|
||||
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
|
||||
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
|
||||
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
|
||||
|
||||
//center of the hull
|
||||
@@ -315,7 +313,7 @@ namespace Barotrauma
|
||||
WorldRect :
|
||||
new Rectangle(
|
||||
(int)(Submarine.DrawPosition.X + WorldPosition.X),
|
||||
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
|
||||
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
|
||||
WorldRect.Width, WorldRect.Height);
|
||||
|
||||
GUI.DrawLine(spriteBatch,
|
||||
@@ -326,22 +324,22 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer)
|
||||
public static void UpdateVertices(Camera cam, WaterRenderer renderer)
|
||||
{
|
||||
foreach (EntityGrid entityGrid in EntityGrids)
|
||||
{
|
||||
if (entityGrid.WorldRect.X > cam.WorldView.Right || entityGrid.WorldRect.Right < cam.WorldView.X) continue;
|
||||
if (entityGrid.WorldRect.Y - entityGrid.WorldRect.Height > cam.WorldView.Y || entityGrid.WorldRect.Y < cam.WorldView.Y - cam.WorldView.Height) continue;
|
||||
if (entityGrid.WorldRect.X > cam.WorldView.Right || entityGrid.WorldRect.Right < cam.WorldView.X) { continue; }
|
||||
if (entityGrid.WorldRect.Y - entityGrid.WorldRect.Height > cam.WorldView.Y || entityGrid.WorldRect.Y < cam.WorldView.Y - cam.WorldView.Height) { continue; }
|
||||
|
||||
var allEntities = entityGrid.GetAllEntities();
|
||||
foreach (Hull hull in allEntities)
|
||||
{
|
||||
hull.UpdateVertices(graphicsDevice, cam, entityGrid, renderer);
|
||||
hull.UpdateVertices(cam, entityGrid, renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, EntityGrid entityGrid, WaterRenderer renderer)
|
||||
private void UpdateVertices(Camera cam, EntityGrid entityGrid, WaterRenderer renderer)
|
||||
{
|
||||
Vector2 submarinePos = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
|
||||
|
||||
@@ -554,11 +552,10 @@ namespace Barotrauma
|
||||
remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
|
||||
bool hasFireSources = message.ReadBoolean();
|
||||
int fireSourceCount = 0;
|
||||
remoteFireSources = new List<Vector3>();
|
||||
if (hasFireSources)
|
||||
{
|
||||
fireSourceCount = message.ReadRangedInteger(0, 16);
|
||||
int fireSourceCount = message.ReadRangedInteger(0, 16);
|
||||
for (int i = 0; i < fireSourceCount; i++)
|
||||
{
|
||||
remoteFireSources.Add(new Vector3(
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (Pair<MapEntityPrefab, Rectangle> entity in DisplayEntities)
|
||||
{
|
||||
if (entity.First is CoreEntityPrefab) { continue; }
|
||||
Rectangle drawRect = entity.Second;
|
||||
drawRect = new Rectangle(
|
||||
(int)(drawRect.X * scale) + drawArea.Center.X, (int)((drawRect.Y) * scale) - drawArea.Center.Y,
|
||||
|
||||
@@ -93,9 +93,9 @@ namespace Barotrauma.Lights
|
||||
public static BasicEffect shadowEffect;
|
||||
public static BasicEffect penumbraEffect;
|
||||
|
||||
private Segment[] segments = new Segment[4];
|
||||
private SegmentPoint[] vertices = new SegmentPoint[4];
|
||||
private SegmentPoint[] losVertices = new SegmentPoint[4];
|
||||
private readonly Segment[] segments = new Segment[4];
|
||||
private readonly SegmentPoint[] vertices = new SegmentPoint[4];
|
||||
private readonly SegmentPoint[] losVertices = new SegmentPoint[4];
|
||||
|
||||
private readonly bool[] backFacing;
|
||||
private readonly bool[] ignoreEdge;
|
||||
@@ -106,6 +106,8 @@ namespace Barotrauma.Lights
|
||||
public VertexPositionTexture[] PenumbraVertices { get; private set; }
|
||||
public int ShadowVertexCount { get; private set; }
|
||||
|
||||
private readonly HashSet<ConvexHull> overlappingHulls = new HashSet<ConvexHull>();
|
||||
|
||||
public MapEntity ParentEntity { get; private set; }
|
||||
|
||||
private bool enabled;
|
||||
@@ -176,7 +178,7 @@ namespace Barotrauma.Lights
|
||||
if (door != null) { isHorizontal = door.IsHorizontal; }
|
||||
}
|
||||
|
||||
var chList = HullLists.Find(x => x.Submarine == parent.Submarine);
|
||||
var chList = HullLists.Find(h => h.Submarine == parent.Submarine);
|
||||
if (chList == null)
|
||||
{
|
||||
chList = new ConvexHullList(parent.Submarine);
|
||||
@@ -194,10 +196,12 @@ namespace Barotrauma.Lights
|
||||
|
||||
private void MergeOverlappingSegments(ConvexHull ch)
|
||||
{
|
||||
if (ch == this) return;
|
||||
|
||||
if (ch == this) { return; }
|
||||
|
||||
if (isHorizontal == ch.isHorizontal)
|
||||
{
|
||||
if (BoundingBox == ch.BoundingBox) { return; }
|
||||
|
||||
//hide segments that are roughly at the some position as some other segment (e.g. the ends of two adjacent wall pieces)
|
||||
float mergeDist = 32;
|
||||
float mergeDistSqr = mergeDist * mergeDist;
|
||||
@@ -206,6 +210,7 @@ namespace Barotrauma.Lights
|
||||
for (int j = 0; j < ch.segments.Length; j++)
|
||||
{
|
||||
if (segments[i].IsHorizontal != ch.segments[j].IsHorizontal) { continue; }
|
||||
if (ignoreEdge[i] || ch.ignoreEdge[j]) { continue; }
|
||||
|
||||
//the segments must be at different sides of the convex hulls to be merged
|
||||
//(e.g. the right edge of a wall piece and the left edge of another one)
|
||||
@@ -247,6 +252,7 @@ namespace Barotrauma.Lights
|
||||
p.Y >= ch.BoundingBox.Y && p.Y <= ch.BoundingBox.Bottom)
|
||||
{
|
||||
ignoreEdge[i] = true;
|
||||
overlappingHulls.Add(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,11 +289,25 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
else
|
||||
{
|
||||
losVertices[startPointIndex].Pos = segment2.ConvexHull.losVertices[startPoint2Index].Pos =
|
||||
(segment1.Start.Pos + segment2.End.Pos) / 2.0f;
|
||||
losVertices[endPointIndex].Pos = segment2.ConvexHull.losVertices[endPoint2Index].Pos =
|
||||
(segment1.End.Pos + segment2.Start.Pos) / 2.0f;
|
||||
if (Vector2.DistanceSquared(losVertices[startPointIndex].Pos, segment1.Start.Pos) <
|
||||
Vector2.DistanceSquared(losVertices[startPointIndex].Pos, segment1.End.Pos))
|
||||
{
|
||||
losVertices[startPointIndex].Pos = segment2.ConvexHull.losVertices[startPoint2Index].Pos =
|
||||
(segment1.Start.Pos + segment2.End.Pos) / 2.0f;
|
||||
losVertices[endPointIndex].Pos = segment2.ConvexHull.losVertices[endPoint2Index].Pos =
|
||||
(segment1.End.Pos + segment2.Start.Pos) / 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
losVertices[startPointIndex].Pos = segment2.ConvexHull.losVertices[startPoint2Index].Pos =
|
||||
(segment1.End.Pos + segment2.Start.Pos) / 2.0f;
|
||||
losVertices[endPointIndex].Pos = segment2.ConvexHull.losVertices[endPoint2Index].Pos =
|
||||
(segment1.Start.Pos + segment2.End.Pos) / 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
overlappingHulls.Add(segment2.ConvexHull);
|
||||
segment2.ConvexHull.overlappingHulls.Add(this);
|
||||
}
|
||||
|
||||
public void Rotate(Vector2 origin, float amount)
|
||||
@@ -328,7 +348,50 @@ namespace Barotrauma.Lights
|
||||
|
||||
LastVertexChangeTime = (float)Timing.TotalTime;
|
||||
|
||||
overlappingHulls.Clear();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ignoreEdge[i] = false;
|
||||
}
|
||||
|
||||
CalculateDimensions();
|
||||
|
||||
if (ParentEntity == null) { return; }
|
||||
|
||||
var chList = HullLists.Find(h => h.Submarine == ParentEntity.Submarine);
|
||||
if (chList != null)
|
||||
{
|
||||
overlappingHulls.Clear();
|
||||
foreach (ConvexHull ch in chList.List)
|
||||
{
|
||||
MergeOverlappingSegments(ch);
|
||||
ch.MergeOverlappingSegments(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RecalculateAll(Submarine sub)
|
||||
{
|
||||
var chList = HullLists.Find(h => h.Submarine == sub);
|
||||
if (chList != null)
|
||||
{
|
||||
foreach (ConvexHull ch in chList.List)
|
||||
{
|
||||
ch.overlappingHulls.Clear();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ch.ignoreEdge[i] = false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < chList.List.Count; i++)
|
||||
{
|
||||
for (int j = i + 1; j < chList.List.Count; j++)
|
||||
{
|
||||
chList.List[i].MergeOverlappingSegments(chList.List[j]);
|
||||
chList.List[j].MergeOverlappingSegments(chList.List[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVertices(Vector2[] points, Matrix? rotationMatrix = null)
|
||||
@@ -348,6 +411,8 @@ namespace Barotrauma.Lights
|
||||
ignoreEdge[i] = false;
|
||||
}
|
||||
|
||||
overlappingHulls.Clear();
|
||||
|
||||
int margin = 0;
|
||||
if (Math.Abs(points[0].X - points[2].X) < Math.Abs(points[0].Y - points[2].Y))
|
||||
{
|
||||
@@ -381,9 +446,10 @@ namespace Barotrauma.Lights
|
||||
|
||||
if (ParentEntity == null) return;
|
||||
|
||||
var chList = HullLists.Find(x => x.Submarine == ParentEntity.Submarine);
|
||||
var chList = HullLists.Find(h => h.Submarine == ParentEntity.Submarine);
|
||||
if (chList != null)
|
||||
{
|
||||
overlappingHulls.Clear();
|
||||
foreach (ConvexHull ch in chList.List)
|
||||
{
|
||||
MergeOverlappingSegments(ch);
|
||||
@@ -484,8 +550,8 @@ namespace Barotrauma.Lights
|
||||
|
||||
//find beginning and ending vertices which
|
||||
//belong to the shadow
|
||||
int startingIndex = 0;
|
||||
int endingIndex = 0;
|
||||
int startingIndex = -1;
|
||||
int endingIndex = -1;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int currentEdge = i;
|
||||
@@ -498,6 +564,8 @@ namespace Barotrauma.Lights
|
||||
startingIndex = nextEdge;
|
||||
}
|
||||
|
||||
if (startingIndex == -1 || endingIndex == -1) { return; }
|
||||
|
||||
//nr of vertices that are in the shadow
|
||||
if (endingIndex > startingIndex)
|
||||
ShadowVertexCount = endingIndex - startingIndex + 1;
|
||||
@@ -663,7 +731,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
var chList = HullLists.Find(x => x.Submarine == ParentEntity.Submarine);
|
||||
var chList = HullLists.Find(h => h.Submarine == ParentEntity.Submarine);
|
||||
|
||||
if (chList != null)
|
||||
{
|
||||
@@ -672,8 +740,19 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
HullLists.Remove(chList);
|
||||
}
|
||||
foreach (ConvexHull ch2 in overlappingHulls)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ch2.ignoreEdge[i] = false;
|
||||
}
|
||||
ch2.overlappingHulls.Remove(this);
|
||||
foreach (ConvexHull ch in chList.List)
|
||||
{
|
||||
ch.MergeOverlappingSegments(ch2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,18 +11,6 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
class LightManager
|
||||
{
|
||||
private const float AmbientLightUpdateInterval = 0.2f;
|
||||
private const float AmbientLightFalloff = 0.8f;
|
||||
|
||||
/// <summary>
|
||||
/// Enables a feature that makes lights inside the hull increase the brightness of the entire hull
|
||||
/// and adjacent ones to some extent, if there are gaps for the lights to pass through.
|
||||
/// Prevents unnaturally dark looking shadows in otherwise well-lit submarines, but disabled at least for
|
||||
/// the time being because it makes the lighting behave unpredictably and may cause rooms to appear
|
||||
/// excessively bright if different lighting conditions aren't tested and accounted for.
|
||||
/// </summary>
|
||||
private static readonly bool UseHullSpecificAmbientLight = false;
|
||||
|
||||
public static Entity ViewTarget { get; set; }
|
||||
|
||||
private float currLightMapScale;
|
||||
@@ -57,7 +45,7 @@ namespace Barotrauma.Lights
|
||||
public Effect LosEffect { get; private set; }
|
||||
public Effect SolidColorEffect { get; private set; }
|
||||
|
||||
private List<LightSource> lights;
|
||||
private readonly List<LightSource> lights;
|
||||
|
||||
public bool LosEnabled = true;
|
||||
public LosMode LosMode = LosMode.Transparent;
|
||||
@@ -66,13 +54,8 @@ namespace Barotrauma.Lights
|
||||
|
||||
public bool ObstructVision;
|
||||
|
||||
private Texture2D visionCircle;
|
||||
private readonly Texture2D visionCircle;
|
||||
|
||||
private Dictionary<Hull, Color> hullAmbientLights;
|
||||
private Dictionary<Hull, Color> smoothedHullAmbientLights;
|
||||
|
||||
private float ambientLightUpdateTimer;
|
||||
|
||||
public IEnumerable<LightSource> Lights
|
||||
{
|
||||
get { return lights; }
|
||||
@@ -80,7 +63,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public LightManager(GraphicsDevice graphics, ContentManager content)
|
||||
{
|
||||
lights = new List<LightSource>();
|
||||
lights = new List<LightSource>(100);
|
||||
|
||||
AmbientLight = new Color(20, 20, 20, 255);
|
||||
|
||||
@@ -114,9 +97,6 @@ namespace Barotrauma.Lights
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
hullAmbientLights = new Dictionary<Hull, Color>();
|
||||
smoothedHullAmbientLights = new Dictionary<Hull, Color>();
|
||||
}
|
||||
|
||||
private void CreateRenderTargets(GraphicsDevice graphics)
|
||||
@@ -167,43 +147,12 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (UseHullSpecificAmbientLight)
|
||||
{
|
||||
if (ambientLightUpdateTimer > 0.0f)
|
||||
{
|
||||
ambientLightUpdateTimer -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
CalculateAmbientLights();
|
||||
ambientLightUpdateTimer = AmbientLightUpdateInterval;
|
||||
}
|
||||
|
||||
foreach (Hull hull in hullAmbientLights.Keys)
|
||||
{
|
||||
if (!smoothedHullAmbientLights.ContainsKey(hull))
|
||||
{
|
||||
smoothedHullAmbientLights.Add(hull, Color.TransparentBlack);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Hull hull in smoothedHullAmbientLights.Keys.ToList())
|
||||
{
|
||||
Color targetColor = Color.TransparentBlack;
|
||||
hullAmbientLights.TryGetValue(hull, out targetColor);
|
||||
smoothedHullAmbientLights[hull] = Color.Lerp(smoothedHullAmbientLights[hull], targetColor, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<LightSource> activeLights = new List<LightSource>(capacity: 100);
|
||||
private readonly List<LightSource> activeLights = new List<LightSource>(capacity: 100);
|
||||
|
||||
public void UpdateLightMap(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, RenderTarget2D backgroundObstructor = null)
|
||||
{
|
||||
if (!LightingEnabled) return;
|
||||
|
||||
if (!LightingEnabled) { return; }
|
||||
|
||||
if (Math.Abs(currLightMapScale - GameMain.Config.LightMapScale) > 0.01f)
|
||||
{
|
||||
//lightmap scale has changed -> recreate render targets
|
||||
@@ -261,16 +210,14 @@ namespace Barotrauma.Lights
|
||||
//draw background lights
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
graphics.SetRenderTarget(LightMap);
|
||||
graphics.Clear(Color.Black);
|
||||
graphics.Clear(AmbientLight);
|
||||
graphics.BlendState = BlendState.Additive;
|
||||
bool backgroundSpritesDrawn = false;
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (!light.IsBackground) { continue; }
|
||||
light.DrawSprite(spriteBatch, cam);
|
||||
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
|
||||
backgroundSpritesDrawn = true;
|
||||
}
|
||||
GameMain.ParticleManager.Draw(spriteBatch, true, null, Particles.ParticleBlendState.Additive);
|
||||
spriteBatch.End();
|
||||
@@ -278,33 +225,34 @@ namespace Barotrauma.Lights
|
||||
//draw a black rectangle on hulls to hide background lights behind subs
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
Dictionary<Hull, Rectangle> visibleHulls = null;
|
||||
if (backgroundSpritesDrawn)
|
||||
if (backgroundObstructor != null)
|
||||
{
|
||||
if (backgroundObstructor != null)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||
spriteBatch.Draw(backgroundObstructor, new Rectangle(0, 0,
|
||||
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)), Color.Black);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
visibleHulls = GetVisibleHulls(cam);
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, transformMatrix: spriteBatchTransform);
|
||||
foreach (Rectangle drawRect in visibleHulls.Values)
|
||||
{
|
||||
//TODO: draw some sort of smoothed rectangle
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(drawRect.X, -drawRect.Y),
|
||||
new Vector2(drawRect.Width, drawRect.Height),
|
||||
Color.Black, true);
|
||||
}
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||
spriteBatch.Draw(backgroundObstructor, new Rectangle(0, 0,
|
||||
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)), Color.Black);
|
||||
spriteBatch.End();
|
||||
|
||||
|
||||
graphics.BlendState = BlendState.Additive;
|
||||
}
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, transformMatrix: spriteBatchTransform);
|
||||
Dictionary<Hull, Rectangle> visibleHulls = GetVisibleHulls(cam);
|
||||
foreach (KeyValuePair<Hull, Rectangle> hull in visibleHulls)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(hull.Value.X, -hull.Value.Y),
|
||||
new Vector2(hull.Value.Width, hull.Value.Height),
|
||||
hull.Key.AmbientLight == Color.TransparentBlack ? Color.Black : hull.Key.AmbientLight.Multiply(hull.Key.AmbientLight.A / 255.0f), true);
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
|
||||
SolidColorEffect.Parameters["color"].SetValue(AmbientLight.ToVector4());
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform, effect: SolidColorEffect);
|
||||
Submarine.DrawDamageable(spriteBatch, null);
|
||||
spriteBatch.End();
|
||||
|
||||
graphics.BlendState = BlendState.Additive;
|
||||
|
||||
|
||||
//draw the focused item and character to highlight them,
|
||||
//and light sprites (done before drawing the actual light volumes so we can make characters obstruct the highlights and sprites)
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
@@ -327,33 +275,37 @@ namespace Barotrauma.Lights
|
||||
//draw characters to obstruct the highlighted items/characters and light sprites
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
|
||||
SolidColorEffect.Parameters["color"].SetValue(Color.Black.ToVector4());
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidVertexColor"];
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.CurrentHull == null || !character.Enabled) continue;
|
||||
if (Character.Controlled?.FocusedCharacter == character) continue;
|
||||
if (character.CurrentHull == null || !character.Enabled) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.DeformSprite != null) continue;
|
||||
limb.Draw(spriteBatch, cam, Color.Black);
|
||||
if (limb.DeformSprite != null) { continue; }
|
||||
limb.Draw(spriteBatch, cam, lightColor);
|
||||
}
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidColor"];
|
||||
DeformableSprite.Effect.Parameters["solidColor"].SetValue(Color.Black.ToVector4());
|
||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidVertexColor"];
|
||||
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.CurrentHull == null || !character.Enabled) continue;
|
||||
if (Character.Controlled?.FocusedCharacter == character) continue;
|
||||
if (character.CurrentHull == null || !character.Enabled) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.DeformSprite == null) continue;
|
||||
limb.Draw(spriteBatch, cam, Color.Black);
|
||||
if (limb.DeformSprite == null) { continue; }
|
||||
limb.Draw(spriteBatch, cam, lightColor);
|
||||
}
|
||||
}
|
||||
spriteBatch.End();
|
||||
@@ -364,8 +316,6 @@ namespace Barotrauma.Lights
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(cam.WorldView.X, -cam.WorldView.Y, cam.WorldView.Width, cam.WorldView.Height), AmbientLight, isFilled: true);
|
||||
|
||||
spriteBatch.Draw(LimbLightMap, new Rectangle(cam.WorldView.X, -cam.WorldView.Y, cam.WorldView.Width, cam.WorldView.Height), Color.White);
|
||||
|
||||
foreach (ElectricalDischarger discharger in ElectricalDischarger.List)
|
||||
@@ -382,24 +332,7 @@ namespace Barotrauma.Lights
|
||||
lightEffect.World = transform;
|
||||
|
||||
GameMain.ParticleManager.Draw(spriteBatch, false, null, Particles.ParticleBlendState.Additive);
|
||||
|
||||
if (UseHullSpecificAmbientLight)
|
||||
{
|
||||
if (visibleHulls == null)
|
||||
{
|
||||
visibleHulls = GetVisibleHulls(cam);
|
||||
}
|
||||
foreach (Hull hull in smoothedHullAmbientLights.Keys)
|
||||
{
|
||||
if (smoothedHullAmbientLights[hull].A < 0.01f) continue;
|
||||
if (!visibleHulls.TryGetValue(hull, out Rectangle drawRect)) continue;
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(drawRect.X, -drawRect.Y),
|
||||
new Vector2(hull.Rect.Width, hull.Rect.Height),
|
||||
smoothedHullAmbientLights[hull], true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
Vector2 haloDrawPos = Character.Controlled.DrawPosition;
|
||||
@@ -601,7 +534,10 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
penumbraVerts.AddRange(convexHull.PenumbraVertices);
|
||||
if (convexHull.ShadowVertexCount > 0)
|
||||
{
|
||||
penumbraVerts.AddRange(convexHull.PenumbraVertices);
|
||||
}
|
||||
}
|
||||
|
||||
if (shadowVerts.Count > 0)
|
||||
@@ -622,86 +558,6 @@ namespace Barotrauma.Lights
|
||||
graphics.SetRenderTarget(null);
|
||||
}
|
||||
|
||||
|
||||
private void CalculateAmbientLights()
|
||||
{
|
||||
hullAmbientLights.Clear();
|
||||
|
||||
foreach (LightSource light in lights)
|
||||
{
|
||||
if (light.Color.A < 1f || light.Range < 1.0f || light.IsBackground) continue;
|
||||
|
||||
var newAmbientLights = AmbientLightHulls(light);
|
||||
foreach (Hull hull in newAmbientLights.Keys)
|
||||
{
|
||||
if (hullAmbientLights.ContainsKey(hull))
|
||||
{
|
||||
//hull already lit by some other light source -> add the ambient lights up
|
||||
hullAmbientLights[hull] = new Color(
|
||||
hullAmbientLights[hull].R + newAmbientLights[hull].R,
|
||||
hullAmbientLights[hull].G + newAmbientLights[hull].G,
|
||||
hullAmbientLights[hull].B + newAmbientLights[hull].B,
|
||||
hullAmbientLights[hull].A + newAmbientLights[hull].A);
|
||||
}
|
||||
else
|
||||
{
|
||||
hullAmbientLights.Add(hull, newAmbientLights[hull]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add ambient light to the hull the lightsource is inside + all adjacent hulls connected by a gap
|
||||
/// </summary>
|
||||
private Dictionary<Hull, Color> AmbientLightHulls(LightSource light)
|
||||
{
|
||||
Dictionary<Hull, Color> hullAmbientLight = new Dictionary<Hull, Color>();
|
||||
|
||||
var hull = Hull.FindHull(light.WorldPosition);
|
||||
if (hull == null) return hullAmbientLight;
|
||||
|
||||
return AmbientLightHulls(hull, hullAmbientLight, light.Color * Math.Min(light.Range / 1000.0f, 1.0f));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A flood fill algorithm that adds ambient light to all hulls the starting hull is connected to
|
||||
/// </summary>
|
||||
private Dictionary<Hull, Color> AmbientLightHulls(Hull hull, Dictionary<Hull, Color> hullAmbientLight, Color currColor)
|
||||
{
|
||||
if (hullAmbientLight.ContainsKey(hull))
|
||||
{
|
||||
if (hullAmbientLight[hull].A > currColor.A)
|
||||
return hullAmbientLight;
|
||||
else
|
||||
hullAmbientLight[hull] = currColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
hullAmbientLight.Add(hull, currColor);
|
||||
}
|
||||
|
||||
Color nextHullLight = currColor * AmbientLightFalloff;
|
||||
//light getting too dark to notice -> no need to spread further
|
||||
if (nextHullLight.A < 20) return hullAmbientLight;
|
||||
|
||||
//use hashset to make sure that each hull is only included once
|
||||
HashSet<Hull> hulls = new HashSet<Hull>();
|
||||
foreach (Gap g in hull.ConnectedGaps)
|
||||
{
|
||||
if (!g.IsRoomToRoom || !g.PassAmbientLight || g.Open < 0.5f) continue;
|
||||
|
||||
hulls.Add((g.linkedTo[0] == hull ? g.linkedTo[1] : g.linkedTo[0]) as Hull);
|
||||
}
|
||||
|
||||
foreach (Hull h in hulls)
|
||||
{
|
||||
hullAmbientLight = AmbientLightHulls(h, hullAmbientLight, nextHullLight);
|
||||
}
|
||||
|
||||
return hullAmbientLight;
|
||||
}
|
||||
|
||||
public void ClearLights()
|
||||
{
|
||||
lights.Clear();
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; private set; } = new Dictionary<string, SerializableProperty>();
|
||||
|
||||
[Serialize("1.0,1.0,1.0,1.0", true), Editable]
|
||||
[Serialize("1.0,1.0,1.0,1.0", true, alwaysUseInstanceValues: true), Editable]
|
||||
public Color Color
|
||||
{
|
||||
get;
|
||||
@@ -25,7 +25,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
private float range;
|
||||
|
||||
[Serialize(100.0f, true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f)]
|
||||
[Serialize(100.0f, true, alwaysUseInstanceValues: true), Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f)]
|
||||
public float Range
|
||||
{
|
||||
get { return range; }
|
||||
@@ -331,7 +331,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
if (lightSourceParams.DeformableLightSpriteElement != null)
|
||||
{
|
||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement);
|
||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement, invert: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ namespace Barotrauma.Lights
|
||||
lightSourceParams.Persistent = true;
|
||||
if (lightSourceParams.DeformableLightSpriteElement != null)
|
||||
{
|
||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement);
|
||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement, invert: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,23 +952,44 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
Vector2 origin = DeformableLightSprite.Origin;
|
||||
Vector2 drawPos = position;
|
||||
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
||||
if (ParentSub != null)
|
||||
{
|
||||
drawPos += ParentSub.DrawPosition;
|
||||
}
|
||||
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
origin.X = DeformableLightSprite.Sprite.SourceRect.Width - origin.X;
|
||||
}
|
||||
if (LightSpriteEffect == SpriteEffects.FlipVertically)
|
||||
{
|
||||
origin.Y = DeformableLightSprite.Sprite.SourceRect.Height - origin.Y;
|
||||
}
|
||||
|
||||
DeformableLightSprite.Draw(
|
||||
cam, new Vector3(drawPos, 0.0f),
|
||||
origin, -Rotation, SpriteScale,
|
||||
new Color(Color, lightSourceParams.OverrideLightSpriteAlpha ?? Color.A / 255.0f),
|
||||
LightSpriteEffect == SpriteEffects.FlipHorizontally);
|
||||
LightSpriteEffect == SpriteEffects.FlipVertically);
|
||||
}
|
||||
|
||||
if (LightSprite != null)
|
||||
{
|
||||
Vector2 origin = LightSprite.Origin;
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) origin.X = LightSprite.SourceRect.Width - origin.X;
|
||||
if (LightSpriteEffect == SpriteEffects.FlipVertically) origin.Y = LightSprite.SourceRect.Height - origin.Y;
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
origin.X = LightSprite.SourceRect.Width - origin.X;
|
||||
}
|
||||
if (LightSpriteEffect == SpriteEffects.FlipVertically)
|
||||
{
|
||||
origin.Y = LightSprite.SourceRect.Height - origin.Y;
|
||||
}
|
||||
|
||||
Vector2 drawPos = position;
|
||||
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
||||
if (ParentSub != null)
|
||||
{
|
||||
drawPos += ParentSub.DrawPosition;
|
||||
}
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
LightSprite.Draw(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
@@ -151,7 +151,8 @@ namespace Barotrauma
|
||||
{
|
||||
selectedList.ForEach(e =>
|
||||
{
|
||||
e.Remove();
|
||||
//orphaned wires may already have been removed
|
||||
if (!e.Removed) { e.Remove(); }
|
||||
});
|
||||
selectedList.Clear();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!GameMain.SubEditorScreen.ShowThalamus && prefab.Category.HasFlag(MapEntityCategory.Thalamus))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return HasBody ? ShowWalls : ShowStructures;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
@@ -31,6 +31,7 @@ namespace Barotrauma
|
||||
Stream = sound.Stream;
|
||||
Range = element.GetAttributeFloat("range", 1000.0f);
|
||||
Volume = element.GetAttributeFloat("volume", 1.0f);
|
||||
sound.IgnoreMuffling = element.GetAttributeBool("dontmuffle", false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +88,7 @@ namespace Barotrauma
|
||||
existingSound = GameMain.SoundManager.LoadSound(filename, stream);
|
||||
if (existingSound == null) { return null; }
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
catch (System.IO.FileNotFoundException e)
|
||||
{
|
||||
string errorMsg = "Failed to load sound file \"" + filename + "\".";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
@@ -19,9 +19,9 @@ namespace Barotrauma
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(Convert.FromBase64String(previewImageData)))
|
||||
using (System.IO.MemoryStream mem = new System.IO.MemoryStream(Convert.FromBase64String(previewImageData)))
|
||||
{
|
||||
var texture = TextureLoader.FromStream(mem, path: FilePath);
|
||||
var texture = TextureLoader.FromStream(mem, path: FilePath, compress: false);
|
||||
if (texture == null) { throw new Exception("PreviewImage texture returned null"); }
|
||||
PreviewImage = new Sprite(texture, null, null);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Barotrauma
|
||||
{
|
||||
partial class WayPoint : MapEntity
|
||||
{
|
||||
private static Dictionary<SpawnType, Sprite> iconSprites;
|
||||
private static Dictionary<string, Sprite> iconSprites;
|
||||
private const int WaypointSize = 12, SpawnPointSize = 32;
|
||||
|
||||
public override bool IsVisible(Rectangle worldView)
|
||||
@@ -56,10 +56,18 @@ namespace Barotrauma
|
||||
Color.White);
|
||||
}
|
||||
|
||||
Sprite sprite = iconSprites[SpawnType];
|
||||
Sprite sprite = iconSprites[SpawnType.ToString()];
|
||||
if (spawnType == SpawnType.Human && AssignedJob?.Icon != null)
|
||||
{
|
||||
sprite = iconSprites[SpawnType.Path];
|
||||
sprite = iconSprites["Path"];
|
||||
}
|
||||
else if (ConnectedDoor != null)
|
||||
{
|
||||
sprite = iconSprites["Door"];
|
||||
}
|
||||
else if (Ladders != null)
|
||||
{
|
||||
sprite = iconSprites["Ladder"];
|
||||
}
|
||||
sprite.Draw(spriteBatch, drawPos, clr, scale: iconSize / (float)sprite.SourceRect.Width, depth: 0.001f);
|
||||
sprite.RelativeOrigin = Vector2.One * 0.5f;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -18,8 +18,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static void Start(ProcessStartInfo processInfo)
|
||||
{
|
||||
writePipe = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
|
||||
readPipe = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
|
||||
writePipe = new AnonymousPipeServerStream(PipeDirection.Out, System.IO.HandleInheritability.Inheritable);
|
||||
readPipe = new AnonymousPipeServerStream(PipeDirection.In, System.IO.HandleInheritability.Inheritable);
|
||||
|
||||
writeStream = writePipe; readStream = readPipe;
|
||||
|
||||
@@ -38,6 +38,13 @@ namespace Barotrauma.Networking
|
||||
localHandlesDisposed = true;
|
||||
}
|
||||
|
||||
public static void ClosePipes()
|
||||
{
|
||||
writePipe?.Close();
|
||||
readPipe?.Close();
|
||||
shutDown = true;
|
||||
}
|
||||
|
||||
public static void ShutDown()
|
||||
{
|
||||
Process?.Kill(); Process = null;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
@@ -100,7 +100,7 @@ namespace Barotrauma.Networking
|
||||
WriteStream = null;
|
||||
}
|
||||
|
||||
WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
WriteStream = File.Open(FilePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
|
||||
TimeStarted = Environment.TickCount;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
newTransfer.OpenStream();
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (System.IO.IOException e)
|
||||
{
|
||||
if (i < maxRetries)
|
||||
{
|
||||
@@ -422,7 +422,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(fileName) ||
|
||||
fileName.IndexOfAny(Path.GetInvalidFileNameChars()) > -1)
|
||||
fileName.IndexOfAny(Path.GetInvalidFileNameChars().ToArray()) > -1)
|
||||
{
|
||||
errorMessage = "Illegal characters in file name ''" + fileName + "''";
|
||||
return false;
|
||||
@@ -455,7 +455,7 @@ namespace Barotrauma.Networking
|
||||
switch (fileTransfer.FileType)
|
||||
{
|
||||
case FileTransferType.Submarine:
|
||||
Stream stream;
|
||||
System.IO.Stream stream;
|
||||
try
|
||||
{
|
||||
stream = SaveUtil.DecompressFiletoStream(fileTransfer.FilePath);
|
||||
|
||||
@@ -3,7 +3,7 @@ using Barotrauma.Steam;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -52,7 +52,7 @@ namespace Barotrauma.Networking
|
||||
public GUITickBox EndVoteTickBox;
|
||||
private GUIComponent buttonContainer;
|
||||
|
||||
private NetStats netStats;
|
||||
public readonly NetStats NetStats;
|
||||
|
||||
protected GUITickBox cameraFollowsSub;
|
||||
|
||||
@@ -169,9 +169,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
allowReconnect = true;
|
||||
|
||||
netStats = new NetStats();
|
||||
NetStats = new NetStats();
|
||||
|
||||
inGameHUD = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null)
|
||||
inGameHUD = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -569,14 +569,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
/*TODO: reimplement
|
||||
if (ShowNetStats && client?.ServerConnection != null)
|
||||
{
|
||||
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, client.ServerConnection.Statistics.ReceivedBytes);
|
||||
netStats.AddValue(NetStats.NetStatType.SentBytes, client.ServerConnection.Statistics.SentBytes);
|
||||
netStats.AddValue(NetStats.NetStatType.ResentMessages, client.ServerConnection.Statistics.ResentMessages);
|
||||
netStats.Update(deltaTime);
|
||||
}*/
|
||||
NetStats.Update(deltaTime);
|
||||
|
||||
UpdateHUD(deltaTime);
|
||||
|
||||
@@ -781,7 +774,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (readyToStart && !CoroutineManager.IsCoroutineRunning("WaitForStartRound"))
|
||||
{
|
||||
CoroutineManager.StartCoroutine(GameMain.NetLobbyScreen.WaitForStartRound(startButton: null, allowCancel: false), "WaitForStartRound");
|
||||
CoroutineManager.StartCoroutine(GameMain.NetLobbyScreen.WaitForStartRound(startButton: null), "WaitForStartRound");
|
||||
}
|
||||
break;
|
||||
case ServerPacketHeader.STARTGAME:
|
||||
@@ -1455,6 +1448,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
var teamID = i == 0 ? Character.TeamType.Team1 : Character.TeamType.Team2;
|
||||
Submarine.MainSubs[i].TeamID = teamID;
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine == null) { continue; }
|
||||
if (item.Submarine != Submarine.MainSubs[i] && !Submarine.MainSubs[i].DockedTo.Contains(item.Submarine)) { continue; }
|
||||
foreach (WifiComponent wifiComponent in item.GetComponents<WifiComponent>())
|
||||
{
|
||||
wifiComponent.TeamID = Submarine.MainSubs[i].TeamID;
|
||||
}
|
||||
}
|
||||
foreach (Submarine sub in Submarine.MainSubs[i].DockedTo)
|
||||
{
|
||||
sub.TeamID = teamID;
|
||||
@@ -1891,8 +1893,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
DebugConsole.ThrowError("Writing object data to \"crashreport_object.bin\", please send this file to us at http://github.com/Regalis11/Barotrauma/issues");
|
||||
|
||||
using (FileStream fl = File.Open("crashreport_object.bin", FileMode.Create))
|
||||
using (BinaryWriter sw = new BinaryWriter(fl))
|
||||
using (FileStream fl = File.Open("crashreport_object.bin", System.IO.FileMode.Create))
|
||||
using (System.IO.BinaryWriter sw = new System.IO.BinaryWriter(fl))
|
||||
{
|
||||
sw.Write(inc.Buffer, (int)(prevBytePos - prevByteLength), (int)(prevByteLength));
|
||||
}
|
||||
@@ -2759,15 +2761,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (!ShowNetStats) return;
|
||||
|
||||
netStats.Draw(spriteBatch, new Rectangle(300, 10, 300, 150));
|
||||
NetStats.Draw(spriteBatch, new Rectangle(300, 10, 300, 150));
|
||||
|
||||
/* TODO: reimplement
|
||||
int width = 200, height = 300;
|
||||
int x = GameMain.GraphicsWidth - width, y = (int)(GameMain.GraphicsHeight * 0.3f);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
||||
GUI.Font.DrawString(spriteBatch, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
||||
|
||||
/* TODO: reimplement
|
||||
if (client.ServerConnection != null)
|
||||
{
|
||||
GUI.Font.DrawString(spriteBatch, "Ping: " + (int)(client.ServerConnection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 10, y + 25), Color.White);
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace Barotrauma.Networking
|
||||
ResentMessages = 2
|
||||
}
|
||||
|
||||
private Graph[] graphs;
|
||||
private readonly Graph[] graphs;
|
||||
|
||||
private float[] totalValue;
|
||||
private float[] lastValue;
|
||||
private readonly float[] totalValue;
|
||||
private readonly float[] lastValue;
|
||||
|
||||
const float UpdateInterval = 0.1f;
|
||||
float updateTimer;
|
||||
@@ -37,9 +37,7 @@ namespace Barotrauma.Networking
|
||||
public void AddValue(NetStatType statType, float value)
|
||||
{
|
||||
float valueChange = value - lastValue[(int)statType];
|
||||
|
||||
totalValue[(int)statType] += valueChange;
|
||||
|
||||
lastValue[(int)statType] = value;
|
||||
}
|
||||
|
||||
@@ -51,7 +49,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
|
||||
graphs[i].Update(totalValue[i] / UpdateInterval);
|
||||
totalValue[i] = 0.0f;
|
||||
}
|
||||
@@ -64,23 +61,22 @@ namespace Barotrauma.Networking
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.Black * 0.4f, true);
|
||||
|
||||
graphs[(int)NetStatType.ReceivedBytes].Draw(spriteBatch, rect, null, 0.0f, Color.Cyan);
|
||||
|
||||
graphs[(int)NetStatType.SentBytes].Draw(spriteBatch, rect, null, 0.0f, GUI.Style.Orange);
|
||||
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, null, 0.0f, GUI.Style.Red);
|
||||
if (graphs[(int)NetStatType.ResentMessages].Average() > 0)
|
||||
{
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, null, 0.0f, GUI.Style.Red);
|
||||
GUI.SmallFont.DrawString(spriteBatch, "Peak resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 50), GUI.Style.Red);
|
||||
}
|
||||
|
||||
GUI.SmallFont.DrawString(spriteBatch,
|
||||
"Peak received: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.ReceivedBytes].LargestValue()) + "/s " +
|
||||
"Avg received: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.ReceivedBytes].Average()) + "/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 10), Color.Cyan);
|
||||
|
||||
|
||||
GUI.SmallFont.DrawString(spriteBatch, "Peak sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].LargestValue()) + "/s " +
|
||||
"Avg sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].Average()) + "/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 30), GUI.Style.Orange);
|
||||
|
||||
GUI.SmallFont.DrawString(spriteBatch, "Peak resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 50), GUI.Style.Red);
|
||||
#if DEBUG
|
||||
/*int y = 10;
|
||||
|
||||
|
||||
@@ -97,6 +97,9 @@ namespace Barotrauma.Networking
|
||||
incomingLidgrenMessages.Clear();
|
||||
netClient.ReadMessages(incomingLidgrenMessages);
|
||||
|
||||
GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.ReceivedBytes, netClient.Statistics.ReceivedBytes);
|
||||
GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.SentBytes, netClient.Statistics.SentBytes);
|
||||
|
||||
foreach (NetIncomingMessage inc in incomingLidgrenMessages)
|
||||
{
|
||||
if (inc.SenderConnection != (ServerConnection as LidgrenConnection).NetConnection) { continue; }
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace Barotrauma.Networking
|
||||
private double timeout;
|
||||
private double heartbeatTimer;
|
||||
|
||||
private long sentBytes, receivedBytes;
|
||||
|
||||
private List<IReadMessage> incomingInitializationMessages;
|
||||
private List<IReadMessage> incomingDataMessages;
|
||||
|
||||
@@ -63,6 +65,7 @@ namespace Barotrauma.Networking
|
||||
outMsg.Write((byte)ConnectionInitialization.ConnectionStarted);
|
||||
|
||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
|
||||
initializationStep = ConnectionInitialization.SteamTicketAndVersion;
|
||||
|
||||
@@ -99,11 +102,11 @@ namespace Barotrauma.Networking
|
||||
if (isConnectionInitializationStep)
|
||||
{
|
||||
ulong low = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8);
|
||||
ulong high = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8+32);
|
||||
ulong high = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8 + 32);
|
||||
ulong lobbyId = low + (high << 32);
|
||||
|
||||
Steam.SteamManager.JoinLobby(lobbyId, false);
|
||||
IReadMessage inc = new ReadOnlyMessage(data, false, 1+8, dataLength - 9, ServerConnection);
|
||||
IReadMessage inc = new ReadOnlyMessage(data, false, 1 + 8, dataLength - 9, ServerConnection);
|
||||
if (initializationStep != ConnectionInitialization.Success)
|
||||
{
|
||||
incomingInitializationMessages.Add(inc);
|
||||
@@ -137,16 +140,20 @@ namespace Barotrauma.Networking
|
||||
timeout -= deltaTime;
|
||||
heartbeatTimer -= deltaTime;
|
||||
|
||||
for (int i=0;i<100;i++)
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
if (!Steamworks.SteamNetworking.IsP2PPacketAvailable()) { break; }
|
||||
var packet = Steamworks.SteamNetworking.ReadP2PPacket();
|
||||
if (packet.HasValue)
|
||||
{
|
||||
OnP2PData(packet?.SteamId ?? 0, packet?.Data, packet?.Data.Length ?? 0, 0);
|
||||
receivedBytes += packet?.Data.Length ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.ReceivedBytes, receivedBytes);
|
||||
GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.SentBytes, sentBytes);
|
||||
|
||||
if (heartbeatTimer < 0.0)
|
||||
{
|
||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||
@@ -154,6 +161,7 @@ namespace Barotrauma.Networking
|
||||
outMsg.Write((byte)PacketHeader.IsHeartbeatMessage);
|
||||
|
||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Unreliable);
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
|
||||
heartbeatTimer = 5.0;
|
||||
}
|
||||
@@ -227,6 +235,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
heartbeatTimer = 5.0;
|
||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
break;
|
||||
case ConnectionInitialization.ContentPackageOrder:
|
||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion ||
|
||||
@@ -254,7 +263,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
break;
|
||||
case ConnectionInitialization.Password:
|
||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion) { initializationStep = ConnectionInitialization.Password; }
|
||||
@@ -334,6 +343,7 @@ namespace Barotrauma.Networking
|
||||
private void Send(byte[] buf, int length, Steamworks.P2PSend sendType)
|
||||
{
|
||||
bool successSend = Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, buf, length + 4, 0, sendType);
|
||||
sentBytes += length + 4;
|
||||
if (!successSend)
|
||||
{
|
||||
if (sendType != Steamworks.P2PSend.Reliable)
|
||||
@@ -341,6 +351,7 @@ namespace Barotrauma.Networking
|
||||
DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + length.ToString() + " bytes)");
|
||||
sendType = Steamworks.P2PSend.Reliable;
|
||||
successSend = Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, buf, length + 4, 0, sendType);
|
||||
sentBytes += length + 4;
|
||||
}
|
||||
if (!successSend)
|
||||
{
|
||||
@@ -364,6 +375,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
heartbeatTimer = 5.0;
|
||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
}
|
||||
|
||||
public override void Close(string msg = null)
|
||||
@@ -380,6 +392,7 @@ namespace Barotrauma.Networking
|
||||
outMsg.Write(msg ?? "Disconnected");
|
||||
|
||||
Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ namespace Barotrauma.Networking
|
||||
private bool isActive;
|
||||
|
||||
private ConnectionInitialization initializationStep;
|
||||
private UInt64 selfSteamID;
|
||||
private readonly UInt64 selfSteamID;
|
||||
|
||||
private long sentBytes, receivedBytes;
|
||||
|
||||
class RemotePeer
|
||||
{
|
||||
@@ -204,22 +206,24 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<100;i++)
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
if (!Steamworks.SteamNetworking.IsP2PPacketAvailable()) { break; }
|
||||
var packet = Steamworks.SteamNetworking.ReadP2PPacket();
|
||||
if (packet.HasValue)
|
||||
{
|
||||
OnP2PData(packet?.SteamId ?? 0, packet?.Data, packet?.Data.Length ?? 0, 0);
|
||||
receivedBytes += packet?.Data.Length ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.ReceivedBytes, receivedBytes);
|
||||
GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.SentBytes, sentBytes);
|
||||
|
||||
while (ChildServerRelay.Read(out byte[] incBuf))
|
||||
{
|
||||
ChildServerRelay.DisposeLocalHandles();
|
||||
|
||||
IReadMessage inc = new ReadOnlyMessage(incBuf, false, 0, incBuf.Length, ServerConnection);
|
||||
|
||||
HandleDataMessage(inc);
|
||||
}
|
||||
}
|
||||
@@ -295,6 +299,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
bool successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType);
|
||||
sentBytes += p2pData.Length;
|
||||
|
||||
if (!successSend)
|
||||
{
|
||||
@@ -303,6 +308,7 @@ namespace Barotrauma.Networking
|
||||
DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + p2pData.Length.ToString() + " bytes)");
|
||||
sendType = Steamworks.P2PSend.Reliable;
|
||||
successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType);
|
||||
sentBytes += p2pData.Length;
|
||||
}
|
||||
if (!successSend)
|
||||
{
|
||||
@@ -336,7 +342,6 @@ namespace Barotrauma.Networking
|
||||
byte[] msgToSend = (byte[])outMsg.Buffer.Clone();
|
||||
Array.Resize(ref msgToSend, outMsg.LengthBytes);
|
||||
ChildServerRelay.Write(msgToSend);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -369,6 +374,7 @@ namespace Barotrauma.Networking
|
||||
outMsg.Write(msg);
|
||||
|
||||
Steamworks.SteamNetworking.SendP2PPacket(peer.SteamID, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
|
||||
sentBytes += outMsg.LengthBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -405,7 +411,7 @@ namespace Barotrauma.Networking
|
||||
ClosePeerSession(remotePeers[i]);
|
||||
}
|
||||
|
||||
ChildServerRelay.ShutDown();
|
||||
ChildServerRelay.ClosePipes();
|
||||
|
||||
OnDisconnect?.Invoke();
|
||||
|
||||
|
||||
@@ -26,10 +26,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void CreateLogFrame()
|
||||
{
|
||||
LogFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker")
|
||||
LogFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null)
|
||||
{
|
||||
OnClicked = (btn, userdata) => { if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) LogFrame = null; return true; }
|
||||
};
|
||||
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, LogFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
new GUIButton(new RectTransform(Vector2.One, LogFrame.RectTransform), "", style: null).OnClicked += (btn, userData) =>
|
||||
{
|
||||
LogFrame = null;
|
||||
|
||||
@@ -266,7 +266,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
//background frame
|
||||
settingsFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f);
|
||||
settingsFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, settingsFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null).OnClicked += (btn, userData) =>
|
||||
{
|
||||
if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) { ToggleSettingsFrame(btn, userData); }
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RestSharp.Contrib;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -250,7 +249,8 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
};
|
||||
|
||||
Steamworks.Data.LobbyQuery lobbyQuery = Steamworks.SteamMatchmaking.CreateLobbyQuery().FilterDistanceWorldwide();
|
||||
//TODO: find a better strategy to fetch all lobbies, this is gonna take forever if we actually have 10000 lobbies
|
||||
Steamworks.Data.LobbyQuery lobbyQuery = Steamworks.SteamMatchmaking.CreateLobbyQuery().FilterDistanceWorldwide().WithMaxResults(10000);
|
||||
|
||||
TaskPool.Add(Task.Run(async () =>
|
||||
{
|
||||
@@ -578,7 +578,7 @@ namespace Barotrauma.Steam
|
||||
if (!isInitialized) return;
|
||||
|
||||
var query = new Steamworks.Ugc.Query(Steamworks.UgcType.All)
|
||||
.RankedByTotalUniqueSubscriptions()
|
||||
.RankedByTrend()
|
||||
.WithLongDescription();
|
||||
if (requireTags != null) query.WithTags(requireTags);
|
||||
|
||||
@@ -754,7 +754,7 @@ namespace Barotrauma.Steam
|
||||
|
||||
if (!CheckWorkshopItemEnabled(existingItem))
|
||||
{
|
||||
if (!EnableWorkShopItem(existingItem, false, out string errorMsg))
|
||||
if (!EnableWorkShopItem(existingItem, out string errorMsg))
|
||||
{
|
||||
DebugConsole.NewMessage(errorMsg, Color.Red);
|
||||
new GUIMessageBox(
|
||||
@@ -881,6 +881,10 @@ namespace Barotrauma.Steam
|
||||
DebugConsole.NewMessage("Published workshop item " + item?.Title + " successfully.", Microsoft.Xna.Framework.Color.LightGreen);
|
||||
|
||||
contentPackage.SteamWorkshopUrl = $"http://steamcommunity.com/sharedfiles/filedetails/?source=Facepunch.Steamworks&id={task.Result.FileId.Value}";
|
||||
//NOTE: This sets InstallTime one hour into the future to guarantee
|
||||
//that the published content package won't be autoupdated incorrectly.
|
||||
//Change if it causes issues.
|
||||
contentPackage.InstallTime = DateTime.UtcNow + TimeSpan.FromHours(1);
|
||||
contentPackage.Save(contentPackage.Path);
|
||||
|
||||
SubscribeToWorkshopItem(task.Result.FileId);
|
||||
@@ -892,7 +896,7 @@ namespace Barotrauma.Steam
|
||||
/// <summary>
|
||||
/// Enables a workshop item by moving it to the game folder.
|
||||
/// </summary>
|
||||
public static bool EnableWorkShopItem(Steamworks.Ugc.Item? item, bool allowFileOverwrite, out string errorMsg, bool selectContentPackage = false, bool suppressInstallNotif = false)
|
||||
public static bool EnableWorkShopItem(Steamworks.Ugc.Item? item, out string errorMsg, bool selectContentPackage = false, bool suppressInstallNotif = false)
|
||||
{
|
||||
if (!(item?.IsInstalled ?? false))
|
||||
{
|
||||
@@ -916,7 +920,8 @@ namespace Barotrauma.Steam
|
||||
};
|
||||
string newContentPackagePath = GetWorkshopItemContentPackagePath(contentPackage);
|
||||
|
||||
if (ContentPackage.List.Any(cp => cp.Path.CleanUpPath() == newContentPackagePath.CleanUpPath()))
|
||||
List<ContentPackage> existingPackages = ContentPackage.List.Where(cp => cp.Path.CleanUpPath() == newContentPackagePath.CleanUpPath()).ToList();
|
||||
if (existingPackages.Any())
|
||||
{
|
||||
if (item?.Owner.Id != Steamworks.SteamClient.SteamId)
|
||||
{
|
||||
@@ -952,15 +957,9 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
if (modCopiesInProgress.ContainsKey(item.Value.Id))
|
||||
{
|
||||
if (!modCopiesInProgress[item.Value.Id].IsCompleted &&
|
||||
!modCopiesInProgress[item.Value.Id].IsFaulted &&
|
||||
!modCopiesInProgress[item.Value.Id].IsCanceled)
|
||||
{
|
||||
errorMsg = ""; return true;
|
||||
}
|
||||
modCopiesInProgress.Remove(item.Value.Id);
|
||||
errorMsg = ""; return true;
|
||||
}
|
||||
newTask = CopyWorkShopItemAsync(item, contentPackage, newContentPackagePath, metaDataFilePath, allowFileOverwrite);
|
||||
newTask = CopyWorkShopItemAsync(item, contentPackage, newContentPackagePath, metaDataFilePath);
|
||||
modCopiesInProgress.Add(item.Value.Id, newTask);
|
||||
}
|
||||
|
||||
@@ -968,67 +967,85 @@ namespace Barotrauma.Steam
|
||||
contentPackage,
|
||||
(task, cp) =>
|
||||
{
|
||||
if (task.IsFaulted || task.IsCanceled)
|
||||
try
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to copy \"{item?.Title}\"", task.Exception);
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(task.Result))
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to copy \"{item?.Title}\": {task.Result}");
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
|
||||
GameMain.Config.SuppressModFolderWatcher = true;
|
||||
|
||||
var newPackage = new ContentPackage(cp.Path, newContentPackagePath)
|
||||
{
|
||||
SteamWorkshopUrl = item?.Url,
|
||||
InstallTime = item?.Updated > item?.Created ? item?.Updated : item?.Created
|
||||
};
|
||||
|
||||
foreach (ContentFile contentFile in newPackage.Files)
|
||||
{
|
||||
contentFile.Path = CorrectContentFilePath(contentFile.Path, cp, true);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(Path.GetDirectoryName(newContentPackagePath)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(newContentPackagePath));
|
||||
}
|
||||
newPackage.Save(newContentPackagePath);
|
||||
ContentPackage.List.Add(newPackage);
|
||||
|
||||
if (selectContentPackage)
|
||||
{
|
||||
if (newPackage.CorePackage)
|
||||
if (task.IsFaulted || task.IsCanceled)
|
||||
{
|
||||
GameMain.Config.SelectCorePackage(newPackage);
|
||||
DebugConsole.ThrowError($"Failed to copy \"{item?.Title}\"", task.Exception);
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (!string.IsNullOrWhiteSpace(task.Result))
|
||||
{
|
||||
GameMain.Config.SelectContentPackage(newPackage);
|
||||
DebugConsole.ThrowError($"Failed to copy \"{item?.Title}\": {task.Result}");
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
GameMain.Config.WarnIfContentPackageSelectionDirty();
|
||||
GameMain.Config.SuppressModFolderWatcher = true;
|
||||
|
||||
if (newPackage.Files.Any(f => f.Type == ContentType.Submarine))
|
||||
var newPackage = new ContentPackage(cp.Path, newContentPackagePath)
|
||||
{
|
||||
SubmarineInfo.RefreshSavedSubs();
|
||||
SteamWorkshopUrl = item?.Url,
|
||||
InstallTime = item?.Updated > item?.Created ? item?.Updated : item?.Created
|
||||
};
|
||||
|
||||
foreach (ContentFile contentFile in newPackage.Files)
|
||||
{
|
||||
contentFile.Path = CorrectContentFilePath(contentFile.Path, contentFile.Type, cp, true);
|
||||
}
|
||||
|
||||
foreach (ContentFile file in existingPackages.SelectMany(p => p.Files))
|
||||
{
|
||||
string path = CorrectContentFilePath(file.Path, file.Type, cp, true).CleanUpPath();
|
||||
if (newPackage.Files.Any(f => f.Path.CleanUpPath() == path)) { continue; }
|
||||
newPackage.AddFile(path, file.Type);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(Path.GetDirectoryName(newContentPackagePath)))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(newContentPackagePath));
|
||||
}
|
||||
newPackage.Save(newContentPackagePath);
|
||||
ContentPackage.List.Add(newPackage);
|
||||
|
||||
if (selectContentPackage)
|
||||
{
|
||||
if (newPackage.CorePackage)
|
||||
{
|
||||
GameMain.Config.SelectCorePackage(newPackage);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Config.SelectContentPackage(newPackage);
|
||||
}
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
GameMain.Config.WarnIfContentPackageSelectionDirty();
|
||||
|
||||
if (newPackage.Files.Any(f => f.Type == ContentType.Submarine))
|
||||
{
|
||||
SubmarineInfo.RefreshSavedSubs();
|
||||
}
|
||||
}
|
||||
else if (!suppressInstallNotif)
|
||||
{
|
||||
GameMain.MainMenuScreen?.SetEnableModsNotification(true);
|
||||
}
|
||||
|
||||
GameMain.Config.SuppressModFolderWatcher = false;
|
||||
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Green);
|
||||
|
||||
}
|
||||
else if (!suppressInstallNotif)
|
||||
catch
|
||||
{
|
||||
GameMain.MainMenuScreen?.SetEnableModsNotification(true);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
modCopiesInProgress.Remove(item.Value.Id);
|
||||
}
|
||||
|
||||
GameMain.Config.SuppressModFolderWatcher = false;
|
||||
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Green);
|
||||
|
||||
});
|
||||
|
||||
errorMsg = "";
|
||||
@@ -1039,7 +1056,7 @@ namespace Barotrauma.Steam
|
||||
/// Asynchronously copies a Workshop item into the Mods folder.
|
||||
/// </summary>
|
||||
/// <returns>Returns an empty string on success, otherwise returns an error message.</returns>
|
||||
private async static Task<string> CopyWorkShopItemAsync(Steamworks.Ugc.Item? item, ContentPackage contentPackage, string newContentPackagePath, string metaDataFilePath, bool allowFileOverwrite)
|
||||
private async static Task<string> CopyWorkShopItemAsync(Steamworks.Ugc.Item? item, ContentPackage contentPackage, string newContentPackagePath, string metaDataFilePath)
|
||||
{
|
||||
await Task.Yield();
|
||||
|
||||
@@ -1052,13 +1069,13 @@ namespace Barotrauma.Steam
|
||||
Directory.CreateDirectory(targetPath);
|
||||
File.WriteAllText(copyingPath, "TEMPORARY FILE");
|
||||
|
||||
SaveUtil.CopyFolder(item?.Directory, targetPath, copySubDirs: true, overwriteExisting: item?.Owner.Id != Steamworks.SteamClient.SteamId);
|
||||
SaveUtil.CopyFolder(item?.Directory, targetPath, copySubDirs: true, overwriteExisting: false);
|
||||
|
||||
File.Delete(copyingPath);
|
||||
return "";
|
||||
}
|
||||
|
||||
var allPackageFiles = Directory.GetFiles(item?.Directory, "*", SearchOption.AllDirectories);
|
||||
var allPackageFiles = Directory.GetFiles(item?.Directory, "*", System.IO.SearchOption.AllDirectories);
|
||||
List<string> nonContentFiles = new List<string>();
|
||||
foreach (string file in allPackageFiles)
|
||||
{
|
||||
@@ -1069,27 +1086,24 @@ namespace Barotrauma.Steam
|
||||
nonContentFiles.Add(relativePath);
|
||||
}
|
||||
|
||||
if (!allowFileOverwrite)
|
||||
/*if (File.Exists(newContentPackagePath) && !CheckFileEquality(newContentPackagePath, metaDataFilePath))
|
||||
{
|
||||
if (File.Exists(newContentPackagePath) && !CheckFileEquality(newContentPackagePath, metaDataFilePath))
|
||||
errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] { "[itemname]", "[filename]" }, new string[2] { item?.Title, newContentPackagePath });
|
||||
DebugConsole.NewMessage(errorMsg, Color.Red);
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
foreach (ContentFile contentFile in contentPackage.Files)
|
||||
{
|
||||
string sourceFile = Path.Combine(item?.Directory, contentFile.Path);
|
||||
|
||||
if (File.Exists(sourceFile) && File.Exists(contentFile.Path) && !CheckFileEquality(sourceFile, contentFile.Path))
|
||||
{
|
||||
errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] { "[itemname]", "[filename]" }, new string[2] { item?.Title, newContentPackagePath });
|
||||
errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] { "[itemname]", "[filename]" }, new string[2] { item?.Title, contentFile.Path });
|
||||
DebugConsole.NewMessage(errorMsg, Color.Red);
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
foreach (ContentFile contentFile in contentPackage.Files)
|
||||
{
|
||||
string sourceFile = Path.Combine(item?.Directory, contentFile.Path);
|
||||
|
||||
if (File.Exists(sourceFile) && File.Exists(contentFile.Path) && !CheckFileEquality(sourceFile, contentFile.Path))
|
||||
{
|
||||
errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] { "[itemname]", "[filename]" }, new string[2] { item?.Title, contentFile.Path });
|
||||
DebugConsole.NewMessage(errorMsg, Color.Red);
|
||||
return errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
Directory.CreateDirectory(targetPath);
|
||||
File.WriteAllText(copyingPath, "TEMPORARY FILE");
|
||||
@@ -1107,7 +1121,7 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
}
|
||||
|
||||
contentFile.Path = CorrectContentFilePath(contentFile.Path, contentPackage,
|
||||
contentFile.Path = CorrectContentFilePath(contentFile.Path, contentFile.Type, contentPackage,
|
||||
contentFile.Type != ContentType.Submarine);
|
||||
|
||||
//path not allowed -> the content file must be a reference to an external file (such as some vanilla file outside the Mods folder)
|
||||
@@ -1145,16 +1159,16 @@ namespace Barotrauma.Steam
|
||||
|
||||
//make sure the destination directory exists
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(contentFile.Path));
|
||||
CorrectContentFileCopy(contentPackage, sourceFile, contentFile.Path, overwrite: item?.Owner.Id != Steamworks.SteamClient.SteamId);
|
||||
CorrectContentFileCopy(contentPackage, sourceFile, contentFile.Path, overwrite: false);
|
||||
}
|
||||
|
||||
foreach (string nonContentFile in nonContentFiles)
|
||||
{
|
||||
string sourceFile = Path.Combine(item?.Directory, nonContentFile);
|
||||
if (!File.Exists(sourceFile)) { continue; }
|
||||
string destinationPath = CorrectContentFilePath(nonContentFile, contentPackage, false);
|
||||
string destinationPath = CorrectContentFilePath(nonContentFile, ContentType.None, contentPackage, false);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
|
||||
CorrectContentFileCopy(contentPackage, sourceFile, destinationPath, overwrite: item?.Owner.Id != Steamworks.SteamClient.SteamId);
|
||||
CorrectContentFileCopy(contentPackage, sourceFile, destinationPath, overwrite: false);
|
||||
}
|
||||
|
||||
File.Delete(copyingPath);
|
||||
@@ -1271,7 +1285,7 @@ namespace Barotrauma.Steam
|
||||
string metaDataPath = Path.Combine(item?.Directory, MetadataFileName);
|
||||
if (!File.Exists(metaDataPath))
|
||||
{
|
||||
throw new FileNotFoundException("Metadata file for the Workshop item \"" + item?.Title + "\" not found. The file may be corrupted.");
|
||||
throw new System.IO.FileNotFoundException("Metadata file for the Workshop item \"" + item?.Title + "\" not found. The file may be corrupted.");
|
||||
}
|
||||
|
||||
ContentPackage contentPackage = new ContentPackage(metaDataPath);
|
||||
@@ -1294,7 +1308,7 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
metaDataPath = Path.Combine(item?.Directory, MetadataFileName);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
catch (ArgumentException)
|
||||
{
|
||||
string errorMessage = "Metadata file for the Workshop item \"" + item?.Title +
|
||||
"\" not found. Could not combine path (" + (item?.Directory ?? "directory name empty") + ").";
|
||||
@@ -1354,6 +1368,8 @@ namespace Barotrauma.Steam
|
||||
|
||||
public static async Task<bool> AutoUpdateWorkshopItemsAsync()
|
||||
{
|
||||
await Task.Yield();
|
||||
|
||||
if (!isInitialized) { return false; }
|
||||
|
||||
var query = new Steamworks.Ugc.Query(Steamworks.UgcType.All)
|
||||
@@ -1381,7 +1397,7 @@ namespace Barotrauma.Steam
|
||||
string errorMsg;
|
||||
if (!CheckWorkshopItemEnabled(item))
|
||||
{
|
||||
installedSuccessfully = EnableWorkShopItem(item, true, out errorMsg);
|
||||
installedSuccessfully = EnableWorkShopItem(item, out errorMsg);
|
||||
}
|
||||
else if (!CheckWorkshopItemUpToDate(item))
|
||||
{
|
||||
@@ -1442,10 +1458,12 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
while (updateNotifications.Count > 0)
|
||||
{
|
||||
float width = updateNotifications.Max(notif => GUI.Font.MeasureString(notif).X) * 1.25f;
|
||||
|
||||
int notificationsPerMsgBox = 20;
|
||||
new GUIMessageBox("", string.Join('\n', updateNotifications.Take(notificationsPerMsgBox)),
|
||||
relativeSize: new Microsoft.Xna.Framework.Vector2(0.5f, 0.0f),
|
||||
minSize: new Microsoft.Xna.Framework.Point(600, 0));
|
||||
relativeSize: new Microsoft.Xna.Framework.Vector2(0.25f, 0.0f),
|
||||
minSize: new Microsoft.Xna.Framework.Point((int)width, 0));
|
||||
updateNotifications.RemoveRange(0, Math.Min(notificationsPerMsgBox, updateNotifications.Count));
|
||||
}
|
||||
});
|
||||
@@ -1465,12 +1483,12 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
errorMsg = "";
|
||||
if (!(item?.IsInstalled ?? false)) { return false; }
|
||||
bool reenable = GameMain.Config.SelectedContentPackages.Any(p => !string.IsNullOrEmpty(p.SteamWorkshopUrl) && GetWorkshopItemIDFromUrl(p.SteamWorkshopUrl) == item?.Id);
|
||||
if (item?.Owner.Id != Steamworks.SteamClient.SteamId)
|
||||
{
|
||||
if (!DisableWorkShopItem(item, false, out errorMsg)) { return false; }
|
||||
}
|
||||
if (!EnableWorkShopItem(item, allowFileOverwrite: false, errorMsg: out errorMsg)) { return false; }
|
||||
|
||||
if (!EnableWorkShopItem(item, errorMsg: out errorMsg, selectContentPackage: reenable)) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1495,7 +1513,9 @@ namespace Barotrauma.Steam
|
||||
attr.Name.ToString() == "characterfile") &&
|
||||
attr.Value.CleanUpPath().Contains("/"))
|
||||
{
|
||||
attr.Value = CorrectContentFilePath(attr.Value, package, true);
|
||||
ContentType type = ContentType.None;
|
||||
Enum.TryParse(attr.Name.LocalName, true, out type);
|
||||
attr.Value = CorrectContentFilePath(attr.Value, type, package, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1515,12 +1535,12 @@ namespace Barotrauma.Steam
|
||||
if (doc != null)
|
||||
{
|
||||
CorrectXMLFilePaths(package, doc.Root);
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
|
||||
settings.Indent = true;
|
||||
settings.Encoding = new System.Text.UTF8Encoding(false);
|
||||
using (var xmlWriter = XmlWriter.Create(stream, settings))
|
||||
using (var xmlWriter = System.Xml.XmlWriter.Create(stream, settings))
|
||||
{
|
||||
doc.WriteTo(xmlWriter);
|
||||
xmlWriter.Flush();
|
||||
@@ -1540,15 +1560,24 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
}
|
||||
|
||||
private static string CorrectContentFilePath(string contentFilePath, ContentPackage package, bool checkIfFileExists = false)
|
||||
private static string CorrectContentFilePath(string contentFilePath, ContentType type, ContentPackage package, bool checkIfFileExists = false)
|
||||
{
|
||||
string packageName = Path.GetDirectoryName(GetWorkshopItemContentPackagePath(package));
|
||||
|
||||
contentFilePath = contentFilePath.CleanUpPathCrossPlatform();
|
||||
|
||||
if (checkIfFileExists && File.Exists(contentFilePath))
|
||||
if (checkIfFileExists)
|
||||
{
|
||||
return contentFilePath;
|
||||
bool exists = File.Exists(contentFilePath);
|
||||
if (type == ContentType.Executable ||
|
||||
type == ContentType.ServerExecutable)
|
||||
{
|
||||
exists |= File.Exists(contentFilePath + ".dll");
|
||||
}
|
||||
if (exists)
|
||||
{
|
||||
return contentFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
string[] splitPath = contentFilePath.Split('/');
|
||||
|
||||
@@ -275,14 +275,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(IWriteMessage msg)
|
||||
{
|
||||
lock (buffers)
|
||||
{
|
||||
base.Write(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
Instance = null;
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Barotrauma.Particles
|
||||
{
|
||||
private ParticlePrefab prefab;
|
||||
|
||||
private string debugName = "Particle (uninitialized)";
|
||||
|
||||
public delegate void OnChangeHullHandler(Vector2 position, Hull currentHull);
|
||||
public OnChangeHullHandler OnChangeHull;
|
||||
|
||||
@@ -92,10 +94,16 @@ namespace Barotrauma.Particles
|
||||
{
|
||||
get { return prefab; }
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return debugName;
|
||||
}
|
||||
|
||||
public void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess = null, bool drawOnTop = false)
|
||||
{
|
||||
this.prefab = prefab;
|
||||
debugName = $"Particle ({prefab.Name})";
|
||||
|
||||
spriteIndex = Rand.Int(prefab.Sprites.Count);
|
||||
|
||||
|
||||
@@ -89,7 +89,21 @@ namespace Barotrauma.Particles
|
||||
{
|
||||
public readonly string Name;
|
||||
|
||||
public readonly ParticlePrefab ParticlePrefab;
|
||||
private string particlePrefabName;
|
||||
|
||||
private ParticlePrefab particlePrefab;
|
||||
public ParticlePrefab ParticlePrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
if (particlePrefab == null && particlePrefabName != null)
|
||||
{
|
||||
particlePrefab = GameMain.ParticleManager?.FindPrefab(particlePrefabName);
|
||||
if (particlePrefab == null) { particlePrefabName = null; }
|
||||
}
|
||||
return particlePrefab;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly float AngleMin, AngleMax;
|
||||
|
||||
@@ -114,8 +128,7 @@ namespace Barotrauma.Particles
|
||||
public ParticleEmitterPrefab(XElement element)
|
||||
{
|
||||
Name = element.Name.ToString();
|
||||
|
||||
ParticlePrefab = GameMain.ParticleManager.FindPrefab(element.GetAttributeString("particle", ""));
|
||||
particlePrefabName = element.GetAttributeString("particle", "");
|
||||
|
||||
if (element.Attribute("startrotation") == null)
|
||||
{
|
||||
|
||||
@@ -120,13 +120,13 @@ namespace Barotrauma.Particles
|
||||
return CreateParticle(prefabName, position, new Vector2((float)Math.Cos(angle), (float)-Math.Sin(angle)) * speed, angle, hullGuess);
|
||||
}
|
||||
|
||||
public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation=0.0f, Hull hullGuess = null)
|
||||
public Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null)
|
||||
{
|
||||
ParticlePrefab prefab = FindPrefab(prefabName);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Particle prefab \"" + prefabName+"\" not found!");
|
||||
DebugConsole.ThrowError("Particle prefab \"" + prefabName + "\" not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Barotrauma.Particles
|
||||
|
||||
public Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation = 0.0f, Hull hullGuess = null, bool drawOnTop = false)
|
||||
{
|
||||
if (particleCount >= MaxParticles || prefab == null) return null;
|
||||
if (particleCount >= MaxParticles || prefab == null || prefab.Sprites.Count == 0) { return null; }
|
||||
|
||||
Vector2 particleEndPos = prefab.CalculateEndPosition(position, velocity);
|
||||
|
||||
@@ -144,8 +144,8 @@ namespace Barotrauma.Particles
|
||||
|
||||
Rectangle expandedViewRect = MathUtils.ExpandRect(cam.WorldView, MaxOutOfViewDist);
|
||||
|
||||
if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) return null;
|
||||
if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) return null;
|
||||
if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) { return null; }
|
||||
if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) { return null; }
|
||||
|
||||
if (particles[particleCount] == null) particles[particleCount] = new Particle();
|
||||
|
||||
|
||||
@@ -255,6 +255,11 @@ namespace Barotrauma.Particles
|
||||
}
|
||||
}
|
||||
|
||||
if (Sprites.Count == 0)
|
||||
{
|
||||
DebugConsole.ThrowError($"Particle prefab \"{Name}\" in the file \"{file}\" has no sprites defined!");
|
||||
}
|
||||
|
||||
//if velocity change in water is not given, it defaults to the normal velocity change
|
||||
if (element.Attribute("velocitychangewater") == null)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Barotrauma
|
||||
get { return bodyShapeTexture; }
|
||||
}
|
||||
|
||||
public void Draw(DeformableSprite deformSprite, Camera cam, Vector2 scale, Color color, bool mirror = false)
|
||||
public void Draw(DeformableSprite deformSprite, Camera cam, Vector2 scale, Color color, bool invert = false)
|
||||
{
|
||||
if (!Enabled) return;
|
||||
UpdateDrawPosition();
|
||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
||||
new Vector3(DrawPosition, MathHelper.Clamp(deformSprite.Sprite.Depth, 0, 1)),
|
||||
deformSprite.Origin,
|
||||
-DrawRotation,
|
||||
scale, color, Dir < 0, mirror);
|
||||
scale, color, Dir < 0, invert);
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Sprite sprite, Color color, float? depth = null, float scale = 1.0f, bool mirrorX = false, bool mirrorY = false)
|
||||
|
||||
@@ -25,6 +25,18 @@ namespace Barotrauma
|
||||
public class KeyOrMouse
|
||||
{
|
||||
public Keys Key { get; private set; }
|
||||
|
||||
private string name;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (name == null) { name = GetName(); }
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public MouseButton MouseButton { get; private set; }
|
||||
|
||||
public KeyOrMouse(Keys keyBinding)
|
||||
@@ -133,6 +145,30 @@ namespace Barotrauma
|
||||
hashCode = hashCode * -1521134295 + EqualityComparer<int?>.Default.GetHashCode((int)MouseButton);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
if (PlayerInput.NumberKeys.Contains(Key))
|
||||
{
|
||||
return Key.ToString().Substring(1, 1);
|
||||
}
|
||||
if (MouseButton != MouseButton.None)
|
||||
{
|
||||
switch (MouseButton)
|
||||
{
|
||||
case MouseButton.PrimaryMouse:
|
||||
return PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse");
|
||||
case MouseButton.SecondaryMouse:
|
||||
return PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse");
|
||||
default:
|
||||
return TextManager.Get("input." + MouseButton.ToString().ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Key.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlayerInput
|
||||
@@ -155,6 +191,8 @@ namespace Barotrauma
|
||||
static bool allowInput;
|
||||
static bool wasWindowActive;
|
||||
|
||||
public static readonly List<Keys> NumberKeys = new List<Keys> { Keys.D0, Keys.D1, Keys.D2, Keys.D3, Keys.D4, Keys.D5, Keys.D6, Keys.D7, Keys.D8, Keys.D9 };
|
||||
|
||||
#if WINDOWS
|
||||
[DllImport("user32.dll")]
|
||||
static extern int GetSystemMetrics(int smIndex);
|
||||
@@ -408,6 +446,12 @@ namespace Barotrauma
|
||||
return (AllowInput && oldKeyboardState.IsKeyDown(button) && keyboardState.IsKeyUp(button));
|
||||
}
|
||||
|
||||
public static bool InventoryKeyHit(int index)
|
||||
{
|
||||
if (index == -1) return false;
|
||||
return AllowInput && GameMain.Config.InventoryKeyBind(index).IsHit();
|
||||
}
|
||||
|
||||
public static bool KeyDown(Keys button)
|
||||
{
|
||||
return (AllowInput && keyboardState.IsKeyDown(button));
|
||||
@@ -425,7 +469,11 @@ namespace Barotrauma
|
||||
|
||||
public static bool IsCtrlDown()
|
||||
{
|
||||
#if !OSX
|
||||
return KeyDown(Keys.LeftControl) || KeyDown(Keys.RightControl);
|
||||
#else
|
||||
return KeyDown(Keys.LeftWindows) || KeyDown(Keys.RightWindows);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Update(double deltaTime)
|
||||
@@ -462,8 +510,9 @@ namespace Barotrauma
|
||||
doubleClicked = false;
|
||||
if (PrimaryMouseButtonClicked())
|
||||
{
|
||||
if (timeSinceClick < DoubleClickDelay &&
|
||||
(mouseState.Position - lastClickPosition).ToVector2().Length() < MaxDoubleClickDistance)
|
||||
float dist = (mouseState.Position - lastClickPosition).ToVector2().Length();
|
||||
|
||||
if (timeSinceClick < DoubleClickDelay && dist < MaxDoubleClickDistance)
|
||||
{
|
||||
doubleClicked = true;
|
||||
timeSinceClick = DoubleClickDelay;
|
||||
@@ -472,16 +521,15 @@ namespace Barotrauma
|
||||
{
|
||||
lastClickPosition = mouseState.Position;
|
||||
}
|
||||
|
||||
timeSinceClick = 0.0;
|
||||
if (!doubleClicked && dist < MaxDoubleClickDistance)
|
||||
{
|
||||
timeSinceClick = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (PrimaryMouseButtonDown())
|
||||
{
|
||||
if (timeSinceClick > DoubleClickDelay)
|
||||
{
|
||||
lastClickPosition = mouseState.Position;
|
||||
}
|
||||
lastClickPosition = mouseState.Position;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#region Using Statements
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using GameAnalyticsSDK.Net;
|
||||
@@ -104,8 +104,6 @@ namespace Barotrauma
|
||||
exeHash = new Md5Hash(stream);
|
||||
}
|
||||
|
||||
StreamWriter sw = new StreamWriter(filePath);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")");
|
||||
sb.AppendLine("\n");
|
||||
@@ -235,8 +233,7 @@ namespace Barotrauma
|
||||
|
||||
string crashReport = sb.ToString();
|
||||
|
||||
sw.WriteLine(crashReport);
|
||||
sw.Close();
|
||||
File.WriteAllText(filePath, crashReport);
|
||||
|
||||
if (GameSettings.SaveDebugConsoleLogs) DebugConsole.SaveLogs();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
#if DEBUG
|
||||
using System.IO;
|
||||
#else
|
||||
using Barotrauma.IO;
|
||||
#endif
|
||||
|
||||
namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
@@ -278,7 +282,7 @@ namespace Barotrauma.CharacterEditor
|
||||
return TextManager.Get(screenTextTag + tag);
|
||||
}
|
||||
|
||||
#region Main methods
|
||||
#region Main methods
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
rightArea.AddToGUIUpdateList();
|
||||
@@ -662,9 +666,6 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
if (!isFrozen)
|
||||
{
|
||||
Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position);
|
||||
Submarine.MainSub.Update((float)deltaTime);
|
||||
|
||||
foreach (PhysicsBody body in PhysicsBody.List)
|
||||
{
|
||||
body.SetPrevTransform(body.SimPosition, body.Rotation);
|
||||
@@ -991,9 +992,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
spriteBatch.End();
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Ragdoll Manipulation
|
||||
#region Ragdoll Manipulation
|
||||
private void UpdateJointCreation()
|
||||
{
|
||||
if (jointCreationMode == JointCreationMode.None)
|
||||
@@ -1320,9 +1321,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
RecreateRagdoll();
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Endless runner
|
||||
#region Endless runner
|
||||
private int min;
|
||||
private int max;
|
||||
private void CalculateMovementLimits()
|
||||
@@ -1425,9 +1426,9 @@ namespace Barotrauma.CharacterEditor
|
||||
AllWalls.ForEach(w => w.SetCollisionCategory(collisionCategory));
|
||||
GameMain.World.ProcessChanges();
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Character spawning
|
||||
#region Character spawning
|
||||
private int characterIndex = -1;
|
||||
private string currentCharacterConfig;
|
||||
private string selectedJob = null;
|
||||
@@ -1749,7 +1750,11 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
Directory.CreateDirectory(mainFolder);
|
||||
}
|
||||
#if DEBUG
|
||||
doc.Save(configFilePath);
|
||||
#else
|
||||
doc.SaveSafe(configFilePath);
|
||||
#endif
|
||||
// Add to the selected content package
|
||||
contentPackage.AddFile(configFilePath, ContentType.Character);
|
||||
contentPackage.Save(contentPackage.Path);
|
||||
@@ -1830,9 +1835,9 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
character.Inventory?.Items.ForEachMod(i => i?.Unequip(character));
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region GUI
|
||||
#region GUI
|
||||
private static Vector2 innerScale = new Vector2(0.95f, 0.95f);
|
||||
|
||||
private GUILayoutGroup rightArea, leftArea;
|
||||
@@ -3147,9 +3152,9 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
fileEditPanel.RectTransform.MinSize = new Point(0, (int)(layoutGroup.RectTransform.Children.Sum(c => c.MinSize.Y + layoutGroup.AbsoluteSpacing) * 1.2f));
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region ToggleButtons
|
||||
#region ToggleButtons
|
||||
private enum Direction
|
||||
{
|
||||
Left,
|
||||
@@ -3211,9 +3216,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Params
|
||||
#region Params
|
||||
private CharacterParams CharacterParams => character.Params;
|
||||
private List<AnimationParams> AnimParams => character.AnimController.AllAnimParams;
|
||||
private AnimationParams CurrentAnimation => character.AnimController.CurrentAnimationParams;
|
||||
@@ -3464,9 +3469,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
#region Helpers
|
||||
private Vector2 ScreenToSim(float x, float y) => ScreenToSim(new Vector2(x, y));
|
||||
private Vector2 ScreenToSim(Vector2 p) => ConvertUnits.ToSimUnits(Cam.ScreenToWorld(p)) + Submarine.MainSub.SimPosition;
|
||||
private Vector2 SimToScreen(float x, float y) => SimToScreen(new Vector2(x, y));
|
||||
@@ -3707,9 +3712,9 @@ namespace Barotrauma.CharacterEditor
|
||||
SetToggle(spritesheetToggle, true);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Animation Controls
|
||||
#region Animation Controls
|
||||
private void DrawAnimationControls(SpriteBatch spriteBatch, float deltaTime)
|
||||
{
|
||||
var collider = character.AnimController.Collider;
|
||||
@@ -4302,9 +4307,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Ragdoll
|
||||
#region Ragdoll
|
||||
private Vector2[] corners = new Vector2[4];
|
||||
private Vector2[] GetLimbPhysicRect(Limb limb)
|
||||
{
|
||||
@@ -4626,9 +4631,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
return otherLimbs;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Spritesheet
|
||||
#region Spritesheet
|
||||
private List<Texture2D> textures;
|
||||
private List<Texture2D> Textures
|
||||
{
|
||||
@@ -5223,9 +5228,9 @@ namespace Barotrauma.CharacterEditor
|
||||
CalculateSpritesheetZoom();
|
||||
spriteSheetZoomBar.BarScroll = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(spriteSheetMinZoom, spriteSheetMaxZoom, spriteSheetZoom));
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Widgets as methods
|
||||
#region Widgets as methods
|
||||
private void DrawRadialWidget(SpriteBatch spriteBatch, Vector2 drawPos, float value, string toolTip, Color color, Action<float> onClick,
|
||||
float circleRadius = 30, int widgetSize = 10, float rotationOffset = 0, bool clockWise = true, bool displayAngle = true, bool? autoFreeze = null, bool wrapAnglePi = false, bool holdPosition = false, int rounding = 1)
|
||||
{
|
||||
@@ -5334,9 +5339,9 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Widgets as classes
|
||||
#region Widgets as classes
|
||||
private Dictionary<string, Widget> animationWidgets = new Dictionary<string, Widget>();
|
||||
private Dictionary<string, Widget> jointSelectionWidgets = new Dictionary<string, Widget>();
|
||||
private Dictionary<string, Widget> limbEditWidgets = new Dictionary<string, Widget>();
|
||||
@@ -5490,6 +5495,6 @@ namespace Barotrauma.CharacterEditor
|
||||
return w;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
@@ -151,7 +151,10 @@ namespace Barotrauma
|
||||
|
||||
GameMain.ParticleManager.UpdateTransforms();
|
||||
|
||||
GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision;
|
||||
GameMain.LightManager.ObstructVision =
|
||||
Character.Controlled != null &&
|
||||
Character.Controlled.ObstructVision &&
|
||||
(Character.Controlled.ViewTarget == Character.Controlled || Character.Controlled.ViewTarget == null);
|
||||
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
@@ -261,7 +264,7 @@ namespace Barotrauma
|
||||
graphics.SetRenderTarget(renderTargetFinal);
|
||||
|
||||
WaterRenderer.Instance.ResetBuffers();
|
||||
Hull.UpdateVertices(graphics, cam, WaterRenderer.Instance);
|
||||
Hull.UpdateVertices(cam, WaterRenderer.Instance);
|
||||
WaterRenderer.Instance.RenderWater(spriteBatch, renderTargetWater, cam);
|
||||
WaterRenderer.Instance.RenderAir(graphics, cam, renderTarget, Cam.ShaderTransform);
|
||||
graphics.DepthStencilState = DepthStencilState.None;
|
||||
|
||||
@@ -3,10 +3,14 @@ using Barotrauma.RuinGeneration;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
#if DEBUG
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
#else
|
||||
using Barotrauma.IO;
|
||||
#endif
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -459,7 +463,7 @@ namespace Barotrauma
|
||||
Submarine.Draw(spriteBatch, false);
|
||||
Submarine.DrawFront(spriteBatch);
|
||||
Submarine.DrawDamageable(spriteBatch, null);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(new Point(0, -Level.Loaded.Size.Y), Level.Loaded.Size), Color.White, thickness: (int)(1.0f / cam.Zoom));
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(new Point(0, -Level.Loaded.Size.Y), Level.Loaded.Size), Color.Gray, thickness: (int)(1.0f / cam.Zoom));
|
||||
spriteBatch.End();
|
||||
|
||||
if (lightingEnabled.Selected)
|
||||
@@ -497,7 +501,7 @@ namespace Barotrauma
|
||||
|
||||
private void SerializeAll()
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
NewLineOnAttributes = true
|
||||
@@ -578,7 +582,7 @@ namespace Barotrauma
|
||||
|
||||
if (elementFound)
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
NewLineOnAttributes = true
|
||||
@@ -595,7 +599,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
|
||||
#region LevelObject Wizard
|
||||
#region LevelObject Wizard
|
||||
private class Wizard
|
||||
{
|
||||
private LevelObjectPrefab newPrefab;
|
||||
@@ -676,8 +680,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
newPrefab.Name = nameBox.Text;
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings { Indent = true };
|
||||
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings { Indent = true };
|
||||
foreach (ContentFile configFile in GameMain.Instance.GetFilesOfType(ContentType.LevelObjectPrefabs))
|
||||
{
|
||||
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
||||
@@ -710,6 +714,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
@@ -409,10 +409,9 @@ namespace Barotrauma
|
||||
|
||||
this.game = game;
|
||||
|
||||
menuTabs[(int)Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
menuTabs[(int)Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, menuTabs[(int)Tab.Credits].RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f);
|
||||
creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml");
|
||||
|
||||
@@ -1010,11 +1009,12 @@ namespace Barotrauma
|
||||
GUI.Draw(Cam, spriteBatch);
|
||||
|
||||
#if !UNSTABLE
|
||||
GUI.Font.DrawString(spriteBatch, "Barotrauma v" + GameMain.Version + " (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")", new Vector2(10, GameMain.GraphicsHeight - 20), Color.White * 0.7f);
|
||||
string versionString = "Barotrauma v" + GameMain.Version + " (" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")";
|
||||
GUI.SmallFont.DrawString(spriteBatch, versionString, new Vector2(HUDLayoutSettings.Padding, GameMain.GraphicsHeight - GUI.SmallFont.MeasureString(versionString).Y - HUDLayoutSettings.Padding * 0.75f), Color.White * 0.7f);
|
||||
#endif
|
||||
if (selectedTab != Tab.Credits)
|
||||
{
|
||||
Vector2 textPos = new Vector2(GameMain.GraphicsWidth - 10, GameMain.GraphicsHeight - 10);
|
||||
Vector2 textPos = new Vector2(GameMain.GraphicsWidth - HUDLayoutSettings.Padding, GameMain.GraphicsHeight - HUDLayoutSettings.Padding * 0.75f);
|
||||
for (int i = legalCrap.Length - 1; i >= 0; i--)
|
||||
{
|
||||
Vector2 textSize = GUI.SmallFont.MeasureString(legalCrap[i]);
|
||||
@@ -1069,7 +1069,7 @@ namespace Barotrauma
|
||||
{
|
||||
File.Copy(selectedSub.FilePath, Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), true);
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (System.IO.IOException e)
|
||||
{
|
||||
DebugConsole.ThrowError("Copying the file \"" + selectedSub.FilePath + "\" failed. The file may have been deleted or in use by another process. Try again or select another submarine.", e);
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user