Pickups + Save-diff

This commit is contained in:
anonoe 2026-02-10 15:18:49 +01:00
parent b49c0ee55f
commit bf874ba633
Signed by: anonoe
SSH key fingerprint: SHA256:OnAs6gNQelOnDiY5tBpDYKQiuTgBvnmIdMo5P09cdqg
11 changed files with 133 additions and 16 deletions

View file

@ -3,6 +3,8 @@
[ext_resource type="PackedScene" uid="uid://bjt15rm720w5g" path="res://scenes/Player.tscn" id="1_elqb8"] [ext_resource type="PackedScene" uid="uid://bjt15rm720w5g" path="res://scenes/Player.tscn" id="1_elqb8"]
[ext_resource type="Script" uid="uid://cqdq8fslu7cyp" path="res://scripts/world/ChunkManager.cs" id="2_0bbpv"] [ext_resource type="Script" uid="uid://cqdq8fslu7cyp" path="res://scripts/world/ChunkManager.cs" id="2_0bbpv"]
[ext_resource type="Script" uid="uid://db2vbbh5737ke" path="res://scripts/core/PackManager.cs" id="3_rarhs"] [ext_resource type="Script" uid="uid://db2vbbh5737ke" path="res://scripts/core/PackManager.cs" id="3_rarhs"]
[ext_resource type="PackedScene" uid="uid://bs7qu34sfgvjx" path="res://scenes/world/PickupMarker.tscn" id="3_vcsgt"]
[ext_resource type="Script" uid="uid://osk74jjhtcjy" path="res://scripts/core/SaveManager.cs" id="4_rarhs"]
[node name="Main" type="Node2D" unique_id=1194367579] [node name="Main" type="Node2D" unique_id=1194367579]
@ -14,10 +16,11 @@
script = ExtResource("2_0bbpv") script = ExtResource("2_0bbpv")
PlayerPath = NodePath("../Player") PlayerPath = NodePath("../Player")
PackManagerPath = NodePath("../../PackManager") PackManagerPath = NodePath("../../PackManager")
PickupMarkerScene = ExtResource("3_vcsgt")
[node name="ColorRect" type="ColorRect" parent="." unique_id=34197065] SaveManagerPath = NodePath("../../SaveManager")
offset_right = 40.0
offset_bottom = 40.0
[node name="PackManager" type="Node" parent="." unique_id=1706387276] [node name="PackManager" type="Node" parent="." unique_id=1706387276]
script = ExtResource("3_rarhs") script = ExtResource("3_rarhs")
[node name="SaveManager" type="Node" parent="." unique_id=1115563669]
script = ExtResource("4_rarhs")

View file

@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://bs7qu34sfgvjx"]
[ext_resource type="Script" uid="uid://u5olxge8tsb4" path="res://scripts/world/PickupVisual.cs" id="1_a75xq"]
[ext_resource type="Script" uid="uid://di8apqyxtfmfp" path="res://scripts/world/PickupMarker.cs" id="1_b3nhw"]
[sub_resource type="CircleShape2D" id="CircleShape2D_b3nhw"]
[node name="PickupMarker" type="Area2D" unique_id=1599778276]
script = ExtResource("1_b3nhw")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1670396427]
shape = SubResource("CircleShape2D_b3nhw")
[node name="Visual" type="Node2D" parent="." unique_id=886979632]
script = ExtResource("1_a75xq")

View file

@ -0,0 +1,36 @@
using Godot;
using System.Text.Json;
public partial class SaveManager : Node
{
public SaveState State { get; private set; } = new();
private const string SavePath = "user://save.json";
public override void _Ready()
{
Load();
}
public void Load()
{
if (!FileAccess.FileExists(SavePath))
{
GD.Print("No save found, starting fresh.");
State = new SaveState();
return;
}
var json = FileAccess.GetFileAsString(SavePath);
State = JsonSerializer.Deserialize<SaveState>(json) ?? new SaveState();
GD.Print($"Loaded save. CollectedPickups={State.CollectedPickups.Count}");
}
public void Save()
{
var json = JsonSerializer.Serialize(State, new JsonSerializerOptions { WriteIndented = true });
using var f = FileAccess.Open(SavePath, FileAccess.ModeFlags.Write);
f.StoreString(json);
GD.Print("Saved.");
}
}

View file

@ -0,0 +1 @@
uid://osk74jjhtcjy

View file

@ -0,0 +1,9 @@
using System.Collections.Generic;
//using Godot;
public class SaveState
{
public HashSet<string> CollectedPickups { get; set; } = new();
//public Vector2I? LastPlayerChunk { get; set; } // optional debug, requires "using Godot;"
//public int[]? LastPlayerChunk { get; set; } // [x,y] same debug as above, does not require Godot
}

View file

@ -0,0 +1 @@
uid://dd83uxjqtlmra

View file

@ -8,10 +8,11 @@ public partial class ChunkManager : Node2D
[Export] public NodePath PlayerPath { get; set; } [Export] public NodePath PlayerPath { get; set; }
[Export] public NodePath PackManagerPath { get; set; } [Export] public NodePath PackManagerPath { get; set; }
[Export] public int LoadRadius { get; set; } = 1; // 1 => 3x3 [Export] public int LoadRadius { get; set; } = 1; // 1 => 3x3
[Export] public PackedScene PickupMarkerScene { get; set; }
[Export] public NodePath SaveManagerPath { get; set; }
private SaveManager? _save;
private CharacterBody2D? _player; private CharacterBody2D? _player;
private PackManager? _packs; private PackManager? _packs;
private WorldIndex? _world; private WorldIndex? _world;
private Dictionary<(int x, int y), string> _chunkMap = new(); private Dictionary<(int x, int y), string> _chunkMap = new();
private readonly Dictionary<(int x, int y), Node2D> _loaded = new(); private readonly Dictionary<(int x, int y), Node2D> _loaded = new();
@ -32,6 +33,9 @@ public partial class ChunkManager : Node2D
return; return;
} }
_save = GetNodeOrNull<SaveManager>(SaveManagerPath);
if (_save == null) GD.PrintErr("ChunkManager: SaveManagerPath not set or invalid.");
LoadWorldIndex(); LoadWorldIndex();
} }
@ -154,21 +158,33 @@ public partial class ChunkManager : Node2D
return n; return n;
} }
private static void AddChunkMarkers(Node2D chunkNode, ChunkData data) private void AddChunkMarkers(Node2D chunkNode, ChunkData data)
{ {
// Pickups: small green squares if (_save == null || PickupMarkerScene == null) return;
if (data.pickups != null)
if (data.pickups != null && _save != null)
{ {
foreach (var p in data.pickups) foreach (var p in data.pickups)
{ {
var r = new ColorRect if (_save.State.CollectedPickups.Contains(p.id))
continue; // already collected
var marker = (PickupMarker)PickupMarkerScene.Instantiate();
marker.Position = new Vector2(p.pos[0], p.pos[1]);
marker.PickupId = p.id;
marker.ItemId = p.item;
marker.PickedUp += (pickupId, itemId) =>
{ {
Size = new Vector2(10, 10), GD.Print($"Picked up {itemId} ({pickupId})");
Color = new Color(0.2f, 1.0f, 0.2f, 0.9f),
MouseFilter = Control.MouseFilterEnum.Ignore, _save.State.CollectedPickups.Add(pickupId);
Position = new Vector2(p.pos[0] - 5, p.pos[1] - 5) _save.Save();
marker.QueueFree();
}; };
chunkNode.AddChild(r);
chunkNode.AddChild(marker);
} }
} }

View file

@ -0,0 +1,23 @@
using Godot;
public partial class PickupMarker : Area2D
{
public string PickupId { get; set; } = "";
public string ItemId { get; set; } = "";
public override void _Ready()
{
BodyEntered += OnBodyEntered;
}
private void OnBodyEntered(Node2D body)
{
if (body is not CharacterBody2D) return;
// Defer to avoid freeing during signal processing edge cases
EmitSignal(SignalName.PickedUp, PickupId, ItemId);
}
[Signal]
public delegate void PickedUpEventHandler(string pickupId, string itemId);
}

View file

@ -0,0 +1 @@
uid://di8apqyxtfmfp

View file

@ -0,0 +1,11 @@
using Godot;
public partial class PickupVisual : Node2D
{
public override void _Draw()
{
DrawRect(new Rect2(-5, -5, 10, 10), new Color(0.2f, 1f, 0.2f, 0.9f));
}
public override void _Ready() => QueueRedraw();
}

View file

@ -0,0 +1 @@
uid://u5olxge8tsb4