Add quick interactions locally
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
using Barotrauma;
|
||||
using HarmonyLib;
|
||||
using Microsoft.Xna.Framework;
|
||||
using QICrabUI;
|
||||
using QIDependencyInjection;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace QuickInteractions
|
||||
{
|
||||
/// <summary>
|
||||
/// A container for buttons that sync their state
|
||||
/// </summary>
|
||||
public class CUICompositeButton : CUIComponent
|
||||
{
|
||||
[CUISerializable] public Color DisabledColor { get; set; }
|
||||
[CUISerializable] public Color InactiveColor { get; set; }
|
||||
[CUISerializable] public Color MouseOverColor { get; set; }
|
||||
[CUISerializable] public Color MousePressedColor { get; set; }
|
||||
|
||||
public Color MasterColor
|
||||
{
|
||||
set
|
||||
{
|
||||
InactiveColor = value.Multiply(0.7f);
|
||||
MouseOverColor = value.Multiply(0.9f);
|
||||
MousePressedColor = value;
|
||||
DetermineColor();
|
||||
}
|
||||
}
|
||||
|
||||
public Color MasterColorOpaque
|
||||
{
|
||||
set
|
||||
{
|
||||
InactiveColor = new Color((int)(value.R * 0.7f), (int)(value.G * 0.7f), (int)(value.B * 0.7f), value.A);
|
||||
MouseOverColor = new Color((int)(value.R * 0.9f), (int)(value.G * 0.9f), (int)(value.B * 0.9f), value.A);
|
||||
MousePressedColor = value;
|
||||
DetermineColor();
|
||||
}
|
||||
}
|
||||
|
||||
public List<CUIButton> Buttons = new();
|
||||
|
||||
public void DetermineColor()
|
||||
{
|
||||
Color cl = Color.Transparent;
|
||||
if (Disabled)
|
||||
{
|
||||
cl = DisabledColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
cl = InactiveColor;
|
||||
if (MouseOver) cl = MouseOverColor;
|
||||
if (MousePressed) cl = MousePressedColor;
|
||||
}
|
||||
|
||||
foreach (CUIButton button in Buttons) button.BackgroundColor = cl;
|
||||
}
|
||||
|
||||
public CUICompositeButton() : base()
|
||||
{
|
||||
ConsumeMouseClicks = true;
|
||||
|
||||
OnChildAdded += (child) =>
|
||||
{
|
||||
if (child is CUIButton button)
|
||||
{
|
||||
Buttons.Add(button);
|
||||
button.AutoUpdateColor = false;
|
||||
button.ConsumeMouseClicks = false;
|
||||
OnMouseOff += (e) => DetermineColor();
|
||||
OnMouseOn += (e) => DetermineColor();
|
||||
}
|
||||
};
|
||||
|
||||
DetermineColor();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
100
Quick Interactions/CSharp/Client/Layers/UI/FabricatorButton.cs
Normal file
100
Quick Interactions/CSharp/Client/Layers/UI/FabricatorButton.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
using Barotrauma;
|
||||
using HarmonyLib;
|
||||
using Microsoft.Xna.Framework;
|
||||
using QICrabUI;
|
||||
using QIDependencyInjection;
|
||||
|
||||
namespace QuickInteractions
|
||||
{
|
||||
public class FabricatorButton : CUIHorizontalList
|
||||
{
|
||||
public static Color GetButtonColor(Item item)
|
||||
{
|
||||
return item.Prefab.Identifier.Value switch
|
||||
{
|
||||
"fabricator" => new Color(255, 255, 255),
|
||||
"medicalfabricator" => new Color(255, 130, 130),
|
||||
"deconstructor" => new Color(255, 255, 130),
|
||||
_ => new Color(255, 255, 255),
|
||||
};
|
||||
}
|
||||
|
||||
public static CUISprite GetIcon(Item item)
|
||||
{
|
||||
return item.Prefab.Identifier.Value switch
|
||||
{
|
||||
"fabricator" => GetIcon(0, 1),
|
||||
"medicalfabricator" => GetIcon(0, 1),
|
||||
"deconstructor" => GetIcon(1, 1),
|
||||
_ => GetIcon(0, 1),
|
||||
};
|
||||
}
|
||||
|
||||
public static CUISprite GetIcon(int x, int y) => QuickTalkButton.GetIcon(x, y);
|
||||
|
||||
public static string GetInteractionText(Item item)
|
||||
{
|
||||
return $"{item.Prefab.Name}";
|
||||
}
|
||||
|
||||
public Item item { get; set; }
|
||||
|
||||
public bool TextVisible
|
||||
{
|
||||
get => Text.Parent != null;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (Text.Parent == null) Append(Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Text.Parent != null) RemoveChild(Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CUIButton Icon;
|
||||
public CUITextBlock Text;
|
||||
|
||||
public FabricatorButton(Item item, CUIDirection direction) : base()
|
||||
{
|
||||
FitContent = new CUIBool2(true, true);
|
||||
Direction = direction;
|
||||
|
||||
this["icon"] = Icon = new CUIButton()
|
||||
{
|
||||
Text = "",
|
||||
Border = new CUIBorder(),
|
||||
BackgroundSprite = GetIcon(item),
|
||||
MasterColorOpaque = GetButtonColor(item),
|
||||
Absolute = QuickTalkButton.IconSize,
|
||||
//ResizeToSprite = true,
|
||||
};
|
||||
|
||||
Icon.OnMouseDown += (e) =>
|
||||
{
|
||||
DispatchUp(new CUICommand("interact", item));
|
||||
};
|
||||
|
||||
Text = new CUITextBlock("")
|
||||
{
|
||||
TextAlign = CUIAnchor.CenterLeft,
|
||||
Text = GetInteractionText(item),
|
||||
TextScale = QuickTalkButton.TextScale,
|
||||
Ghost = new CUIBool2(false, true),
|
||||
};
|
||||
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
using Barotrauma;
|
||||
using HarmonyLib;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using QICrabUI;
|
||||
using QIDependencyInjection;
|
||||
|
||||
namespace QuickInteractions
|
||||
{
|
||||
public class QuickInteractionsUI : CUIFrame
|
||||
{
|
||||
public static string SavePath => Path.Combine(Mod.Instance.Paths.DataUI, "QuickInteractionsUI.xml");
|
||||
[Dependency] public GameStageTracker GameStageTracker { get; set; }
|
||||
[Dependency] public Logger Logger { get; set; }
|
||||
[Dependency] public Debugger Debugger { get; set; }
|
||||
[Dependency] public QuickTalk QuickTalk { get; set; }
|
||||
[Dependency] public Fabricators Fabricators { get; set; }
|
||||
[Dependency] public Debouncer Debouncer { get; set; }
|
||||
|
||||
private bool textVisible;
|
||||
public bool TextVisible
|
||||
{
|
||||
get => textVisible;
|
||||
set
|
||||
{
|
||||
if (textVisible == value) return;
|
||||
textVisible = value;
|
||||
|
||||
//BackgroundColor = value ? new Color(0, 0, 0, 150) : Color.Transparent;
|
||||
|
||||
UpdateAnchor();
|
||||
this["layout"].Children.ForEach(c =>
|
||||
{
|
||||
if (c is QuickTalkButton qtb) qtb.TextVisible = value;
|
||||
if (c is FabricatorButton fb) fb.TextVisible = value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public CUIDirection ButtonDirection => Real.Left < CUI.GameScreenSize.X / 2.0f ? CUIDirection.Straight : CUIDirection.Reverse;
|
||||
|
||||
public void UpdateAnchor()
|
||||
{
|
||||
bool onTheLeft = Real.Left < CUI.GameScreenSize.X / 2.0f;
|
||||
if (onTheLeft)
|
||||
{
|
||||
if (Anchor == CUIAnchor.BottomRight)
|
||||
{
|
||||
Anchor = CUIAnchor.BottomLeft;
|
||||
Absolute = Absolute with { Left = Real.Left };
|
||||
}
|
||||
BackgroundSprite.Effects = SpriteEffects.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Anchor == CUIAnchor.BottomLeft)
|
||||
{
|
||||
Anchor = CUIAnchor.BottomRight;
|
||||
Absolute = Absolute with { Left = (Real.Left + Real.Width) - CUI.GameScreenSize.X };
|
||||
}
|
||||
BackgroundSprite.Effects = SpriteEffects.FlipHorizontally;
|
||||
}
|
||||
}
|
||||
public void CreateUI()
|
||||
{
|
||||
OutlineColor = Color.Transparent;
|
||||
BackgroundColor = new Color(255, 255, 255, 255);//Color.Transparent;
|
||||
BackgroundSprite = CUI.TextureManager.GetCUISprite(4, 1);
|
||||
Absolute = new CUINullRect(y: -50);
|
||||
Anchor = CUIAnchor.BottomLeft;
|
||||
Relative = new CUINullRect(-0.5f, 0);
|
||||
Resizible = false;
|
||||
FitContent = new CUIBool2(true, true);
|
||||
//DragHandle.DragRelative = true;
|
||||
DragHandle.OutputRealPos = true;
|
||||
|
||||
this["layout"] = new CUIVerticalList()
|
||||
{
|
||||
Relative = new CUINullRect(0, 0, 1, 1),
|
||||
FitContent = new CUIBool2(true, true),
|
||||
Scrollable = true,
|
||||
BreakSerialization = true,
|
||||
BottomGap = 0,
|
||||
};
|
||||
|
||||
//SaveToFile(SavePath);
|
||||
LoadSelfFromFile(SavePath);
|
||||
}
|
||||
|
||||
public override void Hydrate()
|
||||
{
|
||||
OnDrag += (x, y) =>
|
||||
{
|
||||
bool onTheLeft = x < CUI.GameScreenSize.X / 2.0f;
|
||||
|
||||
if (onTheLeft && BackgroundSprite.Effects == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
BackgroundSprite.Effects = SpriteEffects.None;
|
||||
}
|
||||
if (!onTheLeft && BackgroundSprite.Effects == SpriteEffects.None)
|
||||
{
|
||||
BackgroundSprite.Effects = SpriteEffects.FlipHorizontally;
|
||||
}
|
||||
|
||||
//UpdateAnchor();
|
||||
this["layout"].Children.ForEach(c =>
|
||||
{
|
||||
if (c is CUIHorizontalList button)
|
||||
{
|
||||
button.Direction = onTheLeft ? CUIDirection.Straight : CUIDirection.Reverse;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
OnMouseOn += (e) => TextVisible = MouseOver;
|
||||
OnMouseOff += (e) => TextVisible = MouseOver;
|
||||
|
||||
AddCommand("interact", (o) =>
|
||||
{
|
||||
if (o is Character character)
|
||||
{
|
||||
QuickTalk.InteractWith(character);
|
||||
}
|
||||
|
||||
if (o is Item item)
|
||||
{
|
||||
Fabricators.SelectItem(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void AfterInject()
|
||||
{
|
||||
Mod.Instance.OnPluginLoad += () => { Revealed = Utils.IsThisAnOutpost; Refresh(); };
|
||||
Mod.Instance.OnPluginUnload += () => { SaveToFile(SavePath); };
|
||||
|
||||
GameStageTracker.OnRoundStart += () => { Revealed = Utils.IsThisAnOutpost; ScheduleRefresh(500); }; // bruh
|
||||
GameStageTracker.OnRoundStartOrInitialize += () => { Revealed = Utils.IsThisAnOutpost; ScheduleRefresh(500); };
|
||||
GameStageTracker.OnRoundEnd += () => Revealed = false;
|
||||
|
||||
QuickTalk.CharacterStatusUpdated += (c) => Refresh();
|
||||
|
||||
CreateUI();
|
||||
}
|
||||
|
||||
public void ScheduleRefresh(int delay = 100)
|
||||
{
|
||||
Debugger.Log("ScheduleRefresh", DebugLevel.UIRefresh);
|
||||
GameMain.LuaCs.Timer.Wait((object[] args) => Refresh(), delay);
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if (!Revealed) return;
|
||||
|
||||
Debouncer.Debounce("refresh", 100, () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this["layout"] == null) return;
|
||||
|
||||
if (GUI.DisableHUD)
|
||||
{
|
||||
ScheduleRefresh(500);
|
||||
return;
|
||||
}
|
||||
Debugger.Log("Refresh", DebugLevel.UIRefresh);
|
||||
|
||||
bool onTheLeft = Real.Left < CUI.GameScreenSize.X / 2.0f;
|
||||
|
||||
this["layout"].RemoveAllChildren();
|
||||
|
||||
foreach (Character character in QuickTalk.WantToTalk)
|
||||
{
|
||||
this["layout"].Append(new QuickTalkButton(character, ButtonDirection));
|
||||
}
|
||||
|
||||
foreach (Character character in QuickTalk.Merchants)
|
||||
{
|
||||
this["layout"].Append(new QuickTalkButton(character, ButtonDirection));
|
||||
}
|
||||
|
||||
if (Fabricators.OutpostFabricator != null)
|
||||
{
|
||||
this["layout"].Append(new FabricatorButton(Fabricators.OutpostFabricator, ButtonDirection));
|
||||
}
|
||||
|
||||
if (Fabricators.OutpostMedFabricator != null)
|
||||
{
|
||||
this["layout"].Append(new FabricatorButton(Fabricators.OutpostMedFabricator, ButtonDirection));
|
||||
}
|
||||
|
||||
if (Fabricators.OutpostDeconstructor != null)
|
||||
{
|
||||
this["layout"].Append(new FabricatorButton(Fabricators.OutpostDeconstructor, ButtonDirection));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
154
Quick Interactions/CSharp/Client/Layers/UI/QuickTalkButton.cs
Normal file
154
Quick Interactions/CSharp/Client/Layers/UI/QuickTalkButton.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
using Barotrauma;
|
||||
using HarmonyLib;
|
||||
using Microsoft.Xna.Framework;
|
||||
using QICrabUI;
|
||||
using QIDependencyInjection;
|
||||
|
||||
namespace QuickInteractions
|
||||
{
|
||||
public class QuickTalkButton : CUIHorizontalList
|
||||
{
|
||||
[Dependency] public static Debugger Debugger { get; set; }
|
||||
public static float MotinorScale = 1.0f;
|
||||
public static Point IconTextureSize = new Point(139, 75);
|
||||
public static float IconProportions = (float)IconTextureSize.X / (float)IconTextureSize.Y;
|
||||
public static float ScreenHeightToIconHeight = (float)IconTextureSize.Y / 3072.0f * MotinorScale;
|
||||
public static CUINullRect IconSize => new CUINullRect(null, null,
|
||||
(float)Math.Round(CUI.GameScreenSize.Y * ScreenHeightToIconHeight * IconProportions),
|
||||
(float)Math.Round(CUI.GameScreenSize.Y * ScreenHeightToIconHeight)
|
||||
);
|
||||
|
||||
public static float TextScale => CUI.GameScreenSize.Y / 840.0f * MotinorScale;
|
||||
|
||||
public static Color GetButtonColor(Character character)
|
||||
{
|
||||
if (character.IsDead) return new Color(255, 0, 0);
|
||||
|
||||
Color cl = character.CampaignInteractionType switch
|
||||
{
|
||||
CampaignMode.InteractionType.Talk => new Color(255, 255, 255),
|
||||
CampaignMode.InteractionType.Examine => character.HumanPrefab?.Identifier.Value switch
|
||||
{
|
||||
"jestmaster" => new Color(255, 64, 255),
|
||||
"huskcultecclesiast" => new Color(80, 80, 255),
|
||||
_ => new Color(255, 255, 255),
|
||||
},
|
||||
CampaignMode.InteractionType.Crew => new Color(198, 211, 242),
|
||||
CampaignMode.InteractionType.Store => character.HumanPrefab?.Identifier.Value switch
|
||||
{
|
||||
"merchantnightclub" => new Color(255, 0, 80),
|
||||
"merchantmedical" => new Color(255, 130, 130),
|
||||
"merchantengineering" => new Color(255, 255, 130),
|
||||
"merchantarmory" => new Color(200, 200, 200),
|
||||
"merchantclown" => new Color(255, 64, 255),
|
||||
"merchanthusk" => new Color(80, 80, 255),
|
||||
_ => new Color(255, 200, 170),
|
||||
},
|
||||
CampaignMode.InteractionType.Upgrade => new Color(106, 250, 115),
|
||||
CampaignMode.InteractionType.PurchaseSub => new Color(169, 212, 187),
|
||||
CampaignMode.InteractionType.MedicalClinic => new Color(255, 130, 130),
|
||||
_ => Color.White,
|
||||
};
|
||||
|
||||
// Ye,ok, doesn't work in multiplayer
|
||||
Debugger.Log($"Interaction: {character.CampaignInteractionType} Id:{character.HumanPrefab?.Identifier.Value} Color:{character}", DebugLevel.ButtonColor);
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
||||
public static CUISprite GetIcon(Character character)
|
||||
{
|
||||
return character.CampaignInteractionType switch
|
||||
{
|
||||
CampaignMode.InteractionType.Talk => GetIcon(2),
|
||||
CampaignMode.InteractionType.Examine => GetIcon(2),
|
||||
CampaignMode.InteractionType.Crew => GetIcon(3),
|
||||
CampaignMode.InteractionType.Store => GetIcon(0),
|
||||
CampaignMode.InteractionType.Upgrade => GetIcon(4),
|
||||
CampaignMode.InteractionType.PurchaseSub => GetIcon(5),
|
||||
CampaignMode.InteractionType.MedicalClinic => GetIcon(1),
|
||||
_ => GetIcon(2),
|
||||
};
|
||||
}
|
||||
|
||||
public static CUISprite GetIcon(int x, int y = 0)
|
||||
{
|
||||
return new CUISprite("Interaction icons.png", new Rectangle(x * IconTextureSize.X, y * IconTextureSize.Y, IconTextureSize.X, IconTextureSize.Y));
|
||||
}
|
||||
|
||||
public static string GetInteractionText(Character character)
|
||||
{
|
||||
string InteractionText = TextManager.Get("CampaignInteraction." + character.CampaignInteractionType).ToString().Replace("[[key]]", "");
|
||||
|
||||
string pname = character.HumanPrefab?.Identifier.Value;
|
||||
bool isAManager = pname != null && pname.Contains("outpostmanager");
|
||||
|
||||
LocalizedString name = character.Info?.DisplayName;
|
||||
if (character.Info?.Title != "") name = character.Info?.Title;
|
||||
if (isAManager) name = TextManager.Get("npctitle.outpostmanager");
|
||||
|
||||
return $"{name} - {InteractionText}";
|
||||
}
|
||||
|
||||
public Character character { get; set; }
|
||||
|
||||
public bool TextVisible
|
||||
{
|
||||
get => Text.Parent != null;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (Text.Parent == null) Append(Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Text.Parent != null) RemoveChild(Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CUIButton Icon;
|
||||
public CUITextBlock Text;
|
||||
|
||||
public QuickTalkButton(Character character, CUIDirection direction) : base()
|
||||
{
|
||||
FitContent = new CUIBool2(true, true);
|
||||
Direction = direction;
|
||||
|
||||
this["icon"] = Icon = new CUIButton()
|
||||
{
|
||||
Text = "",
|
||||
Border = new CUIBorder(),
|
||||
BackgroundSprite = GetIcon(character),
|
||||
MasterColorOpaque = GetButtonColor(character),
|
||||
//ResizeToSprite = true,
|
||||
Absolute = IconSize,
|
||||
};
|
||||
|
||||
Icon.OnMouseDown += (e) =>
|
||||
{
|
||||
DispatchUp(new CUICommand("interact", character));
|
||||
};
|
||||
|
||||
Text = new CUITextBlock("")
|
||||
{
|
||||
TextAlign = CUIAnchor.CenterLeft,
|
||||
Text = GetInteractionText(character),
|
||||
TextScale = TextScale,
|
||||
Ghost = new CUIBool2(false, true),
|
||||
};
|
||||
|
||||
this.character = character;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user