Skip to content

Commit

Permalink
feat: zoomer (#1872)
Browse files Browse the repository at this point in the history
* feat: world zoom (no ui scaling)

* control zoom from chatbox for debugging

* fix: avoid overwriting position of windows

* fix: minor cleanup EscapeMenu and SettingsWindow

* ui changes for zoom

* feat: zoom buttons, fix: corrected camera

* correct zoom direction

* fix: fade scale on main menu when zoomed in
  • Loading branch information
lodicolo authored Aug 26, 2023
1 parent b0aecc5 commit 2df9a08
Show file tree
Hide file tree
Showing 41 changed files with 767 additions and 318 deletions.
3 changes: 3 additions & 0 deletions Intersect (Core)/Config/MapOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ public bool EnableDiagonalMovement
/// </summary>
public int TileWidth { get; set; } = 32;

[JsonIgnore]
public float TileScale => 32f / Math.Min(TileWidth, TileHeight);

/// <summary>
/// The time, in milliseconds, until the map is cleaned up.
/// </summary>
Expand Down
10 changes: 9 additions & 1 deletion Intersect.Client.Framework/Database/GameDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,16 @@ public abstract partial class GameDatabase

public TypewriterBehavior TypewriterBehavior { get; set; }

public float UIScale { get; set; } = 1.0f;

public float WorldZoom { get; set; } = 1.0f;

public abstract void DeletePreference(string key);

public abstract bool HasPreference(string key);

//Saving password, other stuff we don't want in the games directory
public abstract void SavePreference(string key, object value);
public abstract void SavePreference<TValue>(string key, TValue value);

public abstract string LoadPreference(string key);

Expand Down Expand Up @@ -128,6 +132,8 @@ public virtual void LoadPreferences()
ShowHealthAsPercentage = LoadPreference(nameof(ShowHealthAsPercentage), false);
ShowManaAsPercentage = LoadPreference(nameof(ShowManaAsPercentage), false);
TypewriterBehavior = LoadPreference(nameof(TypewriterBehavior), TypewriterBehavior.Word);
UIScale = LoadPreference(nameof(UIScale), 1.0f);
WorldZoom = LoadPreference(nameof(WorldZoom), 1.0f);
}

/// <summary>
Expand Down Expand Up @@ -162,6 +168,8 @@ public virtual void SavePreferences()
SavePreference(nameof(ShowHealthAsPercentage), ShowHealthAsPercentage);
SavePreference(nameof(ShowManaAsPercentage), ShowManaAsPercentage);
SavePreference(nameof(TypewriterBehavior), TypewriterBehavior);
SavePreference(nameof(UIScale), UIScale);
SavePreference(nameof(WorldZoom), WorldZoom);
}

public abstract bool LoadConfig();
Expand Down
2 changes: 1 addition & 1 deletion Intersect.Client.Framework/Entities/IPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public interface IPlayer : IEntity
bool TryTarget();
bool TryTarget(IEntity entity, bool force = false);
void AutoTarget();
void ClearTarget();
bool ClearTarget();
void AddToHotbar(int hotbarSlot, sbyte itemType, int itemSlot);
int FindHotbarItem(IHotbarInstance hotbarInstance);
int FindHotbarSpell(IHotbarInstance hotbarInstance);
Expand Down
31 changes: 30 additions & 1 deletion Intersect.Client.Framework/GenericClasses/FloatRect.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;

namespace Intersect.Client.Framework.GenericClasses
{
Expand Down Expand Up @@ -116,6 +117,34 @@ public bool Contains(Point pt)
return Contains(pt.X, pt.Y);
}

}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FloatRect operator *(FloatRect lhs, float rhs)
{
return new FloatRect(
lhs.X * rhs,
lhs.Y * rhs,
lhs.Width * rhs,
lhs.Height * rhs
);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FloatRect operator *(float lhs, FloatRect rhs) => rhs * lhs;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FloatRect operator /(FloatRect lhs, float rhs)
{
return new FloatRect(
lhs.X / rhs,
lhs.Y / rhs,
lhs.Width / rhs,
lhs.Height / rhs
);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FloatRect operator /(float lhs, FloatRect rhs) => rhs / lhs;

public override string ToString() => $"{Left},{Top} + {Width},{Height} -> {Right},{Bottom}";
}
}
19 changes: 19 additions & 0 deletions Intersect.Client.Framework/Graphics/GameRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ public GameRenderer()

public Resolution PreferredResolution { get; set; }

protected float _scale = 1.0f;

public float Scale
{
get => _scale;
set
{
if (Math.Abs(_scale - value) < 0.001)
{
return;
}

_scale = value;
RecreateSpriteBatch();
}
}

public abstract void Init();

/// <summary>
Expand All @@ -35,6 +52,8 @@ public GameRenderer()

public abstract bool BeginScreenshot();

protected abstract bool RecreateSpriteBatch();

/// <summary>
/// Called when the frame is done being drawn, generally used to finally display the content to the screen.
/// </summary>
Expand Down
53 changes: 23 additions & 30 deletions Intersect.Client.Framework/Gwen/Control/Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ internal bool InheritParentEnablementProperties
private Point mAlignmentTransform;

private Rectangle mBounds;
private Rectangle mBoundsOnDisk;

private bool mCacheTextureDirty;

Expand Down Expand Up @@ -797,43 +798,26 @@ public void RemoveAlignments()
mAlignments.Clear();
}

public virtual string GetJsonUI()
public virtual string GetJsonUI(bool isRoot = false)
{
return JsonConvert.SerializeObject(GetJson(), Formatting.Indented);
return JsonConvert.SerializeObject(GetJson(isRoot), Formatting.Indented);
}

public virtual void WriteBaseUIJson(string path, bool includeBounds = true, bool onlyChildren = false)
{
if (onlyChildren)
{
if (HasNamedChildren())
{
foreach (var ctrl in mChildren)
{
if (!string.IsNullOrEmpty(ctrl.Name))
{
ctrl.WriteBaseUIJson(path);
}
}
}
}
else
{
path = Path.Combine(path, Name + ".json");
File.WriteAllText(path, JsonConvert.SerializeObject(GetJson(), Formatting.Indented));
}
}

public virtual JObject GetJson()
public virtual JObject GetJson(bool isRoot = default)
{
var alignments = new List<string>();
foreach (var alignment in mAlignments)
{
alignments.Add(alignment.ToString());
}

isRoot |= Parent == default;

var boundsToWrite = isRoot
? new Rectangle(mBoundsOnDisk.X, mBoundsOnDisk.Y, mBounds.Width, mBounds.Height)
: mBounds;
var o = new JObject(
new JProperty("Bounds", Rectangle.ToString(mBounds)),
new JProperty("Bounds", Rectangle.ToString(boundsToWrite)),
new JProperty("Padding", Padding.ToString(mPadding)),
new JProperty("AlignmentEdgeDistances", Padding.ToString(mAlignmentDistance)),
new JProperty("AlignmentTransform", Point.ToString(mAlignmentTransform)),
Expand Down Expand Up @@ -896,7 +880,7 @@ public void LoadJsonUi(GameContentManager.UI stage, string resolution, bool save

if (obj != null)
{
LoadJson(obj);
LoadJson(obj, true);
ProcessAlignments();
}
}
Expand All @@ -909,12 +893,12 @@ public void LoadJsonUi(GameContentManager.UI stage, string resolution, bool save

if (!cacheHit && saveOutput)
{
GameContentManager.Current?.SaveUIJson(stage, Name, GetJsonUI(), resolution);
GameContentManager.Current?.SaveUIJson(stage, Name, GetJsonUI(true), resolution);
}
});
}

public virtual void LoadJson(JToken obj)
public virtual void LoadJson(JToken obj, bool isRoot = default)
{
if (obj["Alignments"] != null)
{
Expand Down Expand Up @@ -964,7 +948,16 @@ public virtual void LoadJson(JToken obj)

if (obj["Bounds"] != null)
{
SetBounds(Rectangle.FromString((string) obj["Bounds"]));
mBoundsOnDisk = Rectangle.FromString((string)obj["Bounds"]);
isRoot = isRoot || Parent == default;
if (isRoot)
{
SetSize(mBoundsOnDisk.Width, mBoundsOnDisk.Height);
}
else
{
SetBounds(mBoundsOnDisk);
}
}

if (obj["Padding"] != null)
Expand Down
32 changes: 16 additions & 16 deletions Intersect.Client.Framework/Gwen/Control/Button.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ public bool ToggleState
/// </summary>
public event GwenEventHandler<EventArgs> ToggledOff;

public override JObject GetJson()
public override JObject GetJson(bool isRoot = default)
{
var obj = base.GetJson();
var obj = base.GetJson(isRoot);
if (this.GetType() != typeof(CheckBox))
{
obj.Add("NormalImage", GetImageFilename(ControlState.Normal));
Expand All @@ -194,70 +194,70 @@ public override JObject GetJson()
return base.FixJson(obj);
}

public override void LoadJson(JToken obj)
public override void LoadJson(JToken obj, bool isRoot = default)
{
base.LoadJson(obj);
if (obj["NormalImage"] != null)
{
SetImage(
GameContentManager.Current.GetTexture(
Framework.Content.TextureType.Gui, (string) obj["NormalImage"]
), (string) obj["NormalImage"], ControlState.Normal
Framework.Content.TextureType.Gui, (string)obj["NormalImage"]
), (string)obj["NormalImage"], ControlState.Normal
);
}

if (obj["HoveredImage"] != null)
{
SetImage(
GameContentManager.Current.GetTexture(
Framework.Content.TextureType.Gui, (string) obj["HoveredImage"]
), (string) obj["HoveredImage"], ControlState.Hovered
Framework.Content.TextureType.Gui, (string)obj["HoveredImage"]
), (string)obj["HoveredImage"], ControlState.Hovered
);
}

if (obj["ClickedImage"] != null)
{
SetImage(
GameContentManager.Current.GetTexture(
Framework.Content.TextureType.Gui, (string) obj["ClickedImage"]
), (string) obj["ClickedImage"], ControlState.Clicked
Framework.Content.TextureType.Gui, (string)obj["ClickedImage"]
), (string)obj["ClickedImage"], ControlState.Clicked
);
}

if (obj["DisabledImage"] != null)
{
SetImage(
GameContentManager.Current.GetTexture(
Framework.Content.TextureType.Gui, (string) obj["DisabledImage"]
), (string) obj["DisabledImage"], ControlState.Disabled
Framework.Content.TextureType.Gui, (string)obj["DisabledImage"]
), (string)obj["DisabledImage"], ControlState.Disabled
);
}

if (obj["CenterImage"] != null)
{
mCenterImage = (bool) obj["CenterImage"];
mCenterImage = (bool)obj["CenterImage"];
}

if (this.GetType() != typeof(ComboBox) && this.GetType() != typeof(CheckBox))
{
if (obj["HoverSound"] != null)
{
mHoverSound = (string) obj["HoverSound"];
mHoverSound = (string)obj["HoverSound"];
}

if (obj["MouseUpSound"] != null)
{
mMouseUpSound = (string) obj["MouseUpSound"];
mMouseUpSound = (string)obj["MouseUpSound"];
}

if (obj["MouseDownSound"] != null)
{
mMouseDownSound = (string) obj["MouseDownSound"];
mMouseDownSound = (string)obj["MouseDownSound"];
}

if (obj["ClickSound"] != null)
{
mClickSound = (string) obj["ClickSound"];
mClickSound = (string)obj["ClickSound"];
}
}
}
Expand Down
Loading

0 comments on commit 2df9a08

Please sign in to comment.