From ad3e631d8c1df51225f437a14d7be00fd03c43ee Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Mon, 13 Oct 2025 12:11:50 +0200 Subject: [PATCH] Add initial resource and presenter classes for game entities and effects --- .editorconfig | 4 + .gitattributes | 2 + .gitignore | 3 + Code/Autoloads/PresenterRegistry.cs | 25 ++ Code/Autoloads/PresenterRegistry.cs.uid | 1 + Code/Extensions/Vector3Extensions.cs | 17 ++ Code/Extensions/Vector3Extensions.cs.uid | 1 + Code/Factories/ComponentFactory.cs | 80 +++++++ Code/Factories/ComponentFactory.cs.uid | 1 + Code/Factories/EffectFactory.cs | 24 ++ Code/Factories/EffectFactory.cs.uid | 1 + Code/Factories/PresenterFactory.cs | 99 ++++++++ Code/Factories/PresenterFactory.cs.uid | 1 + Code/Presenters/CameraPresenterComponent.cs | 58 +++++ .../CameraPresenterComponent.cs.uid | 1 + Code/Presenters/CharacterBody3DPresenter.cs | 66 ++++++ .../CharacterBody3DPresenter.cs.uid | 1 + Code/Presenters/EntityPresenter.cs | 11 + Code/Presenters/EntityPresenter.cs.uid | 1 + Code/Presenters/GamePresenter.cs | 157 +++++++++++++ Code/Presenters/GamePresenter.cs.uid | 1 + Code/Presenters/SceneEntity.cs | 10 + Code/Presenters/SceneEntity.cs.uid | 1 + .../Presenters/TransformPresenterComponent.cs | 31 +++ .../TransformPresenterComponent.cs.uid | 1 + Code/Resources/ArchetypeDatabase.cs | 10 + Code/Resources/ArchetypeDatabase.cs.uid | 1 + Code/Resources/AttributeComponentResource.cs | 10 + .../AttributeComponentResource.cs.uid | 1 + .../CharacterStateComponentResource.cs | 9 + .../CharacterStateComponentResource.cs.uid | 1 + Code/Resources/EffectResource.cs | 9 + Code/Resources/EffectResource.cs.uid | 1 + .../Resources/Effects/DamageEffectResource.cs | 9 + .../Effects/DamageEffectResource.cs.uid | 1 + .../Effects/FireProjectileEffectResource.cs | 12 + .../FireProjectileEffectResource.cs.uid | 1 + .../Effects/HitscanEffectResource.cs | 9 + .../Effects/HitscanEffectResource.cs.uid | 1 + Code/Resources/EntityArchetype.cs | 11 + Code/Resources/EntityArchetype.cs.uid | 1 + Code/Resources/InputStateComponentResource.cs | 9 + .../InputStateComponentResource.cs.uid | 1 + Code/Resources/PlayerComponentResource.cs | 9 + Code/Resources/PlayerComponentResource.cs.uid | 1 + Code/Resources/PositionComponentResource.cs | 9 + .../PositionComponentResource.cs.uid | 1 + Code/Resources/ProjectileComponentResource.cs | 10 + .../ProjectileComponentResource.cs.uid | 1 + Code/Resources/RotationComponentResource.cs | 9 + .../RotationComponentResource.cs.uid | 1 + Code/Resources/SimulationConfigResource.cs | 9 + .../Resources/SimulationConfigResource.cs.uid | 1 + Code/Resources/VelocityComponentResource.cs | 9 + .../VelocityComponentResource.cs.uid | 1 + Code/Resources/WeaponComponentResource.cs | 9 + Code/Resources/WeaponComponentResource.cs.uid | 1 + Code/Resources/WeaponResource.cs | 14 ++ Code/Resources/WeaponResource.cs.uid | 1 + Code/Services/GodotInputService.cs | 47 ++++ Code/Services/GodotInputService.cs.uid | 1 + Code/Services/GodotWorldQuery.cs | 59 +++++ Code/Services/GodotWorldQuery.cs.uid | 1 + Objects/bullet.tscn | 13 ++ Objects/player.tscn | 28 +++ Resources/Entities/basic_bullet.tres | 27 +++ Resources/Entities/player.tres | 60 +++++ Resources/Weapons/basic_pistol.tres | 24 ++ Resources/entity_database.tres | 12 + Scenes/game_world.tscn | 215 ++++++++++++++++++ cryptonym-thunder.csproj | 13 ++ cryptonym-thunder.sln | 19 ++ icon.svg | 1 + icon.svg.import | 43 ++++ project.godot | 79 +++++++ 75 files changed, 1423 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Code/Autoloads/PresenterRegistry.cs create mode 100644 Code/Autoloads/PresenterRegistry.cs.uid create mode 100644 Code/Extensions/Vector3Extensions.cs create mode 100644 Code/Extensions/Vector3Extensions.cs.uid create mode 100644 Code/Factories/ComponentFactory.cs create mode 100644 Code/Factories/ComponentFactory.cs.uid create mode 100644 Code/Factories/EffectFactory.cs create mode 100644 Code/Factories/EffectFactory.cs.uid create mode 100644 Code/Factories/PresenterFactory.cs create mode 100644 Code/Factories/PresenterFactory.cs.uid create mode 100644 Code/Presenters/CameraPresenterComponent.cs create mode 100644 Code/Presenters/CameraPresenterComponent.cs.uid create mode 100644 Code/Presenters/CharacterBody3DPresenter.cs create mode 100644 Code/Presenters/CharacterBody3DPresenter.cs.uid create mode 100644 Code/Presenters/EntityPresenter.cs create mode 100644 Code/Presenters/EntityPresenter.cs.uid create mode 100644 Code/Presenters/GamePresenter.cs create mode 100644 Code/Presenters/GamePresenter.cs.uid create mode 100644 Code/Presenters/SceneEntity.cs create mode 100644 Code/Presenters/SceneEntity.cs.uid create mode 100644 Code/Presenters/TransformPresenterComponent.cs create mode 100644 Code/Presenters/TransformPresenterComponent.cs.uid create mode 100644 Code/Resources/ArchetypeDatabase.cs create mode 100644 Code/Resources/ArchetypeDatabase.cs.uid create mode 100644 Code/Resources/AttributeComponentResource.cs create mode 100644 Code/Resources/AttributeComponentResource.cs.uid create mode 100644 Code/Resources/CharacterStateComponentResource.cs create mode 100644 Code/Resources/CharacterStateComponentResource.cs.uid create mode 100644 Code/Resources/EffectResource.cs create mode 100644 Code/Resources/EffectResource.cs.uid create mode 100644 Code/Resources/Effects/DamageEffectResource.cs create mode 100644 Code/Resources/Effects/DamageEffectResource.cs.uid create mode 100644 Code/Resources/Effects/FireProjectileEffectResource.cs create mode 100644 Code/Resources/Effects/FireProjectileEffectResource.cs.uid create mode 100644 Code/Resources/Effects/HitscanEffectResource.cs create mode 100644 Code/Resources/Effects/HitscanEffectResource.cs.uid create mode 100644 Code/Resources/EntityArchetype.cs create mode 100644 Code/Resources/EntityArchetype.cs.uid create mode 100644 Code/Resources/InputStateComponentResource.cs create mode 100644 Code/Resources/InputStateComponentResource.cs.uid create mode 100644 Code/Resources/PlayerComponentResource.cs create mode 100644 Code/Resources/PlayerComponentResource.cs.uid create mode 100644 Code/Resources/PositionComponentResource.cs create mode 100644 Code/Resources/PositionComponentResource.cs.uid create mode 100644 Code/Resources/ProjectileComponentResource.cs create mode 100644 Code/Resources/ProjectileComponentResource.cs.uid create mode 100644 Code/Resources/RotationComponentResource.cs create mode 100644 Code/Resources/RotationComponentResource.cs.uid create mode 100644 Code/Resources/SimulationConfigResource.cs create mode 100644 Code/Resources/SimulationConfigResource.cs.uid create mode 100644 Code/Resources/VelocityComponentResource.cs create mode 100644 Code/Resources/VelocityComponentResource.cs.uid create mode 100644 Code/Resources/WeaponComponentResource.cs create mode 100644 Code/Resources/WeaponComponentResource.cs.uid create mode 100644 Code/Resources/WeaponResource.cs create mode 100644 Code/Resources/WeaponResource.cs.uid create mode 100644 Code/Services/GodotInputService.cs create mode 100644 Code/Services/GodotInputService.cs.uid create mode 100644 Code/Services/GodotWorldQuery.cs create mode 100644 Code/Services/GodotWorldQuery.cs.uid create mode 100644 Objects/bullet.tscn create mode 100644 Objects/player.tscn create mode 100644 Resources/Entities/basic_bullet.tres create mode 100644 Resources/Entities/player.tres create mode 100644 Resources/Weapons/basic_pistol.tres create mode 100644 Resources/entity_database.tres create mode 100644 Scenes/game_world.tscn create mode 100644 cryptonym-thunder.csproj create mode 100644 cryptonym-thunder.sln create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 project.godot diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/Code/Autoloads/PresenterRegistry.cs b/Code/Autoloads/PresenterRegistry.cs new file mode 100644 index 0000000..dd3f902 --- /dev/null +++ b/Code/Autoloads/PresenterRegistry.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using GameCore.ECS; +using Godot; + +namespace CryptonymThunder.Code.Autoloads; + +public partial class PresenterRegistry : Node +{ + private readonly Dictionary _instanceIdToEntity = new(); + + public void RegisterPresenter(Node presenterNode, Entity entity) + { + _instanceIdToEntity[presenterNode.GetInstanceId()] = entity; + } + + public void UnregisterPresenter(Node presenterNode) + { + _instanceIdToEntity.Remove(presenterNode.GetInstanceId()); + } + + public bool TryGetEntity(ulong instanceId, out Entity entity) + { + return _instanceIdToEntity.TryGetValue(instanceId, out entity); + } +} \ No newline at end of file diff --git a/Code/Autoloads/PresenterRegistry.cs.uid b/Code/Autoloads/PresenterRegistry.cs.uid new file mode 100644 index 0000000..99e3876 --- /dev/null +++ b/Code/Autoloads/PresenterRegistry.cs.uid @@ -0,0 +1 @@ +uid://5twln2ckxjj8 diff --git a/Code/Extensions/Vector3Extensions.cs b/Code/Extensions/Vector3Extensions.cs new file mode 100644 index 0000000..d13d80f --- /dev/null +++ b/Code/Extensions/Vector3Extensions.cs @@ -0,0 +1,17 @@ +using GameCoreMath = GameCore.Math.Vector3; +using GodotMath = Godot.Vector3; + +namespace CryptonymThunder.Code.Extensions; + +public static class Vector3Extensions +{ + public static GodotMath ToGodot(this GameCoreMath v) + { + return new GodotMath(v.X, v.Y, v.Z); + } + + public static GameCoreMath ToGameCore(this GodotMath v) + { + return new GameCoreMath(v.X, v.Y, v.Z); + } +} \ No newline at end of file diff --git a/Code/Extensions/Vector3Extensions.cs.uid b/Code/Extensions/Vector3Extensions.cs.uid new file mode 100644 index 0000000..6e2d4d7 --- /dev/null +++ b/Code/Extensions/Vector3Extensions.cs.uid @@ -0,0 +1 @@ +uid://dqwjwnmn7x6ny diff --git a/Code/Factories/ComponentFactory.cs b/Code/Factories/ComponentFactory.cs new file mode 100644 index 0000000..df4bc22 --- /dev/null +++ b/Code/Factories/ComponentFactory.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using CryptonymThunder.Code.Resources; +using GameCore.Attributes; +using GameCore.Combat; +using GameCore.ECS.Interfaces; +using GameCore.Input; +using GameCore.Movement; +using GameCore.Physics; +using GameCore.Player; +using Godot; + +namespace CryptonymThunder.Code.Factories; + +public class ComponentFactory +{ + private readonly Dictionary> _factories = new(); + private readonly EffectFactory _effectFactory = new(); + + public ComponentFactory() + { + Register(CreateAttributeComponent); + Register(CreateWeaponComponent); + Register(CreateProjectileComponent); + Register(_ => new PositionComponent()); + Register(_ => new VelocityComponent()); + Register(_ => new InputStateComponent()); + Register(_ => new PlayerComponent()); + Register(_ => new RotationComponent()); + Register(_ => new CharacterStateComponent()); + } + + public IComponent Create(Resource resource) + { + return _factories.TryGetValue(resource.GetType(), out var factory) + ? factory(resource) + : null; + } + + private void Register(Func factory) where TResource : Resource + { + _factories[typeof(TResource)] = res => factory((TResource)res); + } + + private static AttributeComponent CreateAttributeComponent(AttributeComponentResource resource) + { + var component = new AttributeComponent(); + foreach (var (attribute, value) in resource.BaseValues) + { + component.SetBaseValue(attribute, value); + } + + return component; + } + + private WeaponComponent CreateWeaponComponent(WeaponComponentResource resource) + { + if (resource.WeaponData == null) return null; + var weaponData = resource.WeaponData; + + var onFireEffects = weaponData.OnFireEffects.Select(_effectFactory.Create).ToList(); + var onHitEffects = weaponData.OnHitEffects.Select(_effectFactory.Create).ToList(); + + return new WeaponComponent + { + FireRate = resource.WeaponData.FireRate, + OnFireEffects = onFireEffects, + OnHitEffects = onHitEffects, + }; + } + + private ProjectileComponent CreateProjectileComponent(ProjectileComponentResource resource) + { + return new ProjectileComponent + { + Lifetime = resource.Lifetime, + }; + } +} \ No newline at end of file diff --git a/Code/Factories/ComponentFactory.cs.uid b/Code/Factories/ComponentFactory.cs.uid new file mode 100644 index 0000000..62875af --- /dev/null +++ b/Code/Factories/ComponentFactory.cs.uid @@ -0,0 +1 @@ +uid://cwf0khkssee8b diff --git a/Code/Factories/EffectFactory.cs b/Code/Factories/EffectFactory.cs new file mode 100644 index 0000000..5bd0033 --- /dev/null +++ b/Code/Factories/EffectFactory.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.InteropServices.ComTypes; +using CryptonymThunder.Code.Resources; +using CryptonymThunder.Code.Resources.Effects; +using GameCore.Combat.Effects; +using GameCore.Combat.Interfaces; + +namespace CryptonymThunder.Code.Factories; + +public class EffectFactory +{ + public IEffect Create(EffectResource resource) + { + return resource switch + { + FireProjectileEffectResource fire => + new BulkProjectileEffect(fire.ProjectileArchetypeId, fire.Count, fire.SpreadAngle, fire.ProjectileSpeed), + DamageEffectResource damage => new DamageEffect(damage.Amount), + HitscanEffectResource hitscan => new HitscanEffect(hitscan.Range), + _ => throw new ArgumentOutOfRangeException(nameof(resource), + $"Effect type {resource.GetType().Name} not recognized") + }; + } +} \ No newline at end of file diff --git a/Code/Factories/EffectFactory.cs.uid b/Code/Factories/EffectFactory.cs.uid new file mode 100644 index 0000000..63d9686 --- /dev/null +++ b/Code/Factories/EffectFactory.cs.uid @@ -0,0 +1 @@ +uid://d1n7re7y0g6q4 diff --git a/Code/Factories/PresenterFactory.cs b/Code/Factories/PresenterFactory.cs new file mode 100644 index 0000000..eddcae5 --- /dev/null +++ b/Code/Factories/PresenterFactory.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using CryptonymThunder.Code.Autoloads; +using CryptonymThunder.Code.Resources; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using GameCore.Movement; +using GameCore.Physics; +using Godot; +using Godot.Collections; + +namespace CryptonymThunder.Code.Factories; + +public class PresenterFactory( + World world, + ComponentFactory componentFactory, + PresenterRegistry presenterRegistry, + Node sceneRoot) +{ + private readonly World _world = world; + private readonly ComponentFactory _componentFactory = componentFactory; + private PresenterRegistry _presenterRegistry = presenterRegistry; + private readonly Node _sceneRoot = sceneRoot; + + public PresenterData CreateEntityFromArchetype(EntityArchetype archetype, GameCore.Math.Vector3? position = null, + GameCore.Math.Vector3? rotation = null, GameCore.Math.Vector3? initialVelocity = null) + { + var entity = _world.CreateEntity(); + + foreach (var resource in archetype.ComponentResources) + { + var component = _componentFactory.Create(resource); + if (component != null) _world.AddComponent(entity, component); + } + + var presenterNode = archetype.Scene.Instantiate(); + if (presenterNode is not IEntityPresenter presenter) + { + GD.PrintErr($"Archetype scene '{archetype.ResourcePath}' root does not implement IEntityPresenter!"); + presenterNode.QueueFree(); + return default; + } + + presenter.CoreEntity = entity; + + var components = InitializePresenterComponents(presenterNode, entity); + + if (position.HasValue && _world.GetComponent(entity) is { } posComp) + posComp.Position = position.Value; + if (rotation.HasValue && _world.GetComponent(entity) is { } rotComp) + rotComp.Rotation = rotation.Value; + if (initialVelocity.HasValue && _world.GetComponent(entity) is { } velComp) + velComp.DesiredVelocity = initialVelocity.Value; + + _sceneRoot.AddChild(presenterNode); + return new PresenterData(entity, presenter, components); + } + + public PresenterData RegisterSceneEntity(Node presenterNode, Array componentResources) + { + var entity = _world.CreateEntity(); + + foreach (var resource in componentResources) + { + var component = _componentFactory.Create(resource); + if (component != null) _world.AddComponent(entity, component); + } + + if (presenterNode is not IEntityPresenter presenter) + { + GD.PrintErr($"Scene node '{presenterNode.Name}' does not implement IEntityPresenter!"); + return default; + } + + presenter.CoreEntity = entity; + var components = InitializePresenterComponents(presenterNode, entity); + return new PresenterData(entity, presenter, components); + } + + private List InitializePresenterComponents(Node presenterNode, Entity entity) + { + _presenterRegistry.RegisterPresenter(presenterNode, entity); + + var components = new List(); + foreach (var child in presenterNode.GetChildren(true)) + { + if (child is IPresenterComponent pComponent) + { + pComponent.Initialize(entity, _world); + components.Add(pComponent); + } + } + if (presenterNode is IPresenterComponent rootComponent) + { + rootComponent.Initialize(entity, _world); + components.Add(rootComponent); + } + return components; + } +} \ No newline at end of file diff --git a/Code/Factories/PresenterFactory.cs.uid b/Code/Factories/PresenterFactory.cs.uid new file mode 100644 index 0000000..e8207ab --- /dev/null +++ b/Code/Factories/PresenterFactory.cs.uid @@ -0,0 +1 @@ +uid://balunj6u4ptjq diff --git a/Code/Presenters/CameraPresenterComponent.cs b/Code/Presenters/CameraPresenterComponent.cs new file mode 100644 index 0000000..9c88a8b --- /dev/null +++ b/Code/Presenters/CameraPresenterComponent.cs @@ -0,0 +1,58 @@ +using CryptonymThunder.Code.Extensions; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using GameCore.Input; +using GameCore.Movement; +using Godot; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class CameraPresenterComponent : Node3D, IPresenterComponent +{ + private Entity _coreEntity; + private World _world; + private Camera3D _camera; + private RotationComponent _rotationComponent; + + private bool _cursorLocked = true; + + public void Initialize(Entity coreEntity, World world) + { + _coreEntity = coreEntity; + _world = world; + _rotationComponent = _world.GetComponent(_coreEntity); + _camera = GetNode("Camera3D"); + + if (_cursorLocked) Input.MouseMode = Input.MouseModeEnum.Captured; + } + + public void SyncToPresentation(float delta) + { + if (_rotationComponent == null || _camera == null) return; + + var coreRotation = _rotationComponent.Rotation; + _camera.Rotation = new Vector3(coreRotation.X, 0f, 0f); + } + + public void SyncToCore(float delta) + { + } + + public override void _Input(InputEvent @event) + { + if (Input.IsActionJustPressed("ui_cancel")) + { + if (_cursorLocked) + { + Input.MouseMode = Input.MouseModeEnum.Visible; + _cursorLocked = false; + } + else + { + Input.MouseMode = Input.MouseModeEnum.Captured; + _cursorLocked = true; + } + } + } +} \ No newline at end of file diff --git a/Code/Presenters/CameraPresenterComponent.cs.uid b/Code/Presenters/CameraPresenterComponent.cs.uid new file mode 100644 index 0000000..b312968 --- /dev/null +++ b/Code/Presenters/CameraPresenterComponent.cs.uid @@ -0,0 +1 @@ +uid://crx03e8buoni3 diff --git a/Code/Presenters/CharacterBody3DPresenter.cs b/Code/Presenters/CharacterBody3DPresenter.cs new file mode 100644 index 0000000..33b231f --- /dev/null +++ b/Code/Presenters/CharacterBody3DPresenter.cs @@ -0,0 +1,66 @@ +using CryptonymThunder.Code.Extensions; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using GameCore.Input; +using GameCore.Movement; +using GameCore.Physics; +using Godot; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class CharacterBody3DPresenter : CharacterBody3D, IEntityPresenter, IPresenterComponent +{ + private World _world; + private VelocityComponent _velocity; + private PositionComponent _position; + private RotationComponent _rotation; + private CharacterStateComponent _characterState; + private InputStateComponent _inputState; + private Camera3D _camera; + + public Entity CoreEntity { get; set; } + + public void Initialize(Entity coreEntity, World world) + { + CoreEntity = coreEntity; + _world = world; + _velocity = _world.GetComponent(CoreEntity); + _position = _world.GetComponent(CoreEntity); + _rotation = _world.GetComponent(CoreEntity); + _inputState = _world.GetComponent(CoreEntity); + _characterState = _world.GetComponent(CoreEntity); + _camera = GetNode("CameraPivot/Camera3D"); + } + + public void SyncToPresentation(float delta) + { + if (_rotation != null) + { + var coreRotation = _rotation.Rotation; + Rotation = new Vector3(Rotation.X, coreRotation.Y, Rotation.Z); + } + + if (_velocity == null) return; + + var godotVelocity = Velocity; + godotVelocity.X = _velocity.DesiredVelocity.X; + godotVelocity.Y = _velocity.DesiredVelocity.Y; + godotVelocity.Z = _velocity.DesiredVelocity.Z; + + Velocity = godotVelocity; + MoveAndSlide(); + } + + public void SyncToCore(float delta) + { + if (_position != null) _position.Position = GlobalPosition.ToGameCore(); + if (_velocity != null) _velocity.ActualVelocity = Velocity.ToGameCore(); + if (_characterState != null) _characterState.IsOnFloor = IsOnFloor(); + if (_inputState != null && _camera != null) + { + _inputState.MuzzlePosition = _camera.GlobalPosition.ToGameCore(); + _inputState.MuzzleDirection = (-_camera.GlobalTransform.Basis.Z).ToGameCore(); + } + } +} \ No newline at end of file diff --git a/Code/Presenters/CharacterBody3DPresenter.cs.uid b/Code/Presenters/CharacterBody3DPresenter.cs.uid new file mode 100644 index 0000000..6f3517c --- /dev/null +++ b/Code/Presenters/CharacterBody3DPresenter.cs.uid @@ -0,0 +1 @@ +uid://hkiny1ftv4r7 diff --git a/Code/Presenters/EntityPresenter.cs b/Code/Presenters/EntityPresenter.cs new file mode 100644 index 0000000..2816787 --- /dev/null +++ b/Code/Presenters/EntityPresenter.cs @@ -0,0 +1,11 @@ +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using Godot; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class EntityPresenter : Node3D, IEntityPresenter +{ + public Entity CoreEntity { get; set; } +} \ No newline at end of file diff --git a/Code/Presenters/EntityPresenter.cs.uid b/Code/Presenters/EntityPresenter.cs.uid new file mode 100644 index 0000000..f7aa31c --- /dev/null +++ b/Code/Presenters/EntityPresenter.cs.uid @@ -0,0 +1 @@ +uid://cb7vaw6xqjs1i diff --git a/Code/Presenters/GamePresenter.cs b/Code/Presenters/GamePresenter.cs new file mode 100644 index 0000000..bfb71ba --- /dev/null +++ b/Code/Presenters/GamePresenter.cs @@ -0,0 +1,157 @@ +using System.Collections.Generic; +using CryptonymThunder.Code.Autoloads; +using CryptonymThunder.Code.Factories; +using CryptonymThunder.Code.Resources; +using CryptonymThunder.Code.Services; +using GameCore.Attributes; +using GameCore.Combat; +using GameCore.Config; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using GameCore.Events; +using GameCore.Input; +using GameCore.Movement; +using Godot; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class GamePresenter : Node +{ + [Export] private ArchetypeDatabase ArchetypesDatabase { get; set; } + [Export] private EntityArchetype PlayerArchetype { get; set; } + [Export] private SimulationConfigResource SimulationConfig { get; set; } + + private World _world; + private PresenterRegistry _presenterRegistry; + private GodotInputService _inputService; + private GodotWorldQuery _worldQuery; + private PresenterFactory _presenterFactory; + + private readonly Dictionary> _presenterComponents = new(); + private readonly Dictionary _presenters = new(); + + public override void _Ready() + { + _presenterRegistry = GetNode("/root/PresenterRegistry"); + _inputService = new GodotInputService(); + _worldQuery = new GodotWorldQuery(this); + + var simConfig = new SimulationConfig(); + if (SimulationConfig != null) + { + simConfig.GravityStrength = SimulationConfig.GravityStrength; + } + + _world = new World(_inputService, _worldQuery, simConfig); + + _presenterFactory = new PresenterFactory(_world, new ComponentFactory(), _presenterRegistry, this); + + _world.RegisterSystem(new PlayerInputSystem()); + _world.RegisterSystem(new RotationSystem()); + _world.RegisterSystem(new GroundMovementSystem()); + _world.RegisterSystem(new GravitySystem()); + _world.RegisterSystem(new JumpSystem()); + + _world.RegisterSystem(new AttributeSystem()); + + _world.RegisterSystem(new WeaponSystem()); + _world.RegisterSystem(new ProjectileSystem()); + _world.RegisterSystem(new ProjectileInitializationSystem(_world)); + + _world.RegisterSystem(new DamageSystem(_world)); + _world.RegisterSystem(new ProjectileCleanupSystem()); + _world.RegisterSystem(new DestructionSystem()); + + _world.Subscribe(OnEntityDied); + _world.Subscribe(OnSpawnEntity); + + RegisterAllSceneEntities(); + + var playerData = _presenterFactory.CreateEntityFromArchetype(PlayerArchetype); + _presenters.Add(playerData.Entity.Id, playerData.Presenter); + _presenterComponents.Add(playerData.Entity.Id, playerData.Components); + } + + public override void _Input(InputEvent @event) + { + _inputService?.HandleInputEvent(@event); + } + + public override void _PhysicsProcess(double delta) + { + if (_presenters.Count == 0) return; + + _inputService.Update(); + _world.Update((float)delta); + _world.ProcessEvents(); + + foreach (var componentList in _presenterComponents.Values) + { + foreach (var component in componentList) + { + component.SyncToPresentation((float)delta); + } + } + + foreach (var componentList in _presenterComponents.Values) + { + foreach (var component in componentList) + { + component.SyncToCore((float)delta); + } + } + + _inputService.LateUpdate(); + } + + private void OnSpawnEntity(SpawnEntityEvent @event) + { + if (ArchetypesDatabase.Archetypes.TryGetValue(@event.ArchetypeId, out var archetype)) + { + var presenterData = _presenterFactory.CreateEntityFromArchetype(archetype, @event.Position, @event.Rotation, @event.InitialVelocity); + _presenters.Add(presenterData.Entity.Id, presenterData.Presenter); + _presenterComponents.Add(presenterData.Entity.Id, presenterData.Components); + + _world.PublishEvent(new EntitySpawnedEvent(presenterData.Entity, @event.Owner, @event.ArchetypeId)); + } + } + + private void OnEntityDied(EntityDiedEvent e) + { + if (_presenters.Remove(e.Entity.Id, out var presenter)) + { + _presenterRegistry.UnregisterPresenter(presenter as Node); + _presenterComponents.Remove(e.Entity.Id); + (presenter as Node)?.QueueFree(); + } + } + + private void RegisterAllSceneEntities() + { + var sceneEntities = GetTree().GetNodesInGroup("SceneEntities"); + foreach (var node in sceneEntities) + { + if (node is SceneEntity sceneEntity) + { + var parentNode = sceneEntity.GetParent(); + if (parentNode != null) + { + var presenterData = _presenterFactory.RegisterSceneEntity(parentNode, sceneEntity.ComponentResources); + _presenters.Add(presenterData.Entity.Id, presenterData.Presenter); + _presenterComponents.Add(presenterData.Entity.Id, presenterData.Components); + } + } + } + } + + public Node GetPresenterNode(Entity entity) + { + if (_presenters.TryGetValue(entity.Id, out var presenter)) + { + return presenter as Node; + } + + return null; + } +} \ No newline at end of file diff --git a/Code/Presenters/GamePresenter.cs.uid b/Code/Presenters/GamePresenter.cs.uid new file mode 100644 index 0000000..428dc81 --- /dev/null +++ b/Code/Presenters/GamePresenter.cs.uid @@ -0,0 +1 @@ +uid://cfpm5p102f65x diff --git a/Code/Presenters/SceneEntity.cs b/Code/Presenters/SceneEntity.cs new file mode 100644 index 0000000..f64bcce --- /dev/null +++ b/Code/Presenters/SceneEntity.cs @@ -0,0 +1,10 @@ +using Godot; +using Godot.Collections; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class SceneEntity : Node +{ + [Export] public Array ComponentResources { get; set; } = []; +} \ No newline at end of file diff --git a/Code/Presenters/SceneEntity.cs.uid b/Code/Presenters/SceneEntity.cs.uid new file mode 100644 index 0000000..2117559 --- /dev/null +++ b/Code/Presenters/SceneEntity.cs.uid @@ -0,0 +1 @@ +uid://b6x8llipvutqs diff --git a/Code/Presenters/TransformPresenterComponent.cs b/Code/Presenters/TransformPresenterComponent.cs new file mode 100644 index 0000000..b33aef5 --- /dev/null +++ b/Code/Presenters/TransformPresenterComponent.cs @@ -0,0 +1,31 @@ +using CryptonymThunder.Code.Extensions; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using GameCore.Physics; +using Godot; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class TransformPresenterComponent : Node3D, IPresenterComponent, IEntityPresenter +{ + private PositionComponent _position; + + public Entity CoreEntity { get; set; } + + public void Initialize(Entity coreEntity, World world) + { + CoreEntity = coreEntity; + _position = world.GetComponent(coreEntity); + } + + public void SyncToPresentation(float delta) + { + if (_position != null) GlobalPosition = _position.Position.ToGodot(); + } + + public void SyncToCore(float delta) + { + + } +} \ No newline at end of file diff --git a/Code/Presenters/TransformPresenterComponent.cs.uid b/Code/Presenters/TransformPresenterComponent.cs.uid new file mode 100644 index 0000000..7d5a36e --- /dev/null +++ b/Code/Presenters/TransformPresenterComponent.cs.uid @@ -0,0 +1 @@ +uid://dl2awoy0hyruh diff --git a/Code/Resources/ArchetypeDatabase.cs b/Code/Resources/ArchetypeDatabase.cs new file mode 100644 index 0000000..4c679e9 --- /dev/null +++ b/Code/Resources/ArchetypeDatabase.cs @@ -0,0 +1,10 @@ +using Godot; +using Godot.Collections; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class ArchetypeDatabase : Resource +{ + [Export] public Dictionary Archetypes { get; set; } = new(); +} \ No newline at end of file diff --git a/Code/Resources/ArchetypeDatabase.cs.uid b/Code/Resources/ArchetypeDatabase.cs.uid new file mode 100644 index 0000000..ecbabc9 --- /dev/null +++ b/Code/Resources/ArchetypeDatabase.cs.uid @@ -0,0 +1 @@ +uid://df10ksb6f0pjt diff --git a/Code/Resources/AttributeComponentResource.cs b/Code/Resources/AttributeComponentResource.cs new file mode 100644 index 0000000..dd1b670 --- /dev/null +++ b/Code/Resources/AttributeComponentResource.cs @@ -0,0 +1,10 @@ +using Godot; +using Attribute = GameCore.Attributes.Attribute; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class AttributeComponentResource : Resource +{ + [Export] public Godot.Collections.Dictionary BaseValues { get; set; } = new(); +} \ No newline at end of file diff --git a/Code/Resources/AttributeComponentResource.cs.uid b/Code/Resources/AttributeComponentResource.cs.uid new file mode 100644 index 0000000..653f288 --- /dev/null +++ b/Code/Resources/AttributeComponentResource.cs.uid @@ -0,0 +1 @@ +uid://dc7wq2ij5kwj5 diff --git a/Code/Resources/CharacterStateComponentResource.cs b/Code/Resources/CharacterStateComponentResource.cs new file mode 100644 index 0000000..0db391e --- /dev/null +++ b/Code/Resources/CharacterStateComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class CharacterStateComponentResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/CharacterStateComponentResource.cs.uid b/Code/Resources/CharacterStateComponentResource.cs.uid new file mode 100644 index 0000000..b7d981a --- /dev/null +++ b/Code/Resources/CharacterStateComponentResource.cs.uid @@ -0,0 +1 @@ +uid://cdpbn8eiypfbd diff --git a/Code/Resources/EffectResource.cs b/Code/Resources/EffectResource.cs new file mode 100644 index 0000000..f452144 --- /dev/null +++ b/Code/Resources/EffectResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class EffectResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/EffectResource.cs.uid b/Code/Resources/EffectResource.cs.uid new file mode 100644 index 0000000..0860679 --- /dev/null +++ b/Code/Resources/EffectResource.cs.uid @@ -0,0 +1 @@ +uid://bdo6vrtrsr0an diff --git a/Code/Resources/Effects/DamageEffectResource.cs b/Code/Resources/Effects/DamageEffectResource.cs new file mode 100644 index 0000000..36747d9 --- /dev/null +++ b/Code/Resources/Effects/DamageEffectResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources.Effects; + +[GlobalClass] +public partial class DamageEffectResource : EffectResource +{ + [Export] public float Amount { get; set; } = 10f; +} \ No newline at end of file diff --git a/Code/Resources/Effects/DamageEffectResource.cs.uid b/Code/Resources/Effects/DamageEffectResource.cs.uid new file mode 100644 index 0000000..8c27064 --- /dev/null +++ b/Code/Resources/Effects/DamageEffectResource.cs.uid @@ -0,0 +1 @@ +uid://btv24gsw1p850 diff --git a/Code/Resources/Effects/FireProjectileEffectResource.cs b/Code/Resources/Effects/FireProjectileEffectResource.cs new file mode 100644 index 0000000..30a2d18 --- /dev/null +++ b/Code/Resources/Effects/FireProjectileEffectResource.cs @@ -0,0 +1,12 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources.Effects; + +[GlobalClass] +public partial class FireProjectileEffectResource : EffectResource +{ + [Export] public string ProjectileArchetypeId { get; set; } + [Export(PropertyHint.Range, "1,50,1")] public int Count { get; set; } = 1; + [Export(PropertyHint.Range, "0,90,0.1")] public float SpreadAngle { get; set; } = 0f; + [Export] public float ProjectileSpeed { get; set; } = 30f; +} \ No newline at end of file diff --git a/Code/Resources/Effects/FireProjectileEffectResource.cs.uid b/Code/Resources/Effects/FireProjectileEffectResource.cs.uid new file mode 100644 index 0000000..2b0a231 --- /dev/null +++ b/Code/Resources/Effects/FireProjectileEffectResource.cs.uid @@ -0,0 +1 @@ +uid://cht6trljihvle diff --git a/Code/Resources/Effects/HitscanEffectResource.cs b/Code/Resources/Effects/HitscanEffectResource.cs new file mode 100644 index 0000000..d1afe47 --- /dev/null +++ b/Code/Resources/Effects/HitscanEffectResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources.Effects; + +[GlobalClass] +public partial class HitscanEffectResource : EffectResource +{ + [Export] public float Range { get; set; } = 100f; +} \ No newline at end of file diff --git a/Code/Resources/Effects/HitscanEffectResource.cs.uid b/Code/Resources/Effects/HitscanEffectResource.cs.uid new file mode 100644 index 0000000..1aa47bf --- /dev/null +++ b/Code/Resources/Effects/HitscanEffectResource.cs.uid @@ -0,0 +1 @@ +uid://chc0d0rjcbl65 diff --git a/Code/Resources/EntityArchetype.cs b/Code/Resources/EntityArchetype.cs new file mode 100644 index 0000000..7276121 --- /dev/null +++ b/Code/Resources/EntityArchetype.cs @@ -0,0 +1,11 @@ +using Godot; +using Godot.Collections; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class EntityArchetype : Resource +{ + [Export] public PackedScene Scene { get; set; } + [Export] public Array ComponentResources { get; set; } = []; +} \ No newline at end of file diff --git a/Code/Resources/EntityArchetype.cs.uid b/Code/Resources/EntityArchetype.cs.uid new file mode 100644 index 0000000..06f14c0 --- /dev/null +++ b/Code/Resources/EntityArchetype.cs.uid @@ -0,0 +1 @@ +uid://coe688e2jkyjq diff --git a/Code/Resources/InputStateComponentResource.cs b/Code/Resources/InputStateComponentResource.cs new file mode 100644 index 0000000..a4b813f --- /dev/null +++ b/Code/Resources/InputStateComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class InputStateComponentResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/InputStateComponentResource.cs.uid b/Code/Resources/InputStateComponentResource.cs.uid new file mode 100644 index 0000000..272c320 --- /dev/null +++ b/Code/Resources/InputStateComponentResource.cs.uid @@ -0,0 +1 @@ +uid://y4cbuh2wxigy diff --git a/Code/Resources/PlayerComponentResource.cs b/Code/Resources/PlayerComponentResource.cs new file mode 100644 index 0000000..b3a4199 --- /dev/null +++ b/Code/Resources/PlayerComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class PlayerComponentResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/PlayerComponentResource.cs.uid b/Code/Resources/PlayerComponentResource.cs.uid new file mode 100644 index 0000000..13113f0 --- /dev/null +++ b/Code/Resources/PlayerComponentResource.cs.uid @@ -0,0 +1 @@ +uid://p4vr80n70vkt diff --git a/Code/Resources/PositionComponentResource.cs b/Code/Resources/PositionComponentResource.cs new file mode 100644 index 0000000..4fdf176 --- /dev/null +++ b/Code/Resources/PositionComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class PositionComponentResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/PositionComponentResource.cs.uid b/Code/Resources/PositionComponentResource.cs.uid new file mode 100644 index 0000000..1f273bd --- /dev/null +++ b/Code/Resources/PositionComponentResource.cs.uid @@ -0,0 +1 @@ +uid://df5wmj1jp2oy5 diff --git a/Code/Resources/ProjectileComponentResource.cs b/Code/Resources/ProjectileComponentResource.cs new file mode 100644 index 0000000..68b9c07 --- /dev/null +++ b/Code/Resources/ProjectileComponentResource.cs @@ -0,0 +1,10 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class ProjectileComponentResource : Resource +{ + [Export] public float Speed { get; set; } = 50.0f; + [Export] public float Lifetime { get; set; } = 5.0f; +} \ No newline at end of file diff --git a/Code/Resources/ProjectileComponentResource.cs.uid b/Code/Resources/ProjectileComponentResource.cs.uid new file mode 100644 index 0000000..75795b1 --- /dev/null +++ b/Code/Resources/ProjectileComponentResource.cs.uid @@ -0,0 +1 @@ +uid://ddryrwjq33832 diff --git a/Code/Resources/RotationComponentResource.cs b/Code/Resources/RotationComponentResource.cs new file mode 100644 index 0000000..59cd237 --- /dev/null +++ b/Code/Resources/RotationComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class RotationComponentResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/RotationComponentResource.cs.uid b/Code/Resources/RotationComponentResource.cs.uid new file mode 100644 index 0000000..b91d0a4 --- /dev/null +++ b/Code/Resources/RotationComponentResource.cs.uid @@ -0,0 +1 @@ +uid://blm62f85g7icn diff --git a/Code/Resources/SimulationConfigResource.cs b/Code/Resources/SimulationConfigResource.cs new file mode 100644 index 0000000..f38a146 --- /dev/null +++ b/Code/Resources/SimulationConfigResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class SimulationConfigResource : Resource +{ + [Export] public float GravityStrength { get; set; } = 9.81f; +} \ No newline at end of file diff --git a/Code/Resources/SimulationConfigResource.cs.uid b/Code/Resources/SimulationConfigResource.cs.uid new file mode 100644 index 0000000..97a8c52 --- /dev/null +++ b/Code/Resources/SimulationConfigResource.cs.uid @@ -0,0 +1 @@ +uid://uearpvfk21ym diff --git a/Code/Resources/VelocityComponentResource.cs b/Code/Resources/VelocityComponentResource.cs new file mode 100644 index 0000000..8d3902b --- /dev/null +++ b/Code/Resources/VelocityComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class VelocityComponentResource : Resource +{ + +} \ No newline at end of file diff --git a/Code/Resources/VelocityComponentResource.cs.uid b/Code/Resources/VelocityComponentResource.cs.uid new file mode 100644 index 0000000..46436cf --- /dev/null +++ b/Code/Resources/VelocityComponentResource.cs.uid @@ -0,0 +1 @@ +uid://t4j1urlupxxv diff --git a/Code/Resources/WeaponComponentResource.cs b/Code/Resources/WeaponComponentResource.cs new file mode 100644 index 0000000..e528f02 --- /dev/null +++ b/Code/Resources/WeaponComponentResource.cs @@ -0,0 +1,9 @@ +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class WeaponComponentResource : Resource +{ + [Export] public WeaponResource WeaponData { get; set; } +} \ No newline at end of file diff --git a/Code/Resources/WeaponComponentResource.cs.uid b/Code/Resources/WeaponComponentResource.cs.uid new file mode 100644 index 0000000..8f4458a --- /dev/null +++ b/Code/Resources/WeaponComponentResource.cs.uid @@ -0,0 +1 @@ +uid://bp7mufswr41w6 diff --git a/Code/Resources/WeaponResource.cs b/Code/Resources/WeaponResource.cs new file mode 100644 index 0000000..db611bf --- /dev/null +++ b/Code/Resources/WeaponResource.cs @@ -0,0 +1,14 @@ +using GameCore.Combat; +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class WeaponResource : Resource +{ + [Export] public float FireRate { get; set; } = 1.0f; + + [ExportGroup("Effects")] + [Export] public Godot.Collections.Array OnFireEffects { get; set; } = []; + [Export] public Godot.Collections.Array OnHitEffects { get; set; } = []; +} \ No newline at end of file diff --git a/Code/Resources/WeaponResource.cs.uid b/Code/Resources/WeaponResource.cs.uid new file mode 100644 index 0000000..06ae967 --- /dev/null +++ b/Code/Resources/WeaponResource.cs.uid @@ -0,0 +1 @@ +uid://hf0iut8o8do3 diff --git a/Code/Services/GodotInputService.cs b/Code/Services/GodotInputService.cs new file mode 100644 index 0000000..f3964ec --- /dev/null +++ b/Code/Services/GodotInputService.cs @@ -0,0 +1,47 @@ +using GameCore.Input.Interfaces; +using Godot; +using GameCoreMath = GameCore.Math.Vector3; + +namespace CryptonymThunder.Code.Services; + +public class GodotInputService : IInputService +{ + private Vector2 _mouseDeltaAccumulator = Vector2.Zero; + private const float MouseSensitivity = 0.002f; + + public bool IsFiring { get; private set; } + public bool IsInteracting { get; private set; } + public bool IsJumping { get; private set; } + public GameCoreMath MoveDirection { get; private set; } + public GameCoreMath LookDirection { get; private set; } + + public void HandleInputEvent(InputEvent e) + { + if (e is InputEventMouseMotion mouseMotion) + { + _mouseDeltaAccumulator += mouseMotion.Relative; + } + } + + public void Update() + { + var godotInputVector = Input.GetVector("left", "right", "forward", "backward"); + MoveDirection = new GameCoreMath(godotInputVector.X, 0f, godotInputVector.Y); + + LookDirection = new GameCoreMath( + -_mouseDeltaAccumulator.Y * MouseSensitivity, + -_mouseDeltaAccumulator.X * MouseSensitivity, + 0f); + + _mouseDeltaAccumulator = Vector2.Zero; + + IsJumping = Input.IsActionJustPressed("jump"); + IsFiring = Input.IsActionPressed("fire"); + IsInteracting = Input.IsActionPressed("interact"); + } + + public void LateUpdate() + { + LookDirection = GameCoreMath.Zero; + } +} \ No newline at end of file diff --git a/Code/Services/GodotInputService.cs.uid b/Code/Services/GodotInputService.cs.uid new file mode 100644 index 0000000..5203d9d --- /dev/null +++ b/Code/Services/GodotInputService.cs.uid @@ -0,0 +1 @@ +uid://dp63r0vs7vydp diff --git a/Code/Services/GodotWorldQuery.cs b/Code/Services/GodotWorldQuery.cs new file mode 100644 index 0000000..9ea285a --- /dev/null +++ b/Code/Services/GodotWorldQuery.cs @@ -0,0 +1,59 @@ +using System; +using CryptonymThunder.Code.Autoloads; +using CryptonymThunder.Code.Extensions; +using CryptonymThunder.Code.Presenters; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using Godot; +using GodotWorld = Godot.World3D; +using Vector3 = GameCore.Math.Vector3; + +namespace CryptonymThunder.Code.Services; + +public class GodotWorldQuery(GamePresenter ownerNode) : IWorldQuery +{ + private readonly PresenterRegistry _presenterRegistry = ownerNode.GetNode("/root/PresenterRegistry"); + private readonly GodotWorld _godotWorld = ((SceneTree)Engine.GetMainLoop()).Root.World3D; + + public HitResult Raycast(Vector3 from, Vector3 to, Entity? ownerToExclude = null) + { + var spaceState = _godotWorld.DirectSpaceState; + + var query = PhysicsRayQueryParameters3D.Create(from.ToGodot(), to.ToGodot()); + query.CollisionMask = 1; + query.CollideWithBodies = true; + query.CollideWithAreas = false; + + if (ownerToExclude.HasValue) + { + var ownerPresenter = ownerNode.GetPresenterNode(ownerToExclude.Value); + if (ownerPresenter != null) + { + query.Exclude = [((PhysicsBody3D)ownerPresenter).GetRid()]; + } + } + + var result = spaceState.IntersectRay(query); + + if (result.Count > 0 && result["collider"].Obj is Node3D collider) + { + if (_presenterRegistry.TryGetEntity(collider.GetInstanceId(), out var hitEntity)) + { + return new HitResult + { + DidHit = true, + HitEntity = hitEntity + }; + } + } + + return new HitResult { DidHit = false }; + } + + public Vector3 RotateVectorByYaw(Vector3 vector, float yawRadians) + { + var rotatedX = vector.X * (float)Math.Cos(yawRadians) + vector.Z * (float)Math.Sin(yawRadians); + var rotatedZ = -vector.X * (float)Math.Sin(yawRadians) + vector.Z * (float)Math.Cos(yawRadians); + return new Vector3(rotatedX, vector.Y, rotatedZ); + } +} \ No newline at end of file diff --git a/Code/Services/GodotWorldQuery.cs.uid b/Code/Services/GodotWorldQuery.cs.uid new file mode 100644 index 0000000..f3c402e --- /dev/null +++ b/Code/Services/GodotWorldQuery.cs.uid @@ -0,0 +1 @@ +uid://l1tfuwnumj0m diff --git a/Objects/bullet.tscn b/Objects/bullet.tscn new file mode 100644 index 0000000..8c7850a --- /dev/null +++ b/Objects/bullet.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://i84teqsbrmff"] + +[ext_resource type="Script" uid="uid://dl2awoy0hyruh" path="res://Code/Presenters/TransformPresenterComponent.cs" id="1_ktj6t"] + +[sub_resource type="SphereMesh" id="SphereMesh_48nvk"] +radius = 0.1 +height = 0.1 +radial_segments = 8 +rings = 8 + +[node name="Bullet" type="MeshInstance3D"] +mesh = SubResource("SphereMesh_48nvk") +script = ExtResource("1_ktj6t") diff --git a/Objects/player.tscn b/Objects/player.tscn new file mode 100644 index 0000000..11919d8 --- /dev/null +++ b/Objects/player.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=5 format=3 uid="uid://c576jiewfs5gj"] + +[ext_resource type="Script" uid="uid://hkiny1ftv4r7" path="res://Code/Presenters/CharacterBody3DPresenter.cs" id="2_3y5cq"] +[ext_resource type="Script" uid="uid://crx03e8buoni3" path="res://Code/Presenters/CameraPresenterComponent.cs" id="3_2i4gt"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_y0qk3"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_3y5cq"] + +[node name="Player" type="CharacterBody3D"] +script = ExtResource("2_3y5cq") +metadata/_custom_type_script = "uid://hkiny1ftv4r7" + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0028362, 0) +shape = SubResource("CapsuleShape3D_y0qk3") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0028362, 0) +visible = false +mesh = SubResource("CapsuleMesh_3y5cq") +skeleton = NodePath("") + +[node name="CameraPivot" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5901337, 0) +script = ExtResource("3_2i4gt") + +[node name="Camera3D" type="Camera3D" parent="CameraPivot"] diff --git a/Resources/Entities/basic_bullet.tres b/Resources/Entities/basic_bullet.tres new file mode 100644 index 0000000..605de94 --- /dev/null +++ b/Resources/Entities/basic_bullet.tres @@ -0,0 +1,27 @@ +[gd_resource type="Resource" script_class="EntityArchetype" load_steps=9 format=3 uid="uid://cfwsnjb2nob32"] + +[ext_resource type="Script" uid="uid://df5wmj1jp2oy5" path="res://Code/Resources/PositionComponentResource.cs" id="1_p4pan"] +[ext_resource type="Script" uid="uid://coe688e2jkyjq" path="res://Code/Resources/EntityArchetype.cs" id="1_puol3"] +[ext_resource type="Script" uid="uid://t4j1urlupxxv" path="res://Code/Resources/VelocityComponentResource.cs" id="2_rcqc5"] +[ext_resource type="PackedScene" uid="uid://i84teqsbrmff" path="res://Objects/bullet.tscn" id="3_mwldp"] +[ext_resource type="Script" uid="uid://ddryrwjq33832" path="res://Code/Resources/ProjectileComponentResource.cs" id="3_rcqc5"] + +[sub_resource type="Resource" id="Resource_56sml"] +script = ExtResource("1_p4pan") +metadata/_custom_type_script = "uid://df5wmj1jp2oy5" + +[sub_resource type="Resource" id="Resource_573xv"] +script = ExtResource("2_rcqc5") +metadata/_custom_type_script = "uid://t4j1urlupxxv" + +[sub_resource type="Resource" id="Resource_mwldp"] +script = ExtResource("3_rcqc5") +Speed = 1.0 +Lifetime = 1.0 +metadata/_custom_type_script = "uid://ddryrwjq33832" + +[resource] +script = ExtResource("1_puol3") +Scene = ExtResource("3_mwldp") +ComponentResources = Array[Resource]([SubResource("Resource_56sml"), SubResource("Resource_573xv"), SubResource("Resource_mwldp")]) +metadata/_custom_type_script = "uid://coe688e2jkyjq" diff --git a/Resources/Entities/player.tres b/Resources/Entities/player.tres new file mode 100644 index 0000000..c0c3674 --- /dev/null +++ b/Resources/Entities/player.tres @@ -0,0 +1,60 @@ +[gd_resource type="Resource" script_class="EntityArchetype" load_steps=20 format=3 uid="uid://biev6ri5s8kyf"] + +[ext_resource type="Script" uid="uid://dc7wq2ij5kwj5" path="res://Code/Resources/AttributeComponentResource.cs" id="1_0drlr"] +[ext_resource type="Script" uid="uid://y4cbuh2wxigy" path="res://Code/Resources/InputStateComponentResource.cs" id="2_7o5r3"] +[ext_resource type="Script" uid="uid://p4vr80n70vkt" path="res://Code/Resources/PlayerComponentResource.cs" id="3_l66rq"] +[ext_resource type="Script" uid="uid://df5wmj1jp2oy5" path="res://Code/Resources/PositionComponentResource.cs" id="4_efscl"] +[ext_resource type="Script" uid="uid://t4j1urlupxxv" path="res://Code/Resources/VelocityComponentResource.cs" id="5_55dod"] +[ext_resource type="Script" uid="uid://blm62f85g7icn" path="res://Code/Resources/RotationComponentResource.cs" id="6_8u8a8"] +[ext_resource type="Script" uid="uid://cdpbn8eiypfbd" path="res://Code/Resources/CharacterStateComponentResource.cs" id="7_m2ull"] +[ext_resource type="PackedScene" uid="uid://c576jiewfs5gj" path="res://Objects/player.tscn" id="8_0q1v5"] +[ext_resource type="Resource" uid="uid://tj3ojc3bl7d8" path="res://Resources/Weapons/basic_pistol.tres" id="8_l66rq"] +[ext_resource type="Script" uid="uid://bp7mufswr41w6" path="res://Code/Resources/WeaponComponentResource.cs" id="9_efscl"] +[ext_resource type="Script" uid="uid://coe688e2jkyjq" path="res://Code/Resources/EntityArchetype.cs" id="9_uue6s"] + +[sub_resource type="Resource" id="Resource_d0bjv"] +script = ExtResource("1_0drlr") +BaseValues = Dictionary[int, float]({ +0: 100.0, +1: 100.0, +3: 5.0, +4: 10.0, +5: 30.0, +6: 1.0 +}) +metadata/_custom_type_script = "uid://dc7wq2ij5kwj5" + +[sub_resource type="Resource" id="Resource_l855d"] +script = ExtResource("2_7o5r3") +metadata/_custom_type_script = "uid://y4cbuh2wxigy" + +[sub_resource type="Resource" id="Resource_00aki"] +script = ExtResource("3_l66rq") +metadata/_custom_type_script = "uid://p4vr80n70vkt" + +[sub_resource type="Resource" id="Resource_5qvjo"] +script = ExtResource("4_efscl") +metadata/_custom_type_script = "uid://df5wmj1jp2oy5" + +[sub_resource type="Resource" id="Resource_g7kif"] +script = ExtResource("5_55dod") +metadata/_custom_type_script = "uid://t4j1urlupxxv" + +[sub_resource type="Resource" id="Resource_xqdar"] +script = ExtResource("6_8u8a8") +metadata/_custom_type_script = "uid://blm62f85g7icn" + +[sub_resource type="Resource" id="Resource_xnm3i"] +script = ExtResource("7_m2ull") +metadata/_custom_type_script = "uid://cdpbn8eiypfbd" + +[sub_resource type="Resource" id="Resource_55dod"] +script = ExtResource("9_efscl") +WeaponData = ExtResource("8_l66rq") +metadata/_custom_type_script = "uid://bp7mufswr41w6" + +[resource] +script = ExtResource("9_uue6s") +Scene = ExtResource("8_0q1v5") +ComponentResources = Array[Resource]([SubResource("Resource_d0bjv"), SubResource("Resource_l855d"), SubResource("Resource_00aki"), SubResource("Resource_5qvjo"), SubResource("Resource_g7kif"), SubResource("Resource_xqdar"), SubResource("Resource_xnm3i"), SubResource("Resource_55dod")]) +metadata/_custom_type_script = "uid://coe688e2jkyjq" diff --git a/Resources/Weapons/basic_pistol.tres b/Resources/Weapons/basic_pistol.tres new file mode 100644 index 0000000..6f571a5 --- /dev/null +++ b/Resources/Weapons/basic_pistol.tres @@ -0,0 +1,24 @@ +[gd_resource type="Resource" script_class="WeaponResource" load_steps=6 format=3 uid="uid://tj3ojc3bl7d8"] + +[ext_resource type="Script" uid="uid://cht6trljihvle" path="res://Code/Resources/Effects/FireProjectileEffectResource.cs" id="1_p2b4p"] +[ext_resource type="Script" uid="uid://hf0iut8o8do3" path="res://Code/Resources/WeaponResource.cs" id="1_qn35l"] +[ext_resource type="Script" uid="uid://btv24gsw1p850" path="res://Code/Resources/Effects/DamageEffectResource.cs" id="2_yt3rn"] + +[sub_resource type="Resource" id="Resource_yt3rn"] +script = ExtResource("1_p2b4p") +ProjectileArchetypeId = "basic_bullet" +Count = 3 +SpreadAngle = 5.7 +ProjectileSpeed = 10.0 +metadata/_custom_type_script = "uid://cht6trljihvle" + +[sub_resource type="Resource" id="Resource_wqp4f"] +script = ExtResource("2_yt3rn") +metadata/_custom_type_script = "uid://btv24gsw1p850" + +[resource] +script = ExtResource("1_qn35l") +FireRate = 10.0 +OnFireEffects = Array[Object]([SubResource("Resource_yt3rn")]) +OnHitEffects = Array[Object]([SubResource("Resource_wqp4f")]) +metadata/_custom_type_script = "uid://hf0iut8o8do3" diff --git a/Resources/entity_database.tres b/Resources/entity_database.tres new file mode 100644 index 0000000..0e3c4bc --- /dev/null +++ b/Resources/entity_database.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="ArchetypeDatabase" load_steps=4 format=3 uid="uid://cr4nf1g4w3xye"] + +[ext_resource type="Script" uid="uid://coe688e2jkyjq" path="res://Code/Resources/EntityArchetype.cs" id="1_pa128"] +[ext_resource type="Script" uid="uid://df10ksb6f0pjt" path="res://Code/Resources/ArchetypeDatabase.cs" id="2_7tiqc"] +[ext_resource type="Resource" uid="uid://cfwsnjb2nob32" path="res://Resources/Entities/basic_bullet.tres" id="2_n2q8x"] + +[resource] +script = ExtResource("2_7tiqc") +Archetypes = Dictionary[String, ExtResource("1_pa128")]({ +"basic_bullet": ExtResource("2_n2q8x") +}) +metadata/_custom_type_script = "uid://df10ksb6f0pjt" diff --git a/Scenes/game_world.tscn b/Scenes/game_world.tscn new file mode 100644 index 0000000..0cd4c2b --- /dev/null +++ b/Scenes/game_world.tscn @@ -0,0 +1,215 @@ +[gd_scene load_steps=20 format=4 uid="uid://bkvgcsb8d3v7p"] + +[ext_resource type="Script" uid="uid://cfpm5p102f65x" path="res://Code/Presenters/GamePresenter.cs" id="1_qvgq0"] +[ext_resource type="Resource" uid="uid://biev6ri5s8kyf" path="res://Resources/Entities/player.tres" id="2_alii3"] +[ext_resource type="Resource" uid="uid://cr4nf1g4w3xye" path="res://Resources/entity_database.tres" id="2_hy2kt"] +[ext_resource type="Script" uid="uid://cb7vaw6xqjs1i" path="res://Code/Presenters/EntityPresenter.cs" id="5_d0bjv"] +[ext_resource type="Script" uid="uid://b6x8llipvutqs" path="res://Code/Presenters/SceneEntity.cs" id="5_f1ejf"] +[ext_resource type="Script" uid="uid://dc7wq2ij5kwj5" path="res://Code/Resources/AttributeComponentResource.cs" id="6_d0bjv"] +[ext_resource type="Script" uid="uid://uearpvfk21ym" path="res://Code/Resources/SimulationConfigResource.cs" id="11_xnm3i"] + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_ucfah"] +data = PackedVector3Array(-4.282257, -0.5, 4.977783, -4.282257, -0.5, -4.977783, -4.282257, 0.5, -4.977783, 4.282257, -0.5, -4.977783, -4.282257, -0.5, -4.977783, -4.282257, -0.5, 4.977783, -4.282257, 0.5, -4.977783, -4.282257, -0.5, -4.977783, 4.282257, -0.5, -4.977783, -4.282257, 0.5, -4.977783, -4.282257, 0.5, 4.977783, -4.282257, -0.5, 4.977783, -4.282257, -0.5, 4.977783, -4.282257, 0.5, 4.977783, 4.282257, 0.5, 4.977783, 4.282257, 0.5, 4.977783, -4.282257, 0.5, 4.977783, -4.282257, 0.5, -4.977783, -4.282257, -0.5, 4.977783, 4.282257, -0.5, 4.977783, 4.282257, -0.5, -4.977783, 4.282257, 0.5, 4.977783, 4.282257, -0.5, 4.977783, -4.282257, -0.5, 4.977783, 4.282257, -0.5, -4.977783, 4.282257, -0.5, 4.977783, 4.282257, 0.5, 4.977783, 4.282257, -0.5, -4.977783, 4.282257, 0.5, -4.977783, -4.282257, 0.5, -4.977783, -4.282257, 0.5, -4.977783, 4.282257, 0.5, -4.977783, 4.282257, 0.5, 4.977783, 4.282257, 0.5, 4.977783, 4.282257, 0.5, -4.977783, 4.282257, -0.5, -4.977783) + +[sub_resource type="ArrayMesh" id="ArrayMesh_ucfah"] +_surfaces = [{ +"aabb": AABB(-4.282257, -0.5, -4.977783, 8.564514, 1, 9.955566), +"attribute_data": PackedByteArray("AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/"), +"format": 34359738391, +"primitive": 3, +"uv_scale": Vector4(0, 0, 0, 0), +"vertex_count": 36, +"vertex_data": PackedByteArray("QAiJwAAAAL8ASp9AQAiJwAAAAL8ASp/AQAiJwAAAAD8ASp/AQAiJQAAAAL8ASp/AQAiJwAAAAL8ASp/AQAiJwAAAAL8ASp9AQAiJwAAAAD8ASp/AQAiJwAAAAL8ASp/AQAiJQAAAAL8ASp/AQAiJwAAAAD8ASp/AQAiJwAAAAD8ASp9AQAiJwAAAAL8ASp9AQAiJwAAAAL8ASp9AQAiJwAAAAD8ASp9AQAiJQAAAAD8ASp9AQAiJQAAAAD8ASp9AQAiJwAAAAD8ASp9AQAiJwAAAAD8ASp/AQAiJwAAAAL8ASp9AQAiJQAAAAL8ASp9AQAiJQAAAAL8ASp/AQAiJQAAAAD8ASp9AQAiJQAAAAL8ASp9AQAiJwAAAAL8ASp9AQAiJQAAAAL8ASp/AQAiJQAAAAL8ASp9AQAiJQAAAAD8ASp9AQAiJQAAAAL8ASp/AQAiJQAAAAD8ASp/AQAiJwAAAAD8ASp/AQAiJwAAAAD8ASp/AQAiJQAAAAD8ASp/AQAiJQAAAAD8ASp9AQAiJQAAAAD8ASp9AQAiJQAAAAD8ASp/AQAiJQAAAAL8ASp/AAAD/f/9//n8AAP9//3/+fwAA/3//f/5//38AAP//AAD/fwAA//8AAP9/AAD//wAA/////wAA/z//////AAD/P/////8AAP8/AAD/f/9//n8AAP9//3/+fwAA/3//f/5//3//fwAA/z//f/9/AAD/P/9//38AAP8//3//////AAD/f/////8AAP9//////wAA/38AAP//AAD/fwAA//8AAP9/AAD//wAA/3//fwAA/z//f/9/AAD/P/9//38AAP8/////f/9//n////9//3/+f////3//f/5//////wAA/z//////AAD/P/////8AAP8//3//////AAD/f/////8AAP9//////wAA////f/9//n////9//3/+f////3//f/5/") +}] + +[sub_resource type="SphereMesh" id="SphereMesh_27os8"] + +[sub_resource type="CylinderMesh" id="CylinderMesh_rr1si"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_qvgq0"] +sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1) +ground_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1) + +[sub_resource type="Sky" id="Sky_alii3"] +sky_material = SubResource("ProceduralSkyMaterial_qvgq0") + +[sub_resource type="Environment" id="Environment_hy2kt"] +background_mode = 2 +sky = SubResource("Sky_alii3") +tonemap_mode = 2 +glow_enabled = true + +[sub_resource type="Resource" id="Resource_f4pnd"] +script = ExtResource("11_xnm3i") +metadata/_custom_type_script = "uid://uearpvfk21ym" + +[sub_resource type="BoxShape3D" id="BoxShape3D_hy2kt"] + +[sub_resource type="BoxMesh" id="BoxMesh_p4c8d"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_f1ejf"] +albedo_color = Color(0.34509805, 1, 1, 1) + +[sub_resource type="Resource" id="Resource_27os8"] +script = ExtResource("6_d0bjv") +BaseValues = Dictionary[int, float]({ +0: 50.0, +1: 50.0 +}) +metadata/_custom_type_script = "uid://dc7wq2ij5kwj5" + +[node name="GameWorld" type="Node3D"] + +[node name="Geometry" type="Node" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23013306, 0, 0.34545898) +visible = false +size = Vector3(8.564514, 1, 9.955566) + +[node name="CSGBakedMeshInstance3D" type="StaticBody3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23013306, -1.5645537, 0.34545898) + +[node name="CSGBakedCollisionShape3D" type="CollisionShape3D" parent="Geometry/CSGBakedMeshInstance3D"] +shape = SubResource("ConcavePolygonShape3D_ucfah") + +[node name="CSGBakedMeshInstance3D2" type="MeshInstance3D" parent="Geometry/CSGBakedMeshInstance3D"] +mesh = SubResource("ArrayMesh_ucfah") +skeleton = NodePath("../../..") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.746681, 0, 0) +mesh = SubResource("SphereMesh_27os8") +skeleton = NodePath("../..") + +[node name="MeshInstance3D2" type="MeshInstance3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.746681, 0, 6.6297135) +mesh = SubResource("SphereMesh_27os8") +skeleton = NodePath("../..") + +[node name="MeshInstance3D3" type="MeshInstance3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.746681, 0, -4.5654445) +mesh = SubResource("SphereMesh_27os8") +skeleton = NodePath("../..") + +[node name="MeshInstance3D4" type="MeshInstance3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.4873514, 0, 0) +mesh = SubResource("CylinderMesh_rr1si") + +[node name="MeshInstance3D5" type="MeshInstance3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.4873514, 0, -3.6716075) +mesh = SubResource("CylinderMesh_rr1si") + +[node name="MeshInstance3D6" type="MeshInstance3D" parent="Geometry"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.4873514, 0, 2.8093686) +mesh = SubResource("CylinderMesh_rr1si") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_hy2kt") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.8660254, -0.43301278, 0.25, 0, 0.49999997, 0.86602545, -0.50000006, 0.75, -0.43301266, 0, 0, 0) +shadow_enabled = true + +[node name="GamePresenter" type="Node" parent="."] +script = ExtResource("1_qvgq0") +ArchetypesDatabase = ExtResource("2_hy2kt") +PlayerArchetype = ExtResource("2_alii3") +SimulationConfig = SubResource("Resource_f4pnd") +metadata/_custom_type_script = "uid://cfpm5p102f65x" + +[node name="Enemy" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.6186395, 0, -6.099209) +script = ExtResource("5_d0bjv") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Enemy"] +shape = SubResource("BoxShape3D_hy2kt") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Enemy"] +mesh = SubResource("BoxMesh_p4c8d") +surface_material_override/0 = SubResource("StandardMaterial3D_f1ejf") + +[node name="SceneEntity" type="Node" parent="Enemy" groups=["SceneEntities"]] +script = ExtResource("5_f1ejf") +ComponentResources = Array[Resource]([SubResource("Resource_27os8")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" + +[node name="Enemy2" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.8842628, 0, -6.099209) +script = ExtResource("5_d0bjv") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Enemy2"] +shape = SubResource("BoxShape3D_hy2kt") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Enemy2"] +mesh = SubResource("BoxMesh_p4c8d") +surface_material_override/0 = SubResource("StandardMaterial3D_f1ejf") + +[node name="SceneEntity" type="Node" parent="Enemy2" groups=["SceneEntities"]] +script = ExtResource("5_f1ejf") +ComponentResources = Array[Resource]([SubResource("Resource_27os8")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" + +[node name="Enemy3" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.4516838, 0, -6.099209) +script = ExtResource("5_d0bjv") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Enemy3"] +shape = SubResource("BoxShape3D_hy2kt") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Enemy3"] +mesh = SubResource("BoxMesh_p4c8d") +surface_material_override/0 = SubResource("StandardMaterial3D_f1ejf") + +[node name="SceneEntity" type="Node" parent="Enemy3" groups=["SceneEntities"]] +script = ExtResource("5_f1ejf") +ComponentResources = Array[Resource]([SubResource("Resource_27os8")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" + +[node name="Enemy4" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.3889283, 0, -6.099209) +script = ExtResource("5_d0bjv") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Enemy4"] +shape = SubResource("BoxShape3D_hy2kt") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Enemy4"] +mesh = SubResource("BoxMesh_p4c8d") +surface_material_override/0 = SubResource("StandardMaterial3D_f1ejf") + +[node name="SceneEntity" type="Node" parent="Enemy4" groups=["SceneEntities"]] +script = ExtResource("5_f1ejf") +ComponentResources = Array[Resource]([SubResource("Resource_27os8")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" + +[node name="Enemy5" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.068998575, 0, -6.099209) +script = ExtResource("5_d0bjv") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Enemy5"] +shape = SubResource("BoxShape3D_hy2kt") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Enemy5"] +mesh = SubResource("BoxMesh_p4c8d") +surface_material_override/0 = SubResource("StandardMaterial3D_f1ejf") + +[node name="SceneEntity" type="Node" parent="Enemy5" groups=["SceneEntities"]] +script = ExtResource("5_f1ejf") +ComponentResources = Array[Resource]([SubResource("Resource_27os8")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" + +[node name="Enemy6" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.1687164, 0, -6.099209) +script = ExtResource("5_d0bjv") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Enemy6"] +shape = SubResource("BoxShape3D_hy2kt") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Enemy6"] +mesh = SubResource("BoxMesh_p4c8d") +surface_material_override/0 = SubResource("StandardMaterial3D_f1ejf") + +[node name="SceneEntity" type="Node" parent="Enemy6" groups=["SceneEntities"]] +script = ExtResource("5_f1ejf") +ComponentResources = Array[Resource]([SubResource("Resource_27os8")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" diff --git a/cryptonym-thunder.csproj b/cryptonym-thunder.csproj new file mode 100644 index 0000000..3305f4a --- /dev/null +++ b/cryptonym-thunder.csproj @@ -0,0 +1,13 @@ + + + net8.0 + net9.0 + true + cryptonymthunder + + + + ..\BrickFramework\GameCore\bin\Debug\net8.0\GameCore.dll + + + \ No newline at end of file diff --git a/cryptonym-thunder.sln b/cryptonym-thunder.sln new file mode 100644 index 0000000..385f7a6 --- /dev/null +++ b/cryptonym-thunder.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cryptonym-thunder", "cryptonym-thunder.csproj", "{FA84E88F-33AD-4744-BE22-A61FBD7395EA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + ExportDebug|Any CPU = ExportDebug|Any CPU + ExportRelease|Any CPU = ExportRelease|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FA84E88F-33AD-4744-BE22-A61FBD7395EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA84E88F-33AD-4744-BE22-A61FBD7395EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA84E88F-33AD-4744-BE22-A61FBD7395EA}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {FA84E88F-33AD-4744-BE22-A61FBD7395EA}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {FA84E88F-33AD-4744-BE22-A61FBD7395EA}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {FA84E88F-33AD-4744-BE22-A61FBD7395EA}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + EndGlobalSection +EndGlobal diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..a2fdb44 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnihftpgobl1c" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..a3bd286 --- /dev/null +++ b/project.godot @@ -0,0 +1,79 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="cryptonym-thunder" +run/main_scene="uid://bkvgcsb8d3v7p" +config/features=PackedStringArray("4.5", "C#", "Forward Plus") +config/icon="res://icon.svg" + +[autoload] + +PresenterRegistry="*res://Code/Autoloads/PresenterRegistry.cs" + +[dotnet] + +project/assembly_name="cryptonym-thunder" + +[file_customization] + +folder_colors={ +"res://Code/": "blue", +"res://Objects/": "orange", +"res://Scenes/": "green" +} + +[global_group] + +SceneEntities="" + +[input] + +left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +forward={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +backward={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +debug_damage={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +] +} +interact={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) +] +} +fire={ +"deadzone": 0.2, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(584, 16),"global_position":Vector2(593, 64),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +}