192 lines
4.3 KiB
C#
192 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using Godot;
|
|
using Godot.Bridge;
|
|
using Godot.NativeInterop;
|
|
|
|
[ScriptPath("res://Scripts/Puzzles/CapacitorShot.cs")]
|
|
public partial class CapacitorShot : Node2D
|
|
{
|
|
[Signal]
|
|
public delegate void OnCompletionEventHandler();
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private PackedScene entityBase;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Area2D[] areas;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Node2D target;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Node2D[] activate;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private float[] travelTime = new float[3] { 300f, 225f, 150f };
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Vector2 pushDir = Vector2.Down;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private StringName mapFlag = "None";
|
|
|
|
public Entity entity;
|
|
|
|
private bool hit;
|
|
|
|
private bool done;
|
|
|
|
private float time;
|
|
|
|
private float delay;
|
|
|
|
private int current;
|
|
|
|
private VisibleOnScreenNotifier2D screenTest;
|
|
|
|
public const uint layer = 128u;
|
|
|
|
|
|
public override void _Ready()
|
|
{
|
|
for (int i = 0; i < areas.Length; i++)
|
|
{
|
|
areas[i].CollisionLayer = 128u;
|
|
areas[i].CollisionMask = 128u;
|
|
}
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
if (delay > 0f)
|
|
{
|
|
delay -= Main.deltaTime;
|
|
}
|
|
if (entity == null)
|
|
{
|
|
entity = entityBase.Instantiate<Entity>(PackedScene.GenEditState.Disabled);
|
|
AddChild(entity, forceReadableName: false, InternalMode.Disabled);
|
|
entity.GlobalPosition = base.GlobalPosition;
|
|
time = 0f;
|
|
entity.AddChild(screenTest = new VisibleOnScreenNotifier2D(), forceReadableName: false, InternalMode.Disabled);
|
|
entity.trigger.CollisionLayer = 128u;
|
|
entity.trigger.CollisionMask = 128u;
|
|
entity.trigger.AreaEntered += BulletHit;
|
|
entity.trigger.BodyEntered += HitWall;
|
|
CollisionShape2D collider = entity.collider;
|
|
float[] array = travelTime;
|
|
collider.Disabled = array != null && array.Length > 1;
|
|
float[] array2 = travelTime;
|
|
if (array2 == null || array2.Length <= 1)
|
|
{
|
|
entity.SetDeferred("startPos", target.GlobalPosition);
|
|
}
|
|
return;
|
|
}
|
|
if (hit)
|
|
{
|
|
if (!screenTest.IsOnScreen())
|
|
{
|
|
Kill();
|
|
}
|
|
else
|
|
{
|
|
entity.GlobalPosition += pushDir * 2.25f;
|
|
}
|
|
return;
|
|
}
|
|
float[] array3 = travelTime;
|
|
if (array3 != null && array3.Length > 1)
|
|
{
|
|
time += Main.deltaTime;
|
|
if (time >= travelTime[current])
|
|
{
|
|
entity.QueueFree();
|
|
entity = null;
|
|
}
|
|
else
|
|
{
|
|
entity.GlobalPosition = base.GlobalPosition.Lerp(target.GlobalPosition, time / travelTime[current]);
|
|
}
|
|
}
|
|
else if (time < 30f)
|
|
{
|
|
time += Main.deltaTime;
|
|
entity.GlobalPosition = base.GlobalPosition.Lerp(target.GlobalPosition, time / 30f);
|
|
}
|
|
}
|
|
|
|
private void HitWall(Node other)
|
|
{
|
|
if (other is CollisionObject2D collisionObject2D && (collisionObject2D.CollisionLayer & 0x80) != 0)
|
|
{
|
|
if (hit)
|
|
{
|
|
CameraController.Shake(20f);
|
|
Main.Particle("BadExplosion", entity.GlobalPosition, 1, null, localSpace: false);
|
|
Kill();
|
|
}
|
|
else
|
|
{
|
|
entity.StopMoving();
|
|
entity.GlobalPosition += collisionObject2D.GlobalPosition.DirectionTo(entity.GlobalPosition).Snapped(Vector2.One) * 2f;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Kill()
|
|
{
|
|
entity.QueueFree();
|
|
entity = null;
|
|
hit = false;
|
|
delay = 10f;
|
|
}
|
|
|
|
private void BulletHit(Node other)
|
|
{
|
|
if (done || !IsProcessing())
|
|
{
|
|
return;
|
|
}
|
|
if (other.HasMeta(Enemy.waterTag))
|
|
{
|
|
Main.Particle("WaterBurst", other.GetParent<Node2D>().GlobalPosition, 1, null, localSpace: false);
|
|
other.GetParent().QueueFree();
|
|
entity.anim.Play("Hurt");
|
|
entity.ProcessMode = ProcessModeEnum.Always;
|
|
hit = true;
|
|
Audio.PlaySound("snd_bomb.wav");
|
|
}
|
|
else
|
|
{
|
|
if (other != areas[current])
|
|
{
|
|
return;
|
|
}
|
|
entity.GlobalPosition = areas[current].GlobalPosition + new Vector2(0f, 4f);
|
|
Main.Particle("Sparks", areas[current].GlobalPosition, 1, null, localSpace: false);
|
|
entity.anim.Play("Elec");
|
|
Audio.PlaySound("snd_grab.wav");
|
|
Audio.PlaySound("snd_electric_talk.wav", 1f, 0.9f).Bus = "Reverb";
|
|
Main.SetActive(activate[current], state: true);
|
|
current++;
|
|
entity = null;
|
|
hit = false;
|
|
if (current >= areas.Length)
|
|
{
|
|
if (mapFlag != (StringName)"None")
|
|
{
|
|
Room.current.tempFlags.Add(mapFlag);
|
|
}
|
|
EmitSignal(SignalName.OnCompletion);
|
|
SetDeferred("process_mode", 4);
|
|
done = true;
|
|
}
|
|
delay = 10f;
|
|
}
|
|
}
|
|
|
|
}
|