Compare commits
6 Commits
release/pl
...
v0.2.58
| Author | SHA1 | Date | |
|---|---|---|---|
| 42ff38f39b | |||
| dafb0c96cc | |||
| ef454e9502 | |||
| cc70fb361b | |||
| 7bf19868e7 | |||
| d1f83525b1 |
2
Movement tests.sln.DotSettings
Normal file
2
Movement tests.sln.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/CodeEditing/SuppressNullableWarningFix/Enabled/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
|
||||||
@@ -9,14 +9,58 @@ public partial class ForgeManager : Node
|
|||||||
public CuesManager CuesManager { get; private set; } = new CuesManager();
|
public CuesManager CuesManager { get; private set; } = new CuesManager();
|
||||||
public TagsManager TagsManager { get; private set; } = new TagsManager(
|
public TagsManager TagsManager { get; private set; } = new TagsManager(
|
||||||
[
|
[
|
||||||
|
// entities
|
||||||
"character.player",
|
"character.player",
|
||||||
"class.warrior",
|
"character.enemy",
|
||||||
|
"weapon",
|
||||||
|
|
||||||
|
// Statuses
|
||||||
"status.stunned",
|
"status.stunned",
|
||||||
"status.burning",
|
|
||||||
"status.immune.fire",
|
"status.weapon.inHand",
|
||||||
"cues.damage.fire",
|
"status.weapon.flying",
|
||||||
|
"status.weapon.planted",
|
||||||
|
|
||||||
|
// Abilities
|
||||||
|
"abilities.weapon.land",
|
||||||
|
"abilities.weapon.flying",
|
||||||
|
"abilities.weapon.left",
|
||||||
|
|
||||||
|
// Events
|
||||||
"events.combat.damage",
|
"events.combat.damage",
|
||||||
"events.combat.hit",
|
"events.combat.hit",
|
||||||
|
|
||||||
|
"events.weapon.flyingTick",
|
||||||
|
"events.weapon.startedFlying",
|
||||||
|
"events.weapon.stoppedFlying",
|
||||||
|
"events.weapon.handToFlying",
|
||||||
|
"events.weapon.flyingToHand",
|
||||||
|
"events.weapon.plantedToHand",
|
||||||
|
"events.weapon.plantedToFlying",
|
||||||
|
"events.weapon.planted",
|
||||||
|
|
||||||
|
// Cooldowns
|
||||||
"cooldown.empoweredAction",
|
"cooldown.empoweredAction",
|
||||||
|
"cooldown.empoweredSwordThrow",
|
||||||
|
|
||||||
|
// Cues
|
||||||
|
"cues.resources.mana",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
public static ForgeManager GetForgeManager(Node node)
|
||||||
|
{
|
||||||
|
return node.GetTree().Root.GetNode<ForgeManager>("ForgeManager");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TagsManager GetTagsManager(Node node)
|
||||||
|
{
|
||||||
|
return GetForgeManager(node).TagsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CuesManager GetCuesManager(Node node)
|
||||||
|
{
|
||||||
|
return GetForgeManager(node).CuesManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
forge/abilities/RAbilityBase.cs
Normal file
26
forge/abilities/RAbilityBase.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using Gamesmiths.Forge.Abilities;
|
||||||
|
using Gamesmiths.Forge.Cues;
|
||||||
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Effects.Components;
|
||||||
|
using Gamesmiths.Forge.Effects.Duration;
|
||||||
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||||
|
using Gamesmiths.Forge.Effects.Modifiers;
|
||||||
|
using Gamesmiths.Forge.Tags;
|
||||||
|
using Godot;
|
||||||
|
using Movementtests.interfaces;
|
||||||
|
|
||||||
|
namespace Movementtests.forge.abilities;
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class RAbilityBase : Resource
|
||||||
|
{
|
||||||
|
public RAbilityBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual AbilityData Ability(TagContainer? tags, Node3D owner)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
forge/abilities/RAbilityBase.cs.uid
Normal file
1
forge/abilities/RAbilityBase.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://4eosgwb3h528
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Gamesmiths.Forge.Abilities;
|
using Gamesmiths.Forge.Abilities;
|
||||||
|
using Gamesmiths.Forge.Cues;
|
||||||
using Gamesmiths.Forge.Effects;
|
using Gamesmiths.Forge.Effects;
|
||||||
using Gamesmiths.Forge.Effects.Components;
|
using Gamesmiths.Forge.Effects.Components;
|
||||||
using Gamesmiths.Forge.Effects.Duration;
|
using Gamesmiths.Forge.Effects.Duration;
|
||||||
@@ -25,7 +26,17 @@ public partial class REmpoweredAction(float cost, float cooldown, float manaRege
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public EffectData CostEffect()
|
public AbilityData Ability(TagsManager tagsManager)
|
||||||
|
{
|
||||||
|
return new AbilityData(
|
||||||
|
name: "Empowered Action",
|
||||||
|
costEffect: CostEffect(tagsManager),
|
||||||
|
cooldownEffects: [CooldownEffect(tagsManager)],
|
||||||
|
instancingPolicy: AbilityInstancingPolicy.PerEntity,
|
||||||
|
behaviorFactory: () => new EmpoweredActionBehavior());
|
||||||
|
}
|
||||||
|
|
||||||
|
public EffectData CostEffect(TagsManager tagsManager)
|
||||||
{
|
{
|
||||||
return new(
|
return new(
|
||||||
"Empowered Action Mana Cost",
|
"Empowered Action Mana Cost",
|
||||||
@@ -40,6 +51,16 @@ public partial class REmpoweredAction(float cost, float cooldown, float manaRege
|
|||||||
new ScalableFloat(-Cost)
|
new ScalableFloat(-Cost)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
cues: new []
|
||||||
|
{
|
||||||
|
new CueData(
|
||||||
|
CueTags: Tag.RequestTag(tagsManager, "cues.resources.mana").GetSingleTagContainer(),
|
||||||
|
MinValue: 0,
|
||||||
|
MaxValue: 100,
|
||||||
|
MagnitudeType: CueMagnitudeType.AttributeValueChange,
|
||||||
|
MagnitudeAttribute: "PlayerAttributeSet.Mana"
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
73
forge/abilities/RExplodingSword.cs
Normal file
73
forge/abilities/RExplodingSword.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using Gamesmiths.Forge.Abilities;
|
||||||
|
using Gamesmiths.Forge.Cues;
|
||||||
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Effects.Components;
|
||||||
|
using Gamesmiths.Forge.Effects.Duration;
|
||||||
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||||
|
using Gamesmiths.Forge.Effects.Modifiers;
|
||||||
|
using Gamesmiths.Forge.Tags;
|
||||||
|
using Godot;
|
||||||
|
using Movementtests.interfaces;
|
||||||
|
using Movementtests.systems;
|
||||||
|
|
||||||
|
namespace Movementtests.forge.abilities;
|
||||||
|
|
||||||
|
public record struct ExplodingSwordCreation(Node3D Owner);
|
||||||
|
|
||||||
|
[GlobalClass, Icon("res://assets/ui/IconGodotNode/white/icon_projectile.png")]
|
||||||
|
public partial class RExplodingSword(PackedScene? explosion) : Resource, IAbilityBase<ExplodingSwordCreation, WeaponEventPayload>
|
||||||
|
{
|
||||||
|
[Export] public PackedScene? Explosion { get; set; } = explosion;
|
||||||
|
|
||||||
|
public RExplodingSword() : this(null) {}
|
||||||
|
|
||||||
|
public AbilityData Ability(ExplodingSwordCreation creationData, TagContainer? tags)
|
||||||
|
{
|
||||||
|
return new AbilityData(
|
||||||
|
name: "Exploding Sword Throw",
|
||||||
|
abilityTags: tags,
|
||||||
|
instancingPolicy: AbilityInstancingPolicy.PerEntity,
|
||||||
|
behaviorFactory: () => new ExplodingSwordThrowBehavior<WeaponEventPayload>(creationData.Owner, Explosion));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAbilityBehavior<WeaponEventPayload> Behavior(ExplodingSwordCreation creationData)
|
||||||
|
{
|
||||||
|
return new ExplodingSwordThrowBehavior<WeaponEventPayload>(creationData.Owner, Explosion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ExplodingSwordThrowBehavior<TPayload>(Node3D owner, PackedScene? explosion) : IAbilityBehavior<TPayload>
|
||||||
|
{
|
||||||
|
private Node3D _owner = owner;
|
||||||
|
private PackedScene? _explosion = explosion;
|
||||||
|
public void OnStarted(AbilityBehaviorContext context, TPayload payload)
|
||||||
|
{
|
||||||
|
if (_explosion?.Instantiate() is not Explosion explosion)
|
||||||
|
{
|
||||||
|
GD.Print("Cannot instantiate");
|
||||||
|
context.InstanceHandle.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_owner.IsInsideTree())
|
||||||
|
{
|
||||||
|
GD.Print("Not inside tree");
|
||||||
|
context.InstanceHandle.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GD.Print("EXPLOSION");
|
||||||
|
|
||||||
|
explosion.Radius = 6f;
|
||||||
|
|
||||||
|
_owner.GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, explosion);
|
||||||
|
explosion.CallDeferred(Node3D.MethodName.SetGlobalPosition, _owner.GlobalPosition);
|
||||||
|
|
||||||
|
context.AbilityHandle.CommitAbility();
|
||||||
|
context.InstanceHandle.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEnded(AbilityBehaviorContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
1
forge/abilities/RExplodingSword.cs.uid
Normal file
1
forge/abilities/RExplodingSword.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://rux15j7q78e8
|
||||||
30
forge/calculators/FlyingWeaponExecution.cs
Normal file
30
forge/calculators/FlyingWeaponExecution.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Gamesmiths.Forge.Attributes;
|
||||||
|
using Gamesmiths.Forge.Core;
|
||||||
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Effects.Calculator;
|
||||||
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||||
|
using Gamesmiths.Forge.Effects.Modifiers;
|
||||||
|
using Gamesmiths.Forge.Events;
|
||||||
|
using Godot;
|
||||||
|
using Movementtests.systems;
|
||||||
|
|
||||||
|
namespace Movementtests.tools.calculators;
|
||||||
|
|
||||||
|
|
||||||
|
public class FlyingWeaponExecution(WeaponSystem weaponSystem) : CustomExecution
|
||||||
|
{
|
||||||
|
public override ModifierEvaluatedData[] EvaluateExecution(Effect effect, IForgeEntity target, EffectEvaluatedData? effectEvaluatedData)
|
||||||
|
{
|
||||||
|
GD.Print("Custom execution executed");
|
||||||
|
weaponSystem.Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = weaponSystem.WeaponFlyingTickEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = weaponSystem,
|
||||||
|
EventMagnitude = 12f,
|
||||||
|
Payload = new WeaponEventPayload(Message: "flying")
|
||||||
|
});
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
1
forge/calculators/FlyingWeaponExecution.cs.uid
Normal file
1
forge/calculators/FlyingWeaponExecution.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://br7ut4lbau66w
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
|
using Gamesmiths.Forge.Cues;
|
||||||
using Gamesmiths.Forge.Effects;
|
using Gamesmiths.Forge.Effects;
|
||||||
using Gamesmiths.Forge.Effects.Duration;
|
using Gamesmiths.Forge.Effects.Duration;
|
||||||
using Gamesmiths.Forge.Effects.Magnitudes;
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||||
using Gamesmiths.Forge.Effects.Modifiers;
|
using Gamesmiths.Forge.Effects.Modifiers;
|
||||||
using Gamesmiths.Forge.Effects.Periodic;
|
using Gamesmiths.Forge.Effects.Periodic;
|
||||||
|
using Gamesmiths.Forge.Tags;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace Movementtests.tools.effects;
|
namespace Movementtests.tools.effects;
|
||||||
@@ -20,7 +22,7 @@ public partial class RManaRegen(float manaRegenRate, float frequency) : Resource
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public EffectData ManaRegen()
|
public EffectData ManaRegen(TagsManager tagsManager)
|
||||||
{
|
{
|
||||||
return new EffectData(
|
return new EffectData(
|
||||||
"Mana Regen",
|
"Mana Regen",
|
||||||
@@ -36,6 +38,16 @@ public partial class RManaRegen(float manaRegenRate, float frequency) : Resource
|
|||||||
new ScalableFloat(ManaRegenRate * Frequency))
|
new ScalableFloat(ManaRegenRate * Frequency))
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
cues: new []
|
||||||
|
{
|
||||||
|
new CueData(
|
||||||
|
CueTags: Tag.RequestTag(tagsManager, "cues.resources.mana").GetSingleTagContainer(),
|
||||||
|
MinValue: 0,
|
||||||
|
MaxValue: 100,
|
||||||
|
MagnitudeType: CueMagnitudeType.AttributeValueChange,
|
||||||
|
MagnitudeAttribute: "PlayerAttributeSet.Mana"
|
||||||
|
)
|
||||||
|
},
|
||||||
periodicData: new PeriodicData(
|
periodicData: new PeriodicData(
|
||||||
Period: new ScalableFloat(Frequency),
|
Period: new ScalableFloat(Frequency),
|
||||||
ExecuteOnApplication: true,
|
ExecuteOnApplication: true,
|
||||||
|
|||||||
12
interfaces/IAbilityBase.cs
Normal file
12
interfaces/IAbilityBase.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Gamesmiths.Forge.Abilities;
|
||||||
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Tags;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Movementtests.interfaces;
|
||||||
|
|
||||||
|
public interface IAbilityBase<TCreation, TPayload>
|
||||||
|
{
|
||||||
|
AbilityData Ability(TCreation creationData, TagContainer? tags);
|
||||||
|
IAbilityBehavior<TPayload> Behavior(TCreation creationData);
|
||||||
|
}
|
||||||
1
interfaces/IAbilityBase.cs.uid
Normal file
1
interfaces/IAbilityBase.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://de881c2xsbutk
|
||||||
@@ -90,8 +90,7 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
var baseTags = new TagContainer(
|
var baseTags = new TagContainer(
|
||||||
forgeManager.TagsManager,
|
forgeManager.TagsManager,
|
||||||
[
|
[
|
||||||
Tag.RequestTag(forgeManager.TagsManager, "character.player"),
|
Tag.RequestTag(forgeManager.TagsManager, "character.enemy")
|
||||||
Tag.RequestTag(forgeManager.TagsManager, "class.warrior")
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Attributes = new EntityAttributes(new EnemyAttributeSet());
|
Attributes = new EntityAttributes(new EnemyAttributeSet());
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"]
|
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://inputs/base_mode/base_mode.tres" id="3_cresl"]
|
||||||
[ext_resource type="Resource" uid="uid://dtmhtlix2amme" path="res://scenes/player_controller/resources/player_mana_regen.tres" id="3_n24vh"]
|
[ext_resource type="Resource" uid="uid://dtmhtlix2amme" path="res://scenes/player_controller/resources/player_mana_regen.tres" id="3_n24vh"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://scenes/components/health/CHealth.tscn" id="3_q7bng"]
|
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://scenes/components/health/CHealth.tscn" id="3_q7bng"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cdxbwirfiaipi" path="res://scenes/player_controller/resources/forge/exploding_sword_throw.tres" id="4_11013"]
|
||||||
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="4_abfq8"]
|
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://scenes/components/health/RHealth.cs" id="4_abfq8"]
|
||||||
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://scenes/player_controller/resources/player_health.tres" id="4_m8gvy"]
|
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://scenes/player_controller/resources/player_health.tres" id="4_m8gvy"]
|
||||||
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
|
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="6_q7bng"]
|
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://inputs/base_mode/move_right.tres" id="6_q7bng"]
|
||||||
[ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://scenes/player_controller/scripts/StairsSystem.cs" id="7_bmt5a"]
|
[ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://scenes/player_controller/scripts/StairsSystem.cs" id="7_bmt5a"]
|
||||||
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://inputs/base_mode/move_front.tres" id="7_m8gvy"]
|
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://inputs/base_mode/move_front.tres" id="7_m8gvy"]
|
||||||
[ext_resource type="Resource" uid="uid://7dpkk5rk3di5" path="res://scenes/player_controller/resources/forge_empowered_action.tres" id="7_qheee"]
|
[ext_resource type="Resource" uid="uid://7dpkk5rk3di5" path="res://scenes/player_controller/resources/forge/empowered_action.tres" id="7_qheee"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="7_x835q"]
|
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://scenes/components/knockback/CKnockback.tscn" id="7_x835q"]
|
||||||
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://inputs/base_mode/move_back.tres" id="8_jb43f"]
|
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://inputs/base_mode/move_back.tres" id="8_jb43f"]
|
||||||
[ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://inputs/base_mode/aim_release.tres" id="8_lhb11"]
|
[ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://inputs/base_mode/aim_release.tres" id="8_lhb11"]
|
||||||
@@ -119,6 +120,7 @@ collision_mask = 272
|
|||||||
script = ExtResource("1_poq2x")
|
script = ExtResource("1_poq2x")
|
||||||
EmpoweredAction = ExtResource("7_qheee")
|
EmpoweredAction = ExtResource("7_qheee")
|
||||||
ManaRegen = ExtResource("3_n24vh")
|
ManaRegen = ExtResource("3_n24vh")
|
||||||
|
AbilityLoadout = [ExtResource("4_11013")]
|
||||||
AimAssistStrength = 0.3
|
AimAssistStrength = 0.3
|
||||||
AimAssistReductionWhenCloseToTarget = 0.1
|
AimAssistReductionWhenCloseToTarget = 0.1
|
||||||
AimAssistReductionStartDistance = 8.0
|
AimAssistReductionStartDistance = 8.0
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
using System;
|
||||||
|
using Gamesmiths.Forge.Core;
|
||||||
|
using Gamesmiths.Forge.Cues;
|
||||||
|
using Gamesmiths.Forge.Tags;
|
||||||
using Movementtests.interfaces;
|
using Movementtests.interfaces;
|
||||||
|
using Movementtests.tools;
|
||||||
|
|
||||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
|
[GlobalClass, Icon("res://assets/ui/IconGodotNode/control/icon_text_panel.png")]
|
||||||
public partial class PlayerUi : Control
|
public partial class PlayerUi : Control, ICueHandler
|
||||||
{
|
{
|
||||||
internal TextureRect[] DashIcons = new TextureRect[3];
|
internal TextureRect[] DashIcons = new TextureRect[3];
|
||||||
private TextureRect _enemyTarget = null!;
|
private TextureRect _enemyTarget = null!;
|
||||||
@@ -33,11 +37,17 @@ public partial class PlayerUi : Control
|
|||||||
_enemyTarget = GetNode<TextureRect>("%EnemyTarget");
|
_enemyTarget = GetNode<TextureRect>("%EnemyTarget");
|
||||||
_healthbar = GetNode<Healthbar>("%Healthbar");
|
_healthbar = GetNode<Healthbar>("%Healthbar");
|
||||||
_manabar = GetNode<Healthbar>("%Manabar");
|
_manabar = GetNode<Healthbar>("%Manabar");
|
||||||
|
|
||||||
|
var forgeManager = GetTree().Root.GetNode<ForgeManager>("ForgeManager")!;
|
||||||
|
var tagsManager = forgeManager.TagsManager;
|
||||||
|
var cuesManager = forgeManager.CuesManager;
|
||||||
|
cuesManager.RegisterCue(Tag.RequestTag(tagsManager, "cues.resources.mana"), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(float initialHealth)
|
public void Initialize(float initialHealth, float initialMana)
|
||||||
{
|
{
|
||||||
_healthbar.Initialize(initialHealth);
|
_healthbar.Initialize(initialHealth);
|
||||||
|
_manabar.Initialize(initialMana);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEnemyTargetProperties(TargetProperties targetProperties)
|
public void SetEnemyTargetProperties(TargetProperties targetProperties)
|
||||||
@@ -77,4 +87,24 @@ public partial class PlayerUi : Control
|
|||||||
{
|
{
|
||||||
_manabar.CurrentHealth = newValue;
|
_manabar.CurrentHealth = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
|
||||||
|
{
|
||||||
|
if (target == null || !parameters.HasValue || !IsInstanceValid(_manabar)) return;
|
||||||
|
|
||||||
|
float magnitude = parameters.Value.Magnitude;
|
||||||
|
_manabar.CurrentHealth += magnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnApply(IForgeEntity? target, CueParameters? parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnRemove(IForgeEntity? target, bool interrupted)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Gamesmiths.Forge.Attributes;
|
||||||
|
|
||||||
|
namespace Movementtests.scenes.player_controller.components.weapon;
|
||||||
|
|
||||||
|
public class WeaponAttributeSet : AttributeSet
|
||||||
|
{
|
||||||
|
public EntityAttribute Level { get; }
|
||||||
|
|
||||||
|
public WeaponAttributeSet()
|
||||||
|
{
|
||||||
|
Level = InitializeAttribute(nameof(Level), 1, 1, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://mvc3bv0p021
|
||||||
@@ -1,13 +1,44 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Gamesmiths.Forge.Abilities;
|
||||||
|
using Gamesmiths.Forge.Core;
|
||||||
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Effects.Calculator;
|
||||||
|
using Gamesmiths.Forge.Effects.Components;
|
||||||
|
using Gamesmiths.Forge.Effects.Duration;
|
||||||
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||||
|
using Gamesmiths.Forge.Effects.Periodic;
|
||||||
|
using Gamesmiths.Forge.Events;
|
||||||
|
using Gamesmiths.Forge.Tags;
|
||||||
using Godot;
|
using Godot;
|
||||||
using GodotStateCharts;
|
using GodotStateCharts;
|
||||||
|
using Movementtests.addons.godot_state_charts.csharp;
|
||||||
|
using Movementtests.forge.abilities;
|
||||||
using Movementtests.interfaces;
|
using Movementtests.interfaces;
|
||||||
|
using Movementtests.scenes.player_controller.components.weapon;
|
||||||
using Movementtests.systems.damage;
|
using Movementtests.systems.damage;
|
||||||
|
using Movementtests.tools;
|
||||||
|
using Movementtests.tools.calculators;
|
||||||
|
|
||||||
namespace Movementtests.systems;
|
namespace Movementtests.systems;
|
||||||
|
|
||||||
|
public record struct WeaponEventPayload(String Message);
|
||||||
|
|
||||||
|
|
||||||
|
public class ClosureBehavior<TPayload>(
|
||||||
|
Action<AbilityBehaviorContext, TPayload> callback) : IAbilityBehavior<TPayload>
|
||||||
|
{
|
||||||
|
public void OnStarted(AbilityBehaviorContext context, TPayload data)
|
||||||
|
{
|
||||||
|
callback(context, data);
|
||||||
|
context.InstanceHandle.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEnded(AbilityBehaviorContext context){}
|
||||||
|
}
|
||||||
|
|
||||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png")]
|
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_sword.png")]
|
||||||
public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
public partial class WeaponSystem : RigidBody3D, IDamageDealer, IForgeEntity
|
||||||
{
|
{
|
||||||
[Signal]
|
[Signal]
|
||||||
public delegate void WeaponThrownEventHandler();
|
public delegate void WeaponThrownEventHandler();
|
||||||
@@ -22,11 +53,24 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
|
[Export(PropertyHint.Range, "0,0.2,0.01,or_greater")]
|
||||||
public float StraightThrowDuration { get; set; } = 0.1f;
|
public float StraightThrowDuration { get; set; } = 0.1f;
|
||||||
|
|
||||||
private StateChart _weaponState = null!;
|
public EntityAttributes Attributes { get; set; } = null!;
|
||||||
|
public EntityTags Tags { get; set; } = null!;
|
||||||
|
public EffectsManager EffectsManager { get; set; } = null!;
|
||||||
|
public EntityAbilities Abilities { get; set; } = null!;
|
||||||
|
public EventManager Events { get; set; } = null!;
|
||||||
|
|
||||||
|
private StateChart _weaponState = null!;
|
||||||
public StateChartState InHandState = null!;
|
public StateChartState InHandState = null!;
|
||||||
public StateChartState FlyingState = null!;
|
public StateChartState FlyingState = null!;
|
||||||
public StateChartState PlantedState = null!;
|
public StateChartState PlantedState = null!;
|
||||||
|
private Transition _handToFlying = null!;
|
||||||
|
private Transition _flyingToHand = null!;
|
||||||
|
private Transition _plantedToHand = null!;
|
||||||
|
private Transition _plantedToFlying = null!;
|
||||||
|
private Transition _toPlanted = null!;
|
||||||
|
|
||||||
private ShapeCast3D _dashCast3D = null!;
|
private ShapeCast3D _dashCast3D = null!;
|
||||||
|
public Timer WeaponFlyingTick = null!;
|
||||||
|
|
||||||
private Transform3D _startTransform;
|
private Transform3D _startTransform;
|
||||||
private Vector3 _startMeshRotation;
|
private Vector3 _startMeshRotation;
|
||||||
@@ -40,17 +84,42 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!;
|
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; } = null!;
|
||||||
public MeshInstance3D WeaponMesh { get; set; } = null!;
|
public MeshInstance3D WeaponMesh { get; set; } = null!;
|
||||||
|
|
||||||
|
public Tag WeaponFlyingTickEventTag;
|
||||||
|
public Tag WeaponStartedFlyingEventTag;
|
||||||
|
public Tag WeaponStoppedFlyingEventTag;
|
||||||
|
public Tag WeaponHandToFlyingEventTag;
|
||||||
|
public Tag WeaponFlyingToHandEventTag;
|
||||||
|
public Tag WeaponPlantedToHandEventTag;
|
||||||
|
public Tag WeaponPlantedToFlyingEventTag;
|
||||||
|
public Tag WeaponPlantedEventTag;
|
||||||
|
|
||||||
|
public Tag WeaponInHandStatusTag;
|
||||||
|
public Tag WeaponFlyingStatusTag;
|
||||||
|
public Tag WeaponPlantedStatusTag;
|
||||||
|
|
||||||
|
public Tag WeaponFlyingAbilityTag;
|
||||||
|
|
||||||
|
private RAbilityBase? _flyingAbility;
|
||||||
|
public List<RAbilityBase> AbilityLoadout { get; } = [];
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
_weaponState = StateChart.Of(GetNode("StateChart"));
|
_weaponState = StateChart.Of(GetNode("StateChart"));
|
||||||
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
|
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
|
||||||
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying"));
|
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying"));
|
||||||
PlantedState = StateChartState.Of(GetNode("StateChart/Root/Planted"));
|
PlantedState = StateChartState.Of(GetNode("StateChart/Root/Planted"));
|
||||||
|
_handToFlying = Transition.Of(GetNode("StateChart/Root/InHand/ToFlying"));
|
||||||
|
_flyingToHand = Transition.Of(GetNode("StateChart/Root/Flying/ToHand"));
|
||||||
|
_plantedToHand = Transition.Of(GetNode("StateChart/Root/Planted/ToHand"));
|
||||||
|
_plantedToFlying = Transition.Of(GetNode("StateChart/Root/Planted/ToFlying"));
|
||||||
|
_toPlanted = Transition.Of(GetNode("StateChart/Root/ToPlanted"));
|
||||||
|
|
||||||
WeaponLocationIndicator = GetNode<MeshInstance3D>("WeaponLocationIndicator");
|
WeaponLocationIndicator = GetNode<MeshInstance3D>("WeaponLocationIndicator");
|
||||||
WeaponLocationIndicator.Visible = false;
|
WeaponLocationIndicator.Visible = false;
|
||||||
WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!;
|
WeaponLocationIndicatorMaterial = (WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D)!;
|
||||||
|
|
||||||
|
WeaponFlyingTick = GetNode<Timer>("WeaponFlyingTick");
|
||||||
|
|
||||||
WeaponMesh = GetNode<MeshInstance3D>("Weapon");
|
WeaponMesh = GetNode<MeshInstance3D>("Weapon");
|
||||||
_startMeshRotation = WeaponMesh.Rotation;
|
_startMeshRotation = WeaponMesh.Rotation;
|
||||||
|
|
||||||
@@ -58,10 +127,180 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
Freeze = true;
|
Freeze = true;
|
||||||
Visible = false;
|
Visible = false;
|
||||||
|
|
||||||
|
// Forge
|
||||||
|
var tagsManager = ForgeManager.GetTagsManager(this);
|
||||||
|
var cuesManager = ForgeManager.GetCuesManager(this);
|
||||||
|
|
||||||
|
WeaponFlyingTickEventTag = Tag.RequestTag(tagsManager, "events.weapon.flyingTick");
|
||||||
|
WeaponStartedFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.startedFlying");
|
||||||
|
WeaponStoppedFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.stoppedFlying");
|
||||||
|
WeaponHandToFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.handToFlying");
|
||||||
|
WeaponFlyingToHandEventTag = Tag.RequestTag(tagsManager, "events.weapon.flyingToHand");
|
||||||
|
WeaponPlantedToHandEventTag = Tag.RequestTag(tagsManager, "events.weapon.plantedToHand");
|
||||||
|
WeaponPlantedToFlyingEventTag = Tag.RequestTag(tagsManager, "events.weapon.plantedToFlying");
|
||||||
|
WeaponPlantedEventTag = Tag.RequestTag(tagsManager, "events.weapon.planted");
|
||||||
|
|
||||||
|
WeaponInHandStatusTag = Tag.RequestTag(tagsManager, "status.weapon.inHand");
|
||||||
|
WeaponFlyingStatusTag = Tag.RequestTag(tagsManager, "status.weapon.flying");
|
||||||
|
WeaponPlantedStatusTag = Tag.RequestTag(tagsManager, "status.weapon.planted");
|
||||||
|
|
||||||
|
WeaponFlyingAbilityTag = Tag.RequestTag(tagsManager,"abilities.weapon.flying");
|
||||||
|
|
||||||
|
var baseTags = new TagContainer(
|
||||||
|
tagsManager,
|
||||||
|
[
|
||||||
|
Tag.RequestTag(tagsManager, "weapon"),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Attributes = new EntityAttributes(new WeaponAttributeSet());
|
||||||
|
Tags = new EntityTags(baseTags);
|
||||||
|
EffectsManager = new EffectsManager(this, cuesManager);
|
||||||
|
Abilities = new(this);
|
||||||
|
Events = new();
|
||||||
|
|
||||||
|
CreateFlyingAbility();
|
||||||
|
|
||||||
BodyEntered += OnThrownWeaponReachesGround;
|
BodyEntered += OnThrownWeaponReachesGround;
|
||||||
|
|
||||||
InHandState.StateExited += WeaponLeft;
|
InHandState.StateExited += WeaponLeft;
|
||||||
InHandState.StateEntered += WeaponBack;
|
InHandState.StateEntered += WeaponBack;
|
||||||
|
|
||||||
|
_handToFlying.Taken += () =>
|
||||||
|
{
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponHandToFlyingEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "handToFlying")
|
||||||
|
});
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponStartedFlyingEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "startedFlying")
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_flyingToHand.Taken += () =>
|
||||||
|
{
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponFlyingToHandEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "flyingToHand")
|
||||||
|
});
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponStoppedFlyingEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "stoppedFlying")
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_plantedToHand.Taken += () =>
|
||||||
|
{
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponPlantedToHandEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "plantedToHand")
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_plantedToFlying.Taken += () =>
|
||||||
|
{
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponPlantedToFlyingEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "plantedToFlying")
|
||||||
|
});
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponStartedFlyingEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "startedFlying")
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_toPlanted.Taken += () =>
|
||||||
|
{
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponPlantedEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Target = _plantedEntity,
|
||||||
|
Payload = new WeaponEventPayload(Message: "planted")
|
||||||
|
});
|
||||||
|
Events.Raise(new EventData<WeaponEventPayload>
|
||||||
|
{
|
||||||
|
EventTags = WeaponStoppedFlyingEventTag.GetSingleTagContainer()!,
|
||||||
|
Source = this,
|
||||||
|
Payload = new WeaponEventPayload(Message: "stoppedFlying")
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Events.Subscribe<WeaponEventPayload>(WeaponStoppedFlyingEventTag, data =>
|
||||||
|
{
|
||||||
|
GD.Print("This is removing the periodic effect to the flying weapon");
|
||||||
|
GD.Print(data.Payload.Message);
|
||||||
|
if (_flyingWeaponEffectHandle is { IsValid: true }) EffectsManager.RemoveEffect(_flyingWeaponEffectHandle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private ActiveEffectHandle? _flyingWeaponEffectHandle;
|
||||||
|
|
||||||
|
public void CreateFlyingAbility()
|
||||||
|
{
|
||||||
|
var flyingWeaponEffectData = new EffectData(
|
||||||
|
"Flying Weapon Effect Data",
|
||||||
|
new DurationData(DurationType.Infinite),
|
||||||
|
customExecutions:
|
||||||
|
[
|
||||||
|
new FlyingWeaponExecution(this)
|
||||||
|
],
|
||||||
|
periodicData: new PeriodicData(new ScalableFloat(0.2f), false, PeriodInhibitionRemovedPolicy.ResetPeriod)
|
||||||
|
);
|
||||||
|
|
||||||
|
var weaponHandToFlyingAbilityData = new AbilityData(
|
||||||
|
name: "WeaponHandToFlyingSword",
|
||||||
|
abilityTags: WeaponFlyingAbilityTag.GetSingleTagContainer(),
|
||||||
|
instancingPolicy: AbilityInstancingPolicy.PerEntity,
|
||||||
|
abilityTriggerData: AbilityTriggerData.ForEvent<WeaponEventPayload>(WeaponStartedFlyingEventTag),
|
||||||
|
behaviorFactory: () => new ClosureBehavior<WeaponEventPayload>((ctx, payload) =>
|
||||||
|
{
|
||||||
|
GD.Print("This is applying the periodic effect to the flying weapon");
|
||||||
|
GD.Print(payload.Message);
|
||||||
|
_flyingWeaponEffectHandle = EffectsManager.ApplyEffect(new Effect(flyingWeaponEffectData, new EffectOwnership(this, this)));
|
||||||
|
}));
|
||||||
|
Abilities.GrantAbilityPermanently(weaponHandToFlyingAbilityData, 1, LevelComparison.None, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GrantNewAbilityForWeaponFly(RExplodingSword ability)
|
||||||
|
{
|
||||||
|
var weaponFlyingAbilityData = new AbilityData(
|
||||||
|
name: "WeaponFlyingSwordAbility",
|
||||||
|
abilityTags: WeaponFlyingAbilityTag.GetSingleTagContainer(),
|
||||||
|
instancingPolicy: AbilityInstancingPolicy.PerEntity,
|
||||||
|
abilityTriggerData: AbilityTriggerData.ForEvent<WeaponEventPayload>(WeaponFlyingTickEventTag),
|
||||||
|
behaviorFactory: () => ability.Behavior(new ExplodingSwordCreation(this)));
|
||||||
|
|
||||||
|
var weaponFlyGrantAbilityConfig = new GrantAbilityConfig(
|
||||||
|
weaponFlyingAbilityData,
|
||||||
|
ScalableLevel: new ScalableInt(1),
|
||||||
|
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
|
||||||
|
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
|
||||||
|
TryActivateOnGrant: false,
|
||||||
|
TryActivateOnEnable: false,
|
||||||
|
LevelOverridePolicy: LevelComparison.Higher);
|
||||||
|
|
||||||
|
var weaponFlyGrantComponent = new GrantAbilityEffectComponent([weaponFlyGrantAbilityConfig]);
|
||||||
|
var weaponFlyGrantEffect = new EffectData(
|
||||||
|
"Grant Weapon Fly Ability",
|
||||||
|
new DurationData(DurationType.Infinite),
|
||||||
|
effectComponents: [weaponFlyGrantComponent]);
|
||||||
|
EffectsManager.ApplyEffect(new Effect(weaponFlyGrantEffect, new EffectOwnership(this, this)));
|
||||||
|
|
||||||
|
GD.Print("New weapon flight ability granted");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WeaponLeft()
|
public void WeaponLeft()
|
||||||
@@ -90,14 +329,11 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
{
|
{
|
||||||
_weaponState.SendEvent("throw");
|
_weaponState.SendEvent("throw");
|
||||||
|
|
||||||
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 1f, 1f);
|
|
||||||
|
|
||||||
_throwDirection = (end - GlobalPosition).Normalized();
|
_throwDirection = (end - GlobalPosition).Normalized();
|
||||||
PlantLocation = collisionLocation;
|
PlantLocation = collisionLocation;
|
||||||
PlantNormal = collisionNormal;
|
PlantNormal = collisionNormal;
|
||||||
LookAt(end);
|
LookAt(end);
|
||||||
|
|
||||||
|
|
||||||
var tween = GetTree().CreateTween();
|
var tween = GetTree().CreateTween();
|
||||||
tween.TweenProperty(this, "global_position", end, StraightThrowDuration);
|
tween.TweenProperty(this, "global_position", end, StraightThrowDuration);
|
||||||
if (hasHit)
|
if (hasHit)
|
||||||
@@ -109,11 +345,15 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
tween.Finished += ThrowWeaponOnCurve;
|
tween.Finished += ThrowWeaponOnCurve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IForgeEntity? _plantedEntity;
|
||||||
public void PlantInEnemy(Node3D enemy)
|
public void PlantInEnemy(Node3D enemy)
|
||||||
{
|
{
|
||||||
GetTree().GetRoot().CallDeferred(Node.MethodName.RemoveChild, this);
|
GetTree().GetRoot().CallDeferred(Node.MethodName.RemoveChild, this);
|
||||||
enemy.CallDeferred(Node.MethodName.AddChild, this);
|
enemy.CallDeferred(Node.MethodName.AddChild, this);
|
||||||
|
|
||||||
|
if (enemy is IForgeEntity victim) _plantedEntity = victim;
|
||||||
|
else _plantedEntity = null;
|
||||||
|
|
||||||
if (enemy is IDamageable damageable)
|
if (enemy is IDamageable damageable)
|
||||||
{
|
{
|
||||||
damageable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
|
damageable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
|
||||||
@@ -123,6 +363,7 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
public void RethrowWeapon()
|
public void RethrowWeapon()
|
||||||
{
|
{
|
||||||
_weaponState.SendEvent("throw");
|
_weaponState.SendEvent("throw");
|
||||||
|
|
||||||
_throwDirection = Vector3.Up;
|
_throwDirection = Vector3.Up;
|
||||||
ThrowWeaponOnCurve();
|
ThrowWeaponOnCurve();
|
||||||
}
|
}
|
||||||
@@ -135,16 +376,15 @@ public partial class WeaponSystem : RigidBody3D, IDamageDealer
|
|||||||
|
|
||||||
public void PlantWeaponInWall()
|
public void PlantWeaponInWall()
|
||||||
{
|
{
|
||||||
_weaponState.SendEvent("plant");
|
|
||||||
|
|
||||||
Freeze = true;
|
Freeze = true;
|
||||||
WeaponMesh.Rotation = _startMeshRotation;
|
WeaponMesh.Rotation = _startMeshRotation;
|
||||||
|
|
||||||
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
|
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
|
||||||
if (PlantObject is Node3D node)
|
if (PlantObject is Node3D node)
|
||||||
{
|
|
||||||
PlantInEnemy(node);
|
PlantInEnemy(node);
|
||||||
}
|
|
||||||
|
_weaponState.SendEvent("plant");
|
||||||
|
|
||||||
CallDeferred(Node3D.MethodName.SetGlobalPosition, PlantLocation);
|
CallDeferred(Node3D.MethodName.SetGlobalPosition, PlantLocation);
|
||||||
CallDeferred(Node3D.MethodName.LookAt, GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
|
CallDeferred(Node3D.MethodName.LookAt, GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ max_contacts_reported = 1
|
|||||||
script = ExtResource("1_csqwk")
|
script = ExtResource("1_csqwk")
|
||||||
RDamage = SubResource("Resource_jpdh0")
|
RDamage = SubResource("Resource_jpdh0")
|
||||||
|
|
||||||
|
[node name="WeaponFlyingTick" type="Timer" parent="." unique_id=656309486]
|
||||||
|
wait_time = 0.2
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=884463982]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=884463982]
|
||||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
|
||||||
shape = SubResource("CylinderShape3D_avini")
|
shape = SubResource("CylinderShape3D_avini")
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[gd_resource type="Resource" script_class="RExplodingSword" format=3 uid="uid://cdxbwirfiaipi"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://duju3atqgltkg" path="res://scenes/explosion/explosion.tscn" id="1_aru71"]
|
||||||
|
[ext_resource type="Script" path="res://forge/abilities/RExplodingSword.cs" id="2_syk3q"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("2_syk3q")
|
||||||
|
Explosion = ExtResource("1_aru71")
|
||||||
|
Cost = 10.0
|
||||||
|
metadata/_custom_type_script = "uid://rux15j7q78e8"
|
||||||
@@ -3,7 +3,14 @@ using System.Collections.Generic;
|
|||||||
using Gamesmiths.Forge.Abilities;
|
using Gamesmiths.Forge.Abilities;
|
||||||
using Gamesmiths.Forge.Core;
|
using Gamesmiths.Forge.Core;
|
||||||
using Gamesmiths.Forge.Effects;
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Effects.Calculator;
|
||||||
|
using Gamesmiths.Forge.Effects.Components;
|
||||||
|
using Gamesmiths.Forge.Effects.Duration;
|
||||||
|
using Gamesmiths.Forge.Effects.Magnitudes;
|
||||||
|
using Gamesmiths.Forge.Effects.Modifiers;
|
||||||
|
using Gamesmiths.Forge.Effects.Periodic;
|
||||||
using Gamesmiths.Forge.Events;
|
using Gamesmiths.Forge.Events;
|
||||||
|
using Gamesmiths.Forge.Godot.Resources.Abilities;
|
||||||
using Gamesmiths.Forge.Tags;
|
using Gamesmiths.Forge.Tags;
|
||||||
|
|
||||||
using Godot;
|
using Godot;
|
||||||
@@ -16,6 +23,7 @@ using Movementtests.player_controller.Scripts;
|
|||||||
using Movementtests.scenes.player_controller.scripts;
|
using Movementtests.scenes.player_controller.scripts;
|
||||||
using Movementtests.tools;
|
using Movementtests.tools;
|
||||||
using Movementtests.forge.abilities;
|
using Movementtests.forge.abilities;
|
||||||
|
using Movementtests.tools.calculators;
|
||||||
using Movementtests.tools.effects;
|
using Movementtests.tools.effects;
|
||||||
using RustyOptions;
|
using RustyOptions;
|
||||||
|
|
||||||
@@ -103,6 +111,10 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
[Export] public REmpoweredAction EmpoweredAction = null!;
|
[Export] public REmpoweredAction EmpoweredAction = null!;
|
||||||
[Export] public RManaRegen ManaRegen = null!;
|
[Export] public RManaRegen ManaRegen = null!;
|
||||||
|
|
||||||
|
[ExportGroup("Abilities")]
|
||||||
|
[ExportSubgroup("WeaponThrow")]
|
||||||
|
[Export] public RExplodingSword[] AbilityLoadout = [];
|
||||||
|
|
||||||
// Combat stuff
|
// Combat stuff
|
||||||
[ExportCategory("Combat")]
|
[ExportCategory("Combat")]
|
||||||
[ExportGroup("General")]
|
[ExportGroup("General")]
|
||||||
@@ -429,27 +441,21 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
|
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
|
||||||
|
|
||||||
// Forge stuff
|
// Forge stuff
|
||||||
var forgeManager = GetTree().Root.GetNode<ForgeManager>("ForgeManager")!;
|
var tagsManager = ForgeManager.GetTagsManager(this);
|
||||||
|
var cuesManager = ForgeManager.GetCuesManager(this);
|
||||||
var baseTags = new TagContainer(
|
var baseTags = new TagContainer(
|
||||||
forgeManager.TagsManager,
|
tagsManager,
|
||||||
[
|
[
|
||||||
Tag.RequestTag(forgeManager.TagsManager, "character.player"),
|
Tag.RequestTag(tagsManager, "character.player")
|
||||||
Tag.RequestTag(forgeManager.TagsManager, "class.warrior")
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Attributes = new EntityAttributes(new PlayerAttributeSet());
|
Attributes = new EntityAttributes(new PlayerAttributeSet());
|
||||||
Tags = new EntityTags(baseTags);
|
Tags = new EntityTags(baseTags);
|
||||||
EffectsManager = new EffectsManager(this, forgeManager.CuesManager);
|
EffectsManager = new EffectsManager(this, cuesManager);
|
||||||
Abilities = new(this);
|
Abilities = new(this);
|
||||||
Events = new();
|
Events = new();
|
||||||
|
|
||||||
var empoweredActionData = new AbilityData(
|
var empoweredActionData = EmpoweredAction.Ability(tagsManager);
|
||||||
name: "Empowered Action",
|
|
||||||
costEffect: EmpoweredAction.CostEffect(),
|
|
||||||
cooldownEffects: [EmpoweredAction.CooldownEffect(forgeManager.TagsManager)],
|
|
||||||
instancingPolicy: AbilityInstancingPolicy.PerEntity,
|
|
||||||
behaviorFactory: () => new EmpoweredActionBehavior());
|
|
||||||
|
|
||||||
// Grant permanently
|
// Grant permanently
|
||||||
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
|
_empoweredActionHandle = Abilities.GrantAbilityPermanently(
|
||||||
empoweredActionData,
|
empoweredActionData,
|
||||||
@@ -457,7 +463,7 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
levelOverridePolicy: LevelComparison.None,
|
levelOverridePolicy: LevelComparison.None,
|
||||||
sourceEntity: this);
|
sourceEntity: this);
|
||||||
|
|
||||||
var manaRegenEffect = new Effect(ManaRegen.ManaRegen(), new EffectOwnership(this, this));
|
var manaRegenEffect = new Effect(ManaRegen.ManaRegen(tagsManager), new EffectOwnership(this, this));
|
||||||
_manaRegenEffectHandle = EffectsManager.ApplyEffect(manaRegenEffect);
|
_manaRegenEffectHandle = EffectsManager.ApplyEffect(manaRegenEffect);
|
||||||
|
|
||||||
var health = Attributes["PlayerAttributeSet.Health"].CurrentValue; // 100
|
var health = Attributes["PlayerAttributeSet.Health"].CurrentValue; // 100
|
||||||
@@ -529,7 +535,7 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
}
|
}
|
||||||
if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
|
if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
|
||||||
|
|
||||||
PlayerUi.Initialize(CHealth.CurrentHealth);
|
PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
|
||||||
CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
|
CDamageable.DamageTaken += (damageable, record) => ReduceHealth(damageable, record);
|
||||||
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
|
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
|
||||||
CHealth.HealthChanged += PlayerUi.OnHealthChanged;
|
CHealth.HealthChanged += PlayerUi.OnHealthChanged;
|
||||||
@@ -704,8 +710,74 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
_parryStandard.StateEntered += OnStandardParryStarted;
|
_parryStandard.StateEntered += OnStandardParryStarted;
|
||||||
_parryDash.StateEntered += OnDashParryStarted;
|
_parryDash.StateEntered += OnDashParryStarted;
|
||||||
|
|
||||||
// Testing out kill
|
foreach (var weaponLandAbility in AbilityLoadout)
|
||||||
// GetTree().CreateTimer(2).Timeout += () => Kill(this);
|
{
|
||||||
|
var weaponLeftTag = Tag.RequestTag(tagsManager,"abilities.weapon.left").GetSingleTagContainer();
|
||||||
|
var leftGrantAbilityConfig = new GrantAbilityConfig(
|
||||||
|
weaponLandAbility.Ability(new ExplodingSwordCreation(WeaponSystem), weaponLeftTag),
|
||||||
|
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)));
|
||||||
|
|
||||||
|
var weaponLandedTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer();
|
||||||
|
var landGrantAbilityConfig = new GrantAbilityConfig(
|
||||||
|
weaponLandAbility.Ability(new ExplodingSwordCreation(WeaponSystem), weaponLandedTag),
|
||||||
|
ScalableLevel: new ScalableInt(1),
|
||||||
|
RemovalPolicy: AbilityDeactivationPolicy.CancelImmediately,
|
||||||
|
InhibitionPolicy: AbilityDeactivationPolicy.CancelImmediately,
|
||||||
|
TryActivateOnGrant: false,
|
||||||
|
TryActivateOnEnable: false,
|
||||||
|
LevelOverridePolicy: LevelComparison.Higher);
|
||||||
|
|
||||||
|
var landGrantComponent = new GrantAbilityEffectComponent([landGrantAbilityConfig]);
|
||||||
|
var landGrantEffect = new EffectData(
|
||||||
|
"Grant Weapon Land Ability",
|
||||||
|
new DurationData(DurationType.Infinite),
|
||||||
|
effectComponents: [landGrantComponent]);
|
||||||
|
EffectsManager.ApplyEffect(new Effect(landGrantEffect, new EffectOwnership(this, this)));
|
||||||
|
|
||||||
|
GetTree().CreateTimer(5).Timeout += () => WeaponSystem.GrantNewAbilityForWeaponFly(weaponLandAbility);
|
||||||
|
}
|
||||||
|
// Forge events
|
||||||
|
var weaponLeftToken = WeaponSystem.Events.Subscribe<WeaponEventPayload>(WeaponSystem.WeaponStartedFlyingEventTag, OnWeaponLeft);
|
||||||
|
var weaponLandedToken = WeaponSystem.Events.Subscribe<WeaponEventPayload>(WeaponSystem.WeaponStoppedFlyingEventTag, OnWeaponLanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnWeaponLeft(EventData<WeaponEventPayload> data)
|
||||||
|
{
|
||||||
|
var target = data.Target;
|
||||||
|
|
||||||
|
var tagsManager = ForgeManager.GetTagsManager(this);
|
||||||
|
var weaponLeftTag = Tag.RequestTag(tagsManager, "abilities.weapon.left").GetSingleTagContainer();
|
||||||
|
if (weaponLeftTag == null) return;
|
||||||
|
Abilities.TryActivateAbilitiesByTag(weaponLeftTag, target, out var landedFailures);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnWeaponLanded(EventData<WeaponEventPayload> data)
|
||||||
|
{
|
||||||
|
var source = data.Source;
|
||||||
|
var target = data.Target;
|
||||||
|
var magnitude = data.EventMagnitude;
|
||||||
|
var weaponLandPayload = data.Payload;
|
||||||
|
|
||||||
|
var tagsManager = ForgeManager.GetTagsManager(this);
|
||||||
|
|
||||||
|
var weaponLandTag = Tag.RequestTag(tagsManager, "abilities.weapon.land").GetSingleTagContainer();
|
||||||
|
if (weaponLandTag == null) return;
|
||||||
|
var anyActivated = Abilities.TryActivateAbilitiesByTag(
|
||||||
|
weaponLandTag,
|
||||||
|
target,
|
||||||
|
out var failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
@@ -765,7 +837,7 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
{
|
{
|
||||||
RHealth.StartingHealth = newHealthValue;
|
RHealth.StartingHealth = newHealthValue;
|
||||||
CHealth!.CurrentHealth = newHealthValue;
|
CHealth!.CurrentHealth = newHealthValue;
|
||||||
PlayerUi.Initialize(CHealth.CurrentHealth);
|
PlayerUi.Initialize(CHealth.CurrentHealth, Attributes["PlayerAttributeSet.Mana"].BaseValue);
|
||||||
}
|
}
|
||||||
public void SetPlayerDamageOverride(float newDamageValue)
|
public void SetPlayerDamageOverride(float newDamageValue)
|
||||||
{
|
{
|
||||||
@@ -2309,7 +2381,7 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
HandleEnemyTargeting();
|
HandleEnemyTargeting();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _oldMana = 100;
|
// private float _oldMana = 100;
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
// Manage head and camera movement
|
// Manage head and camera movement
|
||||||
@@ -2317,10 +2389,10 @@ public partial class PlayerController : CharacterBody3D,
|
|||||||
|
|
||||||
EffectsManager.UpdateEffects(delta);
|
EffectsManager.UpdateEffects(delta);
|
||||||
// TODO: change for actual Cue
|
// TODO: change for actual Cue
|
||||||
var currentMana = Attributes["PlayerAttributeSet.Mana"].CurrentValue;
|
// var currentMana = Attributes["PlayerAttributeSet.Mana"].CurrentValue;
|
||||||
if (Mathf.Abs(currentMana - _oldMana) > Mathf.Epsilon)
|
// if (Mathf.Abs(currentMana - _oldMana) > Mathf.Epsilon)
|
||||||
PlayerUi.OnManaChanged(currentMana);
|
// PlayerUi.OnManaChanged(currentMana);
|
||||||
_oldMana = currentMana;
|
// _oldMana = currentMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
|||||||
Reference in New Issue
Block a user