From d8b99e07de4e92abd7b4892a6d6160725168347b Mon Sep 17 00:00:00 2001 From: Zenny Date: Thu, 4 Jun 2026 23:06:01 -0700 Subject: [PATCH] Save when talking to stele and record their ID in the save file --- .../Quest/SarcoData.cs | 7 +++++++ Zennysoft.Game.Ma/src/game/Game.cs | 14 +++++++++++--- Zennysoft.Game.Ma/src/game/GameData.cs | 3 +++ Zennysoft.Game.Ma/src/game/IGame.cs | 2 ++ Zennysoft.Game.Ma/src/map/Placeables/Sarco.cs | 4 ---- .../floors/Special Floors/Overworld.tscn | 16 ++++++++++++++-- Zennysoft.Game.Ma/src/npc/Npc.cs | 19 ++++++++++++++++++- Zennysoft.Game.Ma/stone.dialogue | 2 ++ 8 files changed, 57 insertions(+), 10 deletions(-) diff --git a/Zennysoft.Game.Ma.Implementation/Quest/SarcoData.cs b/Zennysoft.Game.Ma.Implementation/Quest/SarcoData.cs index 8b90d3f3..6cba89dd 100644 --- a/Zennysoft.Game.Ma.Implementation/Quest/SarcoData.cs +++ b/Zennysoft.Game.Ma.Implementation/Quest/SarcoData.cs @@ -27,3 +27,10 @@ public partial record SarcoData [Save("shura_sarco")] public bool ShuraSarcoAcquired { get; set; } = false; } + +[Meta, Id("npc_data")] +public partial record NpcData +{ + [Save("stele_list")] + public required List SteleDiscovered { get; set; } +} diff --git a/Zennysoft.Game.Ma/src/game/Game.cs b/Zennysoft.Game.Ma/src/game/Game.cs index ec5d3a27..c03daaf1 100644 --- a/Zennysoft.Game.Ma/src/game/Game.cs +++ b/Zennysoft.Game.Ma/src/game/Game.cs @@ -72,6 +72,8 @@ public partial class Game : Node3D, IGame public SarcoData SarcoData { get; private set; } + public NpcData NpcData { get; private set; } + public ItemRescueMenu ItemRescueMenu { get => InGameUI.ItemRescueMenu; } private EffectService _effectService; @@ -100,6 +102,7 @@ public partial class Game : Node3D, IGame QuestData = new QuestData(); RescuedItems = new RescuedItemDatabase(20); SarcoData = new SarcoData(); + NpcData = new NpcData() { SteleDiscovered = [] }; ItemDatabase = ItemDatabase.Instance; GameChunk = new SaveChunk( @@ -122,6 +125,10 @@ public partial class Game : Node3D, IGame FerrumSarcoAcquired = SarcoData.FerrumSarcoAcquired, SanktaSarcoAcquired = SarcoData.SanktaSarcoAcquired, ShuraSarcoAcquired = SarcoData.ShuraSarcoAcquired, + }, + NpcData = new NpcData() + { + SteleDiscovered = NpcData.SteleDiscovered } }; return gameData; @@ -129,9 +136,10 @@ public partial class Game : Node3D, IGame onLoad: (chunk, data) => { - RescuedItems = data.RescuedItems; - QuestData = data.QuestData; - SarcoData = data.SarcoData; + RescuedItems = data.RescuedItems ?? new RescuedItemDatabase(); + QuestData = data.QuestData ?? new QuestData(); + SarcoData = data.SarcoData ?? new SarcoData(); + NpcData = data.NpcData ?? new NpcData() { SteleDiscovered = [] }; } ); diff --git a/Zennysoft.Game.Ma/src/game/GameData.cs b/Zennysoft.Game.Ma/src/game/GameData.cs index 0a42177b..0d19e189 100644 --- a/Zennysoft.Game.Ma/src/game/GameData.cs +++ b/Zennysoft.Game.Ma/src/game/GameData.cs @@ -14,5 +14,8 @@ public partial record GameData [Save("sarco_data")] public required SarcoData SarcoData { get; init; } + + [Save("npc_data")] + public required NpcData NpcData { get; init; } } diff --git a/Zennysoft.Game.Ma/src/game/IGame.cs b/Zennysoft.Game.Ma/src/game/IGame.cs index a8b7b603..3bf1974b 100644 --- a/Zennysoft.Game.Ma/src/game/IGame.cs +++ b/Zennysoft.Game.Ma/src/game/IGame.cs @@ -48,6 +48,8 @@ public interface IGame : IProvide, IProvide, IProvide public SarcoData SarcoData { get; } + public NpcData NpcData { get; } + public event Action GameExitRequested; public event Action GameLoaded; diff --git a/Zennysoft.Game.Ma/src/map/Placeables/Sarco.cs b/Zennysoft.Game.Ma/src/map/Placeables/Sarco.cs index 3dce4b03..e454abd2 100644 --- a/Zennysoft.Game.Ma/src/map/Placeables/Sarco.cs +++ b/Zennysoft.Game.Ma/src/map/Placeables/Sarco.cs @@ -40,10 +40,6 @@ public partial class Sarco : Node3D SetPhysicsProcess(true); InteractZone.BodyEntered += InteractZone_BodyEntered; InteractZone.BodyExited += InteractZone_BodyExited; - } - - public void OnResolved() - { _interactionComplete = GetSaveDataByAffinity(); if (_interactionComplete) ShowFlower(); diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/Overworld.tscn b/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/Overworld.tscn index 0ff7fda4..21602823 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/Overworld.tscn +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/Special Floors/Overworld.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=237 format=4 uid="uid://dvnc26rebk6o0"] +[gd_scene load_steps=238 format=4 uid="uid://dvnc26rebk6o0"] [ext_resource type="Script" uid="uid://cuhfkyh3d7noa" path="res://src/map/dungeon/code/Overworld.cs" id="1_5hmt3"] [ext_resource type="Texture2D" uid="uid://co6h8vyi11sl2" path="res://src/map/overworld/Models/Overworld_CLOUD_RINGS_INNER_63.png" id="2_g6b7b"] @@ -41,6 +41,7 @@ [ext_resource type="AudioStream" uid="uid://b5vhghigr263m" path="res://src/audio/AMB/amb_ATMOSTPHERE.ogg" id="53_v60tm"] [ext_resource type="AudioStream" uid="uid://d3uj87dsngy22" path="res://src/audio/AMB/amb_water_lapping2.ogg" id="53_xqf5a"] [ext_resource type="PackedScene" uid="uid://dqjovmlt1y4tb" path="res://src/map/Placeables/Sarco.tscn" id="59_mic3u"] +[ext_resource type="Resource" uid="uid://8wf6jvs78ncf" path="res://stone.dialogue" id="60_1b363"] [ext_resource type="PackedScene" uid="uid://doncarj3f8iua" path="res://src/vfx/Torch.tscn" id="60_xqf5a"] [ext_resource type="PackedScene" uid="uid://b3owhc620qisb" path="res://src/map/Placeables/Stele A.tscn" id="61_v60tm"] [ext_resource type="PackedScene" uid="uid://cn13lho2so7sr" path="res://src/map/Placeables/Stele E.tscn" id="62_o5pdk"] @@ -2793,9 +2794,11 @@ transform = Transform3D(-0.267765, 0, 0.351913, 0, 0.4422, 0, -0.351913, 0, -0.2 [node name="Rat" parent="Actors" instance=ExtResource("75_322om")] transform = Transform3D(1, 0, 1.19209e-07, 0, 1, 0, -1.19209e-07, 0, 1, -36.8943, 3.78707, 44.3599) +ID = null [node name="Clalo" parent="Actors" instance=ExtResource("76_nfcfh")] transform = Transform3D(-1.15777, 0, -1.52161, 0, 1.912, 0, 1.52161, 0, -1.15777, -244.949, 1.16958, 117.235) +ID = null [node name="AnimatedSprite3D" parent="Actors/Clalo" index="0"] transform = Transform3D(1.11, 0, 0, 0, 1.11, 0, 0, 0, 1.11, 0, 0.179583, 0) @@ -2803,6 +2806,7 @@ frame_progress = 0.120696 [node name="Caretaker of Saints" parent="Actors" instance=ExtResource("80_8isf0")] transform = Transform3D(-1.42252, 0, -3.28851, 0, 3.583, 0, 3.28851, 0, -1.42252, -245.674, 3.22781, 272.252) +ID = null [node name="AnimatedSprite3D" parent="Actors/Caretaker of Saints" index="0"] texture_filter = 0 @@ -2818,21 +2822,29 @@ surface_material_override/0 = SubResource("StandardMaterial3D_gdgdy") [node name="SteleA" parent="Actors" instance=ExtResource("61_v60tm")] transform = Transform3D(-2.02763, 0, -1.00137, 0, 2.26142, 0, 1.00137, 0, -2.02763, -269.604, -2.12242, 368.855) +Dialogue = ExtResource("60_1b363") +ID = null [node name="SteleA2" parent="Actors" instance=ExtResource("61_v60tm")] transform = Transform3D(-1.0882, 0, 1.98238, 0, 2.26142, 0, -1.98238, 0, -1.0882, 109.541, -2.96568, -125.703) +ID = null -[node name="SteleB" parent="Actors" instance=ExtResource("32_xqf5a")] +[node name="Stele B Test" parent="Actors" instance=ExtResource("32_xqf5a")] transform = Transform3D(1.76809, 0, -1.40993, 0, 2.26142, 0, 1.40993, 0, 1.76809, -221.316, -2.14605, 87.2701) +Dialogue = ExtResource("60_1b363") +ID = null [node name="SteleA3" parent="Actors" instance=ExtResource("61_v60tm")] transform = Transform3D(-1.36936, 0, -1.79969, 0, 2.26142, 0, 1.79969, 0, -1.36936, -152.306, -2.54626, 264.978) +ID = null [node name="SteleE" parent="Actors" instance=ExtResource("62_o5pdk")] transform = Transform3D(0.868668, 0, -0.723823, 0, 1.13071, 0, 0.723823, 0, 0.868668, -301.766, -2.71211, 324.165) +ID = null [node name="SteleA4" parent="Actors" instance=ExtResource("61_v60tm")] transform = Transform3D(2.24285, 0, 0.289188, 0, 2.26142, 0, -0.289188, 0, 2.24285, -158.475, -2.35288, 110.031) +ID = null [node name="Lighting And Environment" type="Node3D" parent="."] transform = Transform3D(0.66, 0, 0, 0, 0.66, 0, 0, 0, 0.66, -293.644, -2.57557, 69.8565) diff --git a/Zennysoft.Game.Ma/src/npc/Npc.cs b/Zennysoft.Game.Ma/src/npc/Npc.cs index b4e84ae5..72c5ee7c 100644 --- a/Zennysoft.Game.Ma/src/npc/Npc.cs +++ b/Zennysoft.Game.Ma/src/npc/Npc.cs @@ -1,6 +1,7 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System.Threading.Tasks; namespace Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +9,8 @@ public partial class Npc : Node3D { public override void _Notification(int what) => this.Notify(what); + [Dependency] public IGame _game => this.DependOn(); + [Node] public Area3D DialogueZone { get; set; } = default!; [Node] public Area3D DialogueExitZone { get; set; } = default!; @@ -20,6 +23,8 @@ public partial class Npc : Node3D private bool _isInDialogueZone = false; private bool _isIntroductionComplete = false; + public int ID { get; private set; } = 0; + public void OnReady() { SetPhysicsProcess(true); @@ -27,6 +32,7 @@ public partial class Npc : Node3D DialogueZone.BodyExited += DialogueZone_BodyExited; DialogueExitZone.BodyExited += DialogueExitZone_BodyExited; Hitbox.AreaEntered += Hitbox_AreaEntered; + ID = GetHashCode(); } private void Hitbox_AreaEntered(Area3D area) @@ -57,10 +63,19 @@ public partial class Npc : Node3D { if (Dialogue != null && @event.IsActionPressed(GameInputs.Interact) && _isInDialogueZone) { - DialogueController.ShowDialogue(Dialogue, "general"); + DialogueController.ShowDialogue(Dialogue, "general", [this]); } } + public async Task EndDialogue() + { + if (!_game.NpcData.SteleDiscovered.Contains(ID)) + { + _game.NpcData.SteleDiscovered.Add(ID); + await _game.Save(); + } + } + public void OnExitTree() { DialogueZone.BodyEntered -= DialogueZone_BodyEntered; @@ -68,4 +83,6 @@ public partial class Npc : Node3D DialogueExitZone.BodyExited -= DialogueExitZone_BodyExited; Hitbox.AreaEntered -= Hitbox_AreaEntered; } + + public override int GetHashCode() => GetPath().GetHashCode(); } diff --git a/Zennysoft.Game.Ma/stone.dialogue b/Zennysoft.Game.Ma/stone.dialogue index d8a90c43..83e664a3 100644 --- a/Zennysoft.Game.Ma/stone.dialogue +++ b/Zennysoft.Game.Ma/stone.dialogue @@ -1,2 +1,4 @@ ~ general +ID is {{ID}} +do EndDialogue() => END \ No newline at end of file