Extend UI plugins to allow hooking into UI screen processing

Add sample equip menu mod to display extra info for weapons etc.
Correct Tolk focus pan calculation
This commit is contained in:
ficedula 2023-08-15 21:22:35 +01:00
parent 5798d5cf37
commit 1a5e33190d
15 changed files with 351 additions and 67 deletions

View File

@ -4,12 +4,10 @@
//
// SPDX-License-Identifier: EPL-2.0
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Braver {
public enum InputKey {
@ -44,7 +42,7 @@ namespace Braver {
public Dictionary<InputKey, int> DownFor { get; } = new();
public Vector2 Stick1 { get; set; }
//public Vector2 Stick1 { get; set; }
public bool IsDown(InputKey k) => DownFor[k] > 0;
public bool IsJustDown(InputKey k) => DownFor[k] == 1;

View File

@ -5,25 +5,30 @@
// SPDX-License-Identifier: EPL-2.0
using Braver.Field;
using Ficedula.FF7.Field;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Braver.Field {
public struct FocusPoint {
public int WalkmeshTri { get; set; }
public Vector2 WalkmeshCenterScreenPos { get; set; }
public static class FieldUtil {
public static Vector3 ToX(this FieldVertex v) {
return new Vector3(v.X, v.Y, v.Z);
}
public static Vector3 GetMiddlePoint(this WalkmeshTriangle tri) {
return (tri.V0.ToX() + tri.V1.ToX() + tri.V2.ToX()) / 3;
}
}
public class FocusState {
public string TargetName { get; set; }
public Vector3 TargetPosition { get; set; }
public int WalkmeshDistance { get; set; }
public List<FocusPoint> Points { get; set; }
public List<int> WalkmeshTriPoints { get; set; }
}
[Flags]
@ -48,14 +53,18 @@ namespace Braver.Field {
namespace Braver.Plugins.Field {
public interface IField {
Vector3 PlayerPosition { get; }
FocusState GetFocusState();
int FieldID { get; }
string FieldFile { get; }
public FieldOptions Options { get; }
Vector3 PlayerPosition { get; }
IReadOnlyList<WalkmeshTriangle> Walkmesh { get; }
FocusState GetFocusState();
Vector2 Transform(Vector3 position);
}
public interface IFieldLocation : IPluginInstance {
void Init(int fieldID, string fieldFile);
void Step(IField field);
void Init(IField field);
void Step();
void Suspended();
void EntityMoved(IFieldEntity entity, bool isRunning, Vector3 from, Vector3 to);
void FocusChanged();

View File

@ -124,13 +124,19 @@ namespace Braver.Plugins {
foreach (var instance in _instances.OfType<T>())
action(instance);
}
public U Call<U>(Func<T, U> fetch) where U : class {
public U? Call<U>(Func<T, U> fetch) where U : class {
foreach (var instance in _instances.OfType<T>().Reverse()) {
U result = fetch(instance);
if (result != null) return result;
}
return null;
}
public IEnumerable<U> CallAll<U>(Func<T, U> fetch) {
return _instances
.OfType<T>()
.Reverse()
.Select(t => fetch(t));
}
public void Dispose() {
foreach (var instance in _instances.OfType<IDisposable>())

View File

@ -9,16 +9,65 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Braver.Plugins.UI {
public static class ComponentUtil {
public static IComponent? Find(this IComponent component, string id) {
if (id.Equals(component?.ID, StringComparison.InvariantCultureIgnoreCase))
return component;
if (component is IContainer container) {
foreach(var child in container.Children) {
var found = child.Find(id);
if (found != null) return found;
}
}
return null;
}
public static T? Find<T>(this IComponent component, string id) where T : IComponent {
return (T?)component.Find(id);
}
}
public interface IComponent {
string ID { get; }
int X { get; set; }
int Y { get; set; }
bool Visible { get; set; }
IContainer Parent { get; }
}
public interface ISizedComponent : IComponent {
int W { get; set; }
int H { get; set; }
}
public interface IContainer : IComponent {
IList<IComponent> Children { get; }
}
public interface ILayoutScreen {
IComponent Root { get; }
IComponent Load(string templateName, object? model);
IContainer FocusGroup { get; }
IComponent Focus { get; }
dynamic Model { get; }
void PushFocus(IContainer group, IComponent focus);
void PopFocus();
void ChangeFocus(IComponent focus);
}
public interface ISystem : IPluginInstance {
void ActiveScreenChanged(IScreen screen);
}
public interface IUI : IPluginInstance {
void Menu(IEnumerable<string> items, int selected, object container);
void Init(ILayoutScreen screen);
void Reloaded();
bool PreInput(InputState input);
}
public interface IBattleUI : IPluginInstance {

View File

@ -32,7 +32,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Braver.7HShim", "PluginImpl
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Braver.FFNxCompatibility", "PluginImplementations\Braver.FFNxCompatibility\Braver.FFNxCompatibility.csproj", "{0C0F23F0-D790-4102-BBD4-56774E4A089B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IrosArchive", "IrosArchive\IrosArchive.csproj", "{803429DC-A6B4-43C2-9F73-D6EA51EA6B99}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IrosArchive", "IrosArchive\IrosArchive.csproj", "{803429DC-A6B4-43C2-9F73-D6EA51EA6B99}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Braver.EquipMenuMod", "PluginImplementations\Braver.EquipMenuMod\Braver.EquipMenuMod.csproj", "{A6C5FE20-7D00-4FD9-AE27-65176B098FC7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -92,6 +94,10 @@ Global
{803429DC-A6B4-43C2-9F73-D6EA51EA6B99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{803429DC-A6B4-43C2-9F73-D6EA51EA6B99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{803429DC-A6B4-43C2-9F73-D6EA51EA6B99}.Release|Any CPU.Build.0 = Release|Any CPU
{A6C5FE20-7D00-4FD9-AE27-65176B098FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6C5FE20-7D00-4FD9-AE27-65176B098FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6C5FE20-7D00-4FD9-AE27-65176B098FC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6C5FE20-7D00-4FD9-AE27-65176B098FC7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -185,7 +185,7 @@ namespace Braver.Field {
_bgPlugins = GetPlugins<IBackground>(_file);
_moviePlugins = GetPlugins<IMovie>(_file);
_fieldPlugins.Call(f => f.Init(_destination.DestinationFieldID, _file));
_fieldPlugins.Call(f => f.Init(this));
Background = new Background(g, _bgPlugins, graphics, field.GetBackground());
Movie = new Movie(g, graphics, _moviePlugins);
@ -508,7 +508,7 @@ namespace Braver.Field {
entity.Model?.FrameStep();
}
}
_fieldPlugins.Call(loc => loc.Step(this));
_fieldPlugins.Call(loc => loc.Step());
_frame++;
}
@ -1416,18 +1416,18 @@ namespace Braver.Field {
}
private FocusState _currentFocusState;
int IField.FieldID => _fieldID;
string IField.FieldFile => _file;
IReadOnlyList<WalkmeshTriangle> IField.Walkmesh => _walkmesh.AsReadOnly();
Vector3 IField.PlayerPosition => Player?.Model?.Translation ?? Vector3.Zero;
Vector2 IField.Transform(Vector3 position) => _view3D.ProjectTo2D(position).XY();
FocusState IField.GetFocusState() {
if ((_currentFocus != null) && (_currentFocusState == null) && (Player != null) && (_currentFocus.Source != Player)) {
Vector2 GetScreenPos(WalkmeshTriangle tri) {
var middle = (tri.V0.ToX() + tri.V1.ToX() + tri.V2.ToX()) / 3;
return _view3D.ProjectTo2D(middle).XY();
}
Dictionary<WalkmeshTriangle, (int distance, Vector2 screenPos)> calculated = new();
Dictionary<WalkmeshTriangle, int> calculated = new();
var playerTri = _walkmesh[Player.WalkmeshTri];
calculated[playerTri] = (0, GetScreenPos(playerTri));
calculated[playerTri] = 0;
Queue<WalkmeshTriangle> toConsider = new Queue<WalkmeshTriangle>();
toConsider.Enqueue(_walkmesh[Player.WalkmeshTri]);
@ -1436,7 +1436,7 @@ namespace Braver.Field {
foreach(var adjacent in tri.AdjacentTris()) {
var adj = _walkmesh[adjacent];
if (!calculated.ContainsKey(adj)) {
calculated[adj] = (calculated[tri].distance + 1, GetScreenPos(adj));
calculated[adj] = calculated[tri] + 1;
toConsider.Enqueue(adj);
}
}
@ -1445,19 +1445,15 @@ namespace Braver.Field {
_currentFocusState = new FocusState {
TargetName = _currentFocus.Name,
TargetPosition = _currentFocus.Position(),
WalkmeshDistance = calculated[_walkmesh[_currentFocus.WalkmeshTri()]].distance,
Points = new List<FocusPoint>()
WalkmeshDistance = calculated[_walkmesh[_currentFocus.WalkmeshTri()]],
WalkmeshTriPoints = new List<int>(),
};
var last = _currentFocus.WalkmeshTri();
System.Diagnostics.Debug.WriteLine($"Focus target {calculated[_walkmesh[last]].screenPos}");
foreach (int d in Enumerable.Range(0, _currentFocusState.WalkmeshDistance).Reverse()) {
var current = _walkmesh[last];
_currentFocusState.Points.Add(new FocusPoint {
WalkmeshTri = last,
WalkmeshCenterScreenPos = calculated[current].screenPos,
});
_currentFocusState.WalkmeshTriPoints.Add(last);
var next = current.AdjacentTris()
.Where(t => calculated[_walkmesh[t]].distance == d)
.Where(t => calculated[_walkmesh[t]] == d)
.First();
last = next;
}

View File

@ -130,10 +130,6 @@ namespace Braver {
return new Vector3(v.X, v.Y, v.Z);
}
public static Vector3 ToX(this Ficedula.FF7.Field.FieldVertex v) {
return new Vector3(v.X, v.Y, v.Z);
}
public static Color WithAlpha(this Color c, byte alpha) {
c.A = alpha;
return c;

View File

@ -4,8 +4,10 @@
Braver sfx cache is going to make FFNx sequential/shuffle irrelevant!
Tolk:
Faster, configurable tracking speed/frequency
AD on movies
AD on field entry
Pan sound indicating whether can move left/right or not (up/down as well?)
Plugin to respond to keypress on certain screens and pop up extra info. e.g. weapon info in equip screen.
WM:
Gradient background for sky on world map

View File

@ -31,6 +31,14 @@ namespace Braver.UI.Layout {
public Armour Armour => Character.GetArmour(_game);
public Accessory Accessory => Character.GetAccessory(_game);
private Weapon _focusedWeapon;
private Armour _focusedArmour;
private Accessory _focusedAccessory;
public Weapon FocusedWeapon => FocusGroup == lbWeapons ? _focusedWeapon : null;
public Armour FocusedArmour => FocusGroup == lbArmour ? _focusedArmour : null;
public Accessory FocusedAccessory => FocusGroup == lbAccessories ? _focusedAccessory : null;
public List<Weapon> AvailableWeapons { get; } = new();
public List<Armour> AvailableArmour { get; } = new();
public List<Accessory> AvailableAccessories { get; } = new();
@ -147,25 +155,26 @@ namespace Braver.UI.Layout {
}
public void WeaponFocussed() {
var selected = AvailableWeapons[lbWeapons.GetSelectedIndex(this)];
lDescription.Text = selected.Description;
_focusedWeapon = AvailableWeapons[lbWeapons.GetSelectedIndex(this)];
lDescription.Text = _focusedWeapon.Description;
ResetAllLabels();
SetLabels(Character.Strength + Weapon.AttackStrength, Character.Strength + selected.AttackStrength, lAttackFrom, lAttackTo);
SetLabels(Weapon.HitChance, selected.HitChance, lAttackPCFrom, lAttackPCTo);
SetLabels(Character.Strength + Weapon.AttackStrength, Character.Strength + _focusedWeapon.AttackStrength, lAttackFrom, lAttackTo);
SetLabels(Weapon.HitChance, _focusedWeapon.HitChance, lAttackPCFrom, lAttackPCTo);
}
public void ArmourFocussed() {
var selected = AvailableArmour[lbArmour.GetSelectedIndex(this)];
lDescription.Text = selected.Description;
_focusedArmour = AvailableArmour[lbArmour.GetSelectedIndex(this)];
lDescription.Text = _focusedArmour.Description;
ResetAllLabels();
SetLabels(Character.Vitality + Armour.Defense, Character.Vitality + selected.Defense, lDefenseFrom, lDefenseTo);
SetLabels(Character.Dexterity / 4 + Armour.DefensePercent, Character.Dexterity / 4 + selected.DefensePercent, lDefensePCFrom, lDefensePCTo);
SetLabels(Character.Spirit + Armour.MDefense, Character.Spirit + selected.MDefense, lMDefFrom, lMDefTo);
SetLabels(Character.Vitality + Armour.Defense, Character.Vitality + _focusedArmour.Defense, lDefenseFrom, lDefenseTo);
SetLabels(Character.Dexterity / 4 + Armour.DefensePercent, Character.Dexterity / 4 + _focusedArmour.DefensePercent, lDefensePCFrom, lDefensePCTo);
SetLabels(Character.Spirit + Armour.MDefense, Character.Spirit + _focusedArmour.MDefense, lMDefFrom, lMDefTo);
}
public void AccessoryFocussed() {
_focusedAccessory = AvailableAccessories[lbAccessories.GetSelectedIndex(this)];
//TODO - Str/Vit/Spr bonuses would affect things!
lDescription.Text = AvailableAccessories[lbAccessories.GetSelectedIndex(this)].Description;
lDescription.Text = _focusedAccessory.Description;
ResetAllLabels();
}

View File

@ -4,12 +4,14 @@
//
// SPDX-License-Identifier: EPL-2.0
using Braver.Battle;
using Braver.Plugins;
using Braver.Plugins.UI;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RazorEngineCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -19,7 +21,7 @@ using System.Xml.Serialization;
namespace Braver.UI.Layout {
[XmlInclude(typeof(Box)), XmlInclude(typeof(Label)), XmlInclude(typeof(Gauge))]
[XmlInclude(typeof(Group)), XmlInclude(typeof(Image)), XmlInclude(typeof(List))]
public abstract class Component {
public abstract class Component : IComponent {
private static Dictionary<string, Color> _colors = new Dictionary<string, Color>(StringComparer.InvariantCultureIgnoreCase);
@ -72,6 +74,9 @@ namespace Braver.UI.Layout {
}
}
[XmlIgnore]
IContainer IComponent.Parent => Parent;
public Point GetAbsolutePosition() {
int x = X, y = Y;
Container c = Parent;
@ -86,7 +91,7 @@ namespace Braver.UI.Layout {
public abstract void Draw(LayoutModel model, UIBatch ui, int offsetX, int offsetY, Func<float> getZ);
}
public abstract class SizedComponent : Component {
public abstract class SizedComponent : Component, ISizedComponent {
[XmlAttribute]
public int W { get; set; }
[XmlAttribute]
@ -100,13 +105,68 @@ namespace Braver.UI.Layout {
public int Y { get; set; }
}
public abstract class Container : SizedComponent {
public abstract class Container : SizedComponent, IContainer {
[XmlElement("Component")]
public List<Component> Children { get; set; } = new();
[XmlAttribute]
public bool InputPassthrough { get; set; }
private class ChildInterfaceList : IList<IComponent> {
public IComponent this[int index] {
get => UnderlyingList[index];
set => UnderlyingList[index] = value as Component;
}
public List<Component> UnderlyingList { get; set; }
public int Count => UnderlyingList.Count;
public bool IsReadOnly => false;
public void Add(IComponent item) {
UnderlyingList.Add(item as Component);
}
public void Clear() {
UnderlyingList.Clear();
}
public bool Contains(IComponent item) => UnderlyingList.Contains(item);
public void CopyTo(IComponent[] array, int arrayIndex) {
throw new NotImplementedException();
}
public IEnumerator<IComponent> GetEnumerator() {
throw new NotImplementedException();
}
public int IndexOf(IComponent item) => UnderlyingList.IndexOf(item as Component);
public void Insert(int index, IComponent item) {
UnderlyingList.Insert(index, item as Component);
}
public bool Remove(IComponent item) => UnderlyingList.Remove(item as Component);
public void RemoveAt(int index) {
UnderlyingList.RemoveAt(index);
}
IEnumerator IEnumerable.GetEnumerator() => UnderlyingList.GetEnumerator();
}
private ChildInterfaceList _ciList;
[XmlIgnore]
IList<IComponent> IContainer.Children {
get {
_ciList ??= new ChildInterfaceList { UnderlyingList = Children };
return _ciList;
}
}
public override void Draw(LayoutModel model, UIBatch ui, int offsetX, int offsetY, Func<float> getZ) {
foreach (var child in Children.Where(c => c.Visible))
child.Draw(model, ui, offsetX + X, offsetY + Y, getZ);
@ -261,7 +321,8 @@ namespace Braver.UI.Layout {
}
public override void Draw(LayoutModel model, UIBatch ui, int offsetX, int offsetY, Func<float> getZ) {
ui.DrawImage(ImageName, offsetX + X, offsetY + Y, getZ(), Alignment.Left, Scale, Color);
if (!string.IsNullOrWhiteSpace(ImageName))
ui.DrawImage(ImageName, offsetX + X, offsetY + Y, getZ(), Alignment.Left, Scale, Color);
}
}
@ -510,7 +571,7 @@ namespace Braver.UI.Layout {
}
}
public class LayoutScreen : Screen {
public class LayoutScreen : Screen, ILayoutScreen {
private Layout _layout;
private LayoutModel _model;
private UIBatch _ui;
@ -528,6 +589,12 @@ namespace Braver.UI.Layout {
public PluginInstances<IUI> Plugins { get; private set; }
IComponent ILayoutScreen.Root => _layout.Root;
IContainer ILayoutScreen.FocusGroup => _model.FocusGroup;
IComponent ILayoutScreen.Focus => _model.Focus;
dynamic ILayoutScreen.Model => _model;
public LayoutScreen(string layout, LayoutModel model = null, object parm = null) {
_layoutFile = layout;
Param = parm;
@ -548,12 +615,14 @@ namespace Braver.UI.Layout {
_model.Init(_layout);
_ui = new UIBatch(graphics, g);
g.Net.Send(new Net.ScreenReadyMessage());
Plugins.Call(ui => ui.Init(this));
}
public void Reload(bool forceReload = false) {
_model.Created(Game, this);
_layout = Game.Singleton(() => new RazorLayoutCache(Game)).Apply(_layoutFile, forceReload, _model.IsRazorModel ? _model : null);
_model.Init(_layout);
Plugins.Call(ui => ui.Reloaded());
}
protected override void DoRender() {
@ -634,6 +703,10 @@ namespace Braver.UI.Layout {
public override void ProcessInput(InputState input) {
base.ProcessInput(input);
if (Plugins.CallAll(ui => ui.PreInput(input)).Any(b => b))
return;
if (!_model.InputEnabled)
return;
if (_model.ProcessInput(input))
@ -672,5 +745,19 @@ namespace Braver.UI.Layout {
}
}
IComponent ILayoutScreen.Load(string templateName, object? model) {
var cache = Game.Singleton(() => new RazorLayoutCache(Game));
string xml = cache.ApplyPartial(templateName, false, model ?? _model);
return Serialisation.Deserialise<Component>(xml);
}
void ILayoutScreen.PushFocus(IContainer group, IComponent focus) {
_model.PushFocus(group as Container, focus as Component);
}
void ILayoutScreen.PopFocus() => _model.PopFocus();
void ILayoutScreen.ChangeFocus(IComponent focus) => _model.ChangeFocus(focus as Component);
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<BaseOutputPath>C:\Users\ficed\Projects\F7\PluginImplementations\output</BaseOutputPath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Braver.Core\Braver.Core.csproj" />
<ProjectReference Include="..\..\Braver.Plugins\Braver.Plugins.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Layout\EquipMenuMod.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="del $(OutDir)\Braver.Core.*&#xD;&#xA;del $(OutDir)\Ficedula.FF7.*&#xD;&#xA;del $(OutDir)\Braver.Plugins.*" />
</Target>
</Project>

View File

@ -0,0 +1,74 @@
// This program and the accompanying materials are made available under the terms of the
// Eclipse Public License v2.0 which accompanies this distribution, and is available at
// https://www.eclipse.org/legal/epl-v20.html
//
// SPDX-License-Identifier: EPL-2.0
using Braver.Plugins;
using Braver.Plugins.UI;
namespace Braver.EquipMenuMod {
public class EquipMenuModPlugin : Plugin {
public override string Name => "Sample Equip Menu Mod";
public override Version Version => new Version(0, 0, 1);
public override object ConfigObject => null;
public override IEnumerable<IPluginInstance> Get(string context, Type t) {
if (context == "EquipMenu")
yield return new EquipMenuDetails();
}
public override IEnumerable<Type> GetPluginInstances() {
yield return typeof(IUI);
}
public override void Init(BGame game) {
//TODO - change this for a better way of registering data sources alongside plugins
string folder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
game.AddDataSource("Layout", new FileDataSource(Path.Combine(folder, "Layout")));
}
}
public class EquipMenuDetails : IUI {
private ILayoutScreen _screen;
private IComponent _ui;
public void Init(ILayoutScreen screen) {
_screen = screen;
Reloaded();
}
public void Menu(IEnumerable<string> items, int selected, object container) {
//
}
public bool PreInput(InputState input) {
if (input.IsJustDown(InputKey.Select) && (_ui == null)) {
dynamic selected = _screen.Model.FocusedWeapon;
if (selected != null) {
var data = new Model {
Text = selected.Description,
Image = "logo_buster",
};
_ui = _screen.Load("EquipMenuMod", data);
(_screen.Root as IContainer).Children.Add(_ui);
return true;
}
} else if (input.IsJustDown(InputKey.Cancel) && (_ui != null)) {
(_screen.Root as IContainer).Children.Remove(_ui);
_ui = null;
return true;
}
return false;
}
public class Model {
public string Text { get; set; }
public string Image { get; set; }
}
public void Reloaded() {
}
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<Component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:type="Box" X="25" Y="400" W="250" H="250">
<Component xsi:type="Label" X="10" Y="10">@Model.Text</Component>
<Component xsi:type="Image" X="10" Y="50" ID="iEquipImage">@Model.Image</Component>
</Component>

View File

@ -193,15 +193,15 @@ namespace Braver.FFNxCompatibility {
//
}
public void Init(int fieldID, string fieldFile) {
var file = GetAudioEntry(_ambients, $"field_{fieldID}");
public void Init(IField field) {
var file = GetAudioEntry(_ambients, $"field_{field.FieldID}");
if (file != null) {
_audio = _game.Audio.LoadStream("Ambient", file + ".ogg");
}
}
public void Step(IField field) {
public void Step() {
if (_audio == null) return;
if (!_audio.IsPlaying) {

View File

@ -11,7 +11,6 @@ using Braver.Plugins.Field;
using Braver.Plugins.UI;
using Microsoft.Xna.Framework;
using System;
using System.Windows.Forms;
namespace Braver.Tolk {
@ -63,6 +62,7 @@ namespace Braver.Tolk {
public override void Init(BGame game) {
_game = game;
//TODO - this should probably go once MovieAD is split out
string root = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "data");
if (Directory.Exists(root)) {
foreach(string folder in Directory.GetDirectories(root)) {
@ -168,6 +168,18 @@ namespace Braver.Tolk {
public void ChoiceMade(int window, int choice) {
//
}
public void Init(ILayoutScreen screen) {
//
}
public void Reloaded() {
//
}
public bool PreInput(InputState input) {
return false;
}
}
public class FootstepFocusPlugin : IFieldLocation, IDisposable {
@ -177,6 +189,7 @@ namespace Braver.Tolk {
private Queue<Vector3> _positions = new();
private Vector3 _lastPosition;
private string _lastFocusName;
private IField _field;
public FootstepFocusPlugin(BGame game, bool footsteps, bool focus) {
if (footsteps) {
@ -189,6 +202,10 @@ namespace Braver.Tolk {
}
}
public void Init(IField field) {
_field = field;
}
public void EntityMoved(IFieldEntity entity, bool isRunning, Vector3 from, Vector3 to) {
if (entity.IsPlayer) {
_lastPosition = to;
@ -198,7 +215,7 @@ namespace Braver.Tolk {
private const int FOCUS_EVERY_X_FRAMES = 60;
private int _focusCountdown = FOCUS_EVERY_X_FRAMES;
public void Step(IField field) {
public void Step() {
if (_footsteps != null) {
while (_positions.Count > 5)
@ -217,15 +234,23 @@ namespace Braver.Tolk {
}
if ((_focusSound != null) && (--_focusCountdown == 0)) {
var focusState = field.GetFocusState();
var focusState = _field.GetFocusState();
if (focusState != null) {
System.Diagnostics.Debug.WriteLine($"Focus at walkmesh distance {focusState.WalkmeshDistance}");
if (field.Options.HasFlag(FieldOptions.PlayerControls)) {
if (_field.Options.HasFlag(FieldOptions.PlayerControls)) {
float pan = 0f;
if (focusState.Points.Count > 1) {
var direction = focusState.Points[focusState.Points.Count - 2].WalkmeshCenterScreenPos - focusState.Points[focusState.Points.Count - 1].WalkmeshCenterScreenPos;
if (focusState.WalkmeshTriPoints.Count > 1) {
var prev = _field.Walkmesh[focusState.WalkmeshTriPoints[focusState.WalkmeshTriPoints.Count - 2]].GetMiddlePoint();
//var last = _field.Walkmesh[focusState.WalkmeshTriPoints[focusState.WalkmeshTriPoints.Count - 1]].GetMiddlePoint();
var last = _field.PlayerPosition;
var direction = _field.Transform(prev) - _field.Transform(last);
System.Diagnostics.Debug.WriteLine(string.Join(", ", focusState.WalkmeshTriPoints));
System.Diagnostics.Debug.WriteLine(_field.Transform(prev));
System.Diagnostics.Debug.WriteLine(_field.Transform(last));
float sx = direction.X / 640f, sy = direction.Y / 360f;
pan = Math.Clamp(sx / sy, -1f, +1f);
pan = Math.Clamp(sx / Math.Abs(sy), -1f, +1f);
}
_focusSound.Play(1f, pan, false, 0.5f + (float)Math.Pow(0.9, focusState.WalkmeshDistance));
}
@ -252,9 +277,5 @@ namespace Braver.Tolk {
_playing = false;
}
}
public void Init(int fieldID, string fieldFile) {
//
}
}
}