private static int AddToFinderLists(List <GirlPairDefinition> girlPairList, List <LocationDefinition> locationList, GirlPairDefinition girlPairDef, LocationDefinition locationDef, List <PlayerFileGirlPair> fileGirlPairs) { if (girlPairList != null && !girlPairList.Contains(girlPairDef)) { girlPairList.Add(girlPairDef); if (locationList != null && (locationDef == null || !locationList.Contains(locationDef))) { locationList.Add(locationDef); } } for (int i = 0; i < fileGirlPairs.Count; i++) { if (fileGirlPairs[i].girlPairDefinition.girlDefinitionOne == girlPairDef.girlDefinitionOne || fileGirlPairs[i].girlPairDefinition.girlDefinitionTwo == girlPairDef.girlDefinitionOne || fileGirlPairs[i].girlPairDefinition.girlDefinitionOne == girlPairDef.girlDefinitionTwo || fileGirlPairs[i].girlPairDefinition.girlDefinitionTwo == girlPairDef.girlDefinitionTwo) { fileGirlPairs.RemoveAt(i); i--; } } return(-1); }
private void Update() //called by Unity every frame { if (!Game.Manager) { return; //don't run update code before Game.Manager exists } BasePatches.Update(); CheatPatches.Update(); InputPatches.Update(); RunTimerPatches.Update(); if (tooltip != null) { if (tooltipTimer.ElapsedMilliseconds > tooltipLength) { tooltipTimer.Reset(); tooltip.Hide(); tooltip = null; } } //if tooltip became null, stop timer else { tooltipTimer.Reset(); } //Check for the Return hotkey if (ResetKey.Value.IsDown() || ResetKey2.Value.IsDown()) { if (UnloadGame()) { hasReturned = true; BasePatches.searchForMe = -111; if (run != null) { run.reset(); run = null; } } } if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { //display the splits folder on Ctrl+S if (Input.GetKeyDown(KeyCode.S)) { if (Game.Manager.Ui.currentCanvas.titleCanvas) { System.Diagnostics.Process.Start(Directory.GetCurrentDirectory() + "/splits"); } /* * else if (run != null) * { * run.save(); * ShowNotif("Run saved!", 2); * }*/ //don't allow saving midrun, could be done accidentally } //reset run on Ctrl+R if (Input.GetKeyDown(KeyCode.R) && run != null) { run.reset(true); ShowNotif("Run reset!", 2); } //quit run on Ctrl+Q if (Input.GetKeyDown(KeyCode.Q) && run != null) { run.reset(false); ShowNotif("Run quit!", 2); } } //if currently in a puzzle, and the status bar is up, and it's not nonstop mode, send data to autosplitters if (!Game.Manager.Ui.currentCanvas.titleCanvas && Game.Session && Game.Session.Puzzle.isPuzzleActive && !Game.Session.gameCanvas.cellphone.isOpen && Game.Session.Puzzle.puzzleStatus.statusType != PuzzleStatusType.NONSTOP) { //this is a possibly bold but necessary assumption to make about cellphone._currentApp UiCellphoneAppStatus status = (UiCellphoneAppStatus)AccessTools.Field(typeof(UiCellphone), "_currentApp").GetValue(Game.Session.gameCanvas.cellphone); bool isBonusRound = Game.Session.Puzzle.puzzleStatus.bonusRound; if (status.affectionMeter.currentValue == 0) { startingRelationshipType = Game.Persistence.playerFile.GetPlayerFileGirlPair(Game.Session.Location.currentGirlPair).relationshipType; startingCompletedPairs = Game.Persistence.playerFile.completedGirlPairs.Count; } if (status.affectionMeter.currentValue == status.affectionMeter.maxValue && (Game.Session.gameCanvas.puzzleGrid.roundState == PuzzleRoundState.SUCCESS || isBonusRound)) { if (!splitThisDate && run != null) { bool didSplit = false; //always split for the two tutorial splits if (Game.Session.Location.currentGirlPair.girlDefinitionOne.girlName == "Kyu") { didSplit = run.split(isBonusRound); } //don't split for dates in 48 Shoes, or in postgame else if (run.goal != 48 && Game.Persistence.playerFile.storyProgress < 13) { if (run.goal == 1 || SplitRules.Value <= 0) { didSplit = run.split(isBonusRound); } else if (SplitRules.Value == 1 && !isBonusRound) { didSplit = run.split(isBonusRound); } else if (SplitRules.Value == 2 && isBonusRound) { didSplit = run.split(isBonusRound); } //check for final split regardless of option else if (isBonusRound && (run.goal == startingCompletedPairs + 1 || (run.goal == 25 && Game.Session.Puzzle.puzzleStatus.statusType == PuzzleStatusType.BOSS))) { didSplit = run.split(isBonusRound); } } if (didSplit) { //initiate the timers for displaying and removing our split times RunTimerPatches.initialTimerDelay.Start(); if (!isBonusRound) { RunTimerPatches.undoTimer.Start(); } GirlPairDefinition pair = Game.Session.Location.currentGirlPair; int dateNum = 1; if (startingRelationshipType == GirlPairRelationshipType.ATTRACTED) { dateNum = 2; } if (isBonusRound) { dateNum = 3; } //Kyu pair starts at ATTRACTED (2) and her bonus should be 2, not 3, so this is the easiest way if (pair.girlDefinitionOne.girlName == "Kyu") { dateNum--; } if (Game.Session.Puzzle.puzzleStatus.statusType == PuzzleStatusType.BOSS) { dateNum = 5 - (Game.Session.Puzzle.puzzleStatus.girlListCount / 2); } string newSplit = pair.girlDefinitionOne.girlName + " & " + pair.girlDefinitionTwo.girlName; //don't put a number on the date if they started as lovers, or it's nonstop mode? (for 100%) //the storyProgress check probably makes this pointless if (startingRelationshipType != GirlPairRelationshipType.LOVERS && Game.Session.Puzzle.puzzleStatus.statusType != PuzzleStatusType.NONSTOP) { newSplit += " #" + dateNum; } newSplit += "\n " + run.splitText + "\n"; run.push(newSplit); if (isBonusRound && pair.girlDefinitionOne.girlName != "Kyu") { //I think it's possible that, with a huge chain reaction, completedGirlPairs.Count might not have updated yet //so use the number from before the date, +1 //funnily enough, that also makes the final boss's goal of "25" count //but I'll leave the double-check there if (run.goal == startingCompletedPairs + 1 || (run.goal == 25 && Game.Session.Puzzle.puzzleStatus.statusType == PuzzleStatusType.BOSS)) { Logger.LogMessage("initiating run.save"); if (run.rerollOccurred) { run.push("\n(Rerolled for Lillian)\n"); } //run.save(); RunTimerPatches.savePBDelay.Start(); } } } } if (isBonusRound) { BasePatches.searchForMe = 200; } else { BasePatches.searchForMe = 100; } splitThisDate = true; } else { BasePatches.searchForMe = 0; splitThisDate = false; } } //title-screen only options, to prevent non-vanilla things happening midrun if (Game.Manager.Ui.currentCanvas.titleCanvas) { UiTitleCanvas tc = (UiTitleCanvas)Game.Manager.Ui.currentCanvas; bool isLoading = (bool)AccessTools.Field(typeof(UiTitleCanvas), "_loadingGame").GetValue(tc); //display New Version tooltip for 10 seconds if (newVersionAvailable && !alertedOfUpdate) { alertedOfUpdate = true; ShowTooltip("Update Available!\nClick on Credits!", 10000, 0, 45); } if (!InputPatches.codeScreen && Input.GetKeyDown(KeyCode.A)) { CodeDefinition codeDefinition = Game.Data.Codes.Get(ABIAHAIR); if (!Game.Persistence.playerData.unlockedCodes.Contains(codeDefinition)) { Game.Persistence.playerData.unlockedCodes.Add(codeDefinition); ShowTooltip("Abia's Hair Enabled!", 2000); } else { Game.Persistence.playerData.unlockedCodes.Remove(codeDefinition); ShowTooltip("Abia's Hair Disabled!", 2000); } Game.Manager.Ui.currentCanvas.GetComponent <UiTitleCanvas>().coverArt.Refresh(); } //check for Kyu outfits if (Input.GetKey(KeyCode.K)) { bool hairstyle = (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)); for (int i = (int)KeyCode.Alpha0; i <= (int)KeyCode.Alpha5; i++) { //Alpha0 = 48, Keypad0 = 256 int num = i - 48; if ((Input.GetKeyDown((KeyCode)i) || Input.GetKeyDown((KeyCode)(i + 208)))) { SetKyuOutfit(num, hairstyle); string s = "Kyu "; if (hairstyle) { s += "Hairstyle #"; } else { s += "Outfit #"; } s += num + " Chosen!"; ShowTooltip(s, 2000); } } } //check for the Cheat Mode hotkey if (!InputPatches.codeScreen && cheatsEnabled == false && !isLoading && CheatHotkey.Value.IsDown()) { Game.Manager.Audio.Play(AudioCategory.SOUND, Game.Manager.Ui.sfxReject); PlayCheatLine(); Harmony.CreateAndPatchAll(typeof(CheatPatches), null); CheatPatches.UnlockAllCodes(); ShowTooltip("Cheat Mode Activated!", 2000, 0, 30); cheatsEnabled = true; } } }
public static void ExperimentalAllPairsMod(bool specialsToo = false) { Dictionary <int, GirlPairDefinition> allPairs = (Dictionary <int, GirlPairDefinition>)AccessTools.Field(typeof(GirlPairData), "_definitions").GetValue(Game.Data.GirlPairs); if (specialsToo) { foreach (GirlDefinition g in Game.Data.Girls.GetAll()) { g.specialCharacter = false; g.baggageItemDefs.Add(Game.Data.Ailments.Get(UnityEngine.Random.Range(1, 37)).itemDefinition); g.baggageItemDefs.Add(Game.Data.Ailments.Get(UnityEngine.Random.Range(1, 37)).itemDefinition); g.baggageItemDefs.Add(Game.Data.Ailments.Get(UnityEngine.Random.Range(1, 37)).itemDefinition); if (g.cellphoneHead == null) { g.cellphoneHead = g.cellphonePortrait; } } } List <GirlPairDefinition> stockPairs = Game.Data.GirlPairs.GetAllBySpecial(false); int startingID = 27; int maxGirls = 12; if (specialsToo) { startingID = 69; maxGirls = 15; } for (int i = 1; i <= maxGirls - 1; i++) { for (int j = i + 1; j <= maxGirls; j++) { bool addThis = true; for (int k = 0; k < stockPairs.Count; k++) { if (stockPairs[k].HasGirlDef(Game.Data.Girls.Get(i)) && stockPairs[k].HasGirlDef(Game.Data.Girls.Get(j))) { addThis = false; } } if (addThis) { GirlPairDefinition gpd = ScriptableObject.CreateInstance <GirlPairDefinition>(); gpd.girlDefinitionOne = Game.Data.Girls.Get(i); gpd.girlDefinitionTwo = Game.Data.Girls.Get(j); gpd.id = startingID; startingID++; gpd.specialPair = false; gpd.introductionPair = false; gpd.introSidesFlipped = false; gpd.photoDefinition = Game.Data.Photos.Get(1); gpd.meetingLocationDefinition = Game.Data.Locations.GetAllByLocationType(LocationType.SIM)[0]; gpd.hasMeetingStyleOne = false; gpd.meetingStyleTypeOne = GirlStyleType.SEXY; gpd.meetingStyleTypeTwo = GirlStyleType.SEXY; gpd.hasMeetingStyleTwo = false; gpd.sexDaytime = ClockDaytimeType.AFTERNOON; gpd.sexLocationDefinition = Game.Data.Locations.GetAllByLocationType(LocationType.DATE)[0]; gpd.sexStyleTypeOne = GirlStyleType.SEXY; gpd.sexStyleTypeTwo = GirlStyleType.SEXY; gpd.relationshipCutsceneDefinitions = Game.Data.GirlPairs.Get(1).relationshipCutsceneDefinitions; List <GirlPairFavQuestionSubDefinition> Qs = new List <GirlPairFavQuestionSubDefinition>(); //oops all this code was actually useless, no unused pairs have any similarities /* * for (int answer = 0; answer < gpd.girlDefinitionOne.favAnswers.Count && answer < gpd.girlDefinitionTwo.favAnswers.Count; answer++) * { * if (gpd.girlDefinitionOne.favAnswers[answer] == gpd.girlDefinitionTwo.favAnswers[answer]) * { * GirlPairFavQuestionSubDefinition q = new GirlPairFavQuestionSubDefinition(); * q.questionDefinition = Game.Data.Questions.Get(answer + 1); * q.girlResponseIndexOne = Qs.Count; * q.girlResponseIndexTwo = Qs.Count; * Qs.Add(q); * } * }*/ //add a "random" favorite question just so the game doesn't crash if (Qs.Count == 0) { GirlPairFavQuestionSubDefinition q = new GirlPairFavQuestionSubDefinition(); q.questionDefinition = Game.Data.Questions.Get(gpd.id % 20 + 1); q.girlResponseIndexOne = Qs.Count; q.girlResponseIndexTwo = Qs.Count; Qs.Add(q); } gpd.favQuestions = Qs; allPairs.Add(gpd.id, gpd); } } } GirlPairDefinition test = Game.Data.GirlPairs.GetAllBySpecial(false)[Game.Data.GirlPairs.GetAllBySpecial(false).Count - 1]; Logger.LogDebug("pair count: " + Game.Data.GirlPairs.GetAllBySpecial(false).Count); foreach (GirlPairDefinition tester in Game.Data.GirlPairs.GetAllBySpecial(false)) { Logger.LogDebug(tester.girlDefinitionOne.girlName + " " + tester.girlDefinitionTwo.girlName + " " + tester.id); } }
/// <summary> /// Chenges checks to start threesome if lovers /// </summary> /// <param name="__instance">puzzlemanager instance</param> /// <returns></returns> public static bool LoversThreesome(PuzzleManager __instance) { //Access private memebrs var privateFeilds = typeof(PuzzleManager).GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var puzzleGrid = privateFeilds[0].GetValue(__instance) as UiPuzzleGrid; var puzzleStatus = privateFeilds[1].GetValue(__instance) as PuzzleStatus; //5 is roundOverCutscene, 6 is newRoundCutscene privateFeilds[5].SetValue(__instance, __instance.cutsceneFailure); privateFeilds[6].SetValue(__instance, null); bool flag = true; switch (puzzleStatus.statusType) { case PuzzleStatusType.NORMAL: { GirlPairDefinition currentGirlPair = Game.Session.Location.currentGirlPair; PlayerFileGirlPair playerFileGirlPair = Game.Persistence.playerFile.GetPlayerFileGirlPair(currentGirlPair); if (playerFileGirlPair != null) { Game.Persistence.playerFile.GetPlayerFileGirl(currentGirlPair.girlDefinitionOne); Game.Persistence.playerFile.GetPlayerFileGirl(currentGirlPair.girlDefinitionTwo); if (puzzleGrid.roundState == PuzzleRoundState.SUCCESS) { if (playerFileGirlPair.relationshipType == GirlPairRelationshipType.COMPATIBLE) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessCompatible); playerFileGirlPair.RelationshipLevelUp(); } else if ( ( (Game.Session.Location.currentLocation == currentGirlPair.sexLocationDefinition) && ( (playerFileGirlPair.relationshipType == GirlPairRelationshipType.ATTRACTED) || (playerFileGirlPair.relationshipType == GirlPairRelationshipType.LOVERS) ) ) || ( Game.Persistence.playerData.unlockedCodes.Any(x => x.id == 10002) && (playerFileGirlPair.relationshipType == GirlPairRelationshipType.LOVERS) ) ) { if (!puzzleStatus.bonusRound) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessAttracted); privateFeilds[6].SetValue(__instance, __instance.cutsceneNewroundBonus); flag = false; } else { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessBonus); playerFileGirlPair.RelationshipLevelUp(); } } else { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccess); } if (flag && Game.Persistence.playerFile.storyProgress >= 14 && !Game.Persistence.playerData.unlockedCodes.Contains(Game.Session.Puzzle.noAlphaModeCode)) { Game.Persistence.playerFile.alphaDateCount++; } } } else if (puzzleGrid.roundState == PuzzleRoundState.SUCCESS) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccess); } break; } case PuzzleStatusType.NONSTOP: if (puzzleGrid.roundState == PuzzleRoundState.SUCCESS) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessNonstop); privateFeilds[6].SetValue(__instance, __instance.cutsceneNewroundNonstop); flag = false; } else { if (puzzleStatus.roundIndex > 0) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccess); } if (puzzleStatus.roundIndex > Game.Persistence.playerFile.nonstopDateCount) { Game.Persistence.playerFile.nonstopDateCount = puzzleStatus.roundIndex; } } break; case PuzzleStatusType.BOSS: if (puzzleGrid.roundState == PuzzleRoundState.SUCCESS) { if (puzzleStatus.bonusRound) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessBonus); if (Game.Persistence.playerFile.storyProgress <= 11) { Game.Persistence.playerFile.storyProgress = 12; } } else if (puzzleStatus.girlListCount <= 2) { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessBoss); privateFeilds[6].SetValue(__instance, __instance.cutsceneNewroundBossBonus); flag = false; } else { privateFeilds[5].SetValue(__instance, __instance.cutsceneSuccessBoss); privateFeilds[6].SetValue(__instance, __instance.cutsceneNewroundBoss); flag = false; } } else if (Game.Persistence.playerFile.storyProgress < 12 && Game.Persistence.playerFile.GetFlagValue("nymphojinn_failure") < 0) { Game.Persistence.playerFile.SetFlagValue("nymphojinn_failure", 0); } break; } puzzleStatus.gameOver = flag; PuzzleManagerEvents pmEvents = new PuzzleManagerEvents(__instance, privateFeilds); pmEvents.AddOnRoundOverCutsceneComplete(); Game.Session.Cutscenes.StartCutscene(privateFeilds[5].GetValue(__instance) as CutsceneDefinition, null); return(false); }