Move files and folders to new repo format to enable multi-project format

This commit is contained in:
2025-03-06 22:07:25 -08:00
parent 12cbb82ac9
commit a09f6ec5a5
3973 changed files with 1781 additions and 2938 deletions

View File

@@ -0,0 +1,27 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class BossFloor : Node3D, IDungeonFloor
{
public override void _Notification(int what) => this.Notify(what);
private BossRoomA BossRoom;
public ImmutableList<IDungeonRoom> Rooms => [];
public void InitializeDungeon()
{
var bossRoomScene = GD.Load<PackedScene>($"res://src/map/dungeon/scenes/BossRoom.tscn");
BossRoom = bossRoomScene.Instantiate<BossRoomA>();
FloorIsLoaded = true;
}
public bool FloorIsLoaded { get; set; }
public Transform3D GetPlayerSpawnPoint() => BossRoom.PlayerSpawn.GlobalTransform;
}

View File

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

View File

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

View File

@@ -0,0 +1,53 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class BossRoomA : Node3D, IBossRoom
{
public override void _Notification(int what) => this.Notify(what);
[Node] public Marker3D PlayerSpawn { get; set; } = default!;
[Node] public Node3D HorseHeadStatue { get; set; } = default!;
[Node] public Node3D OxFaceStatue { get; set; } = default!;
[Node] public Boss OxFace { get; set; } = default!;
[Node] public Boss HorseFace { get; set; } = default!;
[Node] public Area3D ActivateTrap { get; set; } = default!;
[Node] public Node3D GateCollision { get; set; } = default!;
public void Setup()
{
ActivateTrap.BodyEntered += ActivateTrap_BodyEntered;
OxFace.IsDefeated.Sync += BossStatusUpdate;
HorseFace.IsDefeated.Sync += BossStatusUpdate;
}
private void ActivateTrap_BodyEntered(Node3D body) => StartBossFight();
public void StartBossFight()
{
OxFaceStatue.Hide();
HorseHeadStatue.Hide();
OxFace.Activate();
HorseFace.Activate();
}
public void OnBossFightEnded()
{
GateCollision.CallDeferred(MethodName.QueueFree);
}
private void BossStatusUpdate(bool obj)
{
if (OxFace.IsDefeated.Value && HorseFace.IsDefeated.Value)
OnBossFightEnded();
}
}

View File

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

View File

@@ -0,0 +1,31 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class CorridorRoom : Node3D
{
public override void _Notification(int what) => this.Notify(what);
[Dependency] IGame Game => this.DependOn<IGame>();
[Node] private Area3D _room { get; set; } = default!;
[Node] private MeshInstance3D _minimap { get; set; } = default!;
private bool _playerDiscoveredRoom = false;
public void Setup()
{
_room.BodyEntered += Room_BodyEntered;
}
private void Room_BodyEntered(Node3D body)
{
if (!Game.CurrentFloor.FloorIsLoaded)
return;
if (body is IPlayer)
_minimap.Show();
}
}

View File

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

View File

@@ -0,0 +1,64 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class DungeonFloor : Node3D, IDungeonFloor
{
public override void _Notification(int what) => this.Notify(what);
[Node] public GodotObject DungeonGenerator { get; set; } = default!;
[Node] public EnemyDatabase EnemyDatabase { get; set; } = default!;
private Transform3D _playerSpawnPoint;
public ImmutableList<IDungeonRoom> Rooms { get; private set; }
public bool FloorIsLoaded { get; set; }
public void InitializeDungeon()
{
Rooms = [];
Rooms = FindAllDungeonRooms([.. GetChildren()], Rooms);
_playerSpawnPoint = RandomizePlayerSpawnPoint();
var monsterRooms = Rooms.OfType<MonsterRoom>();
foreach (var room in monsterRooms)
room.SpawnEnemies(EnemyDatabase);
DungeonGenerator.EmitSignal("done_generating");
}
public Transform3D GetPlayerSpawnPoint() => new Transform3D(_playerSpawnPoint.Basis, new Vector3(_playerSpawnPoint.Origin.X, -1.75f, _playerSpawnPoint.Origin.Z));
private Transform3D RandomizePlayerSpawnPoint()
{
var randomSpawnLocations = Rooms
.OfType<MonsterRoom>()
.Select(x => x.PlayerSpawn);
var godotCollection = new Godot.Collections.Array<Marker3D>(randomSpawnLocations);
var result = godotCollection.PickRandom();
return result.GlobalTransform;
}
private static ImmutableList<IDungeonRoom> FindAllDungeonRooms(List<Node> nodesToSearch, ImmutableList<IDungeonRoom> roomsFound)
{
if (nodesToSearch.Count == 0)
return roomsFound;
foreach (var node in nodesToSearch)
{
if (node is IDungeonRoom dungeonRoom)
roomsFound = roomsFound.Add(dungeonRoom);
if (node.HasSignal("dungeon_done_generating"))
node.EmitSignal("dungeon_done_generating");
}
return FindAllDungeonRooms(nodesToSearch.SelectMany(x => x.GetChildren()).ToList(), roomsFound);
}
}

View File

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

View File

@@ -0,0 +1,65 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public abstract partial class DungeonRoom : Node3D, IDungeonRoom
{
public override void _Notification(int what) => this.Notify(what);
[Node] public Marker3D PlayerSpawn { get; set; } = default!;
[Node] private MeshInstance3D _minimap { get; set; } = default!;
public bool IsPlayerInRoom => _isPlayerInRoom;
public bool PlayerDiscoveredRoom => _playerDiscoveredRoom;
public ImmutableList<IEnemy> EnemiesInRoom => _enemiesInRoom;
[Node] private Area3D _room { get; set; } = default!;
private ImmutableList<IEnemy> _enemiesInRoom;
private bool _isPlayerInRoom = false;
private bool _playerDiscoveredRoom = false;
public void Setup()
{
_enemiesInRoom = [];
_room.BodyEntered += Room_BodyEntered;
_room.BodyExited += Room_BodyExited;
}
private void Room_BodyExited(Node3D body)
{
if (body is IEnemy enemy)
_enemiesInRoom = _enemiesInRoom.Remove(enemy);
if (body is IPlayer)
_isPlayerInRoom = false;
}
private void Room_BodyEntered(Node3D body)
{
if (body is IEnemy enemy)
_enemiesInRoom = _enemiesInRoom.Add(enemy);
if (body is IPlayer)
if (_playerDiscoveredRoom)
_isPlayerInRoom = true;
else
OnPlayerDiscoveringRoom();
}
public ImmutableList<IEnemy> GetEnemiesInCurrentRoom()
{
return _enemiesInRoom;
}
private void OnPlayerDiscoveringRoom()
{
_isPlayerInRoom = true;
_playerDiscoveredRoom = true;
_minimap.Show();
}
}

View File

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

View File

@@ -0,0 +1,6 @@
@startuml DungeonRoomLogic
state "DungeonRoomLogic State" as GameJamDungeon_DungeonRoomLogic_State {
state "Idle" as GameJamDungeon_DungeonRoomLogic_State_Idle
}
[*] --> GameJamDungeon_DungeonRoomLogic_State_Idle
@enduml

View File

@@ -0,0 +1,26 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class ExitRoom : DungeonRoom
{
public override void _Notification(int what) => this.Notify(what);
[Dependency] public IGame Game => this.DependOn<IGame>();
[Node] private Area3D _exit { get; set; } = default!;
[Node] private Area3D _room { get; set; } = default!;
public override void _Ready()
{
_exit.AreaEntered += Exit_AreaEntered;
}
public void ExitReached()
=> Game.FloorExitReached();
private void Exit_AreaEntered(Area3D area) => ExitReached();
}

View File

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

View File

@@ -0,0 +1,35 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class Floor0 : Node3D, IDungeonFloor
{
public override void _Notification(int what) => this.Notify(what);
[Dependency] protected IGame Game => this.DependOn<IGame>();
[Node] private Area3D Exit { get; set; } = default!;
[Node] private Marker3D PlayerSpawnPoint { get; set; } = default!;
public ImmutableList<IDungeonRoom> Rooms => [];
public bool FloorIsLoaded { get; set; }
public override void _Ready()
{
Show();
Exit.AreaEntered += Exit_AreaEntered;
FloorIsLoaded = true;
}
private void Exit_AreaEntered(Area3D area) => ExitReached();
public void ExitReached() => Game.FloorExitReached();
public void InitializeDungeon() { return; }
public Transform3D GetPlayerSpawnPoint() { return new Transform3D(PlayerSpawnPoint.Basis, new Vector3(PlayerSpawnPoint.GlobalPosition.X, -3, PlayerSpawnPoint.GlobalPosition.Z)); }
}

View File

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

View File

@@ -0,0 +1,13 @@
using Chickensoft.GodotNodeInterfaces;
using Godot;
namespace Zennysoft.Game.Ma;
public interface IBossRoom : INode3D
{
public void StartBossFight();
public void OnBossFightEnded();
public Marker3D PlayerSpawn { get; }
}

View File

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

View File

@@ -0,0 +1,15 @@
using Chickensoft.GodotNodeInterfaces;
using Godot;
using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
public interface IDungeonFloor : INode3D
{
void InitializeDungeon();
public Transform3D GetPlayerSpawnPoint();
public ImmutableList<IDungeonRoom> Rooms { get; }
public bool FloorIsLoaded { get; set; }
}

View File

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

View File

@@ -0,0 +1,15 @@
using Chickensoft.GodotNodeInterfaces;
using Godot;
using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
public interface IDungeonRoom : INode3D
{
Marker3D PlayerSpawn { get; }
bool IsPlayerInRoom { get; }
bool PlayerDiscoveredRoom { get; }
ImmutableList<IEnemy> EnemiesInRoom { get; }
}

View File

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

View File

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

View File

@@ -0,0 +1,16 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class MinimapManager : Area3D
{
public override void _Notification(int what) => this.Notify(what);
[Node] public MeshInstance3D Minimap { get; set; } = default!;
public void OnResolved() => BodyEntered += MinimapManager_BodyEntered;
private void MinimapManager_BodyEntered(Node3D area) => Minimap.Show();
}

View File

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

View File

@@ -0,0 +1,65 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Linq;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class MonsterRoom : DungeonRoom
{
public override void _Notification(int what) => this.Notify(what);
[Node] public Node3D ItemSpawnPoints { get; set; } = default!;
[Node] public Node3D EnemySpawnPoints { get; set; } = default!;
[Node] public ItemDatabase ItemDatabase { get; set; } = default!;
public override void _Ready()
{
SpawnItems();
}
public void SpawnEnemies(EnemyDatabase enemyDatabase)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
var enemySpawnPoints = EnemySpawnPoints.GetChildren();
var numberOfEnemiesToSpawn = rng.RandiRange(1, enemySpawnPoints.Count);
foreach (var spawnPoint in enemySpawnPoints.Cast<Marker3D>())
{
if (numberOfEnemiesToSpawn <= 0)
break;
numberOfEnemiesToSpawn--;
var enemy = enemyDatabase.EnemyList[rng.RandWeighted(enemyDatabase.SpawnRate)];
var instantiatedEnemy = enemy.Instantiate<Enemy>();
instantiatedEnemy.Position = new Vector3(spawnPoint.Position.X, -0.5f, spawnPoint.Position.Z);
AddChild(instantiatedEnemy);
}
}
private void SpawnItems()
{
var itemSpawnPoints = ItemSpawnPoints.GetChildren();
var rng = new RandomNumberGenerator();
rng.Randomize();
var numberOfItemsToSpawn = rng.RandiRange(1, itemSpawnPoints.Count);
itemSpawnPoints.Shuffle();
var database = ItemDatabase.Initialize();
foreach (var spawnPoint in itemSpawnPoints.Cast<Marker3D>())
{
if (numberOfItemsToSpawn <= 0)
break;
numberOfItemsToSpawn--;
var weights = database.Select(x => x.SpawnRate).ToArray();
var selectedItem = database[rng.RandWeighted(weights)];
var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D;
duplicated.Position = new Vector3(spawnPoint.Position.X, -1.5f, spawnPoint.Position.Z);
AddChild(duplicated);
}
}
}

View File

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

View File

@@ -0,0 +1,35 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class Overworld : Node3D, IDungeonFloor
{
public override void _Notification(int what) => this.Notify(what);
[Node] public Marker3D PlayerSpawnPoint { get; set; } = default!;
[Node] public Marker3D ExitSpawnPoint { get; set; } = default!;
public ImmutableList<IDungeonRoom> Rooms => [];
public bool FloorIsLoaded { get; set; }
public void InitializeDungeon()
{
Show();
FloorIsLoaded = true;
}
public Transform3D GetPlayerSpawnPoint()
{
return PlayerSpawnPoint.GlobalTransform;
}
public Vector3 GetTeleportSpawnPoint()
{
return ExitSpawnPoint.GlobalPosition;
}
}

View File

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

View File

@@ -0,0 +1,17 @@
@tool
extends DungeonRoom3D
# Called when the node enters the scene tree for the first time.
func _ready():
super._ready()
dungeon_done_generating.connect(remove_unused_doors_and_walls)
func remove_unused_doors_and_walls():
if get_door_by_node($"Doors/DOOR?_F_CUT").get_room_leads_to() != null:
$"Doors/DOOR?_F_CUT".queue_free()
if get_door_by_node($"Doors/DOOR?_R_CUT").get_room_leads_to() != null:
$"Doors/DOOR?_R_CUT".queue_free()
if get_door_by_node($"Doors/DOOR?_B_CUT").get_room_leads_to() != null:
$"Doors/DOOR?_B_CUT".queue_free()
if get_door_by_node($"Doors/DOOR?_L_CUT").get_room_leads_to() != null:
$"Doors/DOOR?_L_CUT".queue_free()

View File

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

View File

@@ -0,0 +1,11 @@
extends Node
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
$"../..".connect("dungeon_done_generating", remove_unused_doors)
func remove_unused_doors():
for door in $"../..".get_doors():
if door.get_room_leads_to() == null:
door.door_node.queue_free()

View File

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