using Cirno.Scripts.Components.FSM.Enemy._3D; using Cirno.Scripts.Resources; using Cirno.Scripts.Utils; using Godot; using Godot.Collections; namespace Cirno.Scripts.Actors; [Tool] public partial class EnemyMarker3D : PreviewMarker3D, IActivable { private readonly Vector3 _boxSize = new Vector3(0.5f, 0.8f, 0.5f); private EnemyResource _enemy; [Export] public EnemyResource Enemy { get => _enemy; set { _enemy = value; if (Engine.IsEditorHint()) { //QueueRedraw(); this.Texture = _enemy?.IconSprite; } } } private bool _autoSpawn = false; [Export] public bool AutoSpawn { get => _autoSpawn; set { _autoSpawn = value; if (Engine.IsEditorHint()) { if (_autoSpawn) { Alpha = 1.0f; // SetSpriteAlpha(1); } else { Alpha = 0.5f; //SetSpriteAlpha(0.5f); } QueueRedraw(); } } } private EnemyProxy3D _spawnedEnemy; [Export] public StringName TargetName { get; set; } public void _func_godot_apply_properties(Dictionary props) { //GroupName = (string)props["targetname"]; this.AddToGroup("EnemyMarkers"); _billboard = true; _autoSpawn = props["autospawn"].AsBool(); if (_autoSpawn) { _alpha = 1.0f; // SetSpriteAlpha(1); } else { _alpha = 0.5f; //SetSpriteAlpha(0.5f); } var scriptPath = props["resource_path"].AsString(); if (!string.IsNullOrWhiteSpace(scriptPath)) { Enemy = GD.Load(scriptPath); } else { GD.PushWarning($"Spawner {this.Name} has no enemy assigned"); } TargetName = props["targetname"].AsStringName(); //QueueRedraw(); // Redraw should be automatic when enemy was changed and texture updated //MarkerId = props["id"].AsInt32(); } protected override void QueueRedraw() { if (!Engine.IsEditorHint()) return; if (_autoSpawn) { _alpha = 1.0f; // SetSpriteAlpha(1); } else { _alpha = 0.5f; //SetSpriteAlpha(0.5f); } base.QueueRedraw(); } public override void _Ready() { base._Ready(); if (!string.IsNullOrWhiteSpace(TargetName)) { this.AddToGroup(TargetName); } if (AutoSpawn) { Spawn(false); } } public EnemyProxy3D Spawn(bool deleteMarker) { if (Engine.IsEditorHint()) return null; if (Enemy is null) return null; if (_spawnedEnemy is not null) return _spawnedEnemy; if (deleteMarker) { this.QueueFree(); } var enemyScene = GD.Load(Enemy.PrefabPath); _spawnedEnemy = this.CreateSibling(enemyScene); _spawnedEnemy.Init(Enemy); //Spawned = true; _spawnedEnemy.Death += SpawnedEnemyOnDeath; return _spawnedEnemy; } private void SpawnedEnemyOnDeath(EnemyProxy3D enemy) { _spawnedEnemy.Death -= SpawnedEnemyOnDeath; _spawnedEnemy = null; //Spawned = false; } public bool Activate(ActivationType activationType = ActivationType.Toggle) { if (Engine.IsEditorHint()) return false; Spawn(false); return _spawnedEnemy is not null; } public void Toggle() { Activate(); } public override void _Process(double delta) { if (!Engine.IsEditorHint()) return; #if !DISABLE_DD3D DebugDraw3D.DrawBox(this.GlobalPosition - _boxSize / 2, Quaternion.Identity, _boxSize, Colors.Red); #endif //DebugDraw3D.DrawSphere(this.GlobalPosition, 0.1f, Colors.Green); } }