player progress

This commit is contained in:
Rendo 2025-07-21 02:13:02 +05:00
commit 27d839b86f
27 changed files with 236 additions and 68 deletions

17
scripts/PlayerProgress.cs Normal file
View file

@ -0,0 +1,17 @@
using System.Collections.Generic;
using Godot;
using Newlon;
public partial class PlayerProgress : Node
{
public static PlayerProgress Instance { get; private set; }
public override void _EnterTree()
{
Instance = this;
}
public List<PlantResource> PlayerPlants { get; set; } = new();
public int MaxSeedpackets = 9;
public int Money { get; set; }
}

View file

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

99
scripts/SaveSerializer.cs Normal file
View file

@ -0,0 +1,99 @@
using Godot;
using Godot.Collections;
using Newlon;
using System.Text.Json;
using System.Collections.Generic;
public partial class SaveSerializer : Node
{
const string SAVE_PATH = "user://save.json";
public override void _Ready()
{
GetTree().AutoAcceptQuit = false;
LoadGame();
}
public override void _Notification(int what)
{
if (what == NotificationWMCloseRequest)
{
SaveGame();
GetTree().Quit();
}
}
public static void SaveGame()
{
var access = FileAccess.Open(SAVE_PATH, FileAccess.ModeFlags.Write);
var playerProgress = PlayerProgress.Instance;
var save = new SaveData
{
SFXVolume = (float)Settings.SFX,
MusicVolume = (float)Settings.Music,
SplashSeen = Settings.Splash,
Money = playerProgress.Money,
SeedpacketSlots = playerProgress.MaxSeedpackets,
PlayerPlants = [],
SaveGameVersion = (string)ProjectSettings.GetSetting("application/config/version")
};
foreach (var plant in playerProgress.PlayerPlants)
{
save.PlayerPlants.Add(plant.internal_id);
}
access.StoreString(JsonSerializer.Serialize<SaveData>(save));
access.Close();
}
public static void LoadGame()
{
if (FileAccess.FileExists(SAVE_PATH) == false)
{
InitiateCleanSave();
return;
}
var access = FileAccess.Open(SAVE_PATH, FileAccess.ModeFlags.Read);
var parsed = JsonSerializer.Deserialize<SaveData>(access.GetAsText());
Settings.SFX = parsed.SFXVolume;
Settings.Music = parsed.MusicVolume;
Settings.Splash = parsed.SplashSeen;
AudioServer.SetBusVolumeDb(1, Mathf.LinearToDb((float)Settings.SFX));
AudioServer.SetBusVolumeDb(2, Mathf.LinearToDb((float)Settings.Music));
var playerProgress = PlayerProgress.Instance;
playerProgress.MaxSeedpackets = parsed.SeedpacketSlots;
playerProgress.PlayerPlants = [];
foreach (var plantId in parsed.PlayerPlants)
{
playerProgress.PlayerPlants.Add(GameRegistry.GetPlantByName(plantId));
}
access.Close();
}
private static void InitiateCleanSave()
{
PlayerProgress.Instance.PlayerPlants = new List<PlantResource>([GameRegistry.GetPlantByName("peashooter")]);
PlayerProgress.Instance.Money = 0;
SaveGame();
}
private partial class SaveData
{
public float SFXVolume { get; set; }
public float MusicVolume { get; set; }
public string SaveGameVersion { get; set; }
public bool SplashSeen { get; set; }
public List<string> PlayerPlants { get; set; }
public int Money { get; set; } = 0;
public int SeedpacketSlots { get; set; } = 6;
public List<string> FinishedLevels { get; set; } = new();
}
}

View file

@ -1,41 +0,0 @@
using Godot;
public partial class SettingsSerializer : Node
{
const string CFG_PATH = "user://config.cfg";
public override void _EnterTree()
{
GetTree().AutoAcceptQuit = false;
if (FileAccess.FileExists(CFG_PATH) == false) return;
var access = FileAccess.Open(CFG_PATH, FileAccess.ModeFlags.Read);
Settings.SFX = float.Parse(access.GetLine().Split(" ")[1]);
Settings.Music = float.Parse(access.GetLine().Split(" ")[1]);
Settings.Splash = bool.Parse(access.GetLine().Split(" ")[1]);
AudioServer.SetBusVolumeDb(0, Mathf.LinearToDb((float)Settings.SFX));
AudioServer.SetBusVolumeDb(1, Mathf.LinearToDb((float)Settings.Music));
access.Close();
}
public override void _ExitTree()
{
var access = FileAccess.Open(CFG_PATH, FileAccess.ModeFlags.Write);
access.Resize(0);
access.StoreString(string.Format("SFX {0}\nMusic {1}\nSplash {2}\n", Settings.SFX,Settings.Music,Settings.Splash));
access.Close();
}
public override void _Notification(int what)
{
if (what == NotificationWMCloseRequest)
{
_ExitTree();
GetTree().Quit();
}
}
}

View file

@ -2,7 +2,7 @@ using Godot;
[GlobalClass]
public abstract partial class DroppableItem : Area2D
public partial class DroppableItem : Area2D
{
[Signal] public delegate void PickedUpEventHandler();
public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx)
@ -10,8 +10,9 @@ public abstract partial class DroppableItem : Area2D
if (@event.IsActionPressed("primary_action"))
{
PickUp();
EmitSignal(SignalName.PickedUp);
}
}
public abstract void PickUp();
public virtual void PickUp() {}
}

View file

@ -17,9 +17,4 @@ public partial class DroppableSeedpacket : DroppableItem
_cost.LabelSettings = plant.customFrame.font;
}
}
public override void PickUp()
{
EmitSignal(SignalName.PickedUp);
}
}

View file

@ -28,7 +28,7 @@ public partial class AlmanachGrid : GridContainer
}
else
{
var list = GameRegistry.GetPlants();
var list = PlayerProgress.Instance.PlayerPlants;
list.Sort((a, b) =>
{
return a.Order - b.Order;

View file

@ -11,7 +11,7 @@ public partial class GridLoader : GridContainer
{
_plantCard = ResourceLoader.Load<PackedScene>(SEEDPACKED_UID);
var list = GameRegistry.GetPlants();
var list = PlayerProgress.Instance.PlayerPlants;
list.Sort((a, b) =>
{
return a.Order - b.Order;

View file

@ -8,7 +8,7 @@ public class ChoosableHandler : SeedpacketHandler, ISeedpacketPress
public void Pressed()
{
if (LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() >= PlayerInfo.MaxSeedpackets) return;
if (LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() >= PlayerProgress.Instance.MaxSeedpackets) return;
_owner.disablePacket = true;
var hotbarSeedpacket = Seedpacket.Prefab.Instantiate<Seedpacket>();

View file

@ -58,7 +58,6 @@ public partial class LevelController : Node
RuntimeLevelData.LevelResource = null;
_isLevelRunning = false;
if (Reward != null)
{
GetTree().ChangeSceneToFile(REWARD_SCENE_UID);

View file

@ -127,13 +127,24 @@ public partial class LevelRunner : Node
RuntimeLevelData.Instance.SetLevelState(RuntimeLevelData.LevelStates.Win);
var reward = resource.reward.Scene.Instantiate<DroppableItem>();
DroppableItem reward;
if (resource.reward.Redeem())
{
reward = resource.reward.Scene.Instantiate<DroppableItem>();
LevelController.Instance.SetReward(resource.reward);
}
else
{
defaultReward.Redeem();
reward = defaultReward.Scene.Instantiate<DroppableItem>();
LevelController.Instance.SetReward(defaultReward);
}
if (reward is DroppableSeedpacket seedpacket && resource.reward is PlantReward plantReward)
{
seedpacket.plant = plantReward.Plant;
}
LevelController.Instance.SetReward(resource.reward);
player.Play("win");
Callable.From(() =>
{
rewardParent.AddChild(reward);
@ -145,6 +156,8 @@ public partial class LevelRunner : Node
}).CallDeferred();
reward.PickedUp += () =>
{
player.Play("win");
var tween = CreateTween();
var camera = GetViewport().GetCamera2D();
tween.TweenProperty(reward, "global_position", camera.GlobalPosition, 4.0);

View file

@ -9,5 +9,10 @@ public partial class MoneyReward : RewardResource
{
return Scene;
}
public override bool Redeem()
{
PlayerProgress.Instance.Money += Cost;
return true;
}
}

View file

@ -11,5 +11,18 @@ public partial class PlantReward : RewardResource
{
return Plant.Scene;
}
public override bool Redeem()
{
if (PlayerProgress.Instance.PlayerPlants.Contains(Plant) == false)
{
PlayerProgress.Instance.PlayerPlants.Add(Plant);
return true;
}
else
{
return false;
}
}
}

View file

@ -9,4 +9,5 @@ public abstract partial class RewardResource : Resource
[Export] public string Name { get; private set; }
[Export] public string Description { get; private set; }
public abstract PackedScene GetPreview();
public abstract bool Redeem();
}

View file

@ -10,7 +10,7 @@ public partial class GameRegistry : Node
public static readonly Dictionary<string, PlantResource> PlantDictionary = [];
public static readonly Dictionary<string, ZombieResource> ZombieDictionary = [];
public override void _Ready()
public override void _EnterTree()
{
//Plant init
string[] plantFiles = ResourceLoader.ListDirectory(PLANT_RESOURCE_PATH);

View file

@ -1,7 +0,0 @@
using Godot;
using System;
public partial class PlayerInfo : Node
{
public static int MaxSeedpackets = 9;
}

View file

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