Enhanced bullet scripts

This commit is contained in:
Marco 2025-09-24 17:47:15 +02:00
commit c1f83736f0
7 changed files with 112 additions and 52 deletions

View file

@ -1435,6 +1435,7 @@ script = ExtResource("10_eflie")
mesh = SubResource("ArrayMesh_ark53") mesh = SubResource("ArrayMesh_ark53")
[node name="entity_0_occluder_instance" type="OccluderInstance3D" parent="FuncGodotMap/entity_0_worldspawn"] [node name="entity_0_occluder_instance" type="OccluderInstance3D" parent="FuncGodotMap/entity_0_worldspawn"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0043945313, -0.005493164, 0.004699707)
occluder = SubResource("ArrayOccluder3D_iwcxo") occluder = SubResource("ArrayOccluder3D_iwcxo")
[node name="entity_0_brush_0_collision_shape" type="CollisionShape3D" parent="FuncGodotMap/entity_0_worldspawn"] [node name="entity_0_brush_0_collision_shape" type="CollisionShape3D" parent="FuncGodotMap/entity_0_worldspawn"]

View file

@ -7,6 +7,7 @@
[sub_resource type="Resource" id="Resource_bdx2k"] [sub_resource type="Resource" id="Resource_bdx2k"]
script = ExtResource("3_wsvd4") script = ExtResource("3_wsvd4")
LoopType = 1
BulletResource = ExtResource("1_bdx2k") BulletResource = ExtResource("1_bdx2k")
rotationSpeed = 12.0 rotationSpeed = 12.0
UseParentRotationOffset = true UseParentRotationOffset = true

View file

@ -7,13 +7,14 @@
[sub_resource type="Resource" id="Resource_ww6vs"] [sub_resource type="Resource" id="Resource_ww6vs"]
script = ExtResource("3_tp6n0") script = ExtResource("3_tp6n0")
LoopType = 1
BulletResource = ExtResource("1_ww6vs") BulletResource = ExtResource("1_ww6vs")
bulletCount = 8 bulletCount = 8
BurstRotationSpeed = 12.0 BurstRotationSpeed = 6.0
UseParentRotationOffset = true UseParentRotationOffset = true
burstInterval = 0.1 burstInterval = 0.1
ShotsPerBurst = 4 ShotsPerBurst = 4
BurstRate = 2.0 BurstRate = 0.5
OverrideDamage = true OverrideDamage = true
DamageOverride = 20.0 DamageOverride = 20.0
OverrideOwner = true OverrideOwner = true

View file

@ -7,10 +7,17 @@
[sub_resource type="Resource" id="Resource_c4f5k"] [sub_resource type="Resource" id="Resource_c4f5k"]
script = ExtResource("3_l6rg6") script = ExtResource("3_l6rg6")
LoopType = 1
BulletResource = ExtResource("1_c4f5k") BulletResource = ExtResource("1_c4f5k")
bulletCount = 1 bulletCount = 1
UseParentRotationOffset = true UseParentRotationOffset = true
duration = 0.5
spread = 0.0 spread = 0.0
burstInterval = 0.0
ShotsPerBurst = 1
BurstRate = 0.5
OverrideDamage = true
DamageOverride = 20.0
metadata/_custom_type_script = "uid://bxiprx5nwmpnu" metadata/_custom_type_script = "uid://bxiprx5nwmpnu"
[resource] [resource]

View file

@ -12,6 +12,7 @@ namespace Cirno.Scripts.AttackPatterns;
[Tool] [Tool]
public partial class ShootingPattern3D : AttackPattern public partial class ShootingPattern3D : AttackPattern
{ {
[Export] public float Delay { get; set; }
[Export] public LoopType LoopType { get; set; } [Export] public LoopType LoopType { get; set; }
[Export] public BulletResource BulletResource { get; set; } [Export] public BulletResource BulletResource { get; set; }
@ -22,7 +23,7 @@ public partial class ShootingPattern3D : AttackPattern
[Export] public float BurstRotationSpeed = 0f; [Export] public float BurstRotationSpeed = 0f;
[Export] public bool UseParentRotationOffset { get; set; } = false; [Export] public bool UseParentRotationOffset { get; set; } = false;
[Export] public float _rotationOffset = 0f; [Export] public float _rotationOffset = 0f;
[Export] public float duration = 5f; [Export] public float duration = -1f;
[Export] public float spread = 360f; [Export] public float spread = 360f;
[Export] public float burstInterval = 0.5f; [Export] public float burstInterval = 0.5f;
@ -34,28 +35,40 @@ public partial class ShootingPattern3D : AttackPattern
[ExportCategory("Other")] [Export] public bool _predictPlayer = false; [ExportCategory("Other")] [Export] public bool _predictPlayer = false;
[ExportCategory("Overrides")] [ExportCategory("Overrides")]
[ExportGroup("Override Damage")] [ExportGroup("Override Damage")]
[Export(PropertyHint.GroupEnable)] public bool OverrideDamage { get; private set; } = false; [Export(PropertyHint.GroupEnable)]
public bool OverrideDamage { get; private set; } = false;
[Export] public float DamageOverride { get; private set; } = 10f; [Export] public float DamageOverride { get; private set; } = 10f;
[ExportGroup("Override Speed")] [ExportGroup("Override Speed")]
[Export(PropertyHint.GroupEnable)] public bool OverrideSpeed { get; private set; } = false; [Export(PropertyHint.GroupEnable)]
public bool OverrideSpeed { get; private set; } = false;
[Export] public float SpeedOverride { get; private set; } = 10f; [Export] public float SpeedOverride { get; private set; } = 10f;
[ExportGroup("Override Owner")] [ExportGroup("Override Owner")]
[Export(PropertyHint.GroupEnable)] public bool OverrideOwner { get; private set; } = false; [Export(PropertyHint.GroupEnable)]
public bool OverrideOwner { get; private set; } = false;
[Export] public BulletOwner Owner { get; private set; } = BulletOwner.None; [Export] public BulletOwner Owner { get; private set; } = BulletOwner.None;
[ExportGroup("Override Damage Type")] [ExportGroup("Override Damage Type")]
[Export(PropertyHint.GroupEnable)] public bool OverrideDamageType { get; private set; } = false; [Export(PropertyHint.GroupEnable)]
public bool OverrideDamageType { get; private set; } = false;
[Export] public DamageType DamageType { get; private set; } = DamageType.Neutral; [Export] public DamageType DamageType { get; private set; } = DamageType.Neutral;
[ExportGroup("Override Attributes")] [ExportGroup("Override Attributes")]
[Export(PropertyHint.GroupEnable)] public bool OverrideAttributes { get; private set; } = false; [Export(PropertyHint.GroupEnable)]
public bool OverrideAttributes { get; private set; } = false;
[Export] public BulletFlags AttributesOverride { get; private set; } [Export] public BulletFlags AttributesOverride { get; private set; }
[ExportGroup("Override Controllable (deprecated)")] [ExportGroup("Override Controllable (deprecated)")]
[Export(PropertyHint.GroupEnable)] public bool OverrideControllable { get; private set; } = false; [Export(PropertyHint.GroupEnable)]
public bool OverrideControllable { get; private set; } = false;
[Export] public bool Controllable { get; private set; } = false; [Export] public bool Controllable { get; private set; } = false;
[ExportCategory("Extra Modifiers")] [ExportCategory("Extra Modifiers")]
@ -64,10 +77,12 @@ public partial class ShootingPattern3D : AttackPattern
public bool OverrideCreationModifier { get; private set; } = false; public bool OverrideCreationModifier { get; private set; } = false;
[Export] public BulletCreationModifier Modifier; [Export] public BulletCreationModifier Modifier;
[ExportGroup("Time Modifiers")]
[Export] public Array<TimeModifier> TimeModifiers = [];
protected virtual BulletInfo MakeBullet(Vector2 position, int count = 1, float spread = 0f, float rotationOffset = 0f) [ExportGroup("Time Modifiers")] [Export]
public Array<TimeModifier> TimeModifiers = [];
protected virtual BulletInfo MakeBullet(Vector2 position, int count = 1, float spread = 0f,
float rotationOffset = 0f)
{ {
var bullet = this.BulletResource.MakeBullet(position, count, var bullet = this.BulletResource.MakeBullet(position, count,
spread, rotationOffset); spread, rotationOffset);
@ -125,7 +140,9 @@ public partial class ShootingPattern3D : AttackPattern
public Node Parent => parent; public Node Parent => parent;
public IScriptHost3D ScriptHost { get; private set; } public IScriptHost3D ScriptHost { get; private set; }
private double timer; private double timer;
private double burstTimer; private double burstTimer;
//private double _burstRateTimer; //private double _burstRateTimer;
private BulletSpawner3D spawner; private BulletSpawner3D spawner;
@ -145,7 +162,7 @@ public partial class ShootingPattern3D : AttackPattern
spawner = parent.GetNode<BulletSpawner3D>("BulletSpawner3D"); spawner = parent.GetNode<BulletSpawner3D>("BulletSpawner3D");
_state = ShootStatus.Shooting; _state = pattern.Delay == 0 ? ShootStatus.Shooting : ShootStatus.Idle;
} }
private void WaitingBurstUpdate(double delta) private void WaitingBurstUpdate(double delta)
@ -180,6 +197,12 @@ public partial class ShootingPattern3D : AttackPattern
if (_burstBullets <= 0) if (_burstBullets <= 0)
{ {
if (pattern.LoopType is LoopType.PlayOnce)
{
_state = ShootStatus.Done;
return;
}
_state = ShootStatus.WaitingReload; _state = ShootStatus.WaitingReload;
_currentBurstOffset++; _currentBurstOffset++;
} }
@ -189,11 +212,22 @@ public partial class ShootingPattern3D : AttackPattern
} }
} }
private void IdleUpdate(double delta)
{
timer += delta;
if (timer >= pattern.Delay)
{
_state = ShootStatus.Shooting;
}
}
public void UpdatePattern(double delta) public void UpdatePattern(double delta)
{ {
switch (_state) switch (_state)
{ {
case ShootStatus.Idle: case ShootStatus.Idle:
IdleUpdate(delta);
break;
case ShootStatus.Done: case ShootStatus.Done:
return; return;
case ShootStatus.Shooting: case ShootStatus.Shooting:
@ -207,16 +241,16 @@ public partial class ShootingPattern3D : AttackPattern
break; break;
} }
if (timer >= pattern.duration) if (pattern.duration > -1 && timer >= pattern.duration)
{ {
_state = ShootStatus.Done; _state = ShootStatus.Done;
} }
} }
private void Shoot() private void Shoot()
{ {
float angleOffset = pattern._rotationOffset + (float)(pattern.rotationSpeed * timer) + (float)(pattern.BurstRotationSpeed * _currentBurstOffset); float angleOffset = pattern._rotationOffset + (float)(pattern.rotationSpeed * timer) +
(float)(pattern.BurstRotationSpeed * _currentBurstOffset);
Vector2 direction = pattern.BulletResource.Direction; Vector2 direction = pattern.BulletResource.Direction;
@ -232,7 +266,8 @@ public partial class ShootingPattern3D : AttackPattern
if (pattern._predictPlayer && GameController.Instance.PlayerVelocity.HasValue) if (pattern._predictPlayer && GameController.Instance.PlayerVelocity.HasValue)
{ {
var predictedDirection = MathFunctions.PredictInterceptPosition(spawner.GlobalPosition.ToVector2(), var predictedDirection = MathFunctions.PredictInterceptPosition(spawner.GlobalPosition.ToVector2(),
GameController.Instance.PlayerPosition.Value.ToVector2(), GameController.Instance.PlayerVelocity.Value.ToVector2(), GameController.Instance.PlayerPosition.Value.ToVector2(),
GameController.Instance.PlayerVelocity.Value.ToVector2(),
pattern.BulletResource.BulletSpeed); pattern.BulletResource.BulletSpeed);
if (predictedDirection.HasValue) if (predictedDirection.HasValue)
{ {
@ -241,7 +276,8 @@ public partial class ShootingPattern3D : AttackPattern
} }
else else
{ {
direction = (GameController.Instance.PlayerPosition.Value.ToVector2() - spawner.GlobalPosition.ToVector2()).Normalized(); direction = (GameController.Instance.PlayerPosition.Value.ToVector2() -
spawner.GlobalPosition.ToVector2()).Normalized();
} }
} }
@ -259,8 +295,17 @@ public partial class ShootingPattern3D : AttackPattern
public bool IsComplete() public bool IsComplete()
{ {
//return timer >= pattern.duration; if (!pattern.WaitForCompletion) return _state is ShootStatus.Done;
return _state is ShootStatus.Done; if (_state is not ShootStatus.Done) return false;
// From now on the status is done
if (pattern.duration > -1)
{
// Wait for timer
return (timer >= pattern.duration);
}
// No timer, if it's done it's done
return true;
} }
private enum ShootStatus private enum ShootStatus

View file

@ -11,6 +11,8 @@ namespace Cirno.Scripts.Resources;
public partial class PatternGroup : AttackPattern public partial class PatternGroup : AttackPattern
{ {
[Export] private Array<AttackPattern> patterns; [Export] private Array<AttackPattern> patterns;
[Export(PropertyHint.None, "suffix:s")]
public float Duration { get; private set; } = -1f;
public override IPatternMachine MakeMachine(Node parent) public override IPatternMachine MakeMachine(Node parent)
{ {
@ -53,7 +55,7 @@ public partial class PatternGroup : AttackPattern
public bool IsComplete() public bool IsComplete()
{ {
return _currentPatternIndex >= patternGroup.patterns.Count; return patternGroup.Duration > -1 && _currentPatternIndex >= patternGroup.patterns.Count;
} }
} }

View file

@ -9,7 +9,9 @@ namespace Cirno.Scripts.Resources.ScriptableBullets;
[Tool] [Tool]
public partial class ParallelPatternGroup : AttackPattern public partial class ParallelPatternGroup : AttackPattern
{ {
[Export(PropertyHint.None, "suffix:s")] public float Duration { get; private set; } = 10f; [Export(PropertyHint.None, "suffix:s")]
public float Duration { get; private set; } = 10f;
[Export] public Array<AttackPattern> Patterns { get; private set; } = []; [Export] public Array<AttackPattern> Patterns { get; private set; } = [];
public override IPatternMachine MakeMachine(Node parent) public override IPatternMachine MakeMachine(Node parent)
@ -48,19 +50,20 @@ public partial class ParallelPatternGroup : AttackPattern
if (patternMachine.IsComplete()) continue; if (patternMachine.IsComplete()) continue;
patternMachine.UpdatePattern(delta); patternMachine.UpdatePattern(delta);
} }
} }
public bool IsComplete() public bool IsComplete()
{ {
if (patternGroup.WaitForCompletion) if (patternGroup.WaitForCompletion)
{ {
return _patternMachines.TrueForAll(x => x.IsComplete()) && _progressTimer >= patternGroup.Duration; return _patternMachines.TrueForAll(x => x.IsComplete()) &&
(patternGroup.Duration > -1 &&
_progressTimer >= patternGroup.Duration);
} }
return _patternMachines.TrueForAll(x => x.IsComplete()) || _progressTimer >= patternGroup.Duration; return _patternMachines.TrueForAll(x => x.IsComplete()) ||
(patternGroup.Duration > -1 &&
_progressTimer >= patternGroup.Duration);
} }
} }
} }