2025-05-13 19:22:01 +08:00

461 lines
10 KiB
C#

using System.Collections.Generic;
using Godot;
using Godot.Collections;
using Newtonsoft.Json;
public partial class SaveFile
{
public enum Letters
{
None = -1,
MoAd,
KanakoDay2,
VirgilDay2,
CrumpledNoteD2,
NoiseComplaint
}
public enum Flags
{
NULL = 99999,
HasNecklace = -10,
PartySplit = -9,
FullStorage = -8,
FullWeapon = -7,
FullArmor = -6,
FullLInv = -5,
FullDInv = -4,
SpareMore = -3,
FightMore = -2,
None = -1,
IsInDW = 0,
KanakoFollowing = 1,
AxisFollowing = 2,
StephFollowing = 3,
JuneFollowing = 4,
SawKetsukaneWindow = 5,
AxisCutoutKanako = 6,
Day1End = 7,
Day2End = 8,
Day3End = 9,
Day4End = 10,
Day5End = 11,
Day6End = 12,
CerobaDay1Talk = 13,
IntroEvent = 14,
WeirdStart = 15,
FirstCrateGate = 16,
FirstPuzzleSign = 17,
FirstDW1Chest = 18,
SavedKanakoCh1 = 19,
ApprehendTutorial = 20,
KanakoFirstDWTalk = 21,
KanakoRoomAfterRescueTalk = 22,
SecondDW1Chest = 23,
EnemyAfterKanako1 = 24,
EnemyAfterKanako2 = 25,
EnemyAfterKanako3 = 26,
FreedFromJail = 27,
MossChecked = 28,
AteMoss = 29,
KanakoCommentsOnMoss = 30,
PrisonTriedCrack = 31,
DisagreedWardenFirstTalk = 32,
WardenExposited = 33,
KanakoBearTalk = 34,
DarkPrisonRightTalk = 35,
DarkPrisonSouthTalk = 36,
BearingDefeated = 37,
WeaponTalk = 38,
KanakoTalkAfterTutorial = 39,
DidApprehendTutorial = 40,
KanakoLakeTalk = 41,
MoneyChestLake = 42,
PenniltonFought = 43,
PenniltonCaught = 44,
LuncherFought = 45,
LuncherCaught = 46,
BearingFought = 47,
BearingCaught = 48,
BackpackFirstTalk = 49,
RubbermanTalk = 50,
KanakoTownDiag = 51,
KanakoPhoneEvent = 52,
ChestBridgeRoom = 53,
KanakoLandscapeDiag = 54,
PencellerSidePath = 55,
EraserSidePath = 56,
PencellerSidePath2 = 57,
ChestBridgeRoom2 = 58,
WardenApprehendRegular = 59,
PeniltonDEAD = 60,
LuncherDEAD = 61,
BearingDEAD = 62,
KanakoMemoryGameRoomBefore = 63,
KanakoMemoryGameInProgress = 64,
KanakoMemoryGameRoomAfter = 65,
KanakoPostPennyWeird = 66,
KanakoPostPennyNormal = 67,
MP3DarknerTalk = 68,
BeatMemoryGame = 69,
YellowPaintEvent = 70,
MemoryGameWin = 71,
PenGuyFirstTalk = 72,
KanakoLakeWeird = 73,
BearingFortFirstPuzzle = 74,
KanakoTalkBFortFirstPRoom = 75,
BFortTrashCan = 76,
KanakoGateNote = 77,
KanakoGateEvent = 78,
BearingFortMainGate = 79,
BearingFortUpRoomLock = 80,
MopperMainHall1 = 81,
MopperMainHall2 = 82,
PencellerMainHall = 83,
WeirdedOnce = 84,
BearFortLeftMinigame = 85,
BBallTalk1 = 86,
BBallTalk2 = 87,
BBallPlayedOnce = 88,
BBallKanakoTalk1 = 89,
BBallKanakoTalk2 = 90,
BBallKanakoTalk3 = 91,
KanakoWeirdTalkBreakRoom = 92,
KanakoTalkBreakRoom = 93,
MopperBigCorridor1 = 94,
MopperBigCorridor2 = 95,
MopperBigCorridor3 = 96,
MopperBigCorridor4 = 97,
KanakoTalkFortBigCorridor = 98,
KanakoWarningBeforeBear = 99,
KanakoTalkBearPrison = 100,
KanakoWarningBeforeFountain = 101,
BearFortTreasureRoom = 102,
BearFortGotTreasure = 103,
BearFortTreasureTalk = 104,
BearTreasureChest1 = 105,
BearTreasureChest2 = 106,
BearTreasureChest3 = 107,
BearFortTreasureInvFull = 108,
BearTreasureLost = 109,
KanakoTalkTreasurePost = 110,
NightTime = 111,
SchoolFountainSealed = 112,
FoxFirstTalk = 113,
FoxDefeated = 114,
FoxFullInvSpare = 115,
FoxFullInvDefeat = 116,
FoxGotItem = 117,
PenGuyReturn = 118,
SchoolCheckedLock = 119,
MagicDoorActive = 120,
WardenTalkEndDay1 = 121,
WardenInnocentTalk = 122,
DinaDay1Talk = 123,
VirgilDay1 = 124,
AfterDinnerDay1 = 125,
MartletHouseCheckD1 = 126,
IgnoredCerobaCallD1 = 127,
FirstKetsuShopEvent = 128,
CerobaTalkChujinDoor = 129,
KanakoDiscussDay1 = 130,
ListenedToCCDay1 = 131,
ReturnedNecklace = 132,
GaveLetterMartlet = 133,
LuncherDisappear = 134,
StarloDay1 = 135,
VirgilDay1Weird = 136,
VirgilDay1Rejected = 137,
NicePenceller = 138,
BearingSpareItem = 139,
BearingSpared = 140,
KanakoTalkPostBearingF = 141,
PenGuyPrison = 142,
KanakoTalkNorthPrisonTalk = 143,
KanakoApprehendTalk = 144,
MoochTalkD1 = 145,
AnnoyedDecibat = 146,
MartEventDay2 = 147,
MailWhaleDay2 = 148,
KanakoEventDay2 = 149,
SchoolRecessDay2 = 150,
JuneRecessDay2 = 151,
MelodyEventDay2 = 152,
RedLetterDay2 = 153,
EnterDarkJailDay2 = 154,
WardenTalkDay2 = 155,
PostWardenOutDWTalkDay2 = 156,
CerobaEventDay2 = 157,
FridgeDay2 = 158,
Day2KanakoRoomCheck = 159,
KanakoRedLetterDWEntTalk = 160,
AxisEvent = 161,
AxisFirstTalk = 162,
AxisTalkSlide = 163,
DW2Overview = 164,
DW2MagicDoor = 165,
LockLightWorldPortal = 166,
WardenRobotopiaTalk = 167,
Gizzard1 = 168,
Gizzard2 = 169,
ChestDW2_1 = 170,
FirstPuzzleDW2 = 171,
Gizzard3 = 172,
KanakoTalkWaterGun = 173,
Puzzle2_DW2 = 174,
ChestDW2_2 = 175,
DW2Room2Stapler = 176,
DW2Room2Wrench = 177,
DW2Room2Gear = 178,
DW2PlanTalk = 179,
DW2TownTVEvent = 180,
Puzzle3_DW2 = 181,
FactoryMainEnemyLeft = 182,
FactoryMainEnemyRight = 183,
FactoryPuzzle1 = 184,
FactoryPuzzle2 = 185,
AxisPuzzleTalk = 186,
EnemyBeforeFactory = 187,
FactoryRightPuzzle1 = 188,
TalkFactoryRight = 189,
ChestFactoryRight = 190,
FactoryRightEnemy = 191,
ChestFactoryLeft = 192,
ChestFactoryLeft2 = 193,
TalkFactoryLeft = 194,
FactoryLeftEnemy1 = 195,
FactoryLeftEnemy2 = 196,
FactoryFirstSwitch = 197,
ClawTalk = 198,
TramEvent = 199,
AxisTrashEvent = 200,
AxisSoloTalk = 201,
AxisTrashTreasure = 202,
PuzzleChujinDWTrash = 203,
AxisTrashPuzzleTalk = 204,
AxisHandGet = 205,
FirstUpstairsTalk = 206,
UpstairsOverview = 207,
BunBunEvent1 = 208,
BunBunEvent2 = 209,
KanakoFountainTalk = 210,
KanakoTosterTalk = 211,
UpstairsGreenChest = 212,
UpstairsTalk2 = 213,
RangerEvent = 214,
RangerTalk = 215,
RangerBlueBalloon = 216,
ArchiveChestOutside = 217,
ArchivesPC = 218,
PenGuyTalkDay2 = 219,
ChujinShopTalk = 220,
PenGuyRestRoom = 221,
SchoolJokeDuoD2 = 222,
BBallPity1 = 223,
BBallPity2 = 224,
BBallPitied = 225,
BellCrusherPity = 226,
BBallChestOpen = 227,
EnemyAfterKanako4 = 228,
EnemyAfterKanako5 = 229,
EnemyAfterKanako6 = 230,
AfterKanakoBridgeOpen = 231,
PedlaHospitalD1 = 232,
KTalkPrisonRightBD = 233,
WarpDoorFirst = 234,
BenchTSouth = 235,
BenchTMain = 236,
BenchDW2Archive = 237,
KanakoFishFirstTalk = 238,
FishGuyFirstTalk = 239,
FishGuyTaskDay2 = 240,
PedlaHospitalD2 = 241,
StarloDadDay2 = 242,
ViolettaD2 = 243,
BlackjackD2 = 244,
MochaEventD1 = 245,
StarloEventD2 = 246,
RobaDay2Early = 247
}
public static SaveFile current;
public HashSet<Flags> flags = new HashSet<Flags>();
public int[] values = new int[100];
public int[] time = new int[3];
public List<int[]> partyData = new List<int[]>();
public List<Items.IDs> lwItems = new List<Items.IDs>();
public List<Items.IDs> dwItems = new List<Items.IDs>();
public List<Items.IDs> dwArmor = new List<Items.IDs>();
public List<Items.IDs> dwWeapon = new List<Items.IDs>();
public List<Items.IDs> storage = new List<Items.IDs>();
public List<Items.IDs> dwKey = new List<Items.IDs>();
public List<int> activeParty = new List<int>();
public List<Letters> letters = new List<Letters>();
public HashSet<Letters> readLetters = new HashSet<Letters>();
public List<Entity.IDs> apprehended = new List<Entity.IDs>();
public System.Collections.Generic.Dictionary<int, float[]> fishes = new System.Collections.Generic.Dictionary<int, float[]>();
public List<Entity.IDs> followers = new List<Entity.IDs>();
public bool easyMode;
public int gold = 3;
public int dollars;
public int love = 1;
public int lv = 1;
public int exp;
public int slot;
public Vector2 position;
public Room.IDs room;
public string roomName;
public const int maxInvDW = 12;
public const int maxEquip = 48;
public static bool HasFlags(Array<Flags> flags)
{
if (flags == null || flags.Count == 0)
{
return true;
}
for (int i = 0; i < flags.Count; i++)
{
if (!HasFlag(flags[i]))
{
return false;
}
}
return true;
}
public static string GetRoomName(Room.IDs id = Room.IDs.None)
{
if (id == Room.IDs.None)
{
id = Room.current.id;
}
if (Texts.roomNames.TryGetValue(id, out var value))
{
return value;
}
return "??????";
}
public static bool HasFlag(Flags flags)
{
return flags switch
{
Flags.HasNecklace => current.lwItems.Contains(Items.IDs.KetsukaneHeirloom),
Flags.PartySplit => Player.instance.splitEntity != null,
Flags.SpareMore => current.values[1] >= current.values[2],
Flags.FightMore => current.values[1] < current.values[2],
Flags.FullStorage => Items.CheckFull(Items.Type.Storage),
Flags.FullWeapon => Items.CheckFull(Items.Type.Weapon),
Flags.FullArmor => Items.CheckFull(Items.Type.Equip),
Flags.FullLInv => Items.CheckFull(Items.Type.LightWorld),
Flags.FullDInv => Items.CheckFull(Items.Type.Normal),
_ => current.flags.Contains(flags),
};
}
public static void AddMoney(int value)
{
current.dollars = Mathf.Clamp(current.dollars + value, 0, 9999);
}
public static bool AddFlag(Flags flag)
{
if (flag != Flags.None && !current.flags.Contains(flag))
{
current.flags.Add(flag);
return true;
}
return false;
}
public static bool CanDo(Array<Flags> spawn, Array<Flags> despawn)
{
spawn?.Remove(Flags.None);
despawn?.Remove(Flags.None);
if (spawn == null || spawn.Count == 0 || HasFlags(spawn))
{
if (despawn == null || despawn.Count == 0)
{
return true;
}
return !HasFlags(despawn);
}
return false;
}
public static bool Save()
{
current.roomName = Room.current.mapName;
current.position = Player.instance.GlobalPosition;
current.room = Room.current.id;
current.partyData = Party.GetPartyStats();
current.lv = Party.party[0].LV;
try
{
using FileAccess fileAccess = FileAccess.Open("user://Save" + current.slot + ".dat", FileAccess.ModeFlags.Write);
fileAccess.StoreString(JsonConvert.SerializeObject(current));
fileAccess.Close();
}
catch
{
return false;
}
return true;
}
public void LoadStats()
{
for (int i = 0; i < Party.party.Count; i++)
{
Party.party[i].HP = partyData[i][0];
Party.party[i].MAXHP = partyData[i][1];
Party.party[i].ATKBONUS = partyData[i][2];
Party.party[i].DEFBONUS = partyData[i][3];
Party.party[i].LV = partyData[i][4];
Party.party[i].EQUIP = new int[3]
{
partyData[i][5],
partyData[i][6],
partyData[i][7]
};
if (partyData[i].Length > 8)
{
Party.party[i].title = partyData[i][8];
}
if (partyData[i].Length > 9)
{
Party.party[i].HPBONUS = partyData[i][9];
}
}
}
}