mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-09 01:05:53 +00:00
Generic enemies
This commit is contained in:
parent
762666242e
commit
d99c773641
55 changed files with 968 additions and 204 deletions
|
|
@ -26,6 +26,8 @@ public partial class RogueliteEnemySpawner : Marker2D
|
|||
}
|
||||
}
|
||||
|
||||
[Export] public bool AutoSpawn { get; set; } = false;
|
||||
|
||||
[Export] public int Wave { get; private set; } = 0;
|
||||
|
||||
public bool Spawned { get; private set; } = false;
|
||||
|
|
@ -48,32 +50,51 @@ public partial class RogueliteEnemySpawner : Marker2D
|
|||
QueueRedraw();
|
||||
}
|
||||
|
||||
public EnemyFSMProxy Spawn(RogueliteMapTheme mapTheme)
|
||||
public override void _Ready()
|
||||
{
|
||||
if (Engine.IsEditorHint()) return;
|
||||
if (!AutoSpawn) return;
|
||||
|
||||
Spawn();
|
||||
|
||||
}
|
||||
|
||||
public EnemyFSMProxy Spawn()
|
||||
{
|
||||
if (Engine.IsEditorHint()) return null;
|
||||
if (Spawned) return _spawnedEnemy;
|
||||
|
||||
var enemyScene = GD.Load<PackedScene>(Enemy.PrefabPath);
|
||||
|
||||
_spawnedEnemy = this.CreateSibling<EnemyFSMProxy>(enemyScene);
|
||||
_spawnedEnemy.Init(Enemy);
|
||||
Spawned = true;
|
||||
|
||||
_spawnedEnemy.Death += SpawnedEnemyOnDeath;
|
||||
return _spawnedEnemy;
|
||||
}
|
||||
|
||||
_spawnedEnemy.OverrideLoot = true;
|
||||
_spawnedEnemy.ExtraLoot.Add(new LootDrop()
|
||||
public EnemyFSMProxy Spawn(RogueliteMapTheme mapTheme)
|
||||
{
|
||||
if (Engine.IsEditorHint()) return null;
|
||||
if (Spawned) return _spawnedEnemy;
|
||||
|
||||
var spawnedEnemy = Spawn();
|
||||
|
||||
spawnedEnemy.OverrideLoot = true;
|
||||
spawnedEnemy.ExtraLoot.Add(new LootDrop()
|
||||
{
|
||||
Item = mapTheme.EnemiesLootTable.Items.ToList().Shuffle().First(),
|
||||
Chance = mapTheme.EnemyDropChance
|
||||
});
|
||||
|
||||
_spawnedEnemy.ExtraLoot.Add(new LootDrop()
|
||||
spawnedEnemy.ExtraLoot.Add(new LootDrop()
|
||||
{
|
||||
Item = mapTheme.PointItemResource,
|
||||
Chance = 100
|
||||
});
|
||||
|
||||
Spawned = true;
|
||||
|
||||
_spawnedEnemy.Death += SpawnedEnemyOnDeath;
|
||||
|
||||
return _spawnedEnemy;
|
||||
return spawnedEnemy;
|
||||
}
|
||||
|
||||
private void SpawnedEnemyOnDeath(EnemyFSMProxy enemy)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.AttackPatterns;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class CreateEmitterPattern : AttackPattern
|
||||
{
|
||||
[Export] public Vector2 SpawnOffset { get; set; }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Godot;
|
|||
namespace Cirno.Scripts.AttackPatterns;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class LaserPattern : SpiralPattern
|
||||
{
|
||||
[ExportGroup("Laser")][Export] public float SpawnDelay { get; set; } = 0.3f; // Delay before beam appears
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Godot;
|
|||
namespace Cirno.Scripts.AttackPatterns;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class MovementPattern : AttackPattern
|
||||
{
|
||||
[Export] public Vector2 relativeTargetPosition;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using GTweensGodot.Extensions;
|
|||
namespace Cirno.Scripts.AttackPatterns;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class NodeMovementPattern : AttackPattern
|
||||
{
|
||||
[Export] private Vector2 relativeTargetPosition;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Array = System.Array;
|
|||
namespace Cirno.Scripts.AttackPatterns;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class SpiralPattern : AttackPattern
|
||||
{
|
||||
[Export] public BulletResource BulletResource { get; set; }
|
||||
|
|
|
|||
14
Scripts/Components/BulletFlags.cs
Normal file
14
Scripts/Components/BulletFlags.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Cirno.Scripts.Components;
|
||||
|
||||
[Flags]
|
||||
public enum BulletFlags
|
||||
{
|
||||
Freezable = 1 << 1,
|
||||
Controllable = 1 << 2,
|
||||
Bouncy = 1 << 3,
|
||||
Piercing = 1 << 4,
|
||||
Grazeable = 1 << 5,
|
||||
Rotateable = 1 << 6,
|
||||
}
|
||||
1
Scripts/Components/BulletFlags.cs.uid
Normal file
1
Scripts/Components/BulletFlags.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://d6fmk6vngnxi
|
||||
45
Scripts/Components/BulletInfo.cs
Normal file
45
Scripts/Components/BulletInfo.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using System.Collections.Generic;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components;
|
||||
|
||||
public class BulletInfo(BulletResource originalBulletResource)
|
||||
{
|
||||
public BulletResource OriginalBulletResource { get; set; } = originalBulletResource;
|
||||
public Vector2 Position { get; set; }
|
||||
public Vector2 Direction { get; set; }
|
||||
public float Speed { get; set; }
|
||||
public float LifeTime { get; set; }
|
||||
public bool DestroyOnCollision { get; set; }
|
||||
public BulletOwner Owner { get; set; }
|
||||
public DamageType DamageType { get; set; }
|
||||
public float Damage { get; set; }
|
||||
public float Knockback { get; set; }
|
||||
public int BulletCount { get; set; }
|
||||
public float RotationSpeed { get; set; }
|
||||
public float RotationOffset { get; set; }
|
||||
//public double Time { get; set; }
|
||||
public float Spread { get; set; }
|
||||
public bool RotateSprite { get; set; } = false;
|
||||
public bool Controllabe { get; set; } = false;
|
||||
public bool Freezable { get; set; } = true;
|
||||
public PackedScene BulletScene { get; set; }
|
||||
public PackedScene DestructionParticlesScene { get; set; }
|
||||
public IBulletModifier Modifier { get; set; }
|
||||
public List<TimeModifier> TimeModifiers { get; set; } = new List<TimeModifier>();
|
||||
|
||||
public bool Grazeable { get; set; }
|
||||
public float GrazeValue { get; set; }
|
||||
|
||||
public BulletFlags Attributes { get; set; }
|
||||
|
||||
#region Laser
|
||||
public bool IsLaser { get; set; }
|
||||
public float SpawnDelay { get; set; } = 0.3f; // Delay before beam appears
|
||||
public float PreFireTime { get; set; } = 0.5f; // Time before laser becomes lethal
|
||||
public float LethalTime { get; set; } = 1.5f; // Time laser remains lethal
|
||||
public Color PreFireColor { get; set; } = new Color(1, 0, 0, 0.5f); // Thin red beam
|
||||
public Color LethalColor { get; set; } = new Color(1, 0, 0, 1.0f); // Thicker beam
|
||||
#endregion
|
||||
}
|
||||
1
Scripts/Components/BulletInfo.cs.uid
Normal file
1
Scripts/Components/BulletInfo.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://r80khe0f3jj8
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.Weapons;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
|
@ -90,42 +88,4 @@ public partial class BulletSpawner : Node2D
|
|||
// Vector2 direction = (target - position).Normalized();
|
||||
// SpawnBullet(position, direction, speed, owner, burstCount, spread: spread, bulletScene: bulletScene, modifier: modifier);
|
||||
// }
|
||||
}
|
||||
|
||||
public class BulletInfo(BulletResource originalBulletResource)
|
||||
{
|
||||
public BulletResource OriginalBulletResource { get; set; } = originalBulletResource;
|
||||
public Vector2 Position { get; set; }
|
||||
public Vector2 Direction { get; set; }
|
||||
public float Speed { get; set; }
|
||||
public float LifeTime { get; set; }
|
||||
public bool DestroyOnCollision { get; set; }
|
||||
public BulletOwner Owner { get; set; }
|
||||
public DamageType DamageType { get; set; }
|
||||
public float Damage { get; set; }
|
||||
public float Knockback { get; set; }
|
||||
public int BulletCount { get; set; }
|
||||
public float RotationSpeed { get; set; }
|
||||
public float RotationOffset { get; set; }
|
||||
//public double Time { get; set; }
|
||||
public float Spread { get; set; }
|
||||
public bool RotateSprite { get; set; } = false;
|
||||
public bool Controllabe { get; set; } = false;
|
||||
public bool Freezable { get; set; } = true;
|
||||
public PackedScene BulletScene { get; set; }
|
||||
public PackedScene DestructionParticlesScene { get; set; }
|
||||
public IBulletModifier Modifier { get; set; }
|
||||
public List<TimeModifier> TimeModifiers { get; set; } = new List<TimeModifier>();
|
||||
|
||||
public bool Grazeable { get; set; }
|
||||
public float GrazeValue { get; set; }
|
||||
|
||||
#region Laser
|
||||
public bool IsLaser { get; set; }
|
||||
public float SpawnDelay { get; set; } = 0.3f; // Delay before beam appears
|
||||
public float PreFireTime { get; set; } = 0.5f; // Time before laser becomes lethal
|
||||
public float LethalTime { get; set; } = 1.5f; // Time laser remains lethal
|
||||
public Color PreFireColor { get; set; } = new Color(1, 0, 0, 0.5f); // Thin red beam
|
||||
public Color LethalColor { get; set; } = new Color(1, 0, 0, 1.0f); // Thicker beam
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,16 @@ public partial class Shooting : EnemyStateBase
|
|||
|
||||
public float CurrentHealth => DamageReceiver.HealthProvider.CurrentResource;
|
||||
|
||||
public override void Init(IStateMachine<EnemyState, CharacterBody2D> machine)
|
||||
{
|
||||
base.Init(machine);
|
||||
|
||||
if (StorageModule.Root.EnemyResource.BossScript is not null)
|
||||
{
|
||||
this.BossScript = StorageModule.Root.EnemyResource.BossScript;
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnterState()
|
||||
{
|
||||
base.EnterState();
|
||||
|
|
|
|||
16
Scripts/Components/FSM/Enemy/EnemyFSMAnimatedSprite.cs
Normal file
16
Scripts/Components/FSM/Enemy/EnemyFSMAnimatedSprite.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Components.FSM.Enemy;
|
||||
|
||||
public partial class EnemyFSMAnimatedSprite : AnimatedSprite2D
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
var enemyFsmProxy = this.GetParentOrNull<EnemyFSMProxy>();
|
||||
|
||||
if (enemyFsmProxy?.EnemyResource?.AnimationFrames != null)
|
||||
{
|
||||
this.SpriteFrames = enemyFsmProxy.EnemyResource.AnimationFrames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dathhlufbe6gr
|
||||
|
|
@ -27,6 +27,12 @@ public partial class EnemyFSMProxy : CharacterBody2D, IActivable
|
|||
|
||||
[Signal] public delegate void DeathEventHandler(EnemyFSMProxy enemy);
|
||||
|
||||
public void Init(EnemyResource enemyResource)
|
||||
{
|
||||
this.EnemyResource = enemyResource;
|
||||
|
||||
}
|
||||
|
||||
public void TriggerDeath()
|
||||
{
|
||||
EmitSignalDeath(this);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Godot;
|
|||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public abstract partial class AttackPattern : Resource
|
||||
{
|
||||
//public Node2D Parent;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class BossPhase : Resource
|
||||
{
|
||||
[Export] public string PhaseName = string.Empty;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ public partial class BulletResource : Resource
|
|||
[Export] public bool Grazeable { get; set; } = true;
|
||||
[Export] public float GrazeValue { get; set; } = 0.2f;
|
||||
|
||||
[Export] public BulletFlags Attributes { get; set; }
|
||||
|
||||
[Export]
|
||||
public BulletCreationModifier Modifier;
|
||||
[Export] public Array<TimeModifier> TimeModifiers;
|
||||
|
|
@ -57,6 +59,7 @@ public partial class BulletResource : Resource
|
|||
TimeModifiers = TimeModifiers.Select(x => x).ToList(),
|
||||
Grazeable = Grazeable,
|
||||
GrazeValue = GrazeValue,
|
||||
Attributes = Attributes,
|
||||
// TimeModifiers = TimeModifiers?.Where(mod => mod is TimeModifier).Cast<TimeModifier>().Select(m => new ModifierWrapper()
|
||||
// {
|
||||
// TimeModifier = m,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class BulletScript : Resource
|
||||
{
|
||||
[Export]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Cirno.Scripts.Resources.Loot;
|
||||
using Cirno.Scripts.Resources.ScriptableBullets;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
|
|
@ -33,5 +34,8 @@ public partial class EnemyResource : Resource
|
|||
[Export] public float ResponseTime { get; private set; } = 0.5f;
|
||||
|
||||
[Export] public Texture2D IconSprite { get; private set; }
|
||||
[Export] public SpriteFrames AnimationFrames { get; private set; }
|
||||
|
||||
[Export] public BossScript BossScript { get; private set; }
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using Godot;
|
|||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class FSMMovementPattern : AttackPattern
|
||||
{
|
||||
[Export] private Vector2 relativeTargetPosition;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class PatternGroup : AttackPattern
|
||||
{
|
||||
[Export] private Array<AttackPattern> patterns;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.Resources.ScriptableBullets;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class BossScript : Resource
|
||||
{
|
||||
[Export]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Godot.Collections;
|
|||
namespace Cirno.Scripts.Resources.ScriptableBullets;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class ParallelPatternGroup : AttackPattern
|
||||
{
|
||||
[Export(PropertyHint.None, "suffix:s")] public float Duration { get; private set; } = 10f;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Godot;
|
|||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class SimpleMovementPattern : AttackPattern
|
||||
{
|
||||
[Export] private Vector2 relativeTargetPosition;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue