can plant weapon in targetables, dash towards it, jump in the air.
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) Failing after 1m47s

This commit is contained in:
2026-01-24 15:22:16 +01:00
parent b84b7e4dd5
commit 18c8b741dd
10 changed files with 116 additions and 36 deletions

View File

@@ -3,6 +3,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAction_00602_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c0f83388bfc4d2c9d09befcec9dd79bc90908_003F87_003Fded27e2d_003FAction_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterBody3D_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fe56b84c3fa498fb86fc1eba376f62f482127e3fe80415c5fb2acde2bf6d89793_003FCharacterBody3D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEnemy_005FScriptMethods_002Egenerated_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8e71dc81611862c01a2cb998a1f327de14747655_003FEnemy_005FScriptMethods_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F716d154fef5cbe863cd637bd32beda6e3cec5f12e8fed2dc5b2d8149a0d558ab_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fdf73a4db74df89d59655c5fb6326406f47fbfa9af1fa81518fe0a07c49d34133_003FNode_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneTree_002Ecs_002Fl_003AC_0021_003FUsers_003FMinimata_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F8d6960554e939a669841b1ece03d27df4ab42f92bb80be3767eaec8cdaccf84b_003FSceneTree_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=floorplane/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -93,6 +93,12 @@ use_collision = true
size = Vector3(6.5, 4, 17)
material = ExtResource("2_3uydm")
[node name="CSGBox3D10" type="CSGBox3D" parent="Greybox"]
transform = Transform3D(1, 0, 0, 0, 0.9659258, 0.25881904, 0, -0.25881904, 0.9659258, 13.653999, 0.9705714, -5.336278)
use_collision = true
size = Vector3(6.5, 4, 24.5)
material = ExtResource("2_3uydm")
[node name="CSGBox3D8" type="CSGBox3D" parent="Greybox"]
transform = Transform3D(0.81915206, 0, 0.57357645, 0, 1, 0, -0.57357645, 0, 0.81915206, -7.3460007, 0, -3.9585)
use_collision = true
@@ -124,21 +130,21 @@ size = Vector3(6.5, 11, 5.5)
material = ExtResource("2_3uydm")
[node name="FixedDashthroughTarget" parent="." instance=ExtResource("15_5fa36")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 3.5, 2.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 3.5, 2.5)
[node name="Enemy" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -16.83681)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.5, 2.5, -8.336809)
Target = NodePath("../Player")
RKnockback = SubResource("Resource_q21h6")
RMovement = SubResource("Resource_5fa36")
[node name="Enemy2" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, -16.83681)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13, 0, -17.33681)
Target = NodePath("../Player")
RMovement = SubResource("Resource_5fa36")
[node name="Enemy3" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 0, 0.16319084)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 4, -3.3368092)
Target = NodePath("../Player")
RMovement = SubResource("Resource_5fa36")

View File

@@ -54,7 +54,7 @@
[sub_resource type="Resource" id="Resource_cb2lu"]
script = ExtResource("2_x835q")
DamageDealt = 3.0
DamageDealt = 30.0
metadata/_custom_type_script = "uid://jitubgv6judn"
[sub_resource type="Resource" id="Resource_abfq8"]

View File

@@ -313,6 +313,7 @@ public partial class PlayerController : CharacterBody3D,
private StateChartState _mantling;
private StateChartState _simpleDash;
private StateChartState _aimedDash;
private StateChartState _weaponDash;
private StateChartState _sliding;
private StateChartState _groundSliding;
private StateChartState _airGliding;
@@ -436,6 +437,7 @@ public partial class PlayerController : CharacterBody3D,
_aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On"));
_simpleDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/Dash"));
_aimedDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/AimedDash"));
_weaponDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/ToWeaponDash"));
_slamming = StateChartState.Of(GetNode("StateChart/Root/Movement/Slamming"));
_sliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding"));
@@ -499,7 +501,7 @@ public partial class PlayerController : CharacterBody3D,
MantleSystem.Init();
StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth);
DashSystem.Init(HeadSystem, _camera);
WeaponSystem.Init(HeadSystem, _camera);
WeaponSystem.Init();
WallHugSystem.Init();
EmpoweredActionsLeft = MaxNumberOfEmpoweredActions;
@@ -548,6 +550,8 @@ public partial class PlayerController : CharacterBody3D,
_aimedDash.StateEntered += OnAimedDashStarted;
_aimedDash.StateExited += OnAimedDashFinished;
_weaponDash.StateExited += OnWeaponDashFinished;
_sliding.StateEntered += SlideStarted;
_sliding.StateExited += SlideEnded;
_slideCanceled.StateEntered += OnSlideCanceled;
@@ -576,7 +580,7 @@ public partial class PlayerController : CharacterBody3D,
_onWallRunning.StatePhysicsProcessing += HandleWallRunning;
_onWallHanging.StateExited += RecoverWeapon;
_onDashEnded.Taken += RecoverWeapon;
// _onDashEnded.Taken += RecoverWeapon;
_onJumpFromWall.Taken += OnJumpFromWall;
_onJumpFromWallFalling.Taken += OnJumpFromWall;
@@ -975,7 +979,7 @@ public partial class PlayerController : CharacterBody3D,
}
public void RecoverChildNode(Node3D node)
{
GetTree().GetRoot().RemoveChild(node);
node.GetParent().RemoveChild(node);
AddChild(node);
node.SetGlobalPosition(GlobalPosition);
}
@@ -1703,8 +1707,6 @@ public partial class PlayerController : CharacterBody3D,
if (DashSystem.CanDashThroughTarget && DashSystem.CollidedObject is ITargetable targetable)
correctedLocation = ComputePositionAfterTargetedDash(targetable.GetTargetGlobalPosition(), DashSystem.CollisionPoint);
if (DashSystem.CollidedObject is IDamageable damageable)
_hitEnemies.Add(damageable);
// Start invincibility timer for the duration of the dash and a bit more afterwards
OnHitInvincibility();
@@ -1726,7 +1728,8 @@ public partial class PlayerController : CharacterBody3D,
}
public void OnAimedDashFinished()
{
TriggerDamage();
ManageAttackedEnemyPostDash(DashSystem.CollidedObject as Node);
DashSystem.CollidedObject = null;
if (_customMantle)
{
@@ -1751,23 +1754,27 @@ public partial class PlayerController : CharacterBody3D,
weaponTargetLocation,
DashSystem.HasHit,
DashSystem.CollisionPoint,
DashSystem.CollisionNormal);
DashSystem.CollisionNormal,
DashSystem.CollidedObject as Node);
}
public void RecoverWeapon()
{
if (WeaponSystem.GetParent() == this) return;
HeadSystem.ShowWeapon();
RecoverChildNode(WeaponSystem);
WeaponSystem.ResetWeapon();
RecoverChildNode(WeaponSystem);
}
public void DashToFlyingWeapon()
{
_playerState.SendEvent("cancel_aim");
_playerState.SendEvent("weapon_dash");
PerformEmpoweredAction();
_audioStream.SwitchToClipByName("dash");
// Start invincibility timer for the duration of the dash and a bit more afterwards
OnHitInvincibility();
DashSystem.ShouldMantle = false;
_dashDirection = (WeaponSystem.GlobalPosition - GlobalPosition).Normalized();
@@ -1788,8 +1795,11 @@ public partial class PlayerController : CharacterBody3D,
{
_playerState.SendEvent("cancel_aim");
_playerState.SendEvent("weapon_dash");
PerformEmpoweredAction();
_audioStream.SwitchToClipByName("dash");
// Start invincibility timer for the duration of the dash and a bit more afterwards
OnHitInvincibility();
DashSystem.ShouldMantle = false;
var dashLocation = WeaponSystem.PlantLocation;
@@ -1797,6 +1807,8 @@ public partial class PlayerController : CharacterBody3D,
dashLocation += WeaponSystem.PlantNormal * _playerRadius;
if (WeaponSystem.IsPlantedUnderPlatform())
dashLocation += Vector3.Down * _playerHeight;
if (WeaponSystem.PlantObject is ITargetable targetable)
dashLocation = targetable.GetTargetGlobalPosition();
_wallHugStartNormal = WeaponSystem.PlantNormal;
_currentWallContactPoint = WeaponSystem.PlantLocation;
@@ -1811,12 +1823,38 @@ public partial class PlayerController : CharacterBody3D,
// Store the weapon state before resetting it
var isPlantedOnWall = WeaponSystem.IsPlantedInWall();
var isPlantedUnderPlatform = WeaponSystem.IsPlantedUnderPlatform();
var shouldDashToHanging = isPlantedOnWall || isPlantedUnderPlatform;
var isPlantedInTarget = WeaponSystem.PlantObject is ITargetable;
var shouldDashToHanging = (isPlantedOnWall || isPlantedUnderPlatform) && !isPlantedInTarget;
var resultingEvent = shouldDashToHanging ? "dash_to_planted" : "dash_finished";
if (!shouldDashToHanging) RecoverWeapon(); // Manually recover weapon before enemy is freed in case it owns the weapon object
if (WeaponSystem.PlantObject is ITargetable targetable)
{
HeadSystem.OnMantle(); // Recycle mantle animation
SetVerticalVelocity(PostDashSpeed);
}
ManageAttackedEnemyPostDash(WeaponSystem.PlantObject);
WeaponSystem.PlantObject = null;
_playerState.SendEvent(resultingEvent);
}
public void ManageAttackedEnemyPostDash(Node enemy)
{
if (enemy is IDamageable damageable)
{
_hitEnemies.Add(damageable);
TriggerDamage();
}
if (enemy is IStunnable stunnable)
stunnable.Stun();
}
public void OnWeaponDashFinished()
{
}
///////////////////////////
// Processes //////////////
///////////////////////////

View File

@@ -1,6 +1,7 @@
using System;
using Godot;
using Movementtests.interfaces;
using Movementtests.systems;
[GlobalClass]
public partial class Enemy : CharacterBody3D,
@@ -22,6 +23,8 @@ public partial class Enemy : CharacterBody3D,
// Public export components
[Export]
public Node3D Target { get; set; }
[Export]
public float EnemyHeight { get; set; } = 1f;
[ExportGroup("Health")]
[Export]
@@ -162,11 +165,23 @@ public partial class Enemy : CharacterBody3D,
public void Kill(IHealthable source)
{
// Remove weapon that might be planted there
foreach (var child in GetChildren())
{
if (child is WeaponSystem system)
{
CallDeferred(Node.MethodName.RemoveChild, system);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, system);
system.CallDeferred(Node3D.MethodName.SetGlobalPosition, GlobalPosition + Vector3.Up*EnemyHeight);
system.CallDeferred(WeaponSystem.MethodName.RethrowWeapon);
}
}
foreach (var killable in DeathEffects.ToIKillables())
{
killable.Kill(source);
}
QueueFree();
CallDeferred(Node.MethodName.QueueFree);
}
public void RegisterKnockback(IDamageable source, DamageRecord damageRecord)

View File

@@ -48,6 +48,7 @@ collision_layer = 16
collision_mask = 273
motion_mode = 1
script = ExtResource("1_q8l7o")
EnemyHeight = 0.5
RHealth = ExtResource("2_ma2bq")
DeathEffects = Array[Object]([])
RDamage = ExtResource("2_on7rt")

View File

@@ -4,5 +4,5 @@
[resource]
script = ExtResource("1_jht15")
StartingHealth = 50.0
StartingHealth = 10.0
metadata/_custom_type_script = "uid://baiapod3csndf"

View File

@@ -43,6 +43,7 @@ size = Vector3(1, 2, 1.5)
collision_layer = 16
collision_mask = 273
script = ExtResource("1_r6506")
EnemyHeight = 2.0
RHealth = ExtResource("2_w4lm8")
DeathEffects = Array[Object]([])
RDamage = ExtResource("2_bn56u")

View File

@@ -22,27 +22,23 @@ public partial class WeaponSystem : RigidBody3D
public StateChartState FlyingState;
public StateChartState PlantedState;
private Node3D _head;
private ShapeCast3D _dashCast3D;
private Camera3D _camera;
private TweenQueueSystem _tweenQueueSystem;
private Transform3D _startTransform;
private Transform3D _startMeshTransform;
private Vector3 _startMeshRotation;
private Vector3 _throwDirection;
public Vector3 PlantLocation { get; set; }
public Vector3 PlantNormal { get; set; }
public Node PlantObject { get; set; }
public MeshInstance3D WeaponLocationIndicator { get; set; }
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; }
public MeshInstance3D WeaponMesh { get; set; }
public void Init(Node3D head, Camera3D camera)
public void Init()
{
_head = head;
_camera = camera;
_weaponState = StateChart.Of(GetNode("StateChart"));
InHandState = StateChartState.Of(GetNode("StateChart/Root/InHand"));
FlyingState = StateChartState.Of(GetNode("StateChart/Root/Flying"));
@@ -53,7 +49,7 @@ public partial class WeaponSystem : RigidBody3D
WeaponLocationIndicatorMaterial = WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D;
WeaponMesh = GetNode<MeshInstance3D>("Weapon");
_startMeshTransform = WeaponMesh.Transform;
_startMeshRotation = WeaponMesh.Rotation;
_tweenQueueSystem = GetNode<TweenQueueSystem>("TweenQueueSystem");
_tweenQueueSystem.Init(this);
@@ -90,7 +86,7 @@ public partial class WeaponSystem : RigidBody3D
PlantLocation = location;
}
public void ThrowWeapon(Vector3 end, bool hasHit, Vector3 collisionLocation, Vector3 collisionNormal)
public void ThrowWeapon(Vector3 end, bool hasHit, Vector3 collisionLocation, Vector3 collisionNormal, Node collidedObject)
{
_weaponState.SendEvent("throw");
@@ -103,11 +99,21 @@ public partial class WeaponSystem : RigidBody3D
var tween = _tweenQueueSystem.TweenToLocation(new TweenQueueSystem.TweenInputs(end, StraightThrowDuration));
if (hasHit)
{
PlantObject = collidedObject;
tween.Finished += PlantWeaponInWall;
}
else
tween.Finished += ThrowWeaponOnCurve;
}
public void RethrowWeapon()
{
_weaponState.SendEvent("throw");
_throwDirection = Vector3.Up;
ThrowWeaponOnCurve();
}
public void ThrowWeaponOnCurve()
{
Freeze = false;
@@ -118,16 +124,22 @@ public partial class WeaponSystem : RigidBody3D
{
_weaponState.SendEvent("plant");
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
Freeze = true;
GlobalPosition = PlantLocation;
WeaponMesh.Transform = _startMeshTransform;
LookAt(GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
WeaponMesh.Rotation = _startMeshRotation;
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
if (PlantObject is Node3D node)
{
GetTree().GetRoot().CallDeferred(Node.MethodName.RemoveChild, this);
node.CallDeferred(Node.MethodName.AddChild, this);
}
CallDeferred(Node3D.MethodName.SetGlobalPosition, PlantLocation);
CallDeferred(Node3D.MethodName.LookAt, GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
}
public void OnThrownWeaponReachesGround(Node other)
{
PlantObject = other;
PlantWeaponInWall();
}

View File

@@ -38,7 +38,7 @@ material = SubResource("StandardMaterial3D_m0v1h")
[node name="Weapon" type="RigidBody3D"]
collision_layer = 65536
collision_mask = 256
collision_mask = 304
continuous_cd = true
contact_monitor = true
max_contacts_reported = 1
@@ -54,6 +54,9 @@ shape = SubResource("CylinderShape3D_avini")
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0.8673003)
mesh = ExtResource("3_svc06")
[node name="WeaponLocationIndicator" type="MeshInstance3D" parent="."]
mesh = SubResource("SphereMesh_jpdh0")
[node name="StateChart" type="Node" parent="."]
script = ExtResource("3_5owyf")
metadata/_custom_type_script = "uid://couw105c3bde4"
@@ -89,11 +92,14 @@ delay_in_seconds = "0.0"
[node name="Planted" type="Node" parent="StateChart/Root"]
script = ExtResource("5_m0v1h")
[node name="ToFlying" type="Node" parent="StateChart/Root/Planted"]
script = ExtResource("6_jpdh0")
to = NodePath("../../Flying")
event = &"throw"
delay_in_seconds = "0.0"
[node name="ToHand" type="Node" parent="StateChart/Root/Planted"]
script = ExtResource("6_jpdh0")
to = NodePath("../../InHand")
event = &"recover"
delay_in_seconds = "0.0"
[node name="WeaponLocationIndicator" type="MeshInstance3D" parent="."]
mesh = SubResource("SphereMesh_jpdh0")