562 lines
14 KiB
C#
562 lines
14 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using Godot;
|
|
using Godot.Bridge;
|
|
using Godot.NativeInterop;
|
|
|
|
[ScriptPath("res://Scripts/Events/CommonEvents.cs")]
|
|
public partial class CommonEvents : Node2D
|
|
{
|
|
[Export(PropertyHint.None, "")]
|
|
public Node2D[] nodes;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
public Entity[] entities;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
public Node[] others;
|
|
|
|
private static readonly HashSet<Items.IDs> dontRemove = new HashSet<Items.IDs> { Items.IDs.FoxNecklace };
|
|
|
|
public static CommonEvents instance;
|
|
|
|
private static Node letterObj;
|
|
|
|
public override void _Ready()
|
|
{
|
|
instance = this;
|
|
}
|
|
|
|
public static void DoEvent(string name)
|
|
{
|
|
Party.StopMoving();
|
|
if (instance == null)
|
|
{
|
|
instance = new CommonEvents();
|
|
}
|
|
GD.Print("common event: " + name);
|
|
Main.inEvent = Coroutine.Start((IEnumerator)instance.GetType().GetMethod(name).Invoke(instance, null));
|
|
}
|
|
|
|
public IEnumerator WantedPoster()
|
|
{
|
|
Texture2D[] array = new Texture2D[4]
|
|
{
|
|
GD.Load<Texture2D>("res://Sprites/Menus/Posters/wanted.tres"),
|
|
GD.Load<Texture2D>("res://Sprites/Menus/Posters/caught.tres"),
|
|
GD.Load<Texture2D>("res://Sprites/Menus/Posters/atlarge.tres"),
|
|
GD.Load<Texture2D>("res://Sprites/Menus/Posters/dead.tres")
|
|
};
|
|
List<Texts.Letters> posters = new List<Texts.Letters>();
|
|
foreach (Entity.IDs key in Texts.posters.Keys)
|
|
{
|
|
Texts.Letters letters = Texts.posters[key];
|
|
letters.sound = null;
|
|
letters.backColor = new Color(0.8f, 0.7f, 0.6f);
|
|
if (letters.needFlag == SaveFile.Flags.None || SaveFile.HasFlag(letters.needFlag))
|
|
{
|
|
int num = 0;
|
|
if (SaveFile.HasFlag(letters.deadFlag))
|
|
{
|
|
num = 3;
|
|
}
|
|
else if (SaveFile.current.apprehended.Contains(key) || SaveFile.HasFlag(letters.captureFlag))
|
|
{
|
|
num = 1;
|
|
}
|
|
else if (SaveFile.HasFlag(letters.missFlag))
|
|
{
|
|
num = 2;
|
|
}
|
|
letters.sprites = new Texts.Letters.Sprites[2]
|
|
{
|
|
new Texts.Letters.Sprites
|
|
{
|
|
tex = GD.Load<Texture2D>("res://Sprites/Menus/Posters/" + key.ToString() + ".tres"),
|
|
pos = new Vector2(0f, -60f),
|
|
scale = Vector2.One * 1.25f
|
|
},
|
|
new Texts.Letters.Sprites
|
|
{
|
|
tex = array[num],
|
|
pos = new Vector2(0f, 0f)
|
|
}
|
|
};
|
|
posters.Add(letters);
|
|
}
|
|
}
|
|
Coroutine c = Coroutine.Start(ReadLetter(posters[0]));
|
|
int index = 0;
|
|
while (!c.done)
|
|
{
|
|
int num2 = index;
|
|
if (Input.IsActionJustPressed(Main.keys[2]))
|
|
{
|
|
index = (int)Main.Repeat(index - 1, posters.Count);
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[3]))
|
|
{
|
|
index = (int)Main.Repeat(index + 1, posters.Count);
|
|
}
|
|
if (num2 != index)
|
|
{
|
|
Coroutine.Stop(c, now: true);
|
|
letterObj.QueueFree();
|
|
c = Coroutine.Start(ReadLetter(posters[index]));
|
|
}
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public IEnumerator LockedDoorKnock()
|
|
{
|
|
AudioStreamPlayer ap = Audio.PlaySound("snd_knock_ch1.wav");
|
|
yield return null;
|
|
while (ap.Playing)
|
|
{
|
|
yield return null;
|
|
}
|
|
for (float a = 0f; a < 30f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
TextSystem.GetText("LockedDoor");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public IEnumerator LockedDoorKnockNoResponse()
|
|
{
|
|
AudioStreamPlayer ap = Audio.PlaySound("snd_knock_ch1.wav");
|
|
yield return null;
|
|
while (ap.Playing)
|
|
{
|
|
yield return null;
|
|
}
|
|
for (float a = 0f; a < 30f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
TextSystem.GetText("NoResponse");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public IEnumerator LockedDoorBearingTown()
|
|
{
|
|
AudioStreamPlayer ap = Audio.PlaySound("snd_knock_ch1.wav");
|
|
yield return null;
|
|
while (ap.Playing)
|
|
{
|
|
yield return null;
|
|
}
|
|
for (float a = 0f; a < 30f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
TextSystem.GetText("SchoolDWScaredGuy");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public IEnumerator PhoneEvent()
|
|
{
|
|
bool k = SaveFile.current.flags.Contains(SaveFile.Flags.KanakoFollowing) && !SaveFile.current.flags.Contains(SaveFile.Flags.KanakoPhoneEvent) && !SaveFile.current.flags.Contains(SaveFile.Flags.WeirdStart);
|
|
if (k)
|
|
{
|
|
TextSystem.GetText("KanakoPhoneEvent1");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
Audio.PlaySound("snd_phone.wav");
|
|
float d = Audio.music.VolumeDb;
|
|
Audio.music.VolumeDb = Mathf.LinearToDb(0f);
|
|
TextSystem.GetText("PhoneTry1");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
Audio.music.VolumeDb = d;
|
|
if (k)
|
|
{
|
|
TextSystem.GetText("KanakoPhoneEvent2");
|
|
SaveFile.AddFlag(SaveFile.Flags.KanakoPhoneEvent);
|
|
}
|
|
else
|
|
{
|
|
TextSystem.GetText("PhoneTry2");
|
|
}
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public static IEnumerator EntityJump(Entity entity, Vector2 pos, float frames = 45f, string sound = "snd_cardrive.wav", string anim = "Spin", float height = 40f, bool shakeOnEnd = true)
|
|
{
|
|
Vector2 s = entity.GlobalPosition;
|
|
Vector2 m = new Vector2(s.Lerp(pos, 0.5f).X, 0f - height + Mathf.Min(s.Y, pos.Y));
|
|
if (sound != null && sound.Length > 0)
|
|
{
|
|
Audio.PlaySound(sound);
|
|
}
|
|
entity.anim.Play(anim);
|
|
for (float a = 0f; a < frames; a += Main.deltaTime)
|
|
{
|
|
entity.GlobalPosition = Common.Beizier(s, m, pos, a / frames);
|
|
yield return null;
|
|
}
|
|
entity.GlobalPosition = pos;
|
|
entity.UpdateAnim(force: true);
|
|
if (shakeOnEnd)
|
|
{
|
|
CameraController.Shake(7f);
|
|
Audio.PlaySound("snd_screenshake.wav");
|
|
}
|
|
}
|
|
|
|
public static IEnumerator ShakeObj(Node2D obj, float time, Vector2 freq, Vector2? pos = null)
|
|
{
|
|
pos.GetValueOrDefault();
|
|
if (!pos.HasValue)
|
|
{
|
|
Vector2 globalPosition = obj.GlobalPosition;
|
|
pos = globalPosition;
|
|
}
|
|
if (time == -1f)
|
|
{
|
|
while (true)
|
|
{
|
|
obj.GlobalPosition = pos.Value + new Vector2(Main.RandomRange(0f - freq.X, freq.X), Main.RandomRange(0f - freq.Y, freq.Y));
|
|
yield return null;
|
|
}
|
|
}
|
|
for (float a = 0f; a < time; a += Main.deltaTime)
|
|
{
|
|
obj.GlobalPosition = pos.Value + new Vector2(Main.RandomRange(0f - freq.X, freq.X), Main.RandomRange(0f - freq.Y, freq.Y));
|
|
yield return null;
|
|
}
|
|
obj.GlobalPosition = pos.Value;
|
|
}
|
|
|
|
public void ReturnToLWAnim()
|
|
{
|
|
Main.inEvent = Coroutine.Start(DarkWorldTransition.ReturnToLW());
|
|
}
|
|
|
|
public IEnumerator BallJunkToss()
|
|
{
|
|
TextSystem.GetText("BallJunkTossDiag");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
if (TextSystem.lastPrompt == 0)
|
|
{
|
|
SaveFile.current.lwItems.Remove(Items.IDs.BallOfJunk);
|
|
SaveFile.current.dwArmor.Clear();
|
|
SaveFile.current.dwItems.Clear();
|
|
SaveFile.current.dwWeapon.Clear();
|
|
}
|
|
}
|
|
|
|
public static IEnumerator BeizierMove(Node2D node, Vector2 start, Vector2 mid, Vector2 end, float time)
|
|
{
|
|
for (float a = 0f; a <= time; a += Main.deltaTime)
|
|
{
|
|
node.GlobalPosition = Common.Beizier(start, mid, end, a / time);
|
|
yield return null;
|
|
}
|
|
node.GlobalPosition = end;
|
|
}
|
|
|
|
public IEnumerator GenericToss()
|
|
{
|
|
Texts.TextBlock[] diagClone = Texts.GetDiagClone("TossItem");
|
|
string t = Texts.items[SaveFile.current.lwItems[LWMenu.lastItem]].name;
|
|
diagClone[0].text = diagClone[0].text.Replace("[ITEM]", t);
|
|
TextSystem.SingleText(diagClone);
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
if (TextSystem.lastPrompt == 0)
|
|
{
|
|
SaveFile.current.lwItems.RemoveAt(LWMenu.lastItem);
|
|
diagClone = Texts.GetDiagClone("TossItem2");
|
|
diagClone[0].text = diagClone[0].text.Replace("[ITEM]", t);
|
|
TextSystem.SingleText(diagClone);
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IEnumerator SpinEntity(Entity entity, float delay = 5f, int direction = 1)
|
|
{
|
|
Vector2[] dir = new Vector2[4]
|
|
{
|
|
Vector2.Down,
|
|
Vector2.Right,
|
|
Vector2.Up,
|
|
Vector2.Left
|
|
};
|
|
int current = 0;
|
|
while (true)
|
|
{
|
|
entity.LookAt(dir[current]);
|
|
current = (int)Main.Repeat(current + direction, dir.Length);
|
|
for (float a = 0f; a < delay; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
public static IEnumerator DayAnim(int day)
|
|
{
|
|
CameraController cameraController = CameraController.instance;
|
|
Node2D node;
|
|
Node2D anim = (node = GD.Load<PackedScene>("res://Objects/UI/NewDayAnim.tscn").Instantiate<Node2D>(PackedScene.GenEditState.Disabled));
|
|
cameraController.AddChild(node, forceReadableName: false, InternalMode.Disabled);
|
|
anim.ZIndex = 4000;
|
|
RichTextLabel r = anim.GetChild<RichTextLabel>(0);
|
|
r.Text = "[center]Day " + day;
|
|
float[] pitch = new float[5] { 1f, 1.1f, 1f, 0.9f, 1f };
|
|
float a;
|
|
for (int i = 0; i < pitch.Length; i++)
|
|
{
|
|
for (a = 0f; a < 20f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
Audio.PlaySound("snd_noise.wav", 1f, pitch[i]);
|
|
anim.GetChild<Node2D>(1 + i).Visible = false;
|
|
for (a = 0f; a < 20f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
for (a = 0f; a < 30f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
r.Visible = true;
|
|
SaveFile.current.values[9] = day;
|
|
if (day == 2)
|
|
{
|
|
SaveFile.current.values[10] = 3;
|
|
Audio.PlaySound("snd_electric_talk.wav");
|
|
}
|
|
for (a = 0f; a < 90f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
a = 0f;
|
|
for (float b = 150f; a < b; a += Main.deltaTime)
|
|
{
|
|
anim.Modulate = Main.colorWhite.Lerp(Main.colorClear, a / b);
|
|
yield return null;
|
|
}
|
|
anim.QueueFree();
|
|
}
|
|
|
|
public static IEnumerator ReadLetter(Texts.Letters letter, SaveFile.Letters id = SaveFile.Letters.None)
|
|
{
|
|
Party.StopMoving();
|
|
if (letter == null)
|
|
{
|
|
letter = Texts.letters[id];
|
|
}
|
|
SaveFile.current.readLetters.Add(id);
|
|
if (letter.sound != null)
|
|
{
|
|
Audio.PlaySound(letter.sound, letter.soundVol);
|
|
}
|
|
CameraController cameraController = CameraController.instance;
|
|
Control node;
|
|
Control obj = (node = GD.Load<PackedScene>("res://Objects/UI/Letter.tscn").Instantiate<Control>(PackedScene.GenEditState.Disabled));
|
|
cameraController.AddChild(node, forceReadableName: false, InternalMode.Disabled);
|
|
NinePatchRect b = obj.GetChild<NinePatchRect>(0);
|
|
letterObj = obj;
|
|
if (letter.back != null)
|
|
{
|
|
b.Texture = letter.back;
|
|
}
|
|
b.SelfModulate = letter.backColor;
|
|
RichTextLabel child = obj.GetChild<RichTextLabel>(1);
|
|
child.Text = letter.text;
|
|
Texts.Letters.Sprites[] sprites = letter.sprites;
|
|
if (sprites != null && sprites.Length != 0)
|
|
{
|
|
for (int i = 0; i < letter.sprites.Length; i++)
|
|
{
|
|
obj.AddChild(new Sprite2D
|
|
{
|
|
Texture = letter.sprites[i].tex,
|
|
Position = letter.sprites[i].pos,
|
|
Scale = ((letter.sprites[i].scale == Vector2.Zero) ? Vector2.One : letter.sprites[i].scale)
|
|
}, forceReadableName: false, InternalMode.Disabled);
|
|
}
|
|
}
|
|
int lineCount = child.GetLineCount();
|
|
b.Size = new Vector2(220f, 20 * lineCount + 10);
|
|
int scroll = 0;
|
|
for (float a = 0f; a < 10f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
while (!Input.IsActionJustPressed(Main.keys[4]) && !Input.IsActionJustPressed(Main.keys[5]))
|
|
{
|
|
if (Input.IsActionJustPressed(Main.keys[0]))
|
|
{
|
|
if (scroll > 0)
|
|
{
|
|
scroll -= 20;
|
|
}
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[1]) && (float)scroll < b.Size.Y / 2f)
|
|
{
|
|
scroll += 20;
|
|
}
|
|
obj.Position = new Vector2(0f, -scroll);
|
|
yield return null;
|
|
}
|
|
obj.QueueFree();
|
|
letterObj = null;
|
|
}
|
|
|
|
public IEnumerator WaterFill()
|
|
{
|
|
if (Room.current.tempFlags.Contains("WaterFilled"))
|
|
{
|
|
Audio.PlaySound("snd_switchpull_n.wav");
|
|
for (float a = 0f; a < 40f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
Audio.PlaySound("snd_mercyadd.wav");
|
|
Room.current.waterBullet = 5;
|
|
BattleDR.ShowFloatingText(Texts.common[55], Player.instance.controlling.GlobalPosition + Vector2.Left * 16f);
|
|
yield break;
|
|
}
|
|
TextSystem.GetText("WaterFill");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
if (TextSystem.lastPrompt == 0)
|
|
{
|
|
Audio.PlaySound("snd_switchpull_n.wav");
|
|
for (float a = 0f; a < 40f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
Audio.PlaySound("snd_won.wav");
|
|
TextSystem.GetText("GunFilledWater");
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
Room.current.waterBullet = 5;
|
|
Room.current.tempFlags.Add("WaterFilled");
|
|
}
|
|
}
|
|
|
|
public static IEnumerator Blocker(string mes, Vector2 pos)
|
|
{
|
|
TextSystem.GetText(mes);
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
Player.instance.controlling.DoAutoMove(pos, 0.75f);
|
|
while (Player.instance.controlling.moving != null)
|
|
{
|
|
yield return null;
|
|
}
|
|
Player.instance.ResetFollowStep();
|
|
}
|
|
|
|
public static void WaterBulletHitWall(Node other)
|
|
{
|
|
Main.Particle("WaterBurst", Player.instance.bullet.GlobalPosition, 1, null, localSpace: false);
|
|
Player.instance.bullet.QueueFree();
|
|
}
|
|
|
|
public static IEnumerator ShootWater()
|
|
{
|
|
if (GodotObject.IsInstanceValid(Player.instance.bullet))
|
|
{
|
|
Player.instance.canInput = true;
|
|
yield break;
|
|
}
|
|
Party.StopMoving();
|
|
yield return null;
|
|
bool flag = false;
|
|
Vector2 vector;
|
|
switch (Player.instance.direction)
|
|
{
|
|
case Entity.Direction.North:
|
|
Player.instance.anim.Play("ShootUp");
|
|
vector = new Vector2(-7f, -16f);
|
|
Player.instance.lastDelta = Vector2.Up;
|
|
break;
|
|
case Entity.Direction.South:
|
|
Player.instance.anim.Play("ShootDown");
|
|
vector = new Vector2(7f, -16f);
|
|
flag = true;
|
|
Player.instance.lastDelta = Vector2.Down;
|
|
break;
|
|
default:
|
|
Player.instance.anim.Play("ShootSide");
|
|
Player.instance.sprite.FlipH = !Player.instance.sprite.FlipH;
|
|
if (Player.instance.sprite.FlipH)
|
|
{
|
|
vector = new Vector2(-16f, -16f);
|
|
Player.instance.lastDelta = Vector2.Left;
|
|
}
|
|
else
|
|
{
|
|
vector = new Vector2(16f, -16f);
|
|
Player.instance.lastDelta = Vector2.Right;
|
|
}
|
|
break;
|
|
}
|
|
Room.current.waterBullet--;
|
|
MoveAhead m = GD.Load<PackedScene>("res://Objects/Bullets/WaterBullet.tscn").Instantiate<MoveAhead>(PackedScene.GenEditState.Disabled);
|
|
m.GetChild<Area2D>(1).BodyEntered += WaterBulletHitWall;
|
|
Room.current.AddChild(m, forceReadableName: false, InternalMode.Disabled);
|
|
Player.instance.bullet = m;
|
|
if (flag)
|
|
{
|
|
m.ZIndex = 1;
|
|
}
|
|
Vector2 globalPosition = Player.instance.GlobalPosition + Player.instance.lastDelta * 1.2f + vector;
|
|
m.GlobalPosition = globalPosition;
|
|
m.speed = Player.instance.lastDelta * 2.5f;
|
|
for (float a = 0f; a < 25f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
if (GodotObject.IsInstanceValid(m))
|
|
{
|
|
m.ZIndex = 0;
|
|
}
|
|
Player.instance.UpdateAnim(force: true);
|
|
Player.instance.currentAnim = Entity.Animations.Walk;
|
|
}
|
|
|
|
}
|