Fix spawn point for player, add flee behavior for gold sproingy
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
<Project Sdk="Godot.NET.Sdk/4.4.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
|||||||
38
Zennysoft.Game.Ma/Ma.csproj.old.3
Normal file
38
Zennysoft.Game.Ma/Ma.csproj.old.3
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<WarningsAsErrors>CS9057</WarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Chickensoft.AutoInject" Version="2.5.0" />
|
||||||
|
<PackageReference Include="Chickensoft.GodotNodeInterfaces" Version="2.4.0" />
|
||||||
|
<PackageReference Include="Chickensoft.Introspection" Version="2.2.0" />
|
||||||
|
<PackageReference Include="Chickensoft.Introspection.Generator" Version="2.2.0" />
|
||||||
|
<PackageReference Include="Chickensoft.LogicBlocks" Version="5.16.0" />
|
||||||
|
<PackageReference Include="Chickensoft.LogicBlocks.DiagramGenerator" Version="5.16.0" />
|
||||||
|
<PackageReference Include="Chickensoft.SaveFileBuilder" Version="1.1.0" />
|
||||||
|
<PackageReference Include="Chickensoft.Serialization.Godot" Version="0.7.6" />
|
||||||
|
<PackageReference Include="GodotSharp.SourceGenerators" Version="2.6.0-250131-2115.Release" />
|
||||||
|
<PackageReference Include="SimpleInjector" Version="5.5.0" />
|
||||||
|
<PackageReference Include="SSH.NET" Version="2024.2.0" />
|
||||||
|
<PackageReference Include="System.IO.Abstractions" Version="22.0.11" />
|
||||||
|
<PackageReference Include="Zeroconf" Version="3.7.16" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include=".editorconfig" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Zennysoft.Game.Godot.Implementation\Zennysoft.Game.Implementation.csproj" />
|
||||||
|
<ProjectReference Include="..\Zennysoft.Game.Ma.Implementation\Zennysoft.Ma.Adapter.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="Godot.SourceGenerators" Version="4.4.0-dev.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="GodotSharp" Version="4.4.0-dev.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Update="GodotSharpEditor" Version="4.4.0-dev.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -79,6 +79,8 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
|||||||
|
|
||||||
if (this is IHaveFollowBehavior)
|
if (this is IHaveFollowBehavior)
|
||||||
_enemyLogic.Input(new EnemyLogic.Input.Follow());
|
_enemyLogic.Input(new EnemyLogic.Input.Follow());
|
||||||
|
if (this is IHaveFleeBehavior)
|
||||||
|
_enemyLogic.Input(new EnemyLogic.Input.Flee());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.Handle((in EnemyLogic.Output.Idle _) =>
|
.Handle((in EnemyLogic.Output.Idle _) =>
|
||||||
|
|||||||
58
Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs
Normal file
58
Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using Chickensoft.AutoInject;
|
||||||
|
using Chickensoft.Introspection;
|
||||||
|
using Godot;
|
||||||
|
using System.Linq;
|
||||||
|
using Zennysoft.Game.Abstractions.Entity;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
[Meta(typeof(IAutoNode))]
|
||||||
|
public partial class FleeBehavior : Node3D, IBehavior
|
||||||
|
{
|
||||||
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
|
[Export] private double _fleeSpeed { get; set; } = 300f;
|
||||||
|
|
||||||
|
[Export] private double _thinkTime { get; set; } = 2f;
|
||||||
|
|
||||||
|
[Signal] public delegate void OnVelocityComputedEventHandler(Vector3 safeVelocity);
|
||||||
|
|
||||||
|
[Dependency] public IGame _game => this.DependOn<IGame>();
|
||||||
|
[Dependency] public IMap _map => this.DependOn<IMap>();
|
||||||
|
|
||||||
|
private NavigationAgent3D _navigationAgent;
|
||||||
|
|
||||||
|
|
||||||
|
public void Init(NavigationAgent3D navigationAgent)
|
||||||
|
{
|
||||||
|
_navigationAgent = navigationAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnReady()
|
||||||
|
{
|
||||||
|
SetPhysicsProcess(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartFlee(NavigationAgent3D navigationAgent)
|
||||||
|
{
|
||||||
|
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||||
|
var rooms = _game.CurrentFloor.Rooms;
|
||||||
|
var validRooms = new Godot.Collections.Array<MonsterRoom>(rooms.OfType<MonsterRoom>());
|
||||||
|
var randomRoom = validRooms.PickRandom();
|
||||||
|
_navigationAgent.TargetPosition = randomRoom.PlayerSpawn.GlobalPosition;
|
||||||
|
SetPhysicsProcess(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopFlee()
|
||||||
|
{
|
||||||
|
SetPhysicsProcess(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnPhysicsProcess(double delta)
|
||||||
|
{
|
||||||
|
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||||
|
var parent = GetParent() as Node3D;
|
||||||
|
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)_fleeSpeed * (float)delta;
|
||||||
|
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://drur3hx4p4du4
|
||||||
7
Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.tscn
Normal file
7
Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.tscn
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://g4cupevu280j"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://drur3hx4p4du4" path="res://src/enemy/behaviors/FleeBehavior.cs" id="1_cty3c"]
|
||||||
|
|
||||||
|
[node name="NavigationAgent" type="Node3D"]
|
||||||
|
script = ExtResource("1_cty3c")
|
||||||
|
_thinkTime = 0.8
|
||||||
10
Zennysoft.Game.Ma/src/enemy/behaviors/IHaveFleeBehavior.cs
Normal file
10
Zennysoft.Game.Ma/src/enemy/behaviors/IHaveFleeBehavior.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
public interface IHaveFleeBehavior
|
||||||
|
{
|
||||||
|
public FleeBehavior FleeBehavior { get; }
|
||||||
|
|
||||||
|
public NavigationAgent3D NavigationAgent { get; }
|
||||||
|
}
|
||||||
@@ -1,28 +1,38 @@
|
|||||||
using Chickensoft.AutoInject;
|
using Chickensoft.AutoInject;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using System;
|
||||||
using Zennysoft.Game.Ma;
|
using Zennysoft.Game.Ma;
|
||||||
|
using Zennysoft.Ma.Adapter;
|
||||||
|
|
||||||
[Meta(typeof(IAutoNode))]
|
[Meta(typeof(IAutoNode))]
|
||||||
public partial class GoldSproingy : Enemy2D, IHavePatrolBehavior
|
public partial class GoldSproingy : Enemy2D, IHavePatrolBehavior, IHaveFleeBehavior
|
||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
[Node] public NavigationAgent3D NavigationAgent { get; set; }
|
[Node] public NavigationAgent3D NavigationAgent { get; set; }
|
||||||
[Node] public PatrolBehavior PatrolBehavior { get; set; } = default!;
|
[Node] public PatrolBehavior PatrolBehavior { get; set; } = default!;
|
||||||
|
[Node] public FleeBehavior FleeBehavior { get; set; } = default!;
|
||||||
|
|
||||||
[Node] public Area3D PlayerDetector { get; set; } = default!;
|
[Node] public Area3D PlayerDetector { get; set; } = default!;
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
PatrolBehavior.Init(NavigationAgent);
|
PatrolBehavior.Init(NavigationAgent);
|
||||||
|
FleeBehavior.Init(NavigationAgent);
|
||||||
PatrolBehavior.HomePosition = GlobalPosition;
|
PatrolBehavior.HomePosition = GlobalPosition;
|
||||||
PatrolBehavior.OnVelocityComputed += OnVelocityComputed;
|
PatrolBehavior.OnVelocityComputed += OnVelocityComputed;
|
||||||
PlayerDetector.BodyEntered += PlayerDetector_BodyEntered;
|
FleeBehavior.OnVelocityComputed += OnVelocityComputed;
|
||||||
PlayerDetector.BodyExited += PlayerDetector_BodyExited;
|
PlayerDetector.BodyEntered += GoldSproingyFlee;
|
||||||
SetPhysicsProcess(true);
|
SetPhysicsProcess(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GoldSproingyFlee(Node3D body)
|
||||||
|
{
|
||||||
|
if (body is IPlayer)
|
||||||
|
_enemyLogic.Input(new EnemyLogic.Input.Flee());
|
||||||
|
}
|
||||||
|
|
||||||
public void OnResolved()
|
public void OnResolved()
|
||||||
{
|
{
|
||||||
_enemyLogic.Input(new EnemyLogic.Input.Patrol());
|
_enemyLogic.Input(new EnemyLogic.Input.Patrol());
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
[gd_scene load_steps=10 format=3 uid="uid://c5ugpasira53m"]
|
[gd_scene load_steps=11 format=3 uid="uid://c5ugpasira53m"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://jjulhqd5g3be" path="res://src/enemy/enemy_types/13. gold sproingy/GoldSproingy.cs" id="1_o1o4d"]
|
[ext_resource type="Script" uid="uid://jjulhqd5g3be" path="res://src/enemy/enemy_types/13. gold sproingy/GoldSproingy.cs" id="1_o1o4d"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dobiqowi8mhfi" path="res://src/enemy/enemy_types/13. gold sproingy/GoldSproingyModelView.tscn" id="2_o1o4d"]
|
[ext_resource type="PackedScene" uid="uid://dobiqowi8mhfi" path="res://src/enemy/enemy_types/13. gold sproingy/GoldSproingyModelView.tscn" id="2_o1o4d"]
|
||||||
[ext_resource type="PackedScene" uid="uid://2nkvacxsd46b" path="res://src/enemy/behaviors/PatrolBehavior.tscn" id="3_dxqkk"]
|
[ext_resource type="PackedScene" uid="uid://2nkvacxsd46b" path="res://src/enemy/behaviors/PatrolBehavior.tscn" id="3_dxqkk"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://g4cupevu280j" path="res://src/enemy/behaviors/FleeBehavior.tscn" id="4_58d4o"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cwfph"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cwfph"]
|
||||||
radius = 0.106078
|
radius = 0.106078
|
||||||
@@ -86,6 +87,9 @@ unique_name_in_owner = true
|
|||||||
[node name="PatrolBehavior" parent="Components" instance=ExtResource("3_dxqkk")]
|
[node name="PatrolBehavior" parent="Components" instance=ExtResource("3_dxqkk")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="FleeBehavior" parent="Components" instance=ExtResource("4_58d4o")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
[node name="NavigationAgent" type="NavigationAgent3D" parent="Components"]
|
[node name="NavigationAgent" type="NavigationAgent3D" parent="Components"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
avoidance_enabled = true
|
avoidance_enabled = true
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ public partial class EnemyLogic
|
|||||||
|
|
||||||
public readonly record struct Patrol;
|
public readonly record struct Patrol;
|
||||||
|
|
||||||
|
public readonly record struct Flee;
|
||||||
|
|
||||||
public readonly record struct Follow;
|
public readonly record struct Follow;
|
||||||
|
|
||||||
public readonly record struct Move;
|
public readonly record struct Move;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public partial class EnemyLogic
|
|||||||
IGet<Move>,
|
IGet<Move>,
|
||||||
IGet<Patrol>,
|
IGet<Patrol>,
|
||||||
IGet<Follow>,
|
IGet<Follow>,
|
||||||
|
IGet<Flee>,
|
||||||
IGet<ReachedPlayer>,
|
IGet<ReachedPlayer>,
|
||||||
IGet<Input.LoseTrackOfTarget>,
|
IGet<Input.LoseTrackOfTarget>,
|
||||||
IGet<Input.Defeated>
|
IGet<Input.Defeated>
|
||||||
@@ -27,6 +28,8 @@ public partial class EnemyLogic
|
|||||||
|
|
||||||
public Transition On(in Follow _) => To<FollowPlayer>();
|
public Transition On(in Follow _) => To<FollowPlayer>();
|
||||||
|
|
||||||
|
public Transition On(in Flee _) => To<FleePlayer>();
|
||||||
|
|
||||||
public Transition On(in LoseTrackOfTarget input)
|
public Transition On(in LoseTrackOfTarget input)
|
||||||
{
|
{
|
||||||
Output(new Output.ReturnToDefaultState());
|
Output(new Output.ReturnToDefaultState());
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using Chickensoft.Introspection;
|
||||||
|
using Zennysoft.Ma.Adapter.Entity;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
|
public partial class EnemyLogic
|
||||||
|
{
|
||||||
|
public partial record State
|
||||||
|
{
|
||||||
|
[Meta, Id("enemy_logic_state_fleeplayer")]
|
||||||
|
public partial record FleePlayer : Alive
|
||||||
|
{
|
||||||
|
public FleePlayer()
|
||||||
|
{
|
||||||
|
OnAttach(() =>
|
||||||
|
{
|
||||||
|
var enemy = Get<IEnemy>();
|
||||||
|
if (enemy is IHaveFleeBehavior fleeEnemy)
|
||||||
|
{
|
||||||
|
fleeEnemy.FleeBehavior.StartFlee(fleeEnemy.NavigationAgent);
|
||||||
|
Output(new Output.Move());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
OnDetach(() =>
|
||||||
|
{
|
||||||
|
var enemy = Get<IEnemy>();
|
||||||
|
if (enemy is IHaveFleeBehavior fleeEnemy)
|
||||||
|
{
|
||||||
|
fleeEnemy.FleeBehavior.StopFlee();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -134,6 +134,7 @@ public partial class Game : Node3D, IGame
|
|||||||
_instantiator = new Instantiator(GetTree());
|
_instantiator = new Instantiator(GetTree());
|
||||||
_player = _instantiator.LoadAndInstantiate<Player>("res://src/player/Player.tscn");
|
_player = _instantiator.LoadAndInstantiate<Player>("res://src/player/Player.tscn");
|
||||||
_map = _instantiator.LoadAndInstantiate<Map>("res://src/map/Map.tscn");
|
_map = _instantiator.LoadAndInstantiate<Map>("res://src/map/Map.tscn");
|
||||||
|
_map.SpawnPointCreated += MovePlayer;
|
||||||
PauseContainer.AddChild((Player)_player);
|
PauseContainer.AddChild((Player)_player);
|
||||||
PauseContainer.AddChild((Map)_map);
|
PauseContainer.AddChild((Map)_map);
|
||||||
}
|
}
|
||||||
@@ -167,8 +168,6 @@ public partial class Game : Node3D, IGame
|
|||||||
|
|
||||||
GameRepo.IsPaused.Sync += IsPaused_Sync;
|
GameRepo.IsPaused.Sync += IsPaused_Sync;
|
||||||
InGameUI.PlayerInfoUI.Activate();
|
InGameUI.PlayerInfoUI.Activate();
|
||||||
|
|
||||||
_map.SpawnPointCreated += MovePlayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadExistingGame() => SaveFile.Load().ContinueWith((_) => CallDeferred(nameof(FinishedLoadingSaveFile)));
|
public void LoadExistingGame() => SaveFile.Load().ContinueWith((_) => CallDeferred(nameof(FinishedLoadingSaveFile)));
|
||||||
|
|||||||
Reference in New Issue
Block a user