Compare commits

...

21 Commits

Author SHA1 Message Date
bb21920488 changed runsettings and workflow to always publish test reports
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 32s
Create tag and build when new code gets to main / Export (push) Successful in 9m31s
Create tag and build when new code gets to main / OtherTest (push) Failing after 11m57s
2026-04-26 12:24:51 +02:00
cd2b41b443 fix ci
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 28s
Create tag and build when new code gets to main / Export (push) Successful in 8m58s
Create tag and build when new code gets to main / OtherTest (push) Failing after 11m43s
2026-04-26 11:52:14 +02:00
d025618eb3 retrying new CI
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 29s
Create tag and build when new code gets to main / OtherTest (push) Failing after 1m47s
Create tag and build when new code gets to main / Export (push) Successful in 5m54s
2026-04-26 11:35:45 +02:00
26f6a619cb dependency injection test
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 28s
Create tag and build when new code gets to main / Export (push) Successful in 6m50s
2026-04-25 10:18:41 +02:00
ce48f3b9d7 fixed indent issue
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 1m21s
Create tag and build when new code gets to main / OtherTest (push) Failing after 1m32s
Create tag and build when new code gets to main / Export (push) Successful in 6m53s
Create tag and build when new code gets to main / Test (push) Failing after 8m42s
2026-04-24 19:07:20 +02:00
54796252ce retrying to CI tests
Some checks failed
Create tag and build when new code gets to main / Export (push) Has been cancelled
Create tag and build when new code gets to main / BumpTag (push) Has been cancelled
2026-04-24 19:06:31 +02:00
054115aa89 trying out autoinject on the CI
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 5m46s
2026-04-24 18:48:10 +02:00
f5e47e9f5e minor fixes
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 8m50s
2026-04-22 09:47:15 +02:00
99ed6375a2 fix: enemies dying from falling would remove the weapon from the world. Thrown weapon now respawn like the player. 2026-04-22 08:43:58 +02:00
6888499b78 ground slam damage depends on height
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 7m2s
2026-04-21 18:47:58 +02:00
2a98137653 main scene back to main menu
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 28s
Create tag and build when new code gets to main / Export (push) Successful in 6m6s
2026-04-21 11:40:05 +02:00
b0fe2549ea Inventory management of granted abilities 2026-04-21 11:38:04 +02:00
667d6b2588 Starting an inventory manager 2026-04-20 11:41:22 +02:00
f9ca56e34a removed jump dash bug issue hand set back main scene to opening
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 25s
Create tag and build when new code gets to main / ReleaseName (push) Successful in 6s
Create tag and build when new code gets to main / Export (push) Successful in 7m10s
Create tag and build when new code gets to main / Release (push) Successful in 15m55s
2026-04-19 13:16:13 +02:00
5a59d50be5 Made a menu to select abilities and grant them (with a few hardcoded stuff)
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 26s
Create tag and build when new code gets to main / Export (push) Successful in 6m13s
2026-04-19 11:37:55 +02:00
9464fc7caa removed editor granted weapon abilities and prepared granting abilites through an inventory 2026-04-18 15:44:59 +02:00
9e57641a75 removend empower actions counter and references to previous tutorial 2026-04-18 09:41:38 +02:00
bb2b2ace06 cleanup and changed empowered action cost 2026-04-18 09:28:21 +02:00
585c2302d6 actually calling update effects
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 30s
Create tag and build when new code gets to main / Export (push) Successful in 6m46s
2026-04-14 19:29:43 +02:00
7ab78aa57f putting back Tool 2026-04-13 17:22:26 +02:00
4d10f4e9d7 some few fixes that don't fix anything 2026-04-13 16:34:23 +02:00
62 changed files with 1030 additions and 483 deletions

View File

@@ -38,22 +38,30 @@ jobs:
PRERELEASE: false
INITIAL_VERSION: 0.1.0
DEFAULT_BUMP: patch
# Test:
# runs-on: godot
## env:
## RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
# env:
# RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
# steps:
# - name: Checkout with LFS
# uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
#
#
# - name: Setup Godot
# id: setup-godot
# uses: https://git.game-dev.space/minimata/setup-godot.git@main
# with:
# godot-version: ${GODOT_VERSION}
# dotnet-version: ${DOTNET_VERSION}
#
#
# - name: 🔬 Verify Setup
# run: |
# dotnet --version
# ${{ steps.setup-godot.outputs.godot_bin }} --version
#
# - name: 🧑‍🔬 Generate .NET Bindings
# run: ${{ steps.setup-godot.outputs.godot_bin }} --headless --build-solutions --quit || exit 0
#
# - name: Run C# Tests
# env:
# GODOT_BIN: ${{ steps.setup-godot.outputs.godot_bin }}
@@ -61,25 +69,81 @@ jobs:
# run: |
# dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--verbose --headless --import"
#
## - name: Run tests
## uses: godot-gdunit-labs/gdUnit4-action@v1
## with:
## godot-version: ${GODOT_VERSION}
## godot-net: true
## godot-force-mono: true
## dotnet-version: ${DOTNET_VERSION}
## paths: |
## res://tests/
## publish-report: false
## upload-report: false
## console-verbosity: 'normal'
## arguments: "--verbose --headless --import"
# # - name: Run tests
# # uses: godot-gdunit-labs/gdUnit4-action@v1
# # with:
# # godot-version: ${GODOT_VERSION}
# # godot-net: true
# # godot-force-mono: true
# # dotnet-version: ${DOTNET_VERSION}
# # paths: |
# # res://tests/
# # publish-report: false
# # upload-report: false
# # console-verbosity: 'normal'
# # arguments: "--verbose --headless --import"
#
# - name: Upload test report
# uses: actions/upload-artifact@v3-node20
# with:
# name: Test Report
# path: ${{ github.workspace }}/reports/test-result.html
#
OtherTest:
runs-on: godot
env:
RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
steps:
- name: Checkout with LFS
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
- uses: actions/setup-dotnet@v5
name: 💽 Setup .NET SDK
with:
dotnet-version: '9.0.x'
- name: 📦 Restore Dependencies
run: |
dotnet --version
dotnet restore
dotnet build
dotnet list package
- uses: chickensoft-games/setup-godot@v2
name: 🤖 Setup Godot
with:
# Version must include major, minor, and patch, and be >= 4.0.0
# Pre-release label is optional.
version: '4.6.2'
# Use .NET-enabled version of Godot (the default is also true).
use-dotnet: true
# Include the Godot Export Templates (the default is false).
include-templates: true
- name: 🔬 Verify Setup
run: |
dotnet --version
godot --version
- name: 🧑‍🔬 Generate .NET Bindings
run: godot --headless --build-solutions --import --quit || exit 0
- name: 🦺 Build Projects
run: dotnet build --configuration ExportRelease
- name: Run C# Tests
env:
GODOT_BIN: godot
shell: bash
run: |
dotnet test --no-build --settings .runsettings --results-directory ./reports --logger "console;verbosity=normal" --logger "trx;LogFileName=results.xml" -- GdUnit4.Parameters="--headless --import --quit"
- name: Upload test report
uses: actions/upload-artifact@v3-node20
if: always()
with:
name: Test Report
path: ${{ github.workspace }}/reports/test-result.html
Export:
runs-on: godot

1
.gitignore vendored
View File

@@ -11,6 +11,7 @@
/builds
/communication
/reports
# Imported translations (automatically generated from CSV files)
*.translation

View File

@@ -4,7 +4,7 @@
<MaxCpuCount>1</MaxCpuCount>
<ResultsDirectory>./TestResults</ResultsDirectory>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TestSessionTimeout>180000</TestSessionTimeout>
<TestSessionTimeout>60000</TestSessionTimeout>
<TreatNoTestsAsError>true</TreatNoTestsAsError>
</RunConfiguration>

View File

@@ -3,6 +3,8 @@
<TargetFramework>net9.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>Movementtests</RootNamespace>
<!-- Catch compiler-mismatch issues with the Introspection generator -->
<WarningsAsErrors>CS9057</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Content Include=".runsettings" />
@@ -131,6 +133,13 @@
<ItemGroup>
<PackageReference Include="RustyOptions" Version="0.10.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="3.0.12" />
<PackageReference Include="Chickensoft.Introspection" Version="3.0.2" />
<PackageReference Include="Chickensoft.Introspection.Generator" Version="3.0.2" PrivateAssets="all" OutputItemType="analyzer" />
<PackageReference Include="Chickensoft.AutoInject" Version="2.12.8" PrivateAssets="all" />
<PackageReference Include="Chickensoft.AutoInject.Analyzers" Version="2.12.8" PrivateAssets="all" OutputItemType="analyzer" />
</ItemGroup>
<Import Project="addons/forge/Forge.props" />
<!-- gdUnit4 package dependencies -->

View File

@@ -13,22 +13,28 @@ public partial class CueHandlerInspectorPlugin : EditorInspectorPlugin
public override bool _CanHandle(GodotObject @object)
{
// Find out if its an implementation of CueHandler without having to add [Tool] attribute to them.
if (@object?.GetScript().As<CSharpScript>() is CSharpScript script)
try
{
StringName className = script.GetGlobalName();
Type baseType = typeof(ForgeCueHandler);
System.Reflection.Assembly assembly = baseType.Assembly;
Type? implementationType =
Array.Find(assembly.GetTypes(), x =>
x.Name == className &&
baseType.IsAssignableFrom(x));
return implementationType is not null;
if (@object?.GetScript().As<CSharpScript>() is null)
return false;
}
catch (Exception e)
{
return false;
}
return false;
var script = @object?.GetScript().As<CSharpScript>();
StringName className = script.GetGlobalName();
Type baseType = typeof(ForgeCueHandler);
System.Reflection.Assembly assembly = baseType.Assembly;
Type? implementationType =
Array.Find(assembly.GetTypes(), x =>
x.Name == className &&
baseType.IsAssignableFrom(x));
return implementationType is not null;
}
public override bool _ParseProperty(

View File

@@ -18,7 +18,7 @@ namespace Gamesmiths.Forge.Godot.Nodes;
public partial class ForgeEntity : Node, IForgeEntity
{
[Export]
public ForgeTagContainer BaseTags { get; set; } = new();
public ForgeTagContainer BaseTags { get; set; }
[Export]
public ForgeSharedVariableSet? SharedVariableDefinitions { get; set; }

View File

@@ -10,5 +10,9 @@ namespace Gamesmiths.Forge.Godot.Resources.Abilities;
[Icon("uid://bcx7anhepqfmd")]
public abstract partial class ForgeAbilityBehavior : Resource
{
[Export] public string? Name { get; set; }
[Export] public string? Description { get; set; }
[Export] public Texture2D? Icon { get; set; }
public abstract IAbilityBehavior GetBehavior();
}

View File

@@ -41,8 +41,8 @@ func _input(event : InputEvent) -> void:
if event.is_action_released("ui_cancel"):
if sub_menu:
_close_sub_menu()
else:
get_tree().quit()
# else:
# get_tree().quit()
if event.is_action_released("ui_accept") and get_viewport().gui_get_focus_owner() == null:
%MenuButtonsBoxContainer.focus_first()

View File

@@ -2,5 +2,4 @@
[node name="BackgroundMusicPlayer" type="AudioStreamPlayer" unique_id=676077136]
process_mode = 3
autoplay = true
bus = &"Music"

View File

@@ -24,6 +24,8 @@ var _initial_focus_control
var _scene_tree : SceneTree
func _exit_tree() -> void:
if Engine.is_editor_hint(): return
GUIDE.disable_mapping_context(menu_context)
for previous_context in previous_mapping_contexts:
GUIDE.enable_mapping_context(previous_context)

0
docs/.gdignore Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

View File

@@ -10,17 +10,17 @@ namespace Movementtests.forge.abilities;
public class EffectApplicationBehavior(EffectData effectData) : IAbilityBehavior
{
private Effect? _effect;
private ActiveEffectHandle? _effectHandle;
public void OnStarted(AbilityBehaviorContext context)
{
GD.Print("This is applying the periodic effect to the flying weapon");
_effectHandle = context.Owner.EffectsManager.ApplyEffect(new Effect(effectData, new EffectOwnership(context.Owner, context.Owner)));
{
_effect = new Effect(effectData, new EffectOwnership(context.Owner, context.Owner));
_effectHandle = context.Owner.EffectsManager.ApplyEffect(_effect);
context.AbilityHandle.CommitAbility();
}
public void OnEnded(AbilityBehaviorContext context)
{
GD.Print("This is removing the periodic effect from the flying weapon");
if (_effectHandle is not null)
context.Owner.EffectsManager.RemoveEffect(_effectHandle);
context.InstanceHandle.End();

View File

@@ -6,7 +6,7 @@ using Godot;
namespace Movementtests.forge.abilities;
public class ExplodingSwordBehavior(PackedScene explosion) : IAbilityBehavior
public class ExplodingSwordBehavior(PackedScene explosion, float radius) : IAbilityBehavior
{
public void OnStarted(AbilityBehaviorContext context)
{
@@ -16,7 +16,7 @@ public class ExplodingSwordBehavior(PackedScene explosion) : IAbilityBehavior
return;
}
if (explosion.Instantiate() is not Explosion explosion1)
if (explosion.Instantiate() is not Explosion explo)
{
GD.Print("Cannot instantiate");
context.InstanceHandle.End();
@@ -28,13 +28,10 @@ public class ExplodingSwordBehavior(PackedScene explosion) : IAbilityBehavior
context.InstanceHandle.End();
return;
}
GD.Print("EXPLOSION");
explosion1.Radius = 6f;
explo.Radius = radius;
owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explosion1);
explosion1.CallDeferred(Node3D.MethodName.SetGlobalPosition, owner.GlobalPosition);
owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explo);
explo.CallDeferred(Node3D.MethodName.SetGlobalPosition, owner.GlobalPosition);
context.AbilityHandle.CommitAbility();
context.InstanceHandle.End();
@@ -49,11 +46,10 @@ public class ExplodingSwordBehavior(PackedScene explosion) : IAbilityBehavior
[GlobalClass]
public partial class ForgeExplodingSwordBehavior : ForgeAbilityBehavior
{
[Export] public PackedScene? Explosion { get; set; }
[Export] public PackedScene Explosion { get; set; }
[Export] public float Radius { get; set; } = 5f;
public override IAbilityBehavior GetBehavior()
{
if (Explosion == null)
throw new System.ArgumentException("Explosion is null");
return new ExplodingSwordBehavior(Explosion);
return new ExplodingSwordBehavior(Explosion, Radius);
}
}

View File

@@ -20,15 +20,8 @@ public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
{
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
{
GD.Print("Custom execution executed");
var owner = effect.Ownership.Owner;
if (owner == null) return [];
GD.Print(eventTags.Tags.Count);
foreach (var tag in eventTags.Tags)
{
GD.Print(tag);
}
owner.Events.Raise(new EventData
{
@@ -42,10 +35,11 @@ public class RaiseEventTagExecution(TagContainer eventTags) : CustomExecution
}
[Tool]
[GlobalClass]
public partial class ForgeRaiseEventTagExecution : ForgeCustomExecution
{
[Export] ForgeTagContainer EventTags { get; set; } = new();
[Export] ForgeTagContainer EventTags { get; set; }
public override CustomExecution GetExecutionClass()
{

View File

@@ -39,6 +39,7 @@
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://inputs/base_mode/move_front.tres" id="34_rvpjj"]
[ext_resource type="Resource" uid="uid://ca68r7n3bwba3" path="res://inputs/base_mode/toolbox.tres" id="34_s8kjn"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://inputs/base_mode/move_left.tres" id="35_s8kjn"]
[ext_resource type="Resource" uid="uid://7ne5mdytlidm" path="res://inputs/base_mode/inventory.tres" id="36_4uwbh"]
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="36_vibkn"]
[sub_resource type="Resource" id="Resource_vkvga"]
@@ -487,16 +488,16 @@ action = ExtResource("29_q86qg")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_ai85f"), SubResource("Resource_1ycft")])
metadata/_guide_input_mappings_collapsed = false
[sub_resource type="Resource" id="Resource_8e1uk"]
[sub_resource type="Resource" id="Resource_qd4lk"]
script = ExtResource("19_qkgmj")
button = 4
button = 11
[sub_resource type="Resource" id="Resource_k8i2y"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_ilhhf"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_8e1uk")
input = SubResource("Resource_qd4lk")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_k8i2y")])
[sub_resource type="Resource" id="Resource_qrtf1"]
@@ -516,6 +517,35 @@ script = ExtResource("1_qmhk6")
action = ExtResource("34_s8kjn")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_ilhhf"), SubResource("Resource_4uwbh")])
[sub_resource type="Resource" id="Resource_g1qol"]
script = ExtResource("19_qkgmj")
button = 4
[sub_resource type="Resource" id="Resource_xmmrk"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_oq22i"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_g1qol")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_xmmrk")])
[sub_resource type="Resource" id="Resource_krlhw"]
script = ExtResource("30_cvxqo")
key = 4194306
[sub_resource type="Resource" id="Resource_gpvxe"]
script = ExtResource("15_fykw6")
[sub_resource type="Resource" id="Resource_0nktr"]
script = ExtResource("3_yp12v")
input = SubResource("Resource_krlhw")
triggers = Array[ExtResource("8_2tfaw")]([SubResource("Resource_gpvxe")])
[sub_resource type="Resource" id="Resource_u35df"]
script = ExtResource("1_qmhk6")
action = ExtResource("36_4uwbh")
input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_oq22i"), SubResource("Resource_0nktr")])
[sub_resource type="Resource" id="Resource_kcylj"]
script = ExtResource("30_cvxqo")
key = 83
@@ -570,5 +600,5 @@ input_mappings = Array[ExtResource("3_yp12v")]([SubResource("Resource_7io5e")])
[resource]
script = ExtResource("23_llfhp")
mappings = Array[ExtResource("1_qmhk6")]([SubResource("Resource_88x08"), SubResource("Resource_tgr2g"), SubResource("Resource_iarn8"), SubResource("Resource_cvxqo"), SubResource("Resource_tb8ii"), SubResource("Resource_iihs4"), SubResource("Resource_vibkn"), SubResource("Resource_2hs2y"), SubResource("Resource_d2r0d"), SubResource("Resource_xt1x5"), SubResource("Resource_ew1hw"), SubResource("Resource_3frwi"), SubResource("Resource_0qat1"), SubResource("Resource_vtk18"), SubResource("Resource_weyro"), SubResource("Resource_o5fur"), SubResource("Resource_fjku4"), SubResource("Resource_odnhd"), SubResource("Resource_0eff7"), SubResource("Resource_gt77e")])
mappings = Array[ExtResource("1_qmhk6")]([SubResource("Resource_88x08"), SubResource("Resource_tgr2g"), SubResource("Resource_iarn8"), SubResource("Resource_cvxqo"), SubResource("Resource_tb8ii"), SubResource("Resource_iihs4"), SubResource("Resource_vibkn"), SubResource("Resource_2hs2y"), SubResource("Resource_d2r0d"), SubResource("Resource_xt1x5"), SubResource("Resource_ew1hw"), SubResource("Resource_3frwi"), SubResource("Resource_0qat1"), SubResource("Resource_vtk18"), SubResource("Resource_weyro"), SubResource("Resource_o5fur"), SubResource("Resource_u35df"), SubResource("Resource_fjku4"), SubResource("Resource_odnhd"), SubResource("Resource_0eff7"), SubResource("Resource_gt77e")])
metadata/_custom_type_script = "uid://dsa1dnifd6w32"

View File

@@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="GUIDEAction" format=3 uid="uid://7ne5mdytlidm"]
[ext_resource type="Script" uid="uid://cluhc11vixkf1" path="res://addons/guide/guide_action.gd" id="1_48ulw"]
[resource]
script = ExtResource("1_48ulw")
metadata/_custom_type_script = "uid://cluhc11vixkf1"

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
using Movementtests.systems;
namespace Movementtests.managers;
public partial class WeaponEventAbilityData(WeaponSystem.WeaponEvent forEvent, Resource ability)
: RefCounted
{
public WeaponSystem.WeaponEvent ForEvent { get; private set; } = forEvent;
public Resource Ability { get; private set; } = ability;
}
public partial class InventoryManager : Node
{
[Signal]
public delegate void InventoryChangedEventHandler();
[Signal]
public delegate void WeaponEventInventoryChangedEventHandler();
[Signal]
public delegate void WeaponEventAbilityAddedEventHandler(WeaponEventAbilityData data);
[Signal]
public delegate void WeaponEventAbilityRemovedEventHandler(WeaponEventAbilityData data);
public Dictionary<WeaponSystem.WeaponEvent, HashSet<Resource>> WeaponEventsInventory { get; } = [];
public override void _Ready()
{
WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying] = new HashSet<Resource>();
WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying] = new HashSet<Resource>();
}
public void AddAbilityForWeaponEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
var inventoryForEvent = WeaponEventsInventory[forEvent];
var addedAbilityToInventory = inventoryForEvent.Add(abilityBehavior);
if (!addedAbilityToInventory) return;
EmitSignalWeaponEventInventoryChanged();
EmitSignalWeaponEventAbilityAdded(new WeaponEventAbilityData(forEvent, abilityBehavior));
}
public void RemoveAbilityForWeaponEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
var inventoryForEvent = WeaponEventsInventory[forEvent];
var removedFromInventory = inventoryForEvent.Remove(abilityBehavior);
if (!removedFromInventory) return;
EmitSignalWeaponEventInventoryChanged();
EmitSignalWeaponEventAbilityRemoved(new WeaponEventAbilityData(forEvent, abilityBehavior));
}
}

View File

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

View File

@@ -0,0 +1,88 @@
using Godot;
using System;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Movementtests.interfaces;using Movementtests.managers;
using Movementtests.systems;
[Meta(
typeof(IAutoOn),
typeof(IAutoConnect),
typeof(IProvider)
)]
public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>
{
public override void _Notification(int what) => this.Notify(what);
[Node("PlayerFellRespawn")] private Marker3D? PlayerRespawnMarker { get; set; }
private AnimationPlayer? _animationPlayer;
private Node3D? _respawnabble;
private Area3D? _playerFellPlane;
private Area3D? _deathPlane;
public required InventoryManager InventoryManager { get; set; }
InventoryManager IProvide<InventoryManager>.Value() => InventoryManager;
public void OnReady()
{
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
_playerFellPlane = GetNode<Area3D>("PlayerFellTP");
_deathPlane = GetNode<Area3D>("DeathPlane");
if (PlayerRespawnMarker == null) throw new Exception("Player respawn marker is null");
if (_animationPlayer == null) throw new Exception("Animation player is null");
if (_playerFellPlane == null) throw new Exception("Player reset plane is null");
if (_deathPlane == null) throw new Exception("Enemy death plane is null");
_playerFellPlane.BodyEntered += StartResetPlayerAnimation;
_deathPlane.BodyEntered += KillEnemy;
InventoryManager = new InventoryManager();
AddChild(InventoryManager);
this.Provide();
}
public void OnProvided()
{
// You can optionally implement this method. It gets called once you call
// this.Provide() to inform AutoInject that the provided values are now
// available.
}
public void ResetPlayerPosition()
{
if (_respawnabble == null || PlayerRespawnMarker == null) throw new Exception("Player or respawn marker is null");
_respawnabble.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
}
public void StartResetPlayerAnimation(Node3D body)
{
if (body is WeaponSystem weapon)
{
if (PlayerRespawnMarker == null) throw new Exception("Respawn marker is null");
weapon.GlobalPosition = PlayerRespawnMarker.GlobalPosition;
weapon.SetLinearVelocity(Vector3.Down);
return;
}
_respawnabble = body as PlayerController;
if (_respawnabble == null || _animationPlayer == null) throw new Exception("Player or anim player is null");
_animationPlayer.Play("player_fell");
}
public void KillEnemy(Node3D body)
{
if (body is not IKillable killable)
{
body.QueueFree();
return;
}
if (killable is not IHealthable healthable)
{
body.QueueFree();
return;
}
killable.Kill(healthable);
}
}

View File

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

View File

@@ -1,21 +0,0 @@
extends Node3D
@onready var player_fell_respawn: Marker3D = $PlayerFellRespawn
@onready var animation_player: AnimationPlayer = $AnimationPlayer
var _player: Node3D
func _on_player_fell_tp_body_entered(body: Node3D) -> void:
_player = body
animation_player.play("player_fell")
func reset_player_position() -> void:
if _player == null:
return
_player.position = player_fell_respawn.position
func _on_death_plane_body_entered(body: Node3D) -> void:
body.queue_free()

View File

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

View File

@@ -1,6 +1,6 @@
[gd_scene format=3 uid="uid://55wehh6xombr"]
[ext_resource type="Script" uid="uid://beof168aw2acj" path="res://maps/_templates/main_scene_template.gd" id="1_5g5a0"]
[ext_resource type="Script" uid="uid://br0f18u1iou2d" path="res://maps/_templates/MainSceneTemplate.cs" id="1_5g5a0"]
[ext_resource type="PackedScene" uid="uid://bkcsjsk2ciff" path="res://addons/maaacks_game_template/base/scenes/music_players/background_music_player.tscn" id="2_roiv2"]
[ext_resource type="AudioStream" uid="uid://f8cvr5s041ej" path="res://assets/audio/ambiance/637083__nox_sound__ambiance_nature_night_cricket_calm_loop_stereo.wav" id="3_boadi"]
[ext_resource type="Script" uid="uid://cupqhe3qv7ero" path="res://tools/general_manager.gd" id="3_k6got"]
@@ -237,7 +237,7 @@ tracks/6/keys = {
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"reset_player_position"
"method": &"ResetPlayerPosition"
}]
}
@@ -257,6 +257,9 @@ script = ExtResource("1_5g5a0")
[node name="GuideDebugger" parent="DebugLayer" unique_id=636020765 instance=ExtResource("10_gm8ij")]
visible = false
[node name="InventoryLayer" type="CanvasLayer" parent="." unique_id=406590925]
layer = 10
[node name="BackgroundMusicPlayer" parent="." unique_id=879496303 instance=ExtResource("2_roiv2")]
stream = ExtResource("3_boadi")
@@ -285,7 +288,6 @@ libraries/ = SubResource("AnimationLibrary_nyvgt")
[node name="Player" parent="." unique_id=1309399929 instance=ExtResource("17_clkha")]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
TutorialDone = true
AccelerationAir = 1.5
[node name="ShaderComp-Explosion" parent="Player" unique_id=1876014452 instance=ExtResource("9_r1bdn")]
@@ -298,6 +300,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 300, 0)
[node name="PlayerFellTP" type="Area3D" parent="." unique_id=1277888169]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -200, 0)
collision_layer = 0
collision_mask = 65537
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerFellTP" unique_id=1866249040]

View File

@@ -41,7 +41,7 @@ size = Vector3(6.75, 8.25, 7.25)
[node name="Main" unique_id=955321579 instance=ExtResource("1_jyq54")]
[node name="DirectionalLight3D" parent="." index="5" unique_id=1357990191]
[node name="DirectionalLight3D" parent="." index="6" unique_id=1357990191]
transform = Transform3D(-0.1772511, 0.44628847, 0.87715954, 0.49540228, -0.72966087, 0.4713508, 0.85038733, 0.51809436, -0.09175911, 0, 0, 0)
[node name="Greybox" type="CSGCombiner3D" parent="." index="7" unique_id=2082385716]
@@ -907,9 +907,9 @@ light_energy = 8.571
omni_range = 7.0
[node name="OmniLight3D29" type="OmniLight3D" parent="Lights" index="24" unique_id=2143811783]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37, 25.5, -16.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37, 16.75, -18.75)
light_energy = 4.004
omni_range = 7.0
omni_range = 9.25
[node name="OmniLight3D20" type="OmniLight3D" parent="Lights" index="25" unique_id=1665621589]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -37, 24.5, -35.25)
@@ -934,14 +934,19 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -33.5, 24.5, -47)
light_energy = 2.725
omni_range = 10.0
[node name="OmniLight3D25" type="OmniLight3D" parent="Lights" index="30" unique_id=727558952]
[node name="OmniLight3D34" type="OmniLight3D" parent="Lights" index="30" unique_id=2065211844]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -36.25, 13.75, -45.5)
light_energy = 2.725
omni_range = 10.0
[node name="OmniLight3D25" type="OmniLight3D" parent="Lights" index="31" unique_id=727558952]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -28, 24.5, -51)
[node name="OmniLight3D26" type="OmniLight3D" parent="Lights" index="31" unique_id=1646376304]
[node name="OmniLight3D26" type="OmniLight3D" parent="Lights" index="32" unique_id=1646376304]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -20, 24.5, -51.5)
omni_range = 7.0
[node name="OmniLight3D27" type="OmniLight3D" parent="Lights" index="32" unique_id=1849438050]
[node name="OmniLight3D27" type="OmniLight3D" parent="Lights" index="33" unique_id=1849438050]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -20, 24.5, -51.5)
omni_range = 4.5
@@ -1047,10 +1052,10 @@ tuto_text = "Select next level when ready"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.875, 1.125, -4.625)
shape = SubResource("BoxShape3D_7hd1j")
[node name="Player" parent="." index="11" unique_id=1309399929]
[node name="Player" parent="." index="12" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -0.5, 0.4102497, 0.5415039)
HasSword = false
HasParry = false
[node name="PlayerFellRespawn" parent="." index="12" unique_id=479136076]
[node name="PlayerFellRespawn" parent="." index="13" unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.25, -1.25)

View File

@@ -343,7 +343,7 @@ transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -7.25, 20.5, -27.5)
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1.3647223, 23.75, -13.75)
[node name="Enemy28" parent="Tutorial" index="2" unique_id=1765389924 node_paths=PackedStringArray("Target") instance=ExtResource("7_egib5")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -5, 22, 16.5)
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -5, 22, 15.5)
Target = NodePath("../../Player")
RHealth = SubResource("Resource_invhv")
RDamage = SubResource("Resource_cgfmf")
@@ -520,15 +520,15 @@ size = Vector3(1, 1, 4.75)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D137" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="10" unique_id=1930091014]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 58)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 22.5, 57.5)
use_collision = true
size = Vector3(1, 1, 11)
size = Vector3(1, 1, 12)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D138" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="11" unique_id=1299444131]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 58)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 22.5, 57.5)
use_collision = true
size = Vector3(1, 1, 11)
size = Vector3(1, 1, 12)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D139" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="12" unique_id=1708119368]
@@ -628,9 +628,9 @@ size = Vector3(9.5, 5, 11.75)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D133" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="28" unique_id=672467040]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 58)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 21.487345, 57.5)
use_collision = true
size = Vector3(5, 1, 11)
size = Vector3(5, 1, 12)
material = ExtResource("3_4m8g1")
[node name="CSGBox3D141" type="CSGBox3D" parent="Tutorial/DashWithMantle" index="29" unique_id=1207463075]
@@ -765,10 +765,10 @@ use_collision = true
size = Vector3(2, 3.25, 1)
material = ExtResource("3_4m8g1")
[node name="Player" parent="." index="9" unique_id=1309399929]
[node name="Player" parent="." index="10" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, -0.5, 0, 0)
[node name="PlayerFellRespawn" parent="." index="10" unique_id=479136076]
[node name="PlayerFellRespawn" parent="." index="11" unique_id=479136076]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1.5, 0)
[node name="OmniLight3D" type="OmniLight3D" parent="." index="13" unique_id=702421172]

View File

@@ -112,5 +112,5 @@ tuto_text = "Try to survive!"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.625, -1.875)
shape = SubResource("BoxShape3D_lthgu")
[node name="Player" parent="." index="15" unique_id=1309399929]
[node name="Player" parent="." index="16" unique_id=1309399929]
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 3, 0, 0)

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
using Movementtests.systems;
[Tool, GlobalClass]
public partial class AbilitySelection : Control
{
[Signal] public delegate void AbilityAddedEventHandler(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior behavior);
[Signal] public delegate void AbilityRemovedEventHandler(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior behavior);
[Export] public WeaponSystem.WeaponEvent ForEvent { get; set; } = WeaponSystem.WeaponEvent.StartedFlying;
[Export] public string Title { get; set; } = string.Empty;
[Export] public PackedScene AbilitySelectedItem { get; set; }
[Export] public ForgeAbilityBehavior[] AbilityBehaviors { get; set; }
private VBoxContainer _selectedAbilities;
private MenuButton _addAbility;
private PopupMenu _addAbilityMenu;
public override void _Ready()
{
var titleLabel = GetNode<Label>("%TitleLabel");
titleLabel.Text = Title;
_selectedAbilities = GetNode<VBoxContainer>("%SelectedAbilities");
_addAbility = GetNode<MenuButton>("%AddAbility");
_addAbilityMenu = _addAbility.GetPopup();
if (Engine.IsEditorHint()) return;
var i = 0;
foreach (var behavior in AbilityBehaviors)
{
_addAbilityMenu.AddIconItem(behavior.Icon, behavior.Name);
_addAbilityMenu.SetItemMetadata(i, behavior);
i += 1;
}
_addAbilityMenu.IndexPressed += AddAbilityMenuOnIndexPressed;
}
public void Initialize(IEnumerable<Resource> equippedAbilities)
{
foreach (var equippedAbility in equippedAbilities)
{
if (equippedAbility is not ForgeAbilityBehavior ability) continue;
AddSelectedAbility(ability);
}
}
private void AddAbilityMenuOnIndexPressed(long index)
{
var indexInt = Convert.ToInt32(index);
var metadata = (ForgeAbilityBehavior) _addAbilityMenu.GetItemMetadata(indexInt);
EmitSignalAbilityAdded(ForEvent, metadata);
}
public void AddSelectedAbility(ForgeAbilityBehavior behavior)
{
var newSelectedAbilityItem = AbilitySelectedItem.Instantiate() as SelectedAbility;
if (newSelectedAbilityItem == null) return;
newSelectedAbilityItem.SetAbility(behavior);
newSelectedAbilityItem.AbilityRemoved += ability => EmitSignalAbilityRemoved(ForEvent, ability);
_selectedAbilities.AddChild(newSelectedAbilityItem);
}
public void RemoveSelectedAbility(ForgeAbilityBehavior behavior)
{
foreach (var child in _selectedAbilities.GetChildren())
{
if (child is not SelectedAbility selectedAbility || selectedAbility.Ability != behavior) continue;
_selectedAbilities.RemoveChild(selectedAbility);
_addAbility.GrabFocus();
return;
}
}
}

View File

@@ -0,0 +1 @@
uid://5emed8iegtui

View File

@@ -0,0 +1,56 @@
using Godot;
using System;
using Gamesmiths.Forge.Godot.Resources.Abilities;
[Tool, GlobalClass]
public partial class SelectedAbility : Control
{
[Signal] public delegate void AbilityRemovedEventHandler(ForgeAbilityBehavior ability);
private ForgeAbilityBehavior? _ability;
[Export]
public ForgeAbilityBehavior? Ability
{
get => _ability;
set
{
_ability = value;
if (_ability == null || !Engine.IsEditorHint()) return;
AbilityUpdated();
}
}
private TextureRect? _icon;
private Label? _title;
private Button? _remove;
public override void _Ready()
{
_icon = GetNode<TextureRect>("%Icon");
_title = GetNode<Label>("%Title");
_remove = GetNode<Button>("%Remove");
_remove.Pressed += () => EmitSignalAbilityRemoved(Ability);
}
public void SetAbility(ForgeAbilityBehavior ability)
{
_ability = ability;
AbilityUpdated();
}
public void AbilityUpdated()
{
var icon = _icon ?? GetNode<TextureRect>("%Icon");
var title = _title ?? GetNode<Label>("%Title");
if (icon == null || title == null) return;
if (_ability == null)
{
icon.Texture = null;
title.Text = "";
return;
}
icon.Texture = _ability.Icon;
title.Text = _ability.Name;
}
}

View File

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

View File

@@ -0,0 +1,46 @@
[gd_scene format=3 uid="uid://dmv685sskgh3l"]
[ext_resource type="Script" uid="uid://5emed8iegtui" path="res://menus/scenes/components/AbilitySelection.cs" id="1_fcxyu"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="2_j1yif"]
[ext_resource type="Texture2D" uid="uid://by5v33lu8v1fm" path="res://assets/ui/input-prompts/Flairs/Vector/flair_plus.svg" id="2_uf3m5"]
[ext_resource type="PackedScene" uid="uid://cjnimmo2jyvx7" path="res://menus/scenes/components/selected_ability.tscn" id="3_cndde"]
[node name="AbilitySelection" type="MarginContainer" unique_id=1373426933]
size_flags_horizontal = 3
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
script = ExtResource("1_fcxyu")
Title = "Test"
AbilitySelectedItem = ExtResource("3_cndde")
AbilityBehaviors = [ExtResource("2_j1yif")]
[node name="HBoxContainer" type="VBoxContainer" parent="." unique_id=364343452]
layout_mode = 2
[node name="TitleLabel" type="Label" parent="HBoxContainer" unique_id=8350369]
unique_name_in_owner = true
layout_mode = 2
text = "Test"
[node name="SelectedAbilities" type="VBoxContainer" parent="HBoxContainer" unique_id=1173689490]
unique_name_in_owner = true
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="HBoxContainer" unique_id=51872459]
layout_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
[node name="PanelContainer" type="PanelContainer" parent="HBoxContainer/MarginContainer" unique_id=886085404]
layout_mode = 2
[node name="AddAbility" type="MenuButton" parent="HBoxContainer/MarginContainer/PanelContainer" unique_id=1898027483]
unique_name_in_owner = true
layout_mode = 2
focus_mode = 2
text = "Add ability"
icon = ExtResource("2_uf3m5")

View File

@@ -0,0 +1,30 @@
[gd_scene format=3 uid="uid://cjnimmo2jyvx7"]
[ext_resource type="Script" uid="uid://duest06l5answ" path="res://menus/scenes/components/SelectedAbility.cs" id="1_dc51o"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="2_um64s"]
[ext_resource type="Texture2D" uid="uid://b3403ry3yxw1t" path="res://assets/ui/input-prompts/Flairs/Vector/flair_cross.svg" id="4_x7nho"]
[sub_resource type="AtlasTexture" id="AtlasTexture_2nvj1"]
atlas = ExtResource("4_x7nho")
region = Rect2(20, 20, 24, 24)
[node name="SelectedAbility" type="PanelContainer" unique_id=931414010]
script = ExtResource("1_dc51o")
Ability = ExtResource("2_um64s")
[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=489712453]
layout_mode = 2
[node name="Icon" type="TextureRect" parent="HBoxContainer" unique_id=1615158957]
unique_name_in_owner = true
layout_mode = 2
stretch_mode = 3
[node name="Title" type="Label" parent="HBoxContainer" unique_id=809638027]
unique_name_in_owner = true
layout_mode = 2
[node name="Remove" type="Button" parent="HBoxContainer" unique_id=1761723956]
unique_name_in_owner = true
layout_mode = 2
icon = SubResource("AtlasTexture_2nvj1")

View File

@@ -37,6 +37,7 @@ option_name = "Joystick Sensitivity"
option_section = 1
key = "LookSensitivity"
section = "InputSettings"
default_value = 1.1
[node name="OptionLabel" parent="VBoxContainer/MarginContainer/VBoxContainer/LookSensitivityControl" index="0" unique_id=1789907427]
text = "Joystick Sensitivity :"
@@ -44,8 +45,8 @@ text = "Joystick Sensitivity :"
[node name="HSlider" parent="VBoxContainer/MarginContainer/VBoxContainer/LookSensitivityControl" index="1" unique_id=494926010]
min_value = 0.2
max_value = 2.0
step = 0.2
value = 0.6000000000000001
step = 0.1
value = 1.1
tick_count = 10
[node name="MouseSensitivityControl" parent="VBoxContainer/MarginContainer/VBoxContainer" unique_id=1444662884 instance=ExtResource("2_iyvrj")]
@@ -54,16 +55,17 @@ option_name = "Mouse Sensitivity"
option_section = 1
key = "MouseSensitivity"
section = "InputSettings"
default_value = 25.0
[node name="OptionLabel" parent="VBoxContainer/MarginContainer/VBoxContainer/MouseSensitivityControl" index="0" unique_id=1789907427]
text = "Mouse Sensitivity :"
[node name="HSlider" parent="VBoxContainer/MarginContainer/VBoxContainer/MouseSensitivityControl" index="1" unique_id=494926010]
min_value = 1.0
max_value = 20.0
max_value = 50.0
step = 1.0
value = 8.0
tick_count = 20
value = 25.0
tick_count = 10
[node name="HeadBobbingControl" parent="VBoxContainer/MarginContainer/VBoxContainer" unique_id=1905029466 instance=ExtResource("2_iyvrj")]
layout_mode = 2

View File

@@ -0,0 +1,94 @@
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Godot;
using Movementtests.managers;
using Movementtests.systems;
[Tool, GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_crate.png"), Meta(typeof(IAutoNode))]
public partial class InventoryUi : Control
{
public override void _Notification(int what) => this.Notify(what);
#region Dependencies
[Dependency]
public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
#endregion Dependencies
#region Nodes
[Node]
public required AbilitySelection StartedFlying { get; set; }
[Node]
public required AbilitySelection WhileFlying { get; set; }
[Node]
public required AbilitySelection StoppedFlying { get; set; }
#endregion Nodes
public void OnReady()
{
StartedFlying.AbilityAdded += AddAbilityForEvent;
WhileFlying.AbilityAdded += AddAbilityForEvent;
StoppedFlying.AbilityAdded += AddAbilityForEvent;
StartedFlying.AbilityRemoved += RemoveAbilityForEvent;
WhileFlying.AbilityRemoved += RemoveAbilityForEvent;
StoppedFlying.AbilityRemoved += RemoveAbilityForEvent;
}
public void OnResolved()
{
StartedFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying]);
WhileFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick]);
StoppedFlying.Initialize(InventoryManager.WeaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying]);
InventoryManager.WeaponEventAbilityAdded += OnWeaponEventInventoryAdded;
InventoryManager.WeaponEventAbilityRemoved += OnWeaponEventInventoryRemoved;
}
public void OnExitTree()
{
InventoryManager.WeaponEventAbilityAdded -= OnWeaponEventInventoryAdded;
InventoryManager.WeaponEventAbilityRemoved -= OnWeaponEventInventoryRemoved;
}
public void AddAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
InventoryManager.AddAbilityForWeaponEvent(forEvent, abilityBehavior);
}
public void RemoveAbilityForEvent(WeaponSystem.WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
InventoryManager.RemoveAbilityForWeaponEvent(forEvent, abilityBehavior);
}
public void OnWeaponEventInventoryAdded(WeaponEventAbilityData data)
{
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
var selection = GetAbilitySelection(data.ForEvent);
selection.AddSelectedAbility(abilityBehavior);
}
public void OnWeaponEventInventoryRemoved(WeaponEventAbilityData data)
{
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
var selection = GetAbilitySelection(data.ForEvent);
selection.RemoveSelectedAbility(abilityBehavior);
}
public AbilitySelection GetAbilitySelection(WeaponSystem.WeaponEvent forEvent)
{
var abilitiesSelectionsMap = new Dictionary<WeaponSystem.WeaponEvent, AbilitySelection>
{
{ WeaponSystem.WeaponEvent.StartedFlying, StartedFlying },
{ WeaponSystem.WeaponEvent.StoppedFlying, StoppedFlying },
{ WeaponSystem.WeaponEvent.FlyingTick, WhileFlying },
};
return abilitiesSelectionsMap[forEvent];
}
}

View File

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

View File

@@ -0,0 +1,95 @@
[gd_scene format=3 uid="uid://oq1jjvjs4qga"]
[ext_resource type="Script" uid="uid://vu5kh5amnta" path="res://menus/scenes/overlaid_menus/inventory_wrapper.gd" id="1_yst23"]
[ext_resource type="Script" uid="uid://1nf36h0gms3q" path="res://addons/maaacks_game_template/base/scripts/capture_focus.gd" id="2_ijoei"]
[ext_resource type="Script" uid="uid://cvwiftuay8jep" path="res://menus/scenes/overlaid_menus/InventoryUi.cs" id="2_sb1gh"]
[ext_resource type="PackedScene" uid="uid://dmv685sskgh3l" path="res://menus/scenes/components/ability_selection.tscn" id="3_ijoei"]
[node name="InventoryWrapper" type="Control" unique_id=1853168495]
process_mode = 3
top_level = true
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_yst23")
pauses_game = true
[node name="Inventory" type="MarginContainer" parent="." unique_id=1581374847]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 9
anchor_bottom = 1.0
offset_right = 1920.0
grow_vertical = 2
theme_override_constants/margin_left = 256
theme_override_constants/margin_top = 32
theme_override_constants/margin_right = 256
theme_override_constants/margin_bottom = 32
script = ExtResource("2_sb1gh")
[node name="MenuPanelContainer" type="PanelContainer" parent="Inventory" unique_id=494302799]
unique_name_in_owner = true
process_mode = 3
layout_mode = 2
[node name="MarginContainer" type="MarginContainer" parent="Inventory/MenuPanelContainer" unique_id=890844332]
layout_mode = 2
theme_override_constants/margin_left = 128
theme_override_constants/margin_top = 16
theme_override_constants/margin_right = 128
theme_override_constants/margin_bottom = 16
[node name="BoxContainer" type="BoxContainer" parent="Inventory/MenuPanelContainer/MarginContainer" unique_id=1551508149]
layout_mode = 2
vertical = true
[node name="TitleMargin" type="MarginContainer" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer" unique_id=1278279788]
layout_mode = 2
[node name="TitleLabel" type="Label" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/TitleMargin" unique_id=1966063657]
layout_mode = 2
theme_override_font_sizes/font_size = 24
text = "Inventory"
horizontal_alignment = 1
[node name="PlayerSectionMargin" type="MarginContainer" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer" unique_id=461792371]
layout_mode = 2
theme_override_constants/margin_top = 16
theme_override_constants/margin_bottom = 16
[node name="PlayerSection" type="BoxContainer" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/PlayerSectionMargin" unique_id=469432036]
custom_minimum_size = Vector2(128, 0)
layout_mode = 2
size_flags_vertical = 3
theme_override_constants/separation = 16
vertical = true
[node name="PlayerSectionLabel" type="Label" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/PlayerSectionMargin/PlayerSection" unique_id=1100827847]
layout_mode = 2
text = "Weapon abilities"
horizontal_alignment = 1
[node name="HBoxContainer" type="HBoxContainer" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/PlayerSectionMargin/PlayerSection" unique_id=75337901]
layout_mode = 2
script = ExtResource("2_ijoei")
search_depth = 10
[node name="StartedFlying" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/PlayerSectionMargin/PlayerSection/HBoxContainer" unique_id=1373426933 instance=ExtResource("3_ijoei")]
unique_name_in_owner = true
layout_mode = 2
Title = "Started flying"
[node name="WhileFlying" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/PlayerSectionMargin/PlayerSection/HBoxContainer" unique_id=1771285257 instance=ExtResource("3_ijoei")]
unique_name_in_owner = true
layout_mode = 2
ForEvent = 2
Title = "While flying"
[node name="StoppedFlying" parent="Inventory/MenuPanelContainer/MarginContainer/BoxContainer/PlayerSectionMargin/PlayerSection/HBoxContainer" unique_id=324047638 instance=ExtResource("3_ijoei")]
unique_name_in_owner = true
layout_mode = 2
ForEvent = 1
Title = "Stopped flying"

View File

@@ -0,0 +1,12 @@
@tool
@icon("res://assets/ui/IconGodotNode/control/icon_crate_02.png")
class_name InventoryWrapper
extends OverlaidMenu
@onready var inventory: Control = %Inventory
func _ready() -> void:
if Engine.is_editor_hint(): return
func _on_close_button_pressed() -> void:
close()

View File

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

View File

@@ -15,7 +15,7 @@ warnings/check_invalid_track_paths=false
[application]
config/name="Movement tests"
run/main_scene="uid://dwo50456dv6va"
run/main_scene="uid://vm22i5sv3p3s"
config/features=PackedStringArray("4.6", "C#", "Forward Plus")
config/icon="res://icon.svg"

View File

@@ -8,6 +8,7 @@
[ext_resource type="Script" uid="uid://bjwrpv3jpsc1e" path="res://scenes/components/health/CHealth.cs" id="4_ys4jv"]
[ext_resource type="Script" uid="uid://8uj04dfe8oql" path="res://addons/forge/nodes/ForgeEntity.cs" id="6_wxisp"]
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="7_2digf"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="7_46wn3"]
[ext_resource type="PackedScene" uid="uid://dmw5ibwrb483f" path="res://scenes/components/movement/CFlyingMovement.tscn" id="7_vaeds"]
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_ykkxn"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="8_46wn3"]
@@ -16,23 +17,28 @@
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_dejyg"]
[ext_resource type="Resource" uid="uid://dt7a1io5o0b8s" path="res://scenes/enemies/flying_enemy/flying_enemy_knockback.tres" id="11_mpa2u"]
[sub_resource type="Resource" id="Resource_vfi88"]
script = ExtResource("7_46wn3")
ContainerTags = Array[String](["character.enemy"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_oj1ws"]
script = ExtResource("8_46wn3")
Default = 50
Max = 100
[sub_resource type="Resource" id="Resource_yk4hc"]
script = ExtResource("8_46wn3")
Default = 1
Min = 1
Max = 100
[sub_resource type="Resource" id="Resource_wxisp"]
script = ExtResource("8_46wn3")
Default = 2
Min = 1
Max = 100
[sub_resource type="Resource" id="Resource_yk4hc"]
script = ExtResource("8_46wn3")
Default = 1
Min = 1
Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_hf6k8"]
viewport_path = NodePath("SubViewport")
@@ -84,6 +90,7 @@ RMovement = ExtResource("4_dejyg")
[node name="ForgeEntity" type="Node" parent="." unique_id=622209781]
script = ExtResource("6_wxisp")
BaseTags = SubResource("Resource_vfi88")
metadata/_custom_type_script = "uid://8uj04dfe8oql"
[node name="ForgeAttributeSet" type="Node" parent="ForgeEntity" unique_id=1840910245]

View File

@@ -10,30 +10,36 @@
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="6_yk4hc"]
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://scenes/components/damage/CDamageable.cs" id="7_1tw73"]
[ext_resource type="PackedScene" uid="uid://bwx2um43k0ou4" path="res://scenes/components/health/CHealthbar.tscn" id="7_18xwy"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="7_f22p3"]
[ext_resource type="PackedScene" uid="uid://dbr7ioio158ew" path="res://scenes/components/movement/CGroundedMovement.tscn" id="7_qyswd"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="7_x50ya"]
[ext_resource type="Script" uid="uid://dtpxijlnb2c5" path="res://scenes/components/movement/RMovement.cs" id="8_6d4gl"]
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="10_jqqi6"]
[ext_resource type="Resource" uid="uid://cektf6waf4s04" path="res://scenes/enemies/grounded_enemy/grounded_enemy_knockback.tres" id="11_8k3xb"]
[sub_resource type="Resource" id="Resource_4jf2q"]
script = ExtResource("7_f22p3")
ContainerTags = Array[String](["character.enemy"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_f22p3"]
script = ExtResource("7_x50ya")
Default = 100
Max = 100
[sub_resource type="Resource" id="Resource_yk4hc"]
script = ExtResource("7_x50ya")
Default = 1
Min = 1
Max = 100
[sub_resource type="Resource" id="Resource_x50ya"]
script = ExtResource("7_x50ya")
Default = 1
Min = 1
Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_0mf3g"]
[sub_resource type="Resource" id="Resource_yk4hc"]
script = ExtResource("7_x50ya")
Default = 1
Min = 1
Max = 100
[sub_resource type="ViewportTexture" id="ViewportTexture_ub34u"]
viewport_path = NodePath("SubViewport")
[sub_resource type="Resource" id="Resource_qj0ob"]
@@ -84,6 +90,7 @@ RMovement = ExtResource("4_na24f")
[node name="ForgeEntity" type="Node" parent="." unique_id=432521027]
script = ExtResource("6_x50ya")
BaseTags = SubResource("Resource_4jf2q")
metadata/_custom_type_script = "uid://8uj04dfe8oql"
[node name="ForgeAttributeSet" type="Node" parent="ForgeEntity" unique_id=804252284]
@@ -103,7 +110,7 @@ metadata/_custom_type_script = "uid://bjwrpv3jpsc1e"
[node name="CHealthBar" parent="." unique_id=1278247727 instance=ExtResource("7_18xwy")]
transform = Transform3D(0.4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0)
texture = SubResource("ViewportTexture_0mf3g")
texture = SubResource("ViewportTexture_ub34u")
[node name="CDamageable" type="Node" parent="." unique_id=1601518000]
script = ExtResource("7_1tw73")

View File

@@ -2,6 +2,7 @@
[ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://scenes/player_controller/scripts/PlayerController.cs" id="1_poq2x"]
[ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_u8yay"]
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="2_x835q"]
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://scenes/components/knockback/RKnockback.cs" id="3_cb2lu"]
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"]
@@ -13,6 +14,7 @@
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
[ext_resource type="PackedScene" uid="uid://hpsg4fqwrx1u" path="res://scenes/components/damage/CDamageable.tscn" id="5_jb43f"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://inputs/base_mode/move_left.tres" id="5_q14ux"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="5_u8yay"]
[ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="5_ue7xq"]
[ext_resource type="Resource" uid="uid://dyru7mxo121w6" path="res://scenes/player_controller/resources/player_normal_damage_mod.tres" id="6_cmijs"]
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="6_q7bng"]
@@ -53,12 +55,16 @@
[ext_resource type="Script" uid="uid://cf1nsco3w0mf6" path="res://addons/godot_state_charts/transition.gd" id="28_n7qhm"]
[ext_resource type="PackedScene" uid="uid://ckm3d6k08a72u" path="res://scenes/player_controller/components/weapon/weapon.tscn" id="29_wv70j"]
[ext_resource type="Script" uid="uid://bhuwv2nlcrunt" path="res://scenes/player_controller/PlayerUi.cs" id="30_2ghaa"]
[ext_resource type="Texture2D" uid="uid://bnwj7ltdfximr" path="res://icon.svg" id="30_h23go"]
[ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://scenes/player_controller/components/dash/light-ring.jpg" id="32_lgpc8"]
[ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"]
[ext_resource type="Texture2D" uid="uid://c40orhfdgsim" path="res://assets/ui/IconGodotNode/white/icon_circle.png" id="45_u8rdp"]
[ext_resource type="PackedScene" uid="uid://cyw8p0p6a78tl" path="res://scenes/ui/healthbar/healthbar.tscn" id="47_76kmc"]
[sub_resource type="Resource" id="Resource_mpigw"]
script = ExtResource("2_u8yay")
ContainerTags = Array[String](["character.player"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_5gbhg"]
script = ExtResource("11_u8yay")
Tag = "events.player.empowered_action_used"
@@ -71,7 +77,7 @@ metadata/_custom_type_script = "uid://jitubgv6judn"
[sub_resource type="Resource" id="Resource_abfq8"]
script = ExtResource("3_cb2lu")
Modifier = 20.0
Modifier = 5.0
metadata/_custom_type_script = "uid://b44cse62qru7j"
[sub_resource type="Resource" id="Resource_ue7xq"]
@@ -148,8 +154,10 @@ bg_color = Color(0.15869555, 0.64034444, 0.906125, 1)
[node name="Player" type="CharacterBody3D" unique_id=709076448]
collision_mask = 272
script = ExtResource("1_poq2x")
BaseTags = SubResource("Resource_mpigw")
EmpoweredActionUsed = SubResource("Resource_5gbhg")
EmpoweredActionAbility = ExtResource("10_2rkt1")
WeaponExplosionBehavior = ExtResource("5_u8yay")
DefaultPermanentEffects = [ExtResource("5_2rkt1")]
EmpoweredActionEffects = [ExtResource("6_u8yay")]
AimAssistStrength = 0.3
@@ -182,7 +190,8 @@ MaxNumberOfEmpoweredActions = 3
SimpleDashStrength = 18.0
SimpleDashTime = 0.2
AimedDashTime = 0.2
PostDashSpeed = 30.0
PostDashSpeed = 25.0
TimeScaleAimInAir = 0.08
SlamSpeed = 80.0
FlatGroundSlideSpeedLossRate = 0.996
GroundSlideJumpMultiplier = 0.1
@@ -460,10 +469,6 @@ one_shot = true
[node name="AirborneDashCooldown" type="Timer" parent="." unique_id=976335884]
one_shot = true
[node name="PowerCooldown" type="Timer" parent="." unique_id=1091679675]
wait_time = 2.0
one_shot = true
[node name="TimeScaleAimInAir" type="Timer" parent="." unique_id=1346687662]
wait_time = 5.0
one_shot = true
@@ -487,50 +492,6 @@ grow_vertical = 2
mouse_filter = 1
script = ExtResource("30_2ghaa")
[node name="MarginContainer" type="MarginContainer" parent="UI" unique_id=256626576]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_constants/margin_left = 50
theme_override_constants/margin_top = 50
theme_override_constants/margin_right = 50
theme_override_constants/margin_bottom = 50
[node name="VBoxContainer" type="VBoxContainer" parent="UI/MarginContainer" unique_id=74238183]
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 0
[node name="DashesLabel" type="Label" parent="UI/MarginContainer/VBoxContainer" unique_id=245851052]
layout_mode = 2
text = "Empowered actions"
[node name="HBoxContainer" type="HBoxContainer" parent="UI/MarginContainer/VBoxContainer" unique_id=81461575]
custom_minimum_size = Vector2(0, 30)
layout_mode = 2
[node name="Dash1" type="TextureRect" parent="UI/MarginContainer/VBoxContainer/HBoxContainer" unique_id=108366179]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("30_h23go")
expand_mode = 2
[node name="Dash2" type="TextureRect" parent="UI/MarginContainer/VBoxContainer/HBoxContainer" unique_id=140491034]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("30_h23go")
expand_mode = 2
[node name="Dash3" type="TextureRect" parent="UI/MarginContainer/VBoxContainer/HBoxContainer" unique_id=1447308392]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("30_h23go")
expand_mode = 2
[node name="CenterContainer" type="CenterContainer" parent="UI" unique_id=1479818685]
custom_minimum_size = Vector2(1920, 1080)
layout_mode = 1
@@ -549,24 +510,6 @@ layout_mode = 2
texture = ExtResource("32_lgpc8")
expand_mode = 1
[node name="CenterContainer2" type="CenterContainer" parent="UI" unique_id=1912042835]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="MarginContainer" type="MarginContainer" parent="UI/CenterContainer2" unique_id=812091083]
layout_mode = 2
theme_override_constants/margin_top = 50
[node name="DashCooldownIndicator" type="ColorRect" parent="UI/CenterContainer2/MarginContainer" unique_id=1946930017]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 10)
layout_mode = 2
[node name="EnemyTarget" type="TextureRect" parent="UI" unique_id=1113835926]
unique_name_in_owner = true
modulate = Color(0, 0.61278194, 0.56044877, 1)
@@ -654,43 +597,6 @@ delay_in_seconds = "0.0"
[node name="Canceled" type="Node" parent="StateChart/Root/Aim" unique_id=623373725]
script = ExtResource("27_34snm")
[node name="PowerReserve" type="Node" parent="StateChart/Root" unique_id=240635144]
script = ExtResource("26_infe6")
initial_state = NodePath("Full")
[node name="ToExpired" type="Node" parent="StateChart/Root/PowerReserve" unique_id=1254755786]
script = ExtResource("28_n7qhm")
to = NodePath("../Expired")
event = &"expired"
delay_in_seconds = "0.0"
[node name="Recharge" type="Node" parent="StateChart/Root/PowerReserve" unique_id=832143267]
script = ExtResource("28_n7qhm")
to = NodePath("../AtLeastOneCharge")
event = &"recharge"
delay_in_seconds = "0.0"
[node name="ToFull" type="Node" parent="StateChart/Root/PowerReserve" unique_id=984127202]
script = ExtResource("28_n7qhm")
to = NodePath("../Full")
event = &"fully_charged"
delay_in_seconds = "0.0"
[node name="Expired" type="Node" parent="StateChart/Root/PowerReserve" unique_id=1558500638]
script = ExtResource("27_34snm")
[node name="AtLeastOneCharge" type="Node" parent="StateChart/Root/PowerReserve" unique_id=10506240]
script = ExtResource("27_34snm")
[node name="Full" type="Node" parent="StateChart/Root/PowerReserve" unique_id=1559116737]
script = ExtResource("27_34snm")
[node name="PowerUsed" type="Node" parent="StateChart/Root/PowerReserve/Full" unique_id=397112501]
script = ExtResource("28_n7qhm")
to = NodePath("../../AtLeastOneCharge")
event = &"power_used"
delay_in_seconds = "0.0"
[node name="Attack" type="Node" parent="StateChart/Root" unique_id=808083793]
script = ExtResource("26_infe6")
initial_state = NodePath("Ready")

View File

@@ -10,7 +10,6 @@ using Movementtests.tools;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
public partial class PlayerUi : Control, ICueHandler
{
internal TextureRect[] DashIcons = new TextureRect[3];
private TextureRect _enemyTarget = null!;
private Healthbar _healthbar = null!;
private Healthbar _manabar = null!;
@@ -31,10 +30,6 @@ public partial class PlayerUi : Control, ICueHandler
public override void _Ready()
{
DashIcons[0] = GetNode<TextureRect>("%Dash1");
DashIcons[1] = GetNode<TextureRect>("%Dash2");
DashIcons[2] = GetNode<TextureRect>("%Dash3");
_enemyTarget = GetNode<TextureRect>("%EnemyTarget");
_healthbar = GetNode<Healthbar>("%Healthbar");
_manabar = GetNode<Healthbar>("%Manabar");
@@ -67,17 +62,6 @@ public partial class PlayerUi : Control, ICueHandler
_enemyTarget.SetModulate(modulation);
}
public void SetNumberOfDashesLeft(int numberOfDashes)
{
int index = 1;
foreach (var dashIcon in DashIcons)
{
dashIcon.SetVisible(index <= numberOfDashes);
index++;
}
}
public void OnHealthChanged(IHealthable healthable, HealthChangedRecord healthChanged)
{
_healthbar.CurrentHealth = healthChanged.CurrentHealth;

View File

@@ -40,13 +40,12 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public delegate void WeaponRetrievedEventHandler();
[Export]
public ForgeTagContainer BaseTags { get; set; } = new();
[Export] public ForgeAbilityData[] WeaponAbilities { get; set; } = Array.Empty<ForgeAbilityData>();
[Export] public ForgeAbilityData FlyingTickAbility { get; set; } = new();
public ForgeTagContainer BaseTags { get; set; }
[Export] public ForgeAbilityData FlyingTickAbility { get; set; }
[Export]
public RDamage RDamage { get; set; }
[Export(PropertyHint.Range, "0,100,1,or_greater")]
[Export(PropertyHint.Range, "0,2,0.01,or_greater")]
public float ThrowForce { get; set; } = 1f;
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
public float StraightThrowDuration { get; set; } = 0.1f;
@@ -167,25 +166,6 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
// TODO: Waiting on bug resolve
_weaponFlyingAbility = Abilities.GrantAbilityPermanently(FlyingTickAbility.GetAbilityData(), 1, LevelComparison.None, this);
foreach (var ability in WeaponAbilities)
{
var leftGrantAbilityConfig = new GrantAbilityConfig(
ability.GetAbilityData(),
ScalableLevel: new ScalableInt(1),
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
TryActivateOnGrant: false,
TryActivateOnEnable: false,
LevelOverridePolicy: LevelComparison.Higher);
var leftGrantComponent = new GrantAbilityEffectComponent([leftGrantAbilityConfig]);
var leftGrantEffect = new EffectData(
"Grant Weapon Ability",
new DurationData(DurationType.Infinite),
effectComponents: [leftGrantComponent]);
EffectsManager.ApplyEffect(new Effect(leftGrantEffect, new EffectOwnership(this, this)));
}
BodyEntered += OnThrownWeaponReachesGround;
InHandState.StateExited += WeaponLeft;
@@ -257,11 +237,75 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
});
};
Events.Subscribe(WeaponStoppedFlyingEventTag, data =>
Events.Subscribe(WeaponStoppedFlyingEventTag, _ => { _weaponFlyingAbility.Cancel(); });
}
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStartedFlyingAbilities = new ();
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponStoppedFlyingAbilities = new ();
private Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> _grantedWeaponFlyingTickAbilities = new ();
public enum WeaponEvent
{
StartedFlying,
StoppedFlying,
FlyingTick
}
public void GrantNewAbilityForEvent(WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
var relevantMap = GetGrantedAbilities(forEvent);
GD.Print($"Granted {abilityBehavior} for {forEvent}");
if (relevantMap.ContainsKey(abilityBehavior)) return;
var eventTagsMap = new Dictionary<WeaponEvent, Tag>
{
// TODO: Waiting on bug resolve
_weaponFlyingAbility.Cancel();
});
{ WeaponEvent.StartedFlying, WeaponStartedFlyingEventTag },
{ WeaponEvent.StoppedFlying, WeaponStoppedFlyingEventTag },
{ WeaponEvent.FlyingTick, WeaponFlyingTickEventTag },
};
var ability = new AbilityData(
"Ability",
behaviorFactory: abilityBehavior.GetBehavior,
abilityTriggerData: AbilityTriggerData.ForEvent(eventTagsMap[forEvent]));
var leftGrantAbilityConfig = new GrantAbilityConfig(
ability,
ScalableLevel: new ScalableInt(1),
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
TryActivateOnGrant: false,
TryActivateOnEnable: false,
LevelOverridePolicy: LevelComparison.Higher);
var leftGrantComponent = new GrantAbilityEffectComponent([leftGrantAbilityConfig]);
var leftGrantEffect = new EffectData(
"Grant Weapon Ability",
new DurationData(DurationType.Infinite),
effectComponents: [leftGrantComponent]);
var effectHandle = EffectsManager.ApplyEffect(new Effect(leftGrantEffect, new EffectOwnership(this, this)));
if (effectHandle == null) return;
relevantMap[abilityBehavior] = effectHandle;
}
public void RemoveAbilityForEvent(WeaponEvent forEvent, ForgeAbilityBehavior abilityBehavior)
{
var relevantMap = GetGrantedAbilities(forEvent);
if (!relevantMap.TryGetValue(abilityBehavior, out var effectHandle)) return;
EffectsManager.RemoveEffect(effectHandle);
relevantMap.Remove(abilityBehavior);
}
public Dictionary<ForgeAbilityBehavior, ActiveEffectHandle> GetGrantedAbilities(WeaponEvent forEvent)
{
var abilitiesMap = new Dictionary<WeaponEvent, Dictionary<ForgeAbilityBehavior, ActiveEffectHandle>>
{
{ WeaponEvent.StartedFlying, _grantedWeaponStartedFlyingAbilities },
{ WeaponEvent.StoppedFlying, _grantedWeaponStoppedFlyingAbilities },
{ WeaponEvent.FlyingTick, _grantedWeaponFlyingTickAbilities },
};
return abilitiesMap[forEvent];
}
public void WeaponLeft()
@@ -377,9 +421,12 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
public override void _Process(double delta)
{
EffectsManager.UpdateEffects(delta);
if (!FlyingState.Active) return;
WeaponMesh.Rotation = new Vector3(WeaponMesh.Rotation.X, WeaponMesh.Rotation.Y + (float) delta * 100, WeaponMesh.Rotation.Z);
//GD.Print(Attributes["WeaponAttributeSet.Level"].CurrentValue);
//LookAt(GlobalTransform.Origin + LinearVelocity.Normalized(), Vector3.Up, false);
}

View File

@@ -1,19 +1,22 @@
[gd_scene format=3 uid="uid://ckm3d6k08a72u"]
[ext_resource type="Script" uid="uid://iii3wfto4t5b" path="res://scenes/player_controller/components/weapon/WeaponSystem.cs" id="1_csqwk"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_l1xlx"]
[ext_resource type="Script" uid="uid://jitubgv6judn" path="res://scenes/components/damage/RDamage.cs" id="2_m0v1h"]
[ext_resource type="Resource" uid="uid://cu0685gspk2fk" path="res://scenes/player_controller/resources/forge/exploding_sword_weapon_land.tres" id="2_pgbtr"]
[ext_resource type="Script" uid="uid://cxihb42t2mfqi" path="res://addons/forge/nodes/ForgeAttributeSet.cs" id="3_3xjpi"]
[ext_resource type="Script" uid="uid://couw105c3bde4" path="res://addons/godot_state_charts/state_chart.gd" id="3_5owyf"]
[ext_resource type="Resource" uid="uid://busdbvfi3jiic" path="res://scenes/player_controller/resources/forge/exploding_sword_weapon_left.tres" id="3_7bruw"]
[ext_resource type="ArrayMesh" uid="uid://cho5fixitrbds" path="res://assets/meshes/swords/resources/sword23.tres" id="3_svc06"]
[ext_resource type="Resource" uid="uid://bl0mng4kl1xy8" path="res://scenes/player_controller/resources/forge/exploding_sword_weapon_flight.tres" id="4_2wsgo"]
[ext_resource type="Resource" uid="uid://btnnpqann3ktp" path="res://scenes/player_controller/resources/forge/weapon_flying_tick_ability.tres" id="4_7bruw"]
[ext_resource type="Script" uid="uid://ccovd5i0wr3kk" path="res://addons/forge/editor/attributes/AttributeValues.cs" id="4_q6xv7"]
[ext_resource type="Script" uid="uid://jk2jm1g6q853" path="res://addons/godot_state_charts/compound_state.gd" id="4_svc06"]
[ext_resource type="Script" uid="uid://cytafq8i1y8qm" path="res://addons/godot_state_charts/atomic_state.gd" id="5_m0v1h"]
[ext_resource type="Script" uid="uid://cf1nsco3w0mf6" path="res://addons/godot_state_charts/transition.gd" id="6_jpdh0"]
[sub_resource type="Resource" id="Resource_06gln"]
script = ExtResource("2_l1xlx")
ContainerTags = Array[String](["weapon"])
metadata/_custom_type_script = "uid://cw525n4mjqgw0"
[sub_resource type="Resource" id="Resource_jpdh0"]
script = ExtResource("2_m0v1h")
DamageDealt = 2.0
@@ -60,7 +63,7 @@ continuous_cd = true
contact_monitor = true
max_contacts_reported = 1
script = ExtResource("1_csqwk")
WeaponAbilities = [ExtResource("2_pgbtr"), ExtResource("3_7bruw"), ExtResource("4_2wsgo")]
BaseTags = SubResource("Resource_06gln")
FlyingTickAbility = ExtResource("4_7bruw")
RDamage = SubResource("Resource_jpdh0")

View File

@@ -104,7 +104,7 @@ script = ExtResource("4_5fdax")
[sub_resource type="Resource" id="Resource_uv4a1"]
script = ExtResource("4_5fdax")
BaseValue = -30.0
BaseValue = -50.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_dhni4"]

View File

@@ -2,7 +2,11 @@
[ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="1_mnals"]
[ext_resource type="Script" uid="uid://bnee6amtc2bhj" path="res://forge/abilities/ForgeExplodingSwordBehavior.cs" id="1_ot53g"]
[ext_resource type="Texture2D" uid="uid://c2akxlg7tdb67" path="res://assets/ui/IconGodotNode/node/icon_projectile.png" id="2_l3coe"]
[resource]
script = ExtResource("1_ot53g")
Explosion = ExtResource("1_mnals")
Name = "Exploding Sword"
Description = "Make the sword explode"
Icon = ExtResource("2_l3coe")

View File

@@ -1,6 +1,6 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://cu0685gspk2fk"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="1_l4v7e"]
[ext_resource type="Resource" uid="uid://ifeavnlps7hy" path="res://scenes/player_controller/resources/forge/exploding_sword.tres" id="1_6c3kr"]
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="2_6c3kr"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="2_l4v7e"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="3_ixeut"]
@@ -19,7 +19,7 @@ metadata/_custom_type_script = "uid://dpakv7agvir6y"
script = ExtResource("3_ixeut")
Name = "Exploding Sword on Weapon Land"
CooldownEffects = []
AbilityBehavior = ExtResource("1_l4v7e")
AbilityBehavior = ExtResource("1_6c3kr")
TriggerSource = 1
TriggerTag = SubResource("Resource_6c3kr")
AbilityTags = SubResource("Resource_ixeut")

View File

@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="ForgeEffectApplicationBehavior" format=3 uid="uid://1tmxayi3nygi"]
[ext_resource type="Resource" uid="uid://bvidrwyuoos4g" path="res://scenes/player_controller/resources/forge/raise_flying_tick_event_periodically.tres" id="1_hlq5f"]
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="2_f5qgs"]
[resource]
script = ExtResource("2_f5qgs")
EffectData = ExtResource("1_hlq5f")
Name = "Flying tick application"
metadata/_custom_type_script = "uid://cl5hudinl1rex"

View File

@@ -39,7 +39,7 @@ script = ExtResource("3_fp8ou")
[sub_resource type="Resource" id="Resource_mbpss"]
script = ExtResource("3_fp8ou")
BaseValue = 1.0
BaseValue = 2.0
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_exi3e"]

View File

@@ -0,0 +1,34 @@
[gd_resource type="Resource" script_class="ForgeEffectData" format=3 uid="uid://bvidrwyuoos4g"]
[ext_resource type="Resource" uid="uid://oe2suroa1klj" path="res://scenes/player_controller/resources/forge/raise_flying_tick_event.tres" id="1_cd13a"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="2_yyxtw"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="3_skmyt"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="4_7ma6b"]
[sub_resource type="Resource" id="Resource_dgkld"]
script = ExtResource("2_yyxtw")
BaseValue = 1
[sub_resource type="Resource" id="Resource_1ften"]
script = ExtResource("3_skmyt")
BaseValue = 0.2
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_l278c"]
script = ExtResource("2_yyxtw")
BaseValue = 1
[resource]
script = ExtResource("4_7ma6b")
Name = "Call Flying Tick Event Periodically"
Modifiers = []
Components = []
Executions = Array[Object]([ExtResource("1_cd13a")])
DurationType = 1
HasPeriodicApplication = true
Period = SubResource("Resource_1ften")
ExecuteOnApplication = true
StackLimit = SubResource("Resource_l278c")
InitialStack = SubResource("Resource_dgkld")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"

View File

@@ -1,46 +1,9 @@
[gd_resource type="Resource" script_class="ForgeAbilityData" format=3 uid="uid://btnnpqann3ktp"]
[ext_resource type="Resource" uid="uid://oe2suroa1klj" path="res://scenes/player_controller/resources/forge/raise_flying_tick_event.tres" id="1_pdt6v"]
[ext_resource type="Resource" uid="uid://1tmxayi3nygi" path="res://scenes/player_controller/resources/forge/flying tick application ability behavior.tres" id="1_twa0w"]
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="1_vh0wp"]
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="2_xkoyb"]
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="3_j2gem"]
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="4_e2sm2"]
[ext_resource type="Script" uid="uid://cl5hudinl1rex" path="res://forge/abilities/ForgeEffectApplicationBehavior.cs" id="5_trglf"]
[ext_resource type="Script" uid="uid://dpakv7agvir6y" path="res://addons/forge/resources/ForgeTag.cs" id="6_napws"]
[sub_resource type="Resource" id="Resource_dgkld"]
script = ExtResource("2_xkoyb")
BaseValue = 1
[sub_resource type="Resource" id="Resource_1ften"]
script = ExtResource("3_j2gem")
BaseValue = 0.2
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
[sub_resource type="Resource" id="Resource_l278c"]
script = ExtResource("2_xkoyb")
BaseValue = 1
[sub_resource type="Resource" id="Resource_esyoj"]
script = ExtResource("4_e2sm2")
Name = "Call Flying Tick Event Periodically"
Modifiers = []
Components = []
Executions = Array[Object]([ExtResource("1_pdt6v")])
DurationType = 1
HasPeriodicApplication = true
Period = SubResource("Resource_1ften")
ExecuteOnApplication = true
StackLimit = SubResource("Resource_l278c")
InitialStack = SubResource("Resource_dgkld")
Cues = []
metadata/_custom_type_script = "uid://b83hf13nj37k3"
[sub_resource type="Resource" id="Resource_0xegy"]
script = ExtResource("5_trglf")
EffectData = SubResource("Resource_esyoj")
metadata/_custom_type_script = "uid://cl5hudinl1rex"
[sub_resource type="Resource" id="Resource_4aw8y"]
script = ExtResource("6_napws")
Tag = "events.weapon.startedflying"
@@ -49,8 +12,9 @@ metadata/_custom_type_script = "uid://dpakv7agvir6y"
[resource]
script = ExtResource("1_vh0wp")
Name = "Weapon Flying Tick"
RetriggerInstancedAbility = true
CooldownEffects = []
AbilityBehavior = SubResource("Resource_0xegy")
AbilityBehavior = ExtResource("1_twa0w")
TriggerSource = 1
TriggerTag = SubResource("Resource_4aw8y")
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Attributes;
using Gamesmiths.Forge.Core;
@@ -28,13 +30,15 @@ using Movementtests.player_controller.Scripts;
using Movementtests.scenes.player_controller.scripts;
using Movementtests.tools;
using Movementtests.forge.abilities;
using Movementtests.managers;
using Movementtests.tools.calculators;
using RustyOptions;
using Node = Godot.Node;
public record struct EmpoweredActionPayload;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png")]
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))]
public partial class PlayerController : CharacterBody3D,
IDamageable,
IDamageDealer,
@@ -42,6 +46,11 @@ public partial class PlayerController : CharacterBody3D,
IKnockbackable,
IForgeEntity
{
public override void _Notification(int what) => this.Notify(what);
[Dependency]
public InventoryManager InventoryManager => this.DependOn<InventoryManager>();
// Enums
public enum AllowedInputs
{
@@ -85,8 +94,6 @@ public partial class PlayerController : CharacterBody3D,
public WeaponSystem WeaponSystem = null!;
public WallHugSystem WallHugSystem = null!;
public PlayerUi PlayerUi = null!;
public TextureRect DashIndicator = null!;
public ColorRect PowerCooldownIndicator = null!;
public Node3D DashIndicatorNode = null!;
public MeshInstance3D DashIndicatorMesh = null!;
public CylinderMesh DashIndicatorMeshCylinder = null!;
@@ -108,8 +115,6 @@ public partial class PlayerController : CharacterBody3D,
public Variables SharedVariables { get; }
// Inspector stuff
[Export] public Marker3D TutorialWeaponTarget = null!;
[Export] public bool TutorialDone { get; set; }
[Export] public bool HasSword { get; set; } = true;
[Export] public bool HasParry { get; set; } = true;
@@ -117,15 +122,16 @@ public partial class PlayerController : CharacterBody3D,
[ExportCategory("Forge")]
[ExportGroup("General")]
[Export]
public ForgeTagContainer BaseTags { get; set; } = new();
public ForgeTagContainer BaseTags { get; set; }
[Export] public ForgeTag EmpoweredActionUsed;
[ExportGroup("Abilities")]
[ExportSubgroup("Common and defaults")]
[Export] public ForgeAbilityData EmpoweredActionAbility = null!;
[Export] public ForgeAbilityData[] DefaultPermanentAbilities = [];
[ExportSubgroup("WeaponThrow")]
[Export] public ForgeAbilityData[] AbilityLoadout = [];
[ExportSubgroup("WeaponThrow")] [Export]
public ForgeAbilityBehavior WeaponExplosionBehavior;
[ExportGroup("Effects")]
[ExportSubgroup("Common and defaults")]
@@ -350,16 +356,6 @@ public partial class PlayerController : CharacterBody3D,
private Vector3 _dashDirection = Vector3.Zero;
private Vector3 _postDashThroughPosition = Vector3.Zero;
private Vector3 _preDashVelocity = Vector3.Zero;
private int _empoweredActionsLeft;
public int EmpoweredActionsLeft
{
get => _empoweredActionsLeft;
set
{
_empoweredActionsLeft = value;
PlayerUi.SetNumberOfDashesLeft(value);
}
}
// Settings
private float _lookSensitivityMultiplier = 1.0f;
@@ -373,7 +369,6 @@ public partial class PlayerController : CharacterBody3D,
private Timer _weaponThrowUncatchableTimer = null!;
private Timer _simpleDashCooldownTimer = null!;
private Timer _airborneDashCooldownTimer = null!;
private Timer _powerCooldownTimer = null!;
private Timer _invincibilityTimer = null!;
private Timer _attackCooldown = null!;
@@ -381,9 +376,6 @@ public partial class PlayerController : CharacterBody3D,
private StateChart _playerState = null!;
private StateChartState _aiming = null!;
private StateChartState _powerExpired = null!;
private StateChartState _powerRecharging = null!;
private StateChartState _powerFull = null!;
private StateChartState _grounded = null!;
private StateChartState _airborne = null!;
@@ -442,7 +434,7 @@ public partial class PlayerController : CharacterBody3D,
private AbilityHandle? _empoweredActionHandle;
public override void _Ready()
public void OnReady()
{
LoadSettings();
@@ -510,9 +502,6 @@ public partial class PlayerController : CharacterBody3D,
}
// DashIndicator = GetNode<TextureRect>("%DashIndicator");
PowerCooldownIndicator = GetNode<ColorRect>("%DashCooldownIndicator");
PowerCooldownIndicator.Visible = false;
EmpoweredActionsLeft = MaxNumberOfEmpoweredActions;
TargetSpeed = WalkSpeed;
DashIndicatorNode = GetNode<Node3D>("DashIndicator");
DashIndicatorMesh = GetNode<MeshInstance3D>("DashIndicator/DashIndicatorMesh");
@@ -596,9 +585,6 @@ public partial class PlayerController : CharacterBody3D,
_onGroundSlideJump = Transition.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide/OnJump"));
_onAirGlideDoubleJump = Transition.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled/OnJump"));
// _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging"));
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
_powerRecharging = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/AtLeastOneCharge"));
_powerFull = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Full"));
_grounded = StateChartState.Of(GetNode("StateChart/Root/Movement/Grounded"));
_airborne = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne"));
@@ -625,7 +611,6 @@ public partial class PlayerController : CharacterBody3D,
_parryDash = StateChartState.Of(GetNode("StateChart/Root/Attack/DashParry"));
// State timers
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
_weaponThrowUncatchableTimer = GetNode<Timer>("WeaponThrowUncatchable");
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
_simpleDashCooldownTimer = GetNode<Timer>("DashCooldown");
@@ -653,8 +638,6 @@ public partial class PlayerController : CharacterBody3D,
WeaponSystem.Init();
WallHugSystem.Init();
EmpoweredActionsLeft = MaxNumberOfEmpoweredActions;
// if (!TutorialDone)
// PlaceWeaponForTutorial();
@@ -680,13 +663,6 @@ public partial class PlayerController : CharacterBody3D,
_coyoteEnabled.StateEntered += StartCoyoteTime;
_timeScaleAimInAirTimer.Timeout += ResetTimeScale;
_powerFull.StateEntered += StopPowerCooldown;
_powerFull.StateExited += StartPowerCooldown;
_powerRecharging.StateEntered += StartPowerCooldown;
_powerCooldownTimer.Timeout += PowerCooldownExpired;
_powerRecharging.StateProcessing += PowerRecharging;
_powerExpired.StateProcessing += PowerRecharging;
_simpleJump.StateEntered += OnSimpleJumpStarted;
_simpleJump.StatePhysicsProcessing += HandleSimpleJump;
@@ -747,29 +723,21 @@ public partial class PlayerController : CharacterBody3D,
_attackDash.StateEntered += OnDashAttackStarted;
_parryStandard.StateEntered += OnStandardParryStarted;
_parryDash.StateEntered += OnDashParryStarted;
foreach (var weaponLandAbility in AbilityLoadout)
{
var leftGrantAbilityConfig = new GrantAbilityConfig(
weaponLandAbility.GetAbilityData(),
ScalableLevel: new ScalableInt(1),
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
TryActivateOnGrant: false,
TryActivateOnEnable: false,
LevelOverridePolicy: LevelComparison.Higher);
var leftGrantComponent = new GrantAbilityEffectComponent([leftGrantAbilityConfig]);
var leftGrantEffect = new EffectData(
"Grant Weapon Left Ability",
new DurationData(DurationType.Infinite),
effectComponents: [leftGrantComponent]);
EffectsManager.ApplyEffect(new Effect(leftGrantEffect, new EffectOwnership(this, this)));
}
// Forge events
var weaponLeftToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft);
var weaponLandedToken = WeaponSystem.Events.Subscribe(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded);
}
public void OnResolved()
{
// All of my dependencies are now available! Do whatever you want with
// them here.
// Inventory Management
InventoryManager.WeaponEventAbilityAdded += OnWeaponEventAbilityAdded;
InventoryManager.WeaponEventAbilityRemoved += OnWeaponEventAbilityRemoved;
}
public void OnWeaponLeft(EventData data)
{
@@ -780,7 +748,7 @@ public partial class PlayerController : CharacterBody3D,
if (weaponLeftTag == null) return;
Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures);
}
public void OnWeaponLanded(EventData data)
{
var source = data.Source;
@@ -797,6 +765,20 @@ public partial class PlayerController : CharacterBody3D,
target,
out var failures);
}
public void OnWeaponEventAbilityAdded(WeaponEventAbilityData data)
{
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
WeaponSystem.GrantNewAbilityForEvent(data.ForEvent, abilityBehavior);
}
public void OnWeaponEventAbilityRemoved(WeaponEventAbilityData data)
{
if (data.Ability is not ForgeAbilityBehavior abilityBehavior) return;
WeaponSystem.RemoveAbilityForEvent(data.ForEvent, abilityBehavior);
}
///////////////////////////
// Settings & tutorial //
@@ -832,21 +814,6 @@ public partial class PlayerController : CharacterBody3D,
_fovChangeMultiplier = (float) config.GetValue("InputSettings", "FovChangeWithSpeed", 1.0f);
_aimAssistMultiplier = (float) config.GetValue("InputSettings", "AimAssist", 1.0f);
}
public void OnTutorialDone(Node3D _)
{
TutorialDone = true;
}
public void PlaceWeaponForTutorial()
{
if (TutorialDone)
return;
RemoveChild(WeaponSystem);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponSystem);
WeaponSystem.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition);
WeaponSystem.CallDeferred(WeaponSystem.MethodName.PlaceWeaponForTutorial, TutorialWeaponTarget.GlobalPosition);
}
///////////////////////////
// Toolbox Utils //
@@ -1219,7 +1186,7 @@ public partial class PlayerController : CharacterBody3D,
var tween = GetTree().CreateTween();
tween.SetParallel();
tween.SetTrans(Tween.TransitionType.Cubic);
tween.SetEase(Tween.EaseType.InOut);
tween.SetEase(Tween.EaseType.In);
tween.TweenProperty(this, "global_position", targetLocation, tweenTime);
return tween;
@@ -1267,7 +1234,7 @@ public partial class PlayerController : CharacterBody3D,
_currentInputBufferFrames = InputBufferFrames;
_bufferedAction = _mantling.Active ? BufferedActions.MantleDash : BufferedActions.Dash;
if (_airborne.Active)
if (_airborne.Active || _jumping.Active)
{
if (!_canDashAirborne)
return;
@@ -1980,6 +1947,8 @@ public partial class PlayerController : CharacterBody3D,
///////////////////////////
// Slam Management ///////
///////////////////////////
private Vector3 _slamStartPosition = Vector3.Zero;
public void OnInputSlamPressed()
{
_playerState.SendEvent("slam");
@@ -1987,6 +1956,7 @@ public partial class PlayerController : CharacterBody3D,
public void SlamStarted()
{
_slamStartPosition = GlobalPosition;
SetHorizontalVelocity(Vector2.Zero);
SetVerticalVelocity(-SlamSpeed);
_audioStream.SwitchToClipByName("dash");
@@ -1997,11 +1967,16 @@ public partial class PlayerController : CharacterBody3D,
}
public void SlamEnded()
{
var distanceTraveled = GlobalPosition.DistanceTo(_slamStartPosition);
HeadSystem.OnGetHit();
_audioStream.SwitchToClipByName("slam");
if (Explosion.Instantiate() is not Explosion explosion) return;
explosion.Radius = 10f;
// Basic distance traveled explosion manipulation
explosion.Radius = distanceTraveled;
explosion.RDamage.DamageDealt = distanceTraveled;
GetTree().GetRoot().AddChild(explosion);
explosion.GlobalPosition = GlobalPosition;
}
@@ -2009,55 +1984,19 @@ public partial class PlayerController : CharacterBody3D,
///////////////////////////
// Empowerement management //
///////////////////////////
public void PowerRecharging(float delta)
{
var progress = (float) (_powerCooldownTimer.TimeLeft / _powerCooldownTimer.WaitTime);
PowerCooldownIndicator.SetCustomMinimumSize(new Vector2(100 * progress, 10));
}
public void StartPowerCooldown()
{
_powerCooldownTimer.Start();
PowerCooldownIndicator.Visible = true;
}
public void StopPowerCooldown()
{
_powerCooldownTimer.Stop();
PowerCooldownIndicator.Visible = false;
}
public void PowerCooldownExpired()
{
EmpoweredActionsLeft += 1;
var eventToSend = EmpoweredActionsLeft == MaxNumberOfEmpoweredActions ? "fully_charged" : "recharge";
_playerState.SendEvent(eventToSend);
}
public bool CanPerformEmpoweredAction()
{
if(_empoweredActionHandle == null) return false;
var cooldowns = _empoweredActionHandle.GetCooldownData();
foreach (var cd in cooldowns)
{
//GD.Print($"Cooldown remaining: {cd.RemainingTime}");
}
var costs = _empoweredActionHandle.GetCostData();
foreach (var cost in costs)
{
// Assuming you want to check Mana costs
if (cost.Attribute == "PlayerAttributeSet.Mana")
{
//GD.Print($"Mana Cost: {cost.Cost}");
}
}
// var cooldowns = _empoweredActionHandle.GetCooldownData();
// var costs = _empoweredActionHandle.GetCostData();
var canActivate = _empoweredActionHandle.CanActivate(out var failures);
if (!canActivate)
{
GD.PrintErr($"Cannot activate empowered action: {failures}");
if (failures.HasFlag(AbilityActivationFailures.Cooldown)) GD.PrintErr("In Cooldown");
if (failures.HasFlag(AbilityActivationFailures.InsufficientResources)) GD.PrintErr("Not Enough Mana");
}
return canActivate;
return EmpoweredActionsLeft > 0 && TutorialDone;
}
public void PerformEmpoweredAction()
{
@@ -2066,24 +2005,13 @@ public partial class PlayerController : CharacterBody3D,
var canActivate = _empoweredActionHandle.Activate(out var failures);
if (!canActivate)
{
GD.PrintErr($"Cannot activate empowered action: {failures}");
if (failures.HasFlag(AbilityActivationFailures.Cooldown)) GD.PrintErr("In Cooldown");
if (failures.HasFlag(AbilityActivationFailures.InsufficientResources)) GD.PrintErr("Not Enough Mana");
return;
}
else
{
GD.Print($"Remaining mana: {Attributes["PlayerAttributeSet.Mana"].CurrentValue}");
}
// Inhibit Mana Regeneration for a while after using an empowered action
// TODO: Use Forge events instead of relying on direct referencing
// _manaRegenEffectHandle!.SetInhibit(true);
// GetTree().CreateTimer(EmpoweredAction.ManaRegenPause).Timeout += () => {_manaRegenEffectHandle!.SetInhibit(false);};
_isWallJumpAvailable = true;
_canDashAirborne = true;
EmpoweredActionsLeft--;
_playerState.SendEvent(EmpoweredActionsLeft <= 0 ? "expired" : "power_used");
Events.Raise(new EventData<EmpoweredActionPayload>
{
@@ -2128,8 +2056,8 @@ public partial class PlayerController : CharacterBody3D,
public void OnAimingEntered()
{
if (!CanPerformEmpoweredAction())
return;
// if (!CanPerformEmpoweredAction())
// return;
// DashIndicatorMesh.Visible = true;
if (!isOnFloorCustom())
@@ -2143,8 +2071,8 @@ public partial class PlayerController : CharacterBody3D,
// DashIndicatorMeshCylinder.Height = DashSystem.PlannedLocation.DistanceTo(GlobalPosition);
// DashIndicatorNode.LookAt(DashSystem.PlannedLocation);
if (CanPerformEmpoweredAction())
DashSystem.PrepareDash();
// if (CanPerformEmpoweredAction())
DashSystem.PrepareDash();
}
public void OnAimingExited()
{
@@ -2404,20 +2332,14 @@ public partial class PlayerController : CharacterBody3D,
// Manage gameplay systems
MantleSystem.ProcessMantle(_grounded.Active);
HandleEnemyTargeting();
// Manage head and camera movement
LookAround(delta);
}
// private float _oldMana = 100;
public override void _Process(double delta)
{
// Manage head and camera movement
LookAround(delta);
EffectsManager.UpdateEffects(delta);
// TODO: change for actual Cue
// var currentMana = Attributes["PlayerAttributeSet.Mana"].CurrentValue;
// if (Mathf.Abs(currentMana - _oldMana) > Mathf.Epsilon)
// PlayerUi.OnManaChanged(currentMana);
// _oldMana = currentMana;
}
///////////////////////////
@@ -2600,22 +2522,23 @@ public partial class PlayerController : CharacterBody3D,
if (!HasSword) return;
if (_onWallHanging.Active) return;
if (_aiming.Active && WeaponSystem.InHandState.Active && CanPerformEmpoweredAction())
if (_aiming.Active && WeaponSystem.InHandState.Active)
{
ThrowWeapon();
return;
}
if (WeaponSystem.FlyingState.Active)
if (WeaponSystem.FlyingState.Active && CanPerformEmpoweredAction())
{
DashToFlyingWeapon();
return;
}
if (WeaponSystem.PlantedState.Active)
if (WeaponSystem.PlantedState.Active && CanPerformEmpoweredAction())
{
DashToPlantedWeapon();
return;
}
if (!WeaponSystem.InHandState.Active) return;
var attackToDo = _isEnemyInDashAttackRange ? "dash_attack" : "standard_attack";
_playerState.SendEvent(attackToDo);

View File

@@ -94,22 +94,6 @@ public class PlayerControllerUnitTest
AssertFloat(_player.CHealth.CurrentHealth).IsEqual(75.0f);
}
[TestCase]
public void TestEmpoweredActionsLeft()
{
var mockUi = new PlayerUi();
var dashIcons = new TextureRect[3] { new TextureRect(), new TextureRect(), new TextureRect() };
mockUi.DashIcons = dashIcons;
_player.PlayerUi = mockUi;
_player.EmpoweredActionsLeft = 2;
AssertInt(_player.EmpoweredActionsLeft).IsEqual(2);
AssertBool(dashIcons[0].Visible).IsTrue();
AssertBool(dashIcons[1].Visible).IsTrue();
AssertBool(dashIcons[2].Visible).IsFalse();
}
[TestCase]
public void TestDashCooldownTimeout()
{

View File

@@ -9,22 +9,26 @@ extends Node
@export_group("Overlaid")
@export var lost_menu_scene : PackedScene = preload("uid://ciyq8eiv1mtie")
@export var toolbox_scene : PackedScene = preload("uid://bcn582q8qd4ns")
@export var inventory_scene : PackedScene = preload("uid://oq1jjvjs4qga")
@export_category("Others")
@export var focused_viewport : Viewport
@export var toolbox_action:GUIDEAction = preload("uid://ca68r7n3bwba3")
@export var inventory_action:GUIDEAction = preload("uid://7ne5mdytlidm")
# Debug
@onready var debug_layer: CanvasLayer = $"../DebugLayer"
@onready var inventory_layer: CanvasLayer = $"../InventoryLayer"
@onready var player: PlayerController = $"../Player"
func _ready() -> void:
toolbox_action.triggered.connect(open_toolbox)
inventory_action.triggered.connect(open_inventory)
func open_overlaid_menu(menu: PackedScene) -> Node:
if not focused_viewport:
focused_viewport = get_viewport()
var _initial_focus_control = focused_viewport.gui_get_focus_owner()
var _initial_focus_control: Control = focused_viewport.gui_get_focus_owner()
return menu.instantiate()
func open_toolbox() -> void:
@@ -32,6 +36,11 @@ func open_toolbox() -> void:
toolbox.player = player
debug_layer.call_deferred("add_child", toolbox)
func open_inventory() -> void:
var inventory: Control = open_overlaid_menu(inventory_scene)
# inventory.player = player
inventory_layer.call_deferred("add_child", inventory)
func on_player_died() -> void:
var lost_menu: LevelLostMenu = open_overlaid_menu(lost_menu_scene)
get_tree().current_scene.call_deferred("add_child", lost_menu)