Merge branch 'develop' into feature/showcase_kathi
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class PopUpPostIt : Control
|
||||
{
|
||||
private Label Text => GetNode<Label>("Text");
|
||||
|
||||
private AnimationPlayer Animation => GetNode<AnimationPlayer>("AnimationPlayer");
|
||||
|
||||
QuestManager QM => QuestManager.Instance!;
|
||||
public override void _EnterTree()
|
||||
{
|
||||
QM.QuestBecomesActive += NewQuestPostIt;
|
||||
}
|
||||
|
||||
private void NewQuestPostIt(QuestResource questResource)
|
||||
{
|
||||
Text.Text = questResource.title;
|
||||
Animation.Play("NewPostit");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://byar6yqrlph6k
|
||||
@@ -0,0 +1,11 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Babushka.scripts.CSharp.Common.Util;
|
||||
|
||||
public partial class QuestDescriptionUi : RichTextLabel
|
||||
{
|
||||
public void UpdateText(QuestLog questLog)
|
||||
{
|
||||
Text = questLog.currentDetailQuest?.description ?? "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://b8mywolvj2yq7
|
||||
@@ -0,0 +1,51 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Babushka.scripts.CSharp.Common.Util;
|
||||
using Godot;
|
||||
namespace Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class QuestListItemUi : Control
|
||||
{
|
||||
private Button TitleButton => GetNode<Button>("TitleButton");
|
||||
private Label TitleLabel => GetNode<Label>("TitleButton/HBoxContainer/TitleText");
|
||||
private TextureRect CircleTexture => GetNode<TextureRect>("TitleButton/Circled");
|
||||
private QuestResource? _questResource;
|
||||
|
||||
public void UpdateButton(QuestResource questResource)
|
||||
{
|
||||
_questResource = questResource;
|
||||
var questStatus = QuestManager.Instance!.GetQuestStatus(_questResource);
|
||||
var name = questResource.title;
|
||||
|
||||
name += questStatus.status switch
|
||||
{
|
||||
QuestStatus.Status.Done => " \u2713", // Check
|
||||
QuestStatus.Status.Canceled => " \u2715", // X
|
||||
_ => ""
|
||||
};
|
||||
|
||||
UpdateCircled(questResource == QuestManager.Instance.GetFollowQuest());
|
||||
ShowName(name);
|
||||
TitleButton.Pressed += ClickedTitleButton;
|
||||
|
||||
}
|
||||
private void UpdateCircled(bool value)
|
||||
{
|
||||
CircleTexture.Visible = value;
|
||||
}
|
||||
|
||||
private void ShowName(string questResourceTitle)
|
||||
{
|
||||
TitleLabel.Text = questResourceTitle;
|
||||
}
|
||||
|
||||
public void ClickedTitleButton()
|
||||
{
|
||||
var questLog = this.FindParentByType<QuestLog>();
|
||||
if (_questResource == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(_questResource), "QuestResource is null");
|
||||
}
|
||||
questLog.currentDetailQuest = _questResource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dwhee40ksubke
|
||||
@@ -0,0 +1,48 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class QuestListUi : VBoxContainer
|
||||
{
|
||||
[Export]
|
||||
private PackedScene _questListItemPrefab;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
UpdateList();
|
||||
QuestManager.Instance!.QuestsChanged += UpdateList;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
QuestManager.Instance!.QuestsChanged -= UpdateList;
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
UpdateList();
|
||||
}
|
||||
|
||||
public void UpdateList()
|
||||
{
|
||||
// delete children
|
||||
foreach (Node child in GetChildren())
|
||||
{
|
||||
RemoveChild(child);
|
||||
child.QueueFree();
|
||||
}
|
||||
|
||||
// recreate children
|
||||
var activeQuests = QuestManager.Instance.GetVisibleQuests();
|
||||
|
||||
foreach (var questPair in activeQuests)
|
||||
{
|
||||
var questResource = questPair.Key;
|
||||
var questStatus = questPair.Value;
|
||||
|
||||
var questListItem = _questListItemPrefab.Instantiate<QuestListItemUi>();
|
||||
questListItem.UpdateButton(questResource);
|
||||
AddChild(questListItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://c7ilqe2fmjyvx
|
||||
@@ -0,0 +1,53 @@
|
||||
#nullable enable
|
||||
using Godot;
|
||||
using System;
|
||||
using Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class QuestLog : Control
|
||||
{
|
||||
[Signal]
|
||||
public delegate void DetailQuestChangedEventHandler(QuestLog questLog);
|
||||
|
||||
[Export]
|
||||
private Vector2 _closedPos;
|
||||
|
||||
[Export]
|
||||
private Vector2 _openedPos;
|
||||
|
||||
private bool _isClosed = true;
|
||||
private Tween? _closeOpenTween;
|
||||
|
||||
public QuestResource? currentDetailQuest
|
||||
{
|
||||
get => QuestManager.Instance!.GetFollowQuest();
|
||||
set
|
||||
{
|
||||
QuestManager.Instance!.SetFollowQuest(value); // TODO: fix setup
|
||||
EmitSignalDetailQuestChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
QuestManager.Instance!.QuestsChanged += () => EmitSignalDetailQuestChanged(this);
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent inputEvent)
|
||||
{
|
||||
if (inputEvent.IsActionPressed("ui_inventory_journal_open_close"))
|
||||
{
|
||||
if(_closeOpenTween != null)
|
||||
_closeOpenTween.Kill();
|
||||
|
||||
_isClosed = !_isClosed;
|
||||
|
||||
_closeOpenTween = GetTree().CreateTween();
|
||||
_closeOpenTween
|
||||
.TweenProperty(this, "position", _isClosed ? _closedPos : _openedPos, 0.5)
|
||||
.SetEase(Tween.EaseType.Out)
|
||||
.SetTrans(Tween.TransitionType.Cubic);
|
||||
}
|
||||
}
|
||||
|
||||
//private QuestResource? _currentDetailQuestBacking;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://o1qpo0wdqlw3
|
||||
@@ -0,0 +1,76 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
using QuestPair = KeyValuePair<QuestResource, QuestStatus>;
|
||||
public partial class QuestManager : Node
|
||||
{
|
||||
public static QuestManager? Instance { get; private set; }
|
||||
|
||||
[Signal]
|
||||
public delegate void QuestBecomesActiveEventHandler(QuestResource questResource);
|
||||
|
||||
[Signal]
|
||||
public delegate void QuestsChangedEventHandler();
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private Godot.Collections.Dictionary<QuestResource, QuestStatus> _questStatus = new();
|
||||
|
||||
private QuestResource? _followQuest;
|
||||
|
||||
|
||||
public void ChangeQuestStatus(QuestResource questResource, QuestStatus.Status newStatus)
|
||||
{
|
||||
if (!_questStatus.TryGetValue(questResource, out var value))
|
||||
{
|
||||
value = new QuestStatus();
|
||||
_questStatus.Add(questResource, value);
|
||||
}
|
||||
|
||||
value.status = newStatus;
|
||||
|
||||
EmitSignalQuestsChanged();
|
||||
|
||||
if (newStatus == QuestStatus.Status.Active)
|
||||
{
|
||||
EmitSignalQuestBecomesActive(questResource);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<QuestPair> GetVisibleQuests()
|
||||
{
|
||||
return _questStatus.Where(qs => qs.Value.status != QuestStatus.Status.Hidden);
|
||||
}
|
||||
|
||||
public IEnumerable<QuestPair> GetActiveQuests()
|
||||
{
|
||||
return _questStatus.Where(qs => qs.Value.status == QuestStatus.Status.Active);
|
||||
}
|
||||
public QuestStatus GetQuestStatus(QuestResource questResource)
|
||||
{
|
||||
if (_questStatus.TryGetValue(questResource, out var status))
|
||||
return status;
|
||||
|
||||
status = new QuestStatus();
|
||||
_questStatus.Add(questResource, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
public QuestResource? GetFollowQuest()
|
||||
{
|
||||
return _followQuest;
|
||||
}
|
||||
|
||||
public void SetFollowQuest(QuestResource? questResource)
|
||||
{
|
||||
_followQuest = questResource;
|
||||
EmitSignalQuestsChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dl2uhq12p3qks
|
||||
@@ -0,0 +1,86 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Net.Mime;
|
||||
using Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class QuestMessagePopup : Control
|
||||
{
|
||||
|
||||
private Label Text => GetNode<Label>("Text");
|
||||
|
||||
private QuestResource? _currentlyShown;
|
||||
|
||||
private Tween? _activeTween = null;
|
||||
|
||||
[Export]
|
||||
private Vector2 _showPosition;
|
||||
|
||||
[Export]
|
||||
private Vector2 _hidePosition;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
QuestManager.Instance!.QuestsChanged += NewActiveQuest;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
QuestManager.Instance!.QuestsChanged -= NewActiveQuest;
|
||||
}
|
||||
|
||||
private void NewActiveQuest()
|
||||
{
|
||||
var shownQuest = QuestManager.Instance!.GetFollowQuest();
|
||||
if (_currentlyShown == shownQuest)
|
||||
return;
|
||||
|
||||
if (_activeTween != null)
|
||||
{
|
||||
_activeTween.Kill();
|
||||
}
|
||||
|
||||
if (shownQuest == null)
|
||||
{
|
||||
HideAnimate();
|
||||
_currentlyShown = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentlyShown == null)
|
||||
{
|
||||
Text.Text = shownQuest.title;
|
||||
ShowAnimate();
|
||||
_currentlyShown = shownQuest;
|
||||
return;
|
||||
}
|
||||
|
||||
// else (_currentlyShown != null)
|
||||
|
||||
_currentlyShown = shownQuest;
|
||||
HideAnimate(() =>
|
||||
{
|
||||
Text.Text = shownQuest.title;
|
||||
ShowAnimate();
|
||||
});
|
||||
}
|
||||
|
||||
private void HideAnimate(Action? then = null)
|
||||
{
|
||||
_activeTween = GetTree().CreateTween();
|
||||
_activeTween.TweenProperty(this, "position", _hidePosition, 0.4)
|
||||
.SetTrans(Tween.TransitionType.Cubic)
|
||||
.SetEase(Tween.EaseType.Out);
|
||||
if (then != null)
|
||||
_activeTween.Finished += then;
|
||||
}
|
||||
|
||||
private void ShowAnimate(Action? then = null)
|
||||
{
|
||||
_activeTween = GetTree().CreateTween();
|
||||
_activeTween.TweenProperty(this, "position", _showPosition, 0.4)
|
||||
.SetTrans(Tween.TransitionType.Cubic)
|
||||
.SetEase(Tween.EaseType.Out);
|
||||
if (then != null)
|
||||
_activeTween.Finished += then;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://7wwid23tc8as
|
||||
@@ -0,0 +1,13 @@
|
||||
using Godot;
|
||||
namespace Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class QuestResource : Resource
|
||||
{
|
||||
[Export]
|
||||
public string id = "";
|
||||
[Export]
|
||||
public string title = "";
|
||||
[Export(PropertyHint.MultilineText)]
|
||||
public string description = "";
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://vji5lp4qc8pp
|
||||
@@ -0,0 +1,16 @@
|
||||
using Godot;
|
||||
|
||||
namespace Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class QuestStatus : GodotObject
|
||||
{
|
||||
public enum Status
|
||||
{
|
||||
Hidden,
|
||||
Active,
|
||||
Done,
|
||||
Canceled,
|
||||
}
|
||||
|
||||
public Status status = Status.Hidden;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bpqgcchuubfiy
|
||||
@@ -0,0 +1,20 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Babushka.scripts.CSharp.Common.Quest;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class QuestTestingScript : Node
|
||||
{
|
||||
[Export(PropertyHint.ArrayType)]
|
||||
private Array<QuestResource> _questsToActivate;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
foreach (var questResource in _questsToActivate)
|
||||
{
|
||||
QuestManager.Instance.ChangeQuestStatus(questResource, QuestStatus.Status.Active);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://cg0oqug38c81n
|
||||
@@ -0,0 +1,33 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Babushka.scripts.CSharp.Common.Quest;
|
||||
|
||||
public partial class QuestTrigger : Node
|
||||
{
|
||||
[Export]
|
||||
public QuestResource? questResource;
|
||||
|
||||
[Export]
|
||||
public QuestStatus.Status toStatus;
|
||||
|
||||
[Export]
|
||||
private bool makeCurrent = false;
|
||||
|
||||
public void Trigger()
|
||||
{
|
||||
GD.Print("trigger");
|
||||
|
||||
if(questResource== null)
|
||||
throw new Exception("QuestResource is not set on QuestTrigger node.");
|
||||
|
||||
if(QuestManager.Instance == null)
|
||||
throw new Exception("QuestManager instance is not available. Make sure it is initialized before calling Trigger.");
|
||||
|
||||
QuestManager.Instance.ChangeQuestStatus(questResource, toStatus);
|
||||
|
||||
if (makeCurrent)
|
||||
{
|
||||
QuestManager.Instance.SetFollowQuest(questResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://cldtt4atgymm5
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Godot;
|
||||
namespace Babushka.scripts.CSharp.Common.Util;
|
||||
|
||||
public static class NodeExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches for a parent node of the specified type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parent node to search for. The search is successful, when <code>searchedNode is T</code></typeparam>
|
||||
/// <param name="self">The node from which to start the search.</param>
|
||||
/// <returns>The parent node of type T if found, otherwise throws an exception.</returns>
|
||||
public static T FindParentByType<T>(this Node self)
|
||||
{
|
||||
var parent = self.GetParent();
|
||||
while (parent != null)
|
||||
{
|
||||
if (parent is T tParent)
|
||||
{
|
||||
return tParent;
|
||||
}
|
||||
parent = parent.GetParent();
|
||||
}
|
||||
throw new Exception($"Parent of type {typeof(T)} not found for node {self.Name}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bwisbh2f2ci6l
|
||||
Reference in New Issue
Block a user