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

View file

@ -0,0 +1,12 @@
[gd_resource type="Resource" script_class="MoneyReward" load_steps=3 format=3 uid="uid://kqqqjubwm37a"]
[ext_resource type="PackedScene" uid="uid://3x821ng2yf57" path="res://scenes/templates/money_reward.tscn" id="1_g5bk7"]
[ext_resource type="Script" uid="uid://dtfmy3los1si1" path="res://scripts/resources/MoneyReward.cs" id="1_qd0ii"]
[resource]
script = ExtResource("1_qd0ii")
Cost = 500
Scene = ExtResource("1_g5bk7")
Name = "moneybag"
Description = "rwd_moneybag"
metadata/_custom_type_script = "uid://dtfmy3los1si1"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

View file

@ -0,0 +1,7 @@
[gd_resource type="AtlasTexture" load_steps=2 format=3 uid="uid://c3qw52yoseb1k"]
[ext_resource type="Texture2D" uid="uid://dvldjlg0nr355" path="res://assets/sprites/atlases/atlas1.png" id="1_rucxc"]
[resource]
atlas = ExtResource("1_rucxc")
region = Rect2(504, 16, 46, 49)

BIN
assets/sprites/pon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://br5wk508s7joi"
path="res://.godot/imported/pon.png-3e7efb58dffb516a84244a831349a644.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites/pon.png"
dest_files=["res://.godot/imported/pon.png-3e7efb58dffb516a84244a831349a644.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View file

@ -29,7 +29,8 @@ Cursor="*res://scripts/Cursor.cs"
GameRegistry="*res://scripts/systems/GameRegistry.cs"
Cheats="res://scripts/debug/Cheats.cs"
AudioSequencer="*res://scenes/audio_sequencer.tscn"
SettingsSerializer="*res://scripts/SettingsSerializer.cs"
SaveSerializer="*res://scripts/SaveSerializer.cs"
PlayerProgress="*res://scripts/PlayerProgress.cs"
[display]

View file

@ -20,7 +20,7 @@ tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 1)]
"values": [Color(1, 1, 0.921569, 1)]
}
[sub_resource type="Animation" id="Animation_mbhdb"]
@ -136,6 +136,7 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(1, 1, 0.921569, 1)
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=42 format=3 uid="uid://dd3yegl1xo44m"]
[gd_scene load_steps=43 format=3 uid="uid://dd3yegl1xo44m"]
[ext_resource type="Script" uid="uid://bndu1h5kgcde8" path="res://scripts/level/RuntimeLevelData.cs" id="1_31ltw"]
[ext_resource type="Script" uid="uid://bso32xkw738sy" path="res://scripts/level/PoolContainer.cs" id="2_s5sti"]
@ -24,6 +24,7 @@
[ext_resource type="Script" uid="uid://1lkhoh43h86m" path="res://scripts/level/GameTimer.cs" id="19_s7icd"]
[ext_resource type="Script" uid="uid://84gvlkflxdhk" path="res://scripts/level/zombe_spawners/RowSpawner.cs" id="22_8qqc4"]
[ext_resource type="Script" uid="uid://puqxp2xeg1r2" path="res://scripts/level/LevelRunner.cs" id="23_8vb7v"]
[ext_resource type="Resource" uid="uid://kqqqjubwm37a" path="res://assets/rewards/DefaultReward.tres" id="24_7v6ps"]
[ext_resource type="Script" uid="uid://bc3s06ejbotma" path="res://scripts/gui/ZombieLevelPreviewer.cs" id="24_y5tw7"]
[ext_resource type="Script" uid="uid://b31mnk4enldc4" path="res://scripts/level/InitialPackedSceneSpawner.cs" id="26_i7rp7"]
@ -425,7 +426,7 @@ tracks/0/path = NodePath("WinFade:color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 4, 5),
"times": PackedFloat32Array(0, 3, 5),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 0.92, 0), Color(1, 1, 0.92, 0), Color(1, 1, 0.92, 1)]
@ -704,6 +705,7 @@ wait_time = 2.5
[node name="LevelRunner" type="Node" parent="." node_paths=PackedStringArray("rowSpawner", "waveTimer", "player", "rewardParent")]
script = ExtResource("23_8vb7v")
defaultReward = ExtResource("24_7v6ps")
rowSpawner = NodePath("../RowSpawner")
waveTimer = NodePath("WaveTimer")
approachNotificationTime = 5.0

View file

@ -0,0 +1,16 @@
[gd_scene load_steps=4 format=3 uid="uid://3x821ng2yf57"]
[ext_resource type="Script" uid="uid://cwf2y3pxi6psc" path="res://scripts/droppable-items/DroppableItem.cs" id="1_jgexe"]
[ext_resource type="Texture2D" uid="uid://c3qw52yoseb1k" path="res://assets/sprites/money_bag.tres" id="1_wewwq"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_wewwq"]
size = Vector2(46, 50)
[node name="MoneyReward" type="Area2D"]
script = ExtResource("1_jgexe")
[node name="MoneyBag" type="Sprite2D" parent="."]
texture = ExtResource("1_wewwq")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_wewwq")

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