(f8907b59f) Added: Proper scaling based on resolution for VideoPlayer. Modified: IsFlooding check of contextual tutorial to require water volume

This commit is contained in:
Joonas Rikkonen
2019-03-29 21:50:44 +02:00
parent 140f1894d4
commit 6f919a4de0
9 changed files with 104 additions and 167 deletions
@@ -226,15 +226,8 @@ namespace Barotrauma
if (SelectedConstruction != null && SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null && HUD.CloseHUD(ic.GuiFrame.Rect))) if (SelectedConstruction != null && SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null && HUD.CloseHUD(ic.GuiFrame.Rect)))
{ {
if (GameMain.Client != null) //emulate a Select input to get the character to deselect the item server-side
{ keys[(int)InputType.Select].Hit = true;
//emulate a Select input to get the character to deselect the item server-side
keys[(int)InputType.Select].Hit = true;
}
//reset focus to prevent us from accidentally interacting with another entity
focusedItem = null;
focusedCharacter = null;
findFocusedTimer = 0.2f;
SelectedConstruction = null; SelectedConstruction = null;
} }
@@ -17,11 +17,12 @@ namespace Barotrauma
private GUIFrame background, videoFrame, textFrame; private GUIFrame background, videoFrame, textFrame;
private GUITextBlock title, textContent, objectiveTitle, objectiveText; private GUITextBlock title, textContent, objectiveTitle, objectiveText;
private GUICustomComponent videoView; private GUICustomComponent videoView;
private GUIButton okButton;
private Color backgroundColor = new Color(0f, 0f, 0f, 1f); private Color backgroundColor = new Color(0f, 0f, 0f, 1f);
private Action callbackOnStop; private Action callbackOnStop;
private Point scaledResolution; private Point scaledVideoResolution;
private readonly int borderSize = 20; private readonly int borderSize = 20;
private readonly Point buttonSize = new Point(160, 50); private readonly Point buttonSize = new Point(160, 50);
private readonly int titleHeight = 30; private readonly int titleHeight = 30;
@@ -53,21 +54,20 @@ namespace Barotrauma
public VideoPlayer() // GUI elements with size set to Point.Zero are resized based on content 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.55f);
scaledResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f)); scaledVideoResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f));
int width = scaledResolution.X; int width = scaledVideoResolution.X;
int height = scaledResolution.Y; int height = scaledVideoResolution.Y;
background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor); background = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor);
videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center) { AbsoluteOffset = new Point((int)(-100 / (GUI.Scale * 0.6f)), 0) }, "SonarFrame"); videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center), "SonarFrame");
textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame"); textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame");
textFrame.RectTransform.AbsoluteOffset = new Point(width + borderSize * 2, 0);
videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); }); videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); });
title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(5, 10) }, string.Empty, font: GUI.VideoTitleFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left); title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.VideoTitleFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(0, borderSize + titleHeight) }, string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft); textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft);
objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight, textColor: Color.White); objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
objectiveTitle.Text = TextManager.Get("NewObjective"); objectiveTitle.Text = TextManager.Get("NewObjective");
@@ -110,7 +110,7 @@ namespace Barotrauma
currentVideo.Dispose(); currentVideo.Dispose();
currentVideo = null; currentVideo = null;
currentVideo = CreateVideo(scaledResolution); currentVideo = CreateVideo(scaledVideoResolution);
} }
public void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0) public void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0)
@@ -131,59 +131,28 @@ namespace Barotrauma
return; return;
} }
ResetFrameSizes();
if (currentVideo != null) if (currentVideo != null)
{ {
currentVideo.Dispose(); currentVideo.Dispose();
currentVideo = null; currentVideo = null;
} }
currentVideo = CreateVideo(scaledResolution); currentVideo = CreateVideo(scaledVideoResolution);
videoFrame.RectTransform.NonScaledSize += scaledResolution + new Point(borderSize, borderSize);
videoView.RectTransform.NonScaledSize += scaledResolution;
title.Text = TextManager.Get(contentId); title.Text = TextManager.Get(contentId);
title.RectTransform.NonScaledSize += new Point(textSettings.Width, titleHeight);
if (!string.IsNullOrEmpty(textSettings.Text))
{
textSettings.Text = ToolBox.WrapText(textSettings.Text, textSettings.Width, GUI.Font);
int wrappedHeight = textSettings.Text.Split('\n').Length * textHeight;
textFrame.RectTransform.NonScaledSize += new Point(textSettings.Width + borderSize, wrappedHeight + borderSize + buttonSize.Y + titleHeight);
textContent.RectTransform.NonScaledSize += new Point(textSettings.Width, wrappedHeight);
}
textContent.Text = textSettings.Text; textContent.Text = textSettings.Text;
objectiveText.Text = objective;
if (!string.IsNullOrEmpty(objective)) AdjustFrames(videoSettings, textSettings);
{
objectiveTitle.RectTransform.AbsoluteOffset = new Point(-10, textContent.RectTransform.Rect.Height + (int)(textHeight * 1.95f));
objectiveText.RectTransform.AbsoluteOffset = new Point(-10, textContent.RectTransform.Rect.Height + objectiveTitle.Rect.Height + (int)(textHeight * 2.25f));
textFrame.RectTransform.NonScaledSize += new Point(0, objectiveFrameHeight);
objectiveText.RectTransform.NonScaledSize += new Point(textFrame.Rect.Width, textHeight);
objectiveText.Text = objective;
objectiveTitle.Visible = objectiveText.Visible = true;
}
else
{
textFrame.RectTransform.NonScaledSize += new Point(0, borderSize);
objectiveTitle.Visible = objectiveText.Visible = false;
}
var okButton = new GUIButton(new RectTransform(buttonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(20, 20) },
TextManager.Get("OK"))
{
OnClicked = DisposeVideo
};
if (startPlayback) Play(); if (startPlayback) Play();
} }
private void ResetFrameSizes() private void AdjustFrames(VideoSettings videoSettings, TextSettings textSettings)
{ {
int screenWidth = (int)(GameMain.GraphicsWidth * 0.55f);
scaledVideoResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f));
background.RectTransform.NonScaledSize = Point.Zero;
videoFrame.RectTransform.NonScaledSize = Point.Zero; videoFrame.RectTransform.NonScaledSize = Point.Zero;
videoView.RectTransform.NonScaledSize = Point.Zero; videoView.RectTransform.NonScaledSize = Point.Zero;
@@ -192,6 +161,70 @@ namespace Barotrauma
textContent.RectTransform.NonScaledSize = Point.Zero; textContent.RectTransform.NonScaledSize = Point.Zero;
objectiveText.RectTransform.NonScaledSize = Point.Zero; objectiveText.RectTransform.NonScaledSize = Point.Zero;
title.TextScale = textContent.TextScale = objectiveText.TextScale = objectiveTitle.TextScale = GUI.Scale;
int scaledBorderSize = (int)(borderSize * GUI.Scale);
int scaledTextWidth = (int)(textSettings.Width * GUI.Scale);
int scaledTitleHeight = (int)(titleHeight * GUI.Scale);
int scaledTextHeight = (int)(textHeight * GUI.Scale);
int scaledObjectiveFrameHeight = (int)(objectiveFrameHeight * GUI.Scale);
Point scaledButtonSize = new Point((int)(buttonSize.X * GUI.Scale), (int)(buttonSize.Y * GUI.Scale));
background.RectTransform.NonScaledSize = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
videoFrame.RectTransform.NonScaledSize += scaledVideoResolution + new Point(scaledBorderSize, scaledBorderSize);
videoView.RectTransform.NonScaledSize += scaledVideoResolution;
title.RectTransform.NonScaledSize += new Point(scaledTextWidth, scaledTitleHeight);
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
if (!string.IsNullOrEmpty(textSettings.Text))
{
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUI.Font);
int wrappedHeight = textSettings.Text.Split('\n').Length * scaledTextHeight;
textFrame.RectTransform.NonScaledSize += new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
textFrame.RectTransform.AbsoluteOffset = new Point(scaledVideoResolution.X + scaledBorderSize * 2, 0);
textContent.RectTransform.NonScaledSize += new Point(scaledTextWidth, wrappedHeight);
textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
}
if (!string.IsNullOrEmpty(objectiveText.Text))
{
int scaledXOffset = (int)(-10 * GUI.Scale);
objectiveTitle.RectTransform.AbsoluteOffset = new Point(scaledXOffset, textContent.RectTransform.Rect.Height + (int)(scaledTextHeight * 1.95f));
objectiveText.RectTransform.AbsoluteOffset = new Point(scaledXOffset, textContent.RectTransform.Rect.Height + objectiveTitle.Rect.Height + (int)(scaledTextHeight * 2.25f));
textFrame.RectTransform.NonScaledSize += new Point(0, scaledObjectiveFrameHeight);
objectiveText.RectTransform.NonScaledSize += new Point(textFrame.Rect.Width, scaledTextHeight);
objectiveTitle.Visible = objectiveText.Visible = true;
}
else
{
textFrame.RectTransform.NonScaledSize += new Point(0, scaledBorderSize);
objectiveTitle.Visible = objectiveText.Visible = false;
}
int totalFrameWidth = videoFrame.Rect.Width + textFrame.Rect.Width + scaledBorderSize * 2;
int xOffset = videoFrame.Rect.Width / 2 + scaledBorderSize - (videoFrame.Rect.Width / 2 - textFrame.Rect.Width / 2);
videoFrame.RectTransform.AbsoluteOffset = new Point(-xOffset, (int)(50 * GUI.Scale));
if (okButton != null)
{
textFrame.RemoveChild(okButton);
okButton = null;
}
okButton = new GUIButton(new RectTransform(scaledButtonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("OK"))
{
OnClicked = DisposeVideo
};
} }
private Video CreateVideo(Point resolution) private Video CreateVideo(Point resolution)
@@ -662,6 +662,7 @@ namespace Barotrauma.Tutorials
if (gap.Submarine == null) continue; if (gap.Submarine == null) continue;
if (gap.Submarine.IsOutpost) continue; if (gap.Submarine.IsOutpost) continue;
if (gap.Submarine != Submarine.MainSub) continue; if (gap.Submarine != Submarine.MainSub) continue;
if (gap.FlowTargetHull.WaterPercentage <= 0.0f) continue;
return true; return true;
} }
@@ -453,10 +453,7 @@ namespace Barotrauma.Lights
//raster pattern on top of everything //raster pattern on top of everything
spriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap); spriteBatch.Begin(blendState: BlendState.AlphaBlend, samplerState: SamplerState.LinearWrap);
spriteBatch.Draw(highlightRaster, spriteBatch.Draw(highlightRaster, new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height), Color.White * 0.5f);
new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height),
new Rectangle(0, 0, (int)(HighlightMap.Width / currLightMapScale * 0.5f), (int)(HighlightMap.Height / currLightMapScale * 0.5f)),
Color.White * 0.5f);
spriteBatch.End(); spriteBatch.End();
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"]; DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
@@ -337,24 +337,7 @@ namespace Barotrauma
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting")) var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowLighting"))
{ {
Selected = lightingEnabled, Selected = lightingEnabled,
OnSelected = (GUITickBox obj) => OnSelected = (GUITickBox obj) => { lightingEnabled = obj.Selected; return true; }
{
lightingEnabled = obj.Selected;
if (lightingEnabled)
{
//turn off lights that are inside containers
foreach (Item item in Item.ItemList)
{
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
{
lightComponent.Light.Color = item.Container != null || (item.body != null && !item.body.Enabled) ?
Color.Transparent :
lightComponent.LightColor;
}
}
}
return true;
}
}; };
tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls")) tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.03f), paddedLeftPanel.RectTransform), TextManager.Get("ShowWalls"))
{ {
@@ -115,13 +115,9 @@ namespace Barotrauma
SonarLabel = element.GetAttributeString("sonarlabel", ""); SonarLabel = element.GetAttributeString("sonarlabel", "");
} }
public AITarget(Entity e, float sightRange = -1, float soundRange = 0) public AITarget(Entity e, float sightRange = 3000, float soundRange = 0)
{ {
Entity = e; Entity = e;
if (sightRange < 0)
{
sightRange = StaticSightRange;
}
SightRange = sightRange; SightRange = sightRange;
SoundRange = soundRange; SoundRange = soundRange;
List.Add(this); List.Add(this);
@@ -635,7 +635,6 @@ namespace Barotrauma
var newLimb = GetAttackLimb(attackWorldPos, previousLimb); var newLimb = GetAttackLimb(attackWorldPos, previousLimb);
if (newLimb != null) if (newLimb != null)
{ {
// Attack with the new limb
AttackingLimb = newLimb; AttackingLimb = newLimb;
} }
else else
@@ -660,49 +659,6 @@ namespace Barotrauma
} }
} }
break; break;
case AIBehaviorAfterAttack.FallBackUntilCanAttack:
if (AttackingLimb.attack.SecondaryCoolDown <= 0)
{
// No (valid) secondary cooldown defined.
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
else
{
if (AttackingLimb.attack.SecondaryCoolDownTimer <= 0)
{
// Don't allow attacking when the attack target has just changed.
if (_previousAiTarget != null && SelectedAiTarget != _previousAiTarget)
{
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
else
{
// If the secondary cooldown is defined and expired, check if we can switch the attack
var previousLimb = AttackingLimb;
var newLimb = GetAttackLimb(attackWorldPos, previousLimb);
if (newLimb != null)
{
// Attack with the new limb
AttackingLimb = newLimb;
}
else
{
// No new limb was found.
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
}
}
else
{
// Cooldown not yet expired -> steer away from the target
UpdateFallBack(attackWorldPos, deltaTime);
return;
}
}
break;
case AIBehaviorAfterAttack.FallBack: case AIBehaviorAfterAttack.FallBack:
default: default:
UpdateFallBack(attackWorldPos, deltaTime); UpdateFallBack(attackWorldPos, deltaTime);
@@ -828,39 +784,20 @@ namespace Barotrauma
{ {
AttackContext currentContext = Character.GetAttackContext(); AttackContext currentContext = Character.GetAttackContext();
var target = wallTarget != null ? wallTarget.Structure : SelectedAiTarget.Entity; var target = wallTarget != null ? wallTarget.Structure : SelectedAiTarget.Entity;
Limb selectedLimb = null; var limbs = Character.AnimController.Limbs
float currentPriority = 0; .Where(l =>
foreach (Limb limb in Character.AnimController.Limbs) l != ignoredLimb &&
{ l.attack != null &&
if (limb == ignoredLimb) { continue; } l.attack.CoolDownTimer <= 0 &&
if (limb.IsSevered || limb.IsStuck) { continue; } !l.IsSevered &&
var attack = limb.attack; !l.IsStuck &&
if (attack == null) { continue; } l.attack.IsValidContext(currentContext) &&
if (attack.CoolDownTimer > 0) { continue; } l.attack.IsValidTarget(target) &&
if (!attack.IsValidContext(currentContext)) { continue; } l.attack.Conditionals.All(c => (target is ISerializableEntity se && c.Matches(se)) || !(target is ISerializableEntity) || !(target is Character)))
if (!attack.IsValidTarget(target)) { continue; } .OrderByDescending(l => l.attack.Priority)
if (target is ISerializableEntity se && target is Character) .ThenBy(l => Vector2.Distance(l.WorldPosition, attackWorldPos));
{ // TODO: priority should probably not override the distance -> use values instead of booleans
// TODO: allow conditionals of which matching any is enough instead of having to fulfill all return limbs.FirstOrDefault();
if (attack.Conditionals.Any(c => !c.Matches(se))) { continue; }
}
float priority = CalculatePriority(limb, attackWorldPos);
if (priority > currentPriority)
{
currentPriority = priority;
selectedLimb = limb;
}
}
return selectedLimb;
float CalculatePriority(Limb limb, Vector2 attackPos)
{
float dist = Vector2.Distance(limb.WorldPosition, attackPos);
// The limb is ignored if the target is not close. Prevents character going in reverse if very far away from it.
// We also need a max value that is more than the actual range.
float distanceFactor = MathHelper.Lerp(1, 0, MathUtils.InverseLerp(0, limb.attack.Range * 3, dist));
return (1 + limb.attack.Priority) * distanceFactor;
}
} }
private void UpdateWallTarget() private void UpdateWallTarget()
@@ -28,7 +28,6 @@ namespace Barotrauma
public enum AIBehaviorAfterAttack public enum AIBehaviorAfterAttack
{ {
FallBack, FallBack,
FallBackUntilCanAttack,
PursueIfCanAttack, PursueIfCanAttack,
Pursue Pursue
} }
@@ -189,7 +188,7 @@ namespace Barotrauma
public readonly List<Affliction> Afflictions = new List<Affliction>(); public readonly List<Affliction> Afflictions = new List<Affliction>();
/// <summary> /// <summary>
/// Only affects ai decision making. All the conditionals has to be met in order to select the attack. TODO: allow to define conditionals using any (implemented in StatusEffect -> move from there to PropertyConditional?) /// Only affects ai decision making.
/// </summary> /// </summary>
public List<PropertyConditional> Conditionals { get; private set; } = new List<PropertyConditional>(); public List<PropertyConditional> Conditionals { get; private set; } = new List<PropertyConditional>();
@@ -162,7 +162,6 @@ namespace Barotrauma.Items.Components
if (contained == null) continue; if (contained == null) continue;
if (contained.TryInteract(character)) if (contained.TryInteract(character))
{ {
character.FocusedItem = contained;
return false; return false;
} }
} }
@@ -179,7 +178,6 @@ namespace Barotrauma.Items.Components
if (contained == null) continue; if (contained == null) continue;
if (contained.TryInteract(picker)) if (contained.TryInteract(picker))
{ {
picker.FocusedItem = contained;
return true; return true;
} }
} }