/// <summary> /// Call after ModifyShiny to add cost. /// </summary> public static void AddYNDialogueToShiny(PlayMakerFSM shinyFsm, Cost cost, IEnumerable <AbstractItem> items) { FsmState charm = shinyFsm.GetState("Charm?"); FsmState yesState = shinyFsm.GetState(charm.Transitions[0].ToState); FsmState noState = new FsmState(shinyFsm.GetState("Idle")) { Name = "YN No" }; FsmState giveControl = new FsmState(shinyFsm.GetState("Idle")) { Name = "Give Control" }; FsmStateAction closeYNDialogue = new RandomizerExecuteLambda(() => CloseYNDialogue()); noState.ClearTransitions(); noState.RemoveActionsOfType <FsmStateAction>(); noState.AddTransition("FINISHED", "Give Control"); Tk2dPlayAnimationWithEvents heroUp = new Tk2dPlayAnimationWithEvents { gameObject = new FsmOwnerDefault { OwnerOption = OwnerDefaultOption.SpecifyGameObject, GameObject = SereCore.Ref.Hero.gameObject }, clipName = "Collect Normal 3", animationTriggerEvent = null, animationCompleteEvent = FsmEvent.GetFsmEvent("FINISHED") }; noState.AddAction(closeYNDialogue); noState.AddAction(heroUp); giveControl.ClearTransitions(); giveControl.RemoveActionsOfType <FsmStateAction>(); giveControl.AddTransition("FINISHED", "Idle"); giveControl.AddAction(new RandomizerExecuteLambda(() => PlayMakerFSM.BroadcastEvent("END INSPECT"))); shinyFsm.AddState(noState); shinyFsm.AddState(giveControl); charm.ClearTransitions(); charm.AddTransition("HERO DAMAGED", noState.Name); charm.AddTransition("NO", noState.Name); charm.AddTransition("YES", yesState.Name); yesState.AddFirstAction(new RandomizerExecuteLambda(() => cost.Pay())); yesState.AddFirstAction(closeYNDialogue); charm.AddFirstAction(new RandomizerExecuteLambda(() => OpenYNDialogue(shinyFsm.gameObject, items, cost))); }
public static void AddToShiny(PlayMakerFSM fsm, string text, Func <bool> canBuy) { FsmState noState = new FsmState(fsm.GetState("Idle")) { Name = "YN No" }; noState.ClearTransitions(); noState.RemoveActionsOfType <FsmStateAction>(); noState.AddTransition("FINISHED", "Give Control"); Tk2dPlayAnimationWithEvents heroUp = new Tk2dPlayAnimationWithEvents { gameObject = new FsmOwnerDefault { OwnerOption = OwnerDefaultOption.SpecifyGameObject, GameObject = HeroController.instance.gameObject }, clipName = "Collect Normal 3", animationTriggerEvent = null, animationCompleteEvent = FsmEvent.GetFsmEvent("FINISHED") }; noState.AddAction(new ExecuteLambda(CloseYNDialogue)); noState.AddAction(heroUp); FsmState giveControl = new FsmState(fsm.GetState("Idle")) { Name = "Give Control" }; giveControl.ClearTransitions(); giveControl.RemoveActionsOfType <FsmStateAction>(); giveControl.AddTransition("FINISHED", "Idle"); giveControl.AddAction(new ExecuteLambda(() => PlayMakerFSM.BroadcastEvent("END INSPECT"))); fsm.AddState(noState); fsm.AddState(giveControl); FsmState charm = fsm.GetState("Charm?"); string yesState = charm.Transitions[0].ToState; charm.ClearTransitions(); charm.AddTransition("HERO DAMAGED", noState.Name); charm.AddTransition("NO", noState.Name); charm.AddTransition("YES", yesState); fsm.GetState(yesState).AddAction(new ExecuteLambda(CloseYNDialogue)); charm.AddFirstAction(new ExecuteLambda(() => OpenYNDialogue(fsm.gameObject, text, canBuy))); }
public static void FlingShinyDown(PlayMakerFSM shinyFsm) { FsmState fling = shinyFsm.GetState("Fling?"); fling.ClearTransitions(); fling.AddTransition("FINISHED", "Fling R"); FlingObject flingObj = shinyFsm.GetState("Fling R").GetActionsOfType <FlingObject>()[0]; flingObj.angleMin = flingObj.angleMax = 270; flingObj.speedMin = flingObj.speedMax = 0.1f; }
public static void ModifyGeoRock(PlayMakerFSM rockFsm, FlingType flingType, AbstractPlacement location, IEnumerable <AbstractItem> items) { GameObject rock = rockFsm.gameObject; FsmState init = rockFsm.GetState("Initiate"); FsmState hit = rockFsm.GetState("Hit"); FsmState payout = rockFsm.GetState("Destroy"); FsmState broken = rockFsm.GetState("Broken"); FsmStateAction checkAction = new RandomizerExecuteLambda(() => rockFsm.SendEvent(location.HasVisited() ? "BROKEN" : null)); init.RemoveActionsOfType <IntCompare>(); init.AddAction(checkAction); hit.ClearTransitions(); hit.AddTransition("HIT", "Pause Frame"); hit.AddTransition("FINISHED", "Pause Frame"); hit.RemoveActionsOfType <FlingObjectsFromGlobalPool>(); var payoutAction = payout.GetActionOfType <FlingObjectsFromGlobalPool>(); payoutAction.spawnMin.Value = 0; payoutAction.spawnMax.Value = 0; GameObject itemParent = new GameObject("item"); itemParent.transform.SetParent(rock.transform); itemParent.transform.position = rock.transform.position; itemParent.transform.localPosition = Vector3.zero; itemParent.SetActive(true); FsmStateAction spawnShinies = new ActivateAllChildren { gameObject = new FsmGameObject { Value = itemParent, }, activate = true }; payout.AddAction(spawnShinies); broken.AddAction(spawnShinies); foreach (AbstractItem item in items) { if (item.GiveEarly(Container.GeoRock)) { FsmStateAction giveAction = new RandomizerExecuteLambda(() => item.Give(location, Container.GeoRock, flingType, rockFsm.gameObject.transform, message: MessageType.None)); payout.AddAction(giveAction); } else { GameObject shiny = ShinyUtility.MakeNewShiny(location, item); ShinyUtility.PutShinyInContainer(itemParent, shiny); } } }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName) { return; } GameObject shiny = ObjectCache.ShinyItem; shiny.name = _newShinyName; if (_activeCheck.Invoke()) { // Simply create the shiny to be active, as in CreateNewShiny shiny.transform.position = new Vector3(_x, _y, shiny.transform.position.z); shiny.SetActive(true); // Force the new shiny to fall straight downwards PlayMakerFSM fsm = FSMUtility.LocateFSM(shiny, "Shiny Control"); FsmState fling = fsm.GetState("Fling?"); fling.ClearTransitions(); fling.AddTransition("FINISHED", "Fling R"); FlingObject flingObj = fsm.GetState("Fling R").GetActionsOfType <FlingObject>()[0]; flingObj.angleMin = flingObj.angleMax = 270; // For some reason not setting speed manually messes with the object position flingObj.speedMin = flingObj.speedMax = 0.1f; } else { // Inactive shiny needs a parent so we can find it later, so create a dummy object if necessary string parentName = string.IsNullOrEmpty(_parent) ? _newShinyName + " Parent" : _parent; if (GameObject.Find(parentName) is GameObject go) { shiny.transform.SetParent(go.transform); shiny.transform.localPosition = new Vector3(0, 0, shiny.transform.position.z); } else { GameObject go2 = new GameObject() { name = parentName }; go2.SetActive(true); shiny.transform.SetParent(go2.transform); shiny.SetActive(false); } } }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState bigGetFlash = fsm.GetState("Big Get Flash"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <StringCompare>(); // Change pd bool test to our new bool PlayerDataBoolTest boolTest = pdBool.GetActionsOfType <PlayerDataBoolTest>()[0]; if (_playerdata) { boolTest.boolName = _boolName; } else { RandomizerBoolTest randBoolTest = new RandomizerBoolTest(_boolName, boolTest.isFalse, boolTest.isTrue); pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.AddFirstAction(randBoolTest); } // Force the FSM to show the big item flash charm.ClearTransitions(); charm.AddTransition("FINISHED", "Big Get Flash"); // Set bool and show the popup after the flash bigGetFlash.AddAction(new RandomizerCallStaticMethod( typeof(BigItemPopup), nameof(BigItemPopup.ShowAdditive), _itemDefs, fsm.gameObject, "GET ITEM MSG END")); // Don't actually need to set the skill here, that happens in BigItemPopup // Maybe change that at some point, it's not where it should happen if (!_playerdata) { bigGetFlash.AddAction(new RandomizerSetBool(_boolName, true)); } // Exit the fsm after the popup bigGetFlash.ClearTransitions(); bigGetFlash.AddTransition("GET ITEM MSG END", "Hero Up"); bigGetFlash.AddTransition("HERO DAMAGED", "Finish"); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName) { return; } Scene currentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); string[] objectHierarchy = _objectName.Split('\\'); int i = 1; GameObject obj = currentScene.FindGameObject(objectHierarchy[0]); while (i < objectHierarchy.Length) { obj = obj.FindGameObjectInChildren(objectHierarchy[i++]); } if (obj == null) { return; } // Put a shiny in the same location as the original GameObject shiny = ObjectCache.ShinyItem; shiny.name = _newShinyName; if (obj.transform.parent != null) { shiny.transform.SetParent(obj.transform.parent); } shiny.transform.position = obj.transform.position; shiny.transform.localPosition = obj.transform.localPosition; shiny.SetActive(obj.activeSelf); // Force the new shiny to fall straight downwards PlayMakerFSM fsm = FSMUtility.LocateFSM(shiny, "Shiny Control"); FsmState fling = fsm.GetState("Fling?"); fling.ClearTransitions(); fling.AddTransition("FINISHED", "Fling R"); FlingObject flingObj = fsm.GetState("Fling R").GetActionsOfType <FlingObject>()[0]; flingObj.angleMin = flingObj.angleMax = 270; // For some reason not setting speed manually messes with the object position flingObj.speedMin = flingObj.speedMax = 0.1f; // Destroy the original Object.Destroy(obj); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState bigGetFlash = fsm.GetState("Big Get Flash"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <StringCompare>(); // Change pd bool test to our new bool PlayerDataBoolTest boolTest = pdBool.GetActionsOfType <PlayerDataBoolTest>()[0]; RandomizerBoolTest randBoolTest = new RandomizerBoolTest(_item, boolTest.isFalse, boolTest.isTrue); pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.AddFirstAction(randBoolTest); // Force the FSM to show the big item flash charm.ClearTransitions(); charm.AddTransition("FINISHED", "Big Get Flash"); //bigGetFlash.AddAction(new RandomizerExecuteLambda(() => RandoLogger.LogItemToTrackerByBoolName(logBoolName, _location))); //bigGetFlash.AddAction(new RandomizerExecuteLambda(() => RandoLogger.UpdateHelperLog())); //bigGetFlash.AddFirstAction(new RandomizerExecuteLambda(() => RandomizerMod.Instance.Settings.UpdateObtainedProgressionByBoolName(logBoolName))); // Set bool and show the popup after the flash bigGetFlash.AddAction(new RandomizerCallStaticMethod( typeof(BigItemPopup), nameof(BigItemPopup.ShowAdditive), _itemDefs, fsm.gameObject, "GET ITEM MSG END")); // Don't actually need to set the skill here, that happens in BigItemPopup // Maybe change that at some point, it's not where it should happen bigGetFlash.AddAction(new RandomizerExecuteLambda(() => GiveItem(_action, _item, _location))); // Exit the fsm after the popup bigGetFlash.ClearTransitions(); bigGetFlash.AddTransition("GET ITEM MSG END", "Hero Up"); bigGetFlash.AddTransition("HERO DAMAGED", "Finish"); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState bigGetFlash = fsm.GetState("Big Get Flash"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <StringCompare>(); // Change pd bool test to our new bool pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.AddAction( new RandomizerExecuteLambda(() => fsm.SendEvent( RandomizerMod.Instance.Settings.CheckLocationFound(_location) ? "COLLECTED" : null ))); // Force the FSM to show the big item flash charm.ClearTransitions(); charm.AddTransition("FINISHED", "Big Get Flash"); // Set bool and show the popup after the flash bigGetFlash.AddAction(new RandomizerCallStaticMethod( typeof(BigItemPopup), nameof(BigItemPopup.ShowAdditive), _itemDefs, fsm.gameObject, "GET ITEM MSG END")); // Don't actually need to set the skill here, that happens in BigItemPopup // Maybe change that at some point, it's not where it should happen bigGetFlash.AddAction(new RandomizerExecuteLambda(() => GiveItem(_action, _item, _location))); // Exit the fsm after the popup bigGetFlash.ClearTransitions(); bigGetFlash.AddTransition("GET ITEM MSG END", "Hero Up"); bigGetFlash.AddTransition("HERO DAMAGED", "Finish"); }
public static void ModifyMultiShiny(PlayMakerFSM shinyFsm, FlingType flingType, AbstractPlacement location, IEnumerable <AbstractItem> items) { FsmState pdBool = shinyFsm.GetState("PD Bool?"); FsmState charm = shinyFsm.GetState("Charm?"); FsmState trinkFlash = shinyFsm.GetState("Trink Flash"); FsmStateAction checkAction = new RandomizerExecuteLambda(() => shinyFsm.SendEvent(items.All(i => i.IsObtained()) ? "COLLECTED" : null)); FsmStateAction giveAction = new RandomizerExecuteLambda(() => { foreach (AbstractItem item in items) { item.Give(location, Container.Shiny, flingType, shinyFsm.gameObject.transform, message: MessageType.Corner); } } ); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <StringCompare>(); // Change pd bool test to our new bool pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.AddAction(checkAction); // Charm must be preserved as the entry point for AddYNDialogueToShiny charm.ClearTransitions(); charm.AddTransition("FINISHED", "Trink Flash"); trinkFlash.ClearTransitions(); trinkFlash.Actions = new FsmStateAction[] { trinkFlash.Actions[0], // Audio trinkFlash.Actions[1], // Audio trinkFlash.Actions[2], // visual effect trinkFlash.Actions[3], // hide shiny trinkFlash.Actions[4], // pickup animation // [5] -- spawn message // [6] -- store message text // [7] -- store message icon giveAction, // give item }; trinkFlash.AddTransition("FINISHED", "Hero Up"); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState spawnItems = fsm.GetState("Spawn Items"); // Remove geo from chest foreach (FlingObjectsFromGlobalPool fling in spawnItems.GetActionsOfType <FlingObjectsFromGlobalPool>()) { fling.spawnMin = 0; fling.spawnMax = 0; } // Need to check SpawnFromPool action too because of Mantis Lords chest foreach (SpawnFromPool spawn in spawnItems.GetActionsOfType <SpawnFromPool>()) { spawn.spawnMin = 0; spawn.spawnMax = 0; } // Instantiate a new shiny and set the chest as its parent GameObject item = fsm.gameObject.transform.Find("Item").gameObject; GameObject shiny = ObjectCache.ShinyItem; shiny.SetActive(false); shiny.transform.SetParent(item.transform); shiny.transform.position = item.transform.position; shiny.name = _newShinyName; // Force the new shiny to fling out of the chest PlayMakerFSM shinyControl = FSMUtility.LocateFSM(shiny, "Shiny Control"); FsmState shinyFling = shinyControl.GetState("Fling?"); shinyFling.ClearTransitions(); shinyFling.AddTransition("FINISHED", "Fling R"); }
// Gruz Mother needs a special case because her geo is special public static void DestroyGruzmomGeo(PlayMakerFSM fsm) { if (!RandomizerMod.Instance.Settings.RandomizeBossGeo) { return; } if (fsm.gameObject.name.StartsWith("Corpse Big Fly Burster") && fsm.FsmName == "burster" && GameManager.instance.sceneName == SceneNames.Crossroads_04) { FsmState geoState = fsm.GetState("Initiate"); geoState.RemoveActionsOfType <FlingObjectsFromGlobalPool>(); geoState.AddAction( new RandomizerExecuteLambda(() => GameObject.Find("New Shiny Boss Geo").transform.SetPosition2D( fsm.gameObject.transform.position ))); FsmState initState = fsm.GetState("Initiate"); initState.ClearTransitions(); initState.AddTransition("FINISHED", "In Air"); } }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState trinkFlash = fsm.GetState("Trink Flash"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.RemoveActionsOfType <StringCompare>(); // Force the FSM to follow the path for the correct trinket charm.ClearTransitions(); charm.AddTransition("FINISHED", "Trink Flash"); trinkFlash.ClearTransitions(); trinkFlash.AddTransition("FINISHED", $"Trink {_trinketNum}"); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState trinkFlash = fsm.GetState("Trink Flash"); FsmState giveTrinket = fsm.GetState("Store Key"); // This path works well for our changes // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.RemoveActionsOfType <StringCompare>(); // Add our own check to stop the shiny from being grabbed twice pdBool.AddAction( new RandomizerExecuteLambda(() => fsm.SendEvent( RandomizerMod.Instance.Settings.CheckLocationFound(_location) ? "COLLECTED" : null ))); // Force the FSM to follow the path for the correct trinket charm.ClearTransitions(); charm.AddTransition("FINISHED", "Trink Flash"); trinkFlash.ClearTransitions(); fsm.GetState("Trinket Type").ClearTransitions(); trinkFlash.AddTransition("FINISHED", "Store Key"); giveTrinket.RemoveActionsOfType <SetPlayerDataBool>(); giveTrinket.AddAction(new RandomizerExecuteLambda(() => GiveItem(_action, _item, _location))); // Makes sure the correct icon and text appear giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = _nameKey; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = RandomizerMod.GetSprite(_spriteName); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState getCharm = fsm.GetState("Get Charm"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.RemoveActionsOfType <StringCompare>(); // Add our own check to stop the shiny from being grabbed twice pdBool.AddAction( new RandomizerExecuteLambda(() => fsm.SendEvent( ItemChanger.instance.Settings.CheckObtained(_ilp.id) ? "COLLECTED" : null ))); // The "Charm?" state is a bad entry point for our geo spawning charm.ClearTransitions(); charm.AddTransition("FINISHED", "Get Charm"); // The "Get Charm" state is a good entry point for our geo spawning getCharm.RemoveActionsOfType <SetPlayerDataBool>(); getCharm.RemoveActionsOfType <IncrementPlayerDataInt>(); getCharm.RemoveActionsOfType <SendMessage>(); getCharm.AddAction(new RandomizerExecuteLambda(() => GiveItemActions.GiveItem(_ilp))); getCharm.AddAction(new RandomizerAddGeo(fsm.gameObject, _ilp.item.geo)); // Skip all the other type checks getCharm.ClearTransitions(); getCharm.AddTransition("FINISHED", "Flash"); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState getCharm = fsm.GetState("Get Charm"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.RemoveActionsOfType <StringCompare>(); // Add our own check to stop the shiny from being grabbed twice pdBool.AddAction(new RandomizerBoolTest(_boolName, null, "COLLECTED")); // The "Charm?" state is a bad entry point for our geo spawning charm.ClearTransitions(); charm.AddTransition("FINISHED", "Get Charm"); // The "Get Charm" state is a good entry point for our geo spawning getCharm.RemoveActionsOfType <SetPlayerDataBool>(); getCharm.RemoveActionsOfType <IncrementPlayerDataInt>(); getCharm.RemoveActionsOfType <SendMessage>(); getCharm.AddAction(new RandomizerExecuteLambda(() => RandoLogger.UpdateHelperLog())); getCharm.AddAction(new RandomizerExecuteLambda(() => RandoLogger.LogItemToTrackerByBoolName(_boolName, _location))); getCharm.AddFirstAction(new RandomizerExecuteLambda(() => RandomizerMod.Instance.Settings.UpdateObtainedProgressionByBoolName(_boolName))); getCharm.AddAction(new RandomizerSetBool(_boolName, true)); getCharm.AddAction(new RandomizerAddGeo(fsm.gameObject, _geoAmount)); // Skip all the other type checks getCharm.ClearTransitions(); getCharm.AddTransition("FINISHED", "Flash"); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName) { return; } // Put a shiny in the same location as the original GameObject shiny = ObjectCache.ShinyItem; shiny.name = _newShinyName; if (_atObject) { shiny.transform.position = GameObject.Find(_objectName).transform.position; } else { shiny.transform.position = new Vector3(_x, _y, shiny.transform.position.z); } shiny.SetActive(true); // Force the new shiny to fall straight downwards PlayMakerFSM fsm = FSMUtility.LocateFSM(shiny, "Shiny Control"); FsmState fling = fsm.GetState("Fling?"); fling.ClearTransitions(); fling.AddTransition("FINISHED", "Fling R"); FlingObject flingObj = fsm.GetState("Fling R").GetActionsOfType <FlingObject>()[0]; flingObj.angleMin = flingObj.angleMax = 270; // For some reason not setting speed manually messes with the object position flingObj.speedMin = flingObj.speedMax = 0.1f; }
public static void ApplyHintChanges(Scene newScene) { switch (newScene.name) { // King Fragment hint case SceneNames.Abyss_05: { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "King_Fragment").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString( "Lore Tablets", "DUSK_KNIGHT_CORPSE", "A corpse in white armour. You can clearly see the " + itemName + " it's holding, " + "but for some reason you get the feeling you're going to have to go" + " through an unnecessarily long gauntlet of spikes and sawblades just to pick it up." ); } break; // Colosseum hints case SceneNames.Room_Colosseum_01: { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "Charm_Notch-Colosseum").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString("Prompts", "TRIAL_BOARD_BRONZE", "Trial of the Warrior. Fight for " + itemName + ".\n" + "Place a mark and begin the Trial?"); } { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "Pale_Ore-Colosseum").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString("Prompts", "TRIAL_BOARD_SILVER", "Trial of the Conqueror. Fight for " + itemName + ".\n" + "Place a mark and begin the Trial?"); } break; // Grey Mourner hint case SceneNames.Room_Mansion: { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "Mask_Shard-Grey_Mourner").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString( "Prompts", "XUN_OFFER", "Accept the Gift, even knowing you'll only get a lousy " + itemName + "?" ); } break; // Enable Jiji hints when the player does not have a shade case SceneNames.Room_Ouiji: if (PlayerData.instance.shadeScene != "None") { PlayMakerFSM jijiFsm = GameObject.Find("Jiji NPC").LocateMyFSM("Conversation Control"); FsmState HasShade = jijiFsm.GetState("Has Shade?"); HasShade.RemoveTransitionsTo("Check Location"); HasShade.AddTransition("YES", "Offer"); } else if (RandomizerMod.Instance.Settings.Jiji) { PlayerData.instance.SetString("shadeMapZone", "HIVE"); PlayMakerFSM jijiFsm = GameObject.Find("Jiji NPC").LocateMyFSM("Conversation Control"); FsmState BoxUp = jijiFsm.GetState("Box Up"); BoxUp.ClearTransitions(); BoxUp.AddFirstAction(jijiFsm.GetState("Convo Choice").GetActionsOfType <GetPlayerDataInt>()[0]); BoxUp.AddTransition("FINISHED", "Offer"); FsmState SendText = jijiFsm.GetState("Send Text"); SendText.RemoveTransitionsTo("Yes"); SendText.AddTransition("YES", "Check Location"); FsmState CheckLocation = jijiFsm.GetState("Check Location"); CheckLocation.AddFirstAction(BoxUp.GetActionsOfType <SendEventByName>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Convo Choice").GetActionsOfType <GetPlayerDataInt>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Yes").GetActionsOfType <PlayerDataIntAdd>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Yes").GetActionsOfType <SendEventByName>()[0]); } break; // Tuk only sells eggs when you have no eggs in your inventory, if Jiji hints are on case SceneNames.Waterways_03 when RandomizerMod.Instance.Settings.Jiji: GameObject.Find("Tuk NPC").LocateMyFSM("Conversation Control").GetState("Convo Choice").GetActionOfType <IntCompare>().integer2 = 1; break; } }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } // Begin showing lore state FsmState startReading = fsm.GetState("Trink 1"); startReading.ClearTransitions(); startReading.RemoveActionsOfType <FsmStateAction>(); // Yeeting the shop menu probably isn't ideal; however, we can't close it because the shop menu's descendant is carrying // this FSM that's showing the lore. So welcome to spaghetti-land I guess startReading.AddAction(new RandomizerExecuteLambda(() => { GameObject.Find("Shop Menu").transform.SetPositionY(200); })); startReading.AddAction(new RandomizerExecuteLambda(() => GameObject.Find("DialogueManager") .LocateMyFSM("Box Open").SendEvent("BOX UP"))); startReading.AddAction(new Wait() { time = 0.3f, finishEvent = FsmEvent.Finished }); // Reading FsmState loreReading = new FsmState(fsm.GetState("No")) { Name = "Lore Reading" }; loreReading.ClearTransitions(); loreReading.RemoveActionsOfType <FsmStateAction>(); loreReading.AddAction(new RandomizerExecuteLambda(() => { GameObject dialogueManager = GameObject.Find("DialogueManager"); GameObject textObj = dialogueManager.transform.Find("Text").gameObject; // Extract the parameters of the shown lore ReqDef loredef = LogicManager.GetItemDef(fsm.FsmVariables.StringVariables.First(v => v.Name == "PD Bool Name").Value.Split('.')[2]); string key = loredef.loreKey; string sheet = string.IsNullOrEmpty(loredef.loreSheet) ? "Lore Tablets" : loredef.loreSheet; TextAlignmentOptions align = loredef.textType == ChangeShinyIntoText.TextType.LeftLore ? TextAlignmentOptions.TopLeft : TextAlignmentOptions.Top; textObj.GetComponent <TextMeshPro>().alignment = align; textObj.GetComponent <DialogueBox>().StartConversation(key, sheet); })); // Finished Reading FsmState finishReading = new FsmState(fsm.GetState("No")) { Name = "Lore Finish Reading" }; finishReading.ClearTransitions(); finishReading.RemoveActionsOfType <FsmStateAction>(); finishReading.AddAction(new RandomizerExecuteLambda(() => { GameObject dialogueManager = GameObject.Find("DialogueManager"); GameObject textObj = dialogueManager.transform.Find("Text").gameObject; dialogueManager.LocateMyFSM("Box Open").SendEvent("BOX DOWN"); textObj.GetComponent <TextMeshPro>().alignment = TextAlignmentOptions.TopLeft; })); // Add a useless wait here; this is basically just to give the dialogue box time to disappear before returning the shop menu. // The time value isn't a special number; I just found that it seemed to work well. finishReading.AddAction(new Wait() { time = 0.15f, finishEvent = FsmEvent.Finished }); // Return the shop menu to its rightful position fsm.GetState("Reset").AddFirstAction(new RandomizerExecuteLambda(() => { GameObject.Find("Shop Menu").transform.SetPositionY(0.5f); })); // Adding states startReading.AddTransition("FINISHED", loreReading.Name); loreReading.AddTransition("CONVO_FINISH", finishReading.Name); finishReading.AddTransition("FINISHED", "Reset"); fsm.AddState(loreReading); fsm.AddState(finishReading); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState bigItem = fsm.GetState("Big Item?"); FsmState bigGetFlash = fsm.GetState("Big Get Flash"); FsmState trinkFlash = fsm.GetState("Trink Flash"); FsmState giveTrinket = fsm.GetState("Store Key"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <StringCompare>(); // Change pd bool test to our new bool pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.AddAction( new RandomizerExecuteLambda(() => fsm.SendEvent( RandomizerMod.Instance.Settings.CheckLocationFound(_location) ? "COLLECTED" : null ))); // Charm must be preserved as the entry point for AddYNDialogueToShiny charm.ClearTransitions(); charm.AddTransition("FINISHED", "Big Item?"); // Check if each additive item has already been obtained. Give 100 geo instead of popup if so. bigItem.ClearTransitions(); bigItem.AddFirstAction(new RandomizerExecuteLambda(() => bigItem.AddTransition("FINISHED", BigItemPopup.AdditiveMaxedOut(_itemDefs) ? "Trink Flash" : "Big Get Flash"))); // if we have duplicates, the last item is not a big popup // give 300 geo for last duplicate trinkFlash.ClearTransitions(); trinkFlash.AddTransition("FINISHED", "Store Key"); fsm.GetState("Trinket Type").ClearTransitions(); trinkFlash.AddTransition("FINISHED", "Store Key"); giveTrinket.RemoveActionsOfType <SetPlayerDataBool>(); giveTrinket.AddAction(new RandomizerExecuteLambda(() => GiveItem(GiveItemActions.GiveAction.AddGeo, _item, _location, 300))); giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = _itemDefs.Last().NameKey; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = RandomizerMod.GetSprite(Randomization.LogicManager.GetItemDef(_itemDefs.Last().Name).shopSpriteKey); // Normal path for big items. Set bool and show the popup after the flash bigGetFlash.AddAction(new RandomizerCallStaticMethod( typeof(BigItemPopup), nameof(BigItemPopup.ShowAdditive), _itemDefs, fsm.gameObject, "GET ITEM MSG END")); // Don't actually need to set the skill here, that happens in BigItemPopup // Maybe change that at some point, it's not where it should happen bigGetFlash.AddAction(new RandomizerExecuteLambda(() => GiveItem(_action, _item, _location))); // Exit the fsm after the popup bigGetFlash.ClearTransitions(); bigGetFlash.AddTransition("GET ITEM MSG END", "Hero Up"); bigGetFlash.AddTransition("HERO DAMAGED", "Finish"); }
private static void ApplyRandomizerChanges(Scene newScene) { string sceneName = newScene.name; // Remove quake floors in Soul Sanctum to prevent soft locks if (Ref.PD.quakeLevel <= 0 && Ref.PD.killedMageLord && (sceneName == SceneNames.Ruins1_23 || sceneName == SceneNames.Ruins1_30 || sceneName == SceneNames.Ruins1_32)) { Ref.PD.SetBool(nameof(PlayerData.brokenMageWindow), true); Ref.PD.SetBool(nameof(PlayerData.brokenMageWindowGlass), true); foreach (GameObject obj in newScene.GetRootGameObjects()) { if (obj.name.Contains("Quake Floor")) { Object.Destroy(obj); } } } // Make baldurs always able to spit rollers if (sceneName == SceneNames.Crossroads_11_alt || sceneName == SceneNames.Crossroads_ShamanTemple || sceneName == SceneNames.Fungus1_28) { foreach (GameObject obj in Object.FindObjectsOfType <GameObject>()) { if (obj.name.Contains("Blocker")) { PlayMakerFSM fsm = FSMUtility.LocateFSM(obj, "Blocker Control"); if (fsm != null) { fsm.GetState("Can Roller?").RemoveActionsOfType <IntCompare>(); } } } } switch (sceneName) { case SceneNames.Room_Ouiji: if (PlayerData.instance.shadeScene != "None") { PlayMakerFSM jijiFsm = GameObject.Find("Jiji NPC").LocateMyFSM("Conversation Control"); FsmState HasShade = jijiFsm.GetState("Has Shade?"); HasShade.RemoveTransitionsTo("Check Location"); HasShade.AddTransition("YES", "Offer"); } else if (AreaRando.Instance.Settings.Jiji) { PlayerData.instance.SetString("shadeMapZone", "HIVE"); PlayMakerFSM jijiFsm = GameObject.Find("Jiji NPC").LocateMyFSM("Conversation Control"); FsmState BoxUp = jijiFsm.GetState("Box Up"); BoxUp.ClearTransitions(); BoxUp.AddFirstAction(jijiFsm.GetState("Convo Choice").GetActionsOfType <GetPlayerDataInt>()[0]); BoxUp.AddTransition("FINISHED", "Offer"); FsmState SendText = jijiFsm.GetState("Send Text"); SendText.RemoveTransitionsTo("Yes"); SendText.AddTransition("YES", "Check Location"); FsmState CheckLocation = jijiFsm.GetState("Check Location"); CheckLocation.AddFirstAction(BoxUp.GetActionsOfType <SendEventByName>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Convo Choice").GetActionsOfType <GetPlayerDataInt>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Yes").GetActionsOfType <PlayerDataIntAdd>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Yes").GetActionsOfType <SendEventByName>()[0]); } break; case SceneNames.Grimm_Main_Tent: PlayerData.instance.metGrimm = true; break; case SceneNames.Room_Final_Boss_Atrium: if (AreaRando.Instance.Settings.RandomizeDreamers) { GameObject.Find("Tut_tablet_top").LocateMyFSM("Inspection").GetState("Init").ClearTransitions(); } break; case SceneNames.Abyss_04: if (AreaRando.Instance.Settings.RandomizeVesselFragments) { Object.Destroy(GameObject.Find("Fountain Donation")); } break; case SceneNames.Abyss_06_Core: // Opens door to LBC if (PlayerData.instance.healthBlue > 0 || PlayerData.instance.joniHealthBlue > 0 || GameManager.instance.entryGateName == "left1") { PlayerData.instance.SetBoolInternal("blueVineDoor", true); PlayMakerFSM BlueDoorFSM = GameObject.Find("Blue Door").LocateMyFSM("Control"); BlueDoorFSM.GetState("Init").RemoveTransitionsTo("Got Charm"); } break; case SceneNames.Abyss_12: // Destroy shriek pickup if the player doesn't have wraiths if (Ref.PD.screamLevel == 0) { Object.Destroy(GameObject.Find("Randomizer Shiny")); } break; case SceneNames.Abyss_15: GameObject.Find("Dream Enter Abyss").LocateMyFSM("Control").GetState("Init").RemoveTransitionsTo("Idle"); GameObject.Find("Dream Enter Abyss").LocateMyFSM("Control").GetState("Init").AddTransition("FINISHED", "Inactive"); if (!PlayerData.instance.hasDreamNail) { Object.Destroy(GameObject.Find("New Shiny")); } break; case SceneNames.GG_Waterways: PlayerData.instance.SetBool("godseekerUnlocked", true); if (PlayerData.instance.simpleKeys < 1 || (!PlayerData.instance.openedWaterwaysManhole && PlayerData.instance.simpleKeys < 2)) { Object.Destroy(GameObject.Find("Randomizer Shiny")); } else { GameObject.Find("Randomizer Shiny").LocateMyFSM("Shiny Control").GetState("Charm?").AddFirstAction(new RandomizerExecuteLambda(() => PlayerData.instance.DecrementInt("simpleKeys"))); } break; case SceneNames.Crossroads_09: // Mawlek shard if (AreaRando.Instance.Settings.RandomizeMaskShards) { Object.Destroy(GameObject.Find("Heart Piece")); } break; case SceneNames.Crossroads_38: if (AreaRando.Instance.Settings.RandomizeMaskShards) { Object.Destroy(GameObject.Find("Reward 5")); } if (AreaRando.Instance.Settings.RandomizeCharms) { Object.Destroy(GameObject.Find("Reward 10")); Object.Destroy(GameObject.Find("Reward 46")); } if (AreaRando.Instance.Settings.RandomizeRancidEggs) { Object.Destroy(GameObject.Find("Reward 16")); } if (AreaRando.Instance.Settings.RandomizeRelics) { Object.Destroy(GameObject.Find("Reward 23")); Object.Destroy(GameObject.Find("Reward 38")); } if (AreaRando.Instance.Settings.RandomizePaleOre) { Object.Destroy(GameObject.Find("Reward 31")); } break; case SceneNames.Deepnest_East_02: if (GameManager.instance.entryGateName.StartsWith("bot2")) { Object.Destroy(GameObject.Find("Quake Floor").FindGameObjectInChildren("Active").FindGameObjectInChildren("msk_generic")); Object.Destroy(GameObject.Find("Quake Floor").FindGameObjectInChildren("Active").FindGameObjectInChildren("msk_generic (1)")); Object.Destroy(GameObject.Find("Quake Floor").FindGameObjectInChildren("Active").FindGameObjectInChildren("msk_generic (2)")); Object.Destroy(GameObject.Find("Quake Floor").FindGameObjectInChildren("Active").FindGameObjectInChildren("msk_generic (3)")); } break; case SceneNames.Crossroads_ShamanTemple: // Remove gate in shaman hut Object.Destroy(GameObject.Find("Bone Gate")); // Add hard save to shaman shiny FSMUtility.LocateFSM(GameObject.Find("Randomizer Shiny"), "Shiny Control").GetState("Finish") .AddAction(new RandomizerSetHardSave()); break; case SceneNames.Deepnest_Spider_Town: // Make it so the first part of Beast's Den can't become inaccessible GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Deepnest_Spider_Town", id = "Collapser Small (12)", activated = true, semiPersistent = false }); if (AreaRando.Instance.Settings.RandomizeDreamers) { Object.Destroy(GameObject.Find("Dreamer Hegemol")); Object.Destroy(GameObject.Find("Dream Enter")); Object.Destroy(GameObject.Find("Dream Impact")); Object.Destroy(GameObject.Find("Shield")); if (!PlayerData.instance.hasDreamNail) { Object.Destroy(GameObject.Find("New Shiny")); } } break; case SceneNames.Dream_Nailcollection: // Make picking up shiny load new scene FSMUtility.LocateFSM(GameObject.Find("Randomizer Shiny"), "Shiny Control").GetState("Finish") .AddAction(new RandomizerChangeScene("RestingGrounds_07", "right1")); break; case SceneNames.Fungus2_15: if (GameManager.instance.entryGateName.StartsWith("left")) { Object.Destroy(GameObject.Find("deepnest_mantis_gate").FindGameObjectInChildren("Collider")); Object.Destroy(GameObject.Find("deepnest_mantis_gate")); } break; case SceneNames.Fungus2_21: // Make city crest gate openable infinite times and not hard save FSMUtility.LocateFSM(GameObject.Find("City Gate Control"), "Conversation Control") .GetState("Activate").RemoveActionsOfType <SetPlayerDataBool>(); FsmState gateSlam = FSMUtility.LocateFSM(GameObject.Find("Ruins_gate_main"), "Open") .GetState("Slam"); gateSlam.RemoveActionsOfType <SetPlayerDataBool>(); gateSlam.RemoveActionsOfType <CallMethodProper>(); gateSlam.RemoveActionsOfType <SendMessage>(); break; case SceneNames.Fungus2_25: if (GameManager.instance.entryGateName.StartsWith("right")) { Object.Destroy(GameObject.Find("mantis_big_door")); } break; case SceneNames.Fungus2_26: // Prevent leg eater from doing anything but opening the shop PlayMakerFSM legEater = FSMUtility.LocateFSM(GameObject.Find("Leg Eater"), "Conversation Control"); FsmState legEaterChoice = legEater.GetState("Convo Choice"); legEaterChoice.RemoveTransitionsTo("Convo 1"); legEaterChoice.RemoveTransitionsTo("Convo 2"); legEaterChoice.RemoveTransitionsTo("Convo 3"); legEaterChoice.RemoveTransitionsTo("Infected Crossroad"); legEaterChoice.RemoveTransitionsTo("Bought Charm"); legEaterChoice.RemoveTransitionsTo("Gold Convo"); legEaterChoice.RemoveTransitionsTo("All Gold"); legEaterChoice.RemoveTransitionsTo("Ready To Leave"); legEater.GetState("All Gold?").RemoveTransitionsTo("No Shop"); // Just in case something other than the "Ready To Leave" state controls this Ref.PD.legEaterLeft = false; break; case SceneNames.Fungus3_archive_02: if (AreaRando.Instance.Settings.RandomizeDreamers) { PlayerData.instance.SetBool("summonedMonomon", true); Object.Destroy(GameObject.Find("Inspect Region")); Object.Destroy(GameObject.Find("Quirrel Wounded")); Object.Destroy(GameObject.Find("Quirrel")); Object.Destroy(GameObject.Find("Monomon")); Object.Destroy(GameObject.Find("Dream Enter")); Object.Destroy(GameObject.Find("Dream Impact")); Object.Destroy(GameObject.Find("Shield")); if (!PlayerData.instance.hasDreamNail) { Object.Destroy(GameObject.Find("New Shiny")); } } break; case SceneNames.Fungus3_44: GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Fungus3_44", id = "Secret Mask", activated = true, semiPersistent = false }); break; case SceneNames.Mines_33: // Make tolls always interactable if (AreaRando.Instance.Settings.MiscSkips && !AreaRando.Instance.Settings.RandomizeKeys) { GameObject[] tolls = new GameObject[] { GameObject.Find("Toll Gate Machine"), GameObject.Find("Toll Gate Machine (1)") }; foreach (GameObject toll in tolls) { Object.Destroy(FSMUtility.LocateFSM(toll, "Disable if No Lantern")); } } break; case SceneNames.RestingGrounds_07: // Make Moth NPC not give items since those are now shinies PlayMakerFSM moth = FSMUtility.LocateFSM(GameObject.Find("Dream Moth"), "Conversation Control"); if (AreaRando.Instance.Settings.RandomizeRelics) { PlayerData.instance.dreamReward1 = true; moth.FsmVariables.GetFsmBool("Got Reward 1").Value = true; PlayerData.instance.dreamReward6 = true; moth.FsmVariables.GetFsmBool("Got Reward 6").Value = true; } if (AreaRando.Instance.Settings.RandomizePaleOre) { PlayerData.instance.dreamReward3 = true; moth.FsmVariables.GetFsmBool("Got Reward 3").Value = true; } if (AreaRando.Instance.Settings.RandomizeCharms) { PlayerData.instance.dreamReward4 = true; moth.FsmVariables.GetFsmBool("Got Reward 4").Value = true; } if (AreaRando.Instance.Settings.RandomizeVesselFragments) { PlayerData.instance.dreamReward5 = true; moth.FsmVariables.GetFsmBool("Got Reward 5").Value = true; } if (AreaRando.Instance.Settings.RandomizeSkills) { PlayerData.instance.dreamReward5b = true; moth.FsmVariables.GetFsmBool("Got Reward 5b").Value = true; } if (AreaRando.Instance.Settings.RandomizeMaskShards) { PlayerData.instance.dreamReward7 = true; moth.FsmVariables.GetFsmBool("Got Reward 7").Value = true; } break; case SceneNames.Room_Sly_Storeroom: // Make Sly pickup send Sly back upstairs FsmState slyFinish = FSMUtility.LocateFSM(GameObject.Find("Randomizer Shiny"), "Shiny Control") .GetState("Finish"); slyFinish.AddAction(new RandomizerSetBool("SlyCharm", true)); // The game breaks if you leave the storeroom after this, so just send the player out of the shop completely // People will think it's an intentional feature to cut out pointless walking anyway slyFinish.AddAction(new RandomizerChangeScene("Town", "door_sly")); break; case SceneNames.Ruins1_05: // Slight adjustment to breakable so wings is enough to progress, just like on old patches GameObject chandelier = GameObject.Find("ruind_dressing_light_02 (10)"); chandelier.transform.SetPositionX(chandelier.transform.position.x - 2); chandelier.GetComponent <NonBouncer>().active = false; break; case SceneNames.Ruins1_09: if (GameManager.instance.entryGateName.StartsWith("t")) { Object.Destroy(GameObject.Find("Battle Gate")); Object.Destroy(GameObject.Find("Battle Scene")); } break; case SceneNames.Ruins1_24: // Pickup (Quake Pickup) -> Idle -> GetPlayerDataInt (quakeLevel) // Quake (Quake Item) -> Get -> SetPlayerDataInt (quakeLevel) // Stop spell container from destroying itself PlayMakerFSM quakePickup = FSMUtility.LocateFSM(GameObject.Find("Quake Pickup"), "Pickup"); quakePickup.GetState("Idle").RemoveActionsOfType <IntCompare>(); foreach (PlayMakerFSM childFSM in quakePickup.gameObject.GetComponentsInChildren <PlayMakerFSM>(true) ) { if (childFSM.FsmName == "Shiny Control") { // Make spell container spawn shiny instead quakePickup.GetState("Appear").GetActionsOfType <ActivateGameObject>()[1].gameObject .GameObject.Value = childFSM.gameObject; // Make shiny open gates on pickup/destroy SendEvent openGate = new SendEvent { eventTarget = new FsmEventTarget { target = FsmEventTarget.EventTarget.BroadcastAll, excludeSelf = true }, sendEvent = FsmEvent.FindEvent("BG OPEN"), delay = 0, everyFrame = false }; childFSM.GetState("Destroy").AddFirstAction(openGate); childFSM.GetState("Finish").AddFirstAction(openGate); // Add hard save after picking up item childFSM.GetState("Finish").AddFirstAction(new RandomizerSetHardSave()); break; } } // Stop the weird invisible floor from appearing if dive has been obtained // I don't think it really serves any purpose, so destroying it should be fine if (Ref.PD.quakeLevel > 0) { Object.Destroy(GameObject.Find("Roof Collider Battle")); } // Change battle gate to be destroyed if Soul Master is dead instead of it the player has quake FsmState checkQuake = FSMUtility.LocateFSM(GameObject.Find("Battle Gate (1)"), "Destroy if Quake") .GetState("Check"); checkQuake.RemoveActionsOfType <FsmStateAction>(); checkQuake.AddAction(new RandomizerBoolTest(nameof(PlayerData.killedMageLord), null, "DESTROY", true)); break; case SceneNames.Ruins1_32 when !Ref.PD.hasWalljump: // Platform after soul master GameObject plat = Object.Instantiate(GameObject.Find("ruind_int_plat_float_02 (3)")); plat.SetActive(true); plat.transform.position = new Vector2(40.5f, 72f); break; case SceneNames.Ruins2_04: // Shield husk doesn't walk as far as on old patches, making something pogoable to make up for this GameObject.Find("Direction Pole White Palace").GetComponent <NonBouncer>().active = false; // Prevent simple key softlocks FsmState hotSpringsKey = GameObject.Find("Inspect").LocateMyFSM("Conversation Control").GetState("Got Key?"); hotSpringsKey.RemoveActionsOfType <IntCompare>(); hotSpringsKey.AddAction(new RandomizerExecuteLambda(() => { if (GameManager.instance.GetPlayerDataInt("simpleKeys") > 1 || (PlayerData.instance.openedWaterwaysManhole && GameManager.instance.GetPlayerDataInt("simpleKeys") > 0)) { PlayMakerFSM.BroadcastEvent("YES"); } else { PlayMakerFSM.BroadcastEvent("NO"); } })); break; case SceneNames.Ruins2_11: // Prevent the jars below Collector from being permanently destroyed GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (1)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (2)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (3)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (4)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (5)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (6)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (7)", activated = false, semiPersistent = false }); GameManager.instance.sceneData.SaveMyState(new PersistentBoolData { sceneName = "Ruins2_11", id = "Break Jar (8)", activated = false, semiPersistent = false }); break; case SceneNames.Ruins2_Watcher_Room: if (AreaRando.Instance.Settings.RandomizeDreamers) { Object.Destroy(GameObject.Find("Dreamer Lurien")); Object.Destroy(GameObject.Find("Dream Enter")); Object.Destroy(GameObject.Find("Dream Impact")); Object.Destroy(GameObject.Find("Shield")); if (!PlayerData.instance.hasDreamNail) { Object.Destroy(GameObject.Find("New Shiny")); } } break; case SceneNames.Room_Mansion: if (!PlayerData.instance.xunFlowerGiven) { Object.Destroy(GameObject.Find("Randomizer Shiny")); //Should not actually be necessary, but left in as a precaution } break; case SceneNames.Room_Wyrm: //Make King's Brand cutscene function properly //This stops only stops the cutscene, not the avalanche itself Object.Destroy(GameObject.Find("Avalanche End")); break; case SceneNames.Room_Colosseum_Bronze: GameObject.Find("Colosseum Manager").LocateMyFSM("Geo Pool").GetState("Open Gates").AddFirstAction(new RandomizerSetBool("colosseumBronzeCompleted", true, true)); break; case SceneNames.Room_Colosseum_Silver: GameObject.Find("Colosseum Manager").LocateMyFSM("Geo Pool").GetState("Open Gates").AddFirstAction(new RandomizerSetBool("colosseumSilverCompleted", true, true)); break; case SceneNames.Town: // Prevent simple key softlocks FsmState jijiKey = GameObject.Find("Jiji Door").LocateMyFSM("Conversation Control").GetState("Key?"); jijiKey.RemoveActionsOfType <GetPlayerDataInt>(); jijiKey.RemoveActionsOfType <IntCompare>(); jijiKey.AddAction(new RandomizerExecuteLambda(() => { if (GameManager.instance.GetPlayerDataInt("simpleKeys") > 1 || (PlayerData.instance.openedWaterwaysManhole && GameManager.instance.GetPlayerDataInt("simpleKeys") > 0)) { PlayMakerFSM.BroadcastEvent("KEY"); } else { PlayMakerFSM.BroadcastEvent("NOKEY"); } })); break; case SceneNames.Waterways_01: if (GameManager.instance.entryGateName.StartsWith("t")) { Object.Destroy(GameObject.Find("waterways_manhole_open")); } break; case SceneNames.Waterways_03: if (AreaRando.Instance.Settings.Jiji) { LanguageStringManager.SetLanguageString("TUK_RANCIDEGG_MIN", "Prices", "800"); LanguageStringManager.SetLanguageString("TUK_RANCIDEGG_MAX", "Prices", "1000"); } else { LanguageStringManager.SetLanguageString("TUK_RANCIDEGG_MIN", "Prices", "80"); LanguageStringManager.SetLanguageString("TUK_RANCIDEGG_MAX", "Prices", "100"); } break; case SceneNames.Waterways_09: if (GameManager.instance.entryGateName.StartsWith("left")) { Object.Destroy(GameObject.Find("Waterways Gate")); } GameObject.Find("Ruins Lever").LocateMyFSM("Switch Control").GetState("Hit").AddFirstAction(new RandomizerExecuteLambda(() => GameManager.instance.SetPlayerDataBool("waterwaysGate", true))); break; } }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState getCharm = fsm.GetState("Get Charm"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.RemoveActionsOfType <StringCompare>(); // Add our own check to stop the shiny from being grabbed twice pdBool.AddAction( new RandomizerExecuteLambda(() => fsm.SendEvent( RandomizerMod.Instance.Settings.CheckLocationFound(_location) ? "COLLECTED" : null ))); // The "Charm?" state is a bad entry point for our lore showing charm.ClearTransitions(); charm.AddTransition("FINISHED", "Get Charm"); // The "Get Charm" state is a good entry point for our lore showing getCharm.RemoveActionsOfType <SetPlayerDataBool>(); getCharm.RemoveActionsOfType <IncrementPlayerDataInt>(); getCharm.RemoveActionsOfType <SendMessage>(); getCharm.AddAction(new RandomizerExecuteLambda(() => GiveItemActions.GiveItem(GiveItemActions.GiveAction.None, _item, _location))); getCharm.ClearTransitions(); // Begin showing lore state FsmState startReading = new FsmState(fsm.GetState("Idle")) { Name = "Lore Start Reading" }; startReading.ClearTransitions(); startReading.RemoveActionsOfType <FsmStateAction>(); if (_textType == TextType.MajorLore) { startReading.AddAction(new RandomizerExecuteLambda(() => { AudioSource audio = fsm.gameObject.GetComponent <AudioSource>(); audio.PlayOneShot(ObjectCache.LoreSound); })); startReading.AddAction(new RandomizerExecuteLambda(() => PlayMakerFSM.BroadcastEvent("LORE PROMPT UP"))); } else { startReading.AddAction(new RandomizerExecuteLambda(() => GameObject.Find("DialogueManager") .LocateMyFSM("Box Open").SendEvent("BOX UP"))); } startReading.AddAction(new Wait() { time = _textType == TextType.MajorLore ? 0.85f : 0.3f, finishEvent = FsmEvent.Finished }); // Reading FsmState loreReading = new FsmState(fsm.GetState("Idle")) { Name = "Lore Reading" }; loreReading.ClearTransitions(); loreReading.RemoveActionsOfType <FsmStateAction>(); loreReading.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(ShowLoreDialogue), fsm.gameObject, _key, _sheetTitle, _textType)); // Finished Reading FsmState finishReading = new FsmState(fsm.GetState("Idle")) { Name = "Lore Finish Reading" }; finishReading.ClearTransitions(); finishReading.RemoveActionsOfType <FsmStateAction>(); finishReading.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(HideLoreDialogue), _textType)); if (_textType == TextType.MajorLore) { finishReading.AddAction(new Wait() { time = 0.5f, finishEvent = FsmEvent.Finished }); } // Once we're done we have to reset the text box fsm.GetState("Flash").AddFirstAction(new RandomizerCallStaticMethod(GetType(), nameof(ResetTextBox))); // Cancel Reading (Hero Damaged) FsmState cancelReading = new FsmState(fsm.GetState("Idle")) { Name = "Lore Cancel Reading" }; cancelReading.ClearTransitions(); cancelReading.RemoveActionsOfType <FsmStateAction>(); cancelReading.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(HideLoreDialogue), _textType)); cancelReading.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(ResetTextBox))); // The code in "Finish" doesn't yeet the inspect region - we can do it here just by doing this cancelReading.AddAction(new RandomizerExecuteLambda(() => Object.Destroy(fsm.gameObject))); // Adding states getCharm.AddTransition("FINISHED", startReading.Name); startReading.AddTransition("FINISHED", loreReading.Name); startReading.AddTransition("HERO DAMAGED", cancelReading.Name); loreReading.AddTransition("CONVO_FINISH", finishReading.Name); loreReading.AddTransition("HERO DAMAGED", cancelReading.Name); finishReading.AddTransition("FINISHED", "Flash"); finishReading.AddTransition("HERO DAMAGED", cancelReading.Name); cancelReading.AddTransition("FINISHED", "Finish"); fsm.AddState(startReading); fsm.AddState(loreReading); fsm.AddState(finishReading); fsm.AddState(cancelReading); }
public override void Process(string scene, UnityEngine.Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState pdBool = fsm.GetState("PD Bool?"); FsmState charm = fsm.GetState("Charm?"); FsmState trinkFlash = fsm.GetState("Trink Flash"); FsmState giveTrinket = fsm.GetState("Store Key"); // Remove actions that stop shiny from spawning pdBool.RemoveActionsOfType <PlayerDataBoolTest>(); pdBool.RemoveActionsOfType <StringCompare>(); // Add our own check to stop the shiny from being grabbed twice pdBool.AddAction(new RandomizerBoolTest(_boolName, null, "COLLECTED", true)); // Force the FSM to follow the path for the correct trinket charm.ClearTransitions(); charm.AddTransition("FINISHED", "Trink Flash"); trinkFlash.ClearTransitions(); fsm.GetState("Trinket Type").ClearTransitions(); trinkFlash.AddTransition("FINISHED", "Store Key"); giveTrinket.AddFirstAction(new RandomizerExecuteLambda(() => AreaRando.Instance.Settings.UpdateObtainedProgressionByBoolName(_boolName))); giveTrinket.AddAction(new RandomizerExecuteLambda(() => RandoLogger.LogItemToTrackerByBoolName(_boolName, _location))); giveTrinket.AddAction(new RandomizerExecuteLambda(() => RandoLogger.UpdateHelperLog())); giveTrinket.GetActionsOfType <SetPlayerDataBool>().First().boolName = _boolName; // Makes sure the correct icon and text appear switch (_trinketNum) { case 1: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_TRINKET1"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.WanderersJournal"); break; case 2: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_TRINKET2"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.HallownestSeal"); break; case 3: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_TRINKET3"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.KingsIdol"); break; case 4: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_TRINKET4"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.ArcaneEgg"); break; case 6: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_TRAM_PASS"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.TramPass"); break; case 8: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_STOREKEY"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.ShopkeepersKey"); break; case 9: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_CITYKEY"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.CityKey"); break; case 10: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_LOVEKEY"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.LoveKey"); break; case 11: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_RANCIDEGG"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.RancidEgg"); break; case 12: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_SIMPLEKEY"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.SimpleKey"); break; case 13: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "RANDOMIZER_NAME_CHARM_NOTCH"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.CharmNotch"); break; case 14: giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "RANDOMIZER_NAME_PALE_ORE"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.PaleOre"); break; case 20: //lantern giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_LANTERN"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.Lantern"); break; case 21: //elegant key giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "INV_NAME_WHITEKEY"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.ElegantKey"); break; case 22: //mask shards giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "RANDOMIZER_NAME_MASK_SHARD"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.MaskShard"); break; case 23: //vessel fragments giveTrinket.GetActionsOfType <GetLanguageString>().First().convName = "RANDOMIZER_NAME_VESSEL_FRAGMENT"; giveTrinket.GetActionsOfType <SetSpriteRendererSprite>().First().sprite = AreaRando.GetSprite("ShopIcons.VesselFragment"); break; } }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState noState = new FsmState(fsm.GetState("Idle")) { Name = "YN No" }; noState.ClearTransitions(); noState.RemoveActionsOfType <FsmStateAction>(); noState.AddTransition("FINISHED", "Give Control"); Tk2dPlayAnimationWithEvents heroUp = new Tk2dPlayAnimationWithEvents { gameObject = new FsmOwnerDefault { OwnerOption = OwnerDefaultOption.SpecifyGameObject, GameObject = Ref.Hero.gameObject }, clipName = "Collect Normal 3", animationTriggerEvent = null, animationCompleteEvent = FsmEvent.GetFsmEvent("FINISHED") }; noState.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(CloseYNDialogue))); noState.AddAction(heroUp); FsmState giveControl = new FsmState(fsm.GetState("Idle")) { Name = "Give Control" }; giveControl.ClearTransitions(); giveControl.RemoveActionsOfType <FsmStateAction>(); giveControl.AddTransition("FINISHED", "Idle"); giveControl.AddAction(new RandomizerExecuteLambda(() => PlayMakerFSM.BroadcastEvent("END INSPECT"))); fsm.AddState(noState); fsm.AddState(giveControl); FsmState charm = fsm.GetState("Charm?"); string yesState = charm.Transitions[0].ToState; charm.ClearTransitions(); charm.AddTransition("HERO DAMAGED", noState.Name); charm.AddTransition("NO", noState.Name); charm.AddTransition("YES", yesState); fsm.GetState(yesState).AddAction(new RandomizerCallStaticMethod(GetType(), nameof(CloseYNDialogue))); charm.AddFirstAction(new RandomizerCallStaticMethod(GetType(), nameof(OpenYNDialogue), fsm.gameObject, _itemName, _cost, _type)); }
public override void Process(string scene, Object changeObj) { if (scene != _sceneName || !(changeObj is PlayMakerFSM fsm) || fsm.FsmName != _fsmName || fsm.gameObject.name != _objectName) { return; } FsmState noState = new FsmState(fsm.GetState("Idle")) { Name = "YN No" }; noState.ClearTransitions(); noState.RemoveActionsOfType <FsmStateAction>(); noState.AddTransition("FINISHED", "Give Control"); Tk2dPlayAnimationWithEvents heroUp = new Tk2dPlayAnimationWithEvents { gameObject = new FsmOwnerDefault { OwnerOption = OwnerDefaultOption.SpecifyGameObject, GameObject = Ref.Hero.gameObject }, clipName = "Collect Normal 3", animationTriggerEvent = null, animationCompleteEvent = FsmEvent.GetFsmEvent("FINISHED") }; noState.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(CloseYNDialogue))); noState.AddAction(heroUp); // For some reason playing the animation doesn't work if we come here from being damaged, locking us in the // YN No state. I think just having a separate state to come from if we were damaged is the simplest fix. FsmState damageState = new FsmState(fsm.GetState("Idle")) { Name = "YN Damaged" }; damageState.ClearTransitions(); damageState.RemoveActionsOfType <FsmStateAction>(); damageState.AddTransition("FINISHED", "Give Control"); damageState.AddAction(new RandomizerCallStaticMethod(GetType(), nameof(CloseYNDialogue))); FsmState giveControl = new FsmState(fsm.GetState("Idle")) { Name = "Give Control" }; giveControl.ClearTransitions(); giveControl.RemoveActionsOfType <FsmStateAction>(); giveControl.AddTransition("FINISHED", "Idle"); giveControl.AddAction(new RandomizerExecuteLambda(() => PlayMakerFSM.BroadcastEvent("END INSPECT"))); fsm.AddState(noState); fsm.AddState(damageState); fsm.AddState(giveControl); FsmState charm = fsm.GetState("Charm?"); string yesState = charm.Transitions[0].ToState; charm.ClearTransitions(); charm.AddTransition("HERO DAMAGED", damageState.Name); charm.AddTransition("NO", noState.Name); charm.AddTransition("YES", yesState); // Here is a good place to remove the spent simple key if (_type == CostType.Simple) { fsm.GetState(yesState).AddFirstAction(new RandomizerExecuteLambda(() => PlayerData.instance.DecrementInt("simpleKeys"))); } fsm.GetState(yesState).AddAction(new RandomizerCallStaticMethod(GetType(), nameof(CloseYNDialogue))); charm.AddFirstAction(new RandomizerCallStaticMethod(GetType(), nameof(OpenYNDialogue), fsm.gameObject, _itemName, _cost, _type)); }
public static void ApplyHintChanges(Scene newScene) { switch (newScene.name) { // King Fragment hint case SceneNames.Abyss_05: { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "King_Fragment").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString( "Lore Tablets", "DUSK_KNIGHT_CORPSE", "A corpse in white armour. You can clearly see the " + itemName + " it's holding, " + "but for some reason you get the feeling you're going to have to go" + " through an unnecessarily long gauntlet of spikes and sawblades just to pick it up." ); } break; // Colosseum hints case SceneNames.Room_Colosseum_01: { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "Charm_Notch-Colosseum").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString("Prompts", "TRIAL_BOARD_BRONZE", "Trial of the Warrior. Fight for " + itemName + ".\n" + "Place a mark and begin the Trial?"); } { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "Pale_Ore-Colosseum").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString("Prompts", "TRIAL_BOARD_SILVER", "Trial of the Conqueror. Fight for " + itemName + ".\n" + "Place a mark and begin the Trial?"); } break; // Grey Mourner hint case SceneNames.Room_Mansion: { string item = RandomizerMod.Instance.Settings.ItemPlacements.FirstOrDefault(pair => pair.Item2 == "Mask_Shard-Grey_Mourner").Item1; string itemName = LanguageStringManager.GetLanguageString(LogicManager.GetItemDef(item).nameKey, "UI"); LanguageStringManager.SetString( "Prompts", "XUN_OFFER", "Accept the Gift, even knowing you'll only get a lousy " + itemName + "?" ); } break; // Enable Jiji hints when the player does not have a shade case SceneNames.Room_Ouiji: if (PlayerData.instance.shadeScene != "None") { PlayMakerFSM jijiFsm = GameObject.Find("Jiji NPC").LocateMyFSM("Conversation Control"); FsmState HasShade = jijiFsm.GetState("Has Shade?"); HasShade.RemoveTransitionsTo("Check Location"); HasShade.AddTransition("YES", "Offer"); } else if (RandomizerMod.Instance.Settings.Jiji) { PlayerData.instance.SetString("shadeMapZone", "HIVE"); PlayMakerFSM jijiFsm = GameObject.Find("Jiji NPC").LocateMyFSM("Conversation Control"); FsmState BoxUp = jijiFsm.GetState("Box Up"); BoxUp.ClearTransitions(); BoxUp.AddFirstAction(jijiFsm.GetState("Convo Choice").GetActionsOfType <GetPlayerDataInt>()[0]); BoxUp.AddTransition("FINISHED", "Offer"); FsmState SendText = jijiFsm.GetState("Send Text"); SendText.RemoveTransitionsTo("Yes"); SendText.AddTransition("YES", "Check Location"); FsmState CheckLocation = jijiFsm.GetState("Check Location"); CheckLocation.AddFirstAction(BoxUp.GetActionsOfType <SendEventByName>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Convo Choice").GetActionsOfType <GetPlayerDataInt>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Yes").GetActionsOfType <PlayerDataIntAdd>()[0]); CheckLocation.AddFirstAction(jijiFsm.GetState("Yes").GetActionsOfType <SendEventByName>()[0]); } // I don't think Jinn necessarily belongs in the ApplyHintChanges function, but w/e { GameObject Jinn = ObjectCache.Jinn; Jinn.SetActive(true); Jinn.transform.position = GameObject.Find("Jiji NPC").transform.position + new Vector3(-10f, 0, 0); FsmState transaction = Jinn.LocateMyFSM("Conversation Control").GetState("Transaction"); transaction.RemoveActionsOfType <RandomInt>(); transaction.RemoveActionsOfType <CallMethodProper>(); transaction.AddFirstAction(new RandomizerExecuteLambda(() => HeroController.instance.AddGeo(450))); // Jinn Sell All if (RandomizerMod.Instance.Settings.JinnSellAll) { PlayMakerFSM fsm = Jinn.FindGameObjectInChildren("Talk NPC").LocateMyFSM("Conversation Control"); fsm.GetState("Talk Finish").AddFirstAction(new RandomizerExecuteLambda(() => { int n = Ref.PD.GetInt(nameof(Ref.PD.rancidEggs)); if (n > 0) { Ref.Hero.AddGeo(450 * n); Ref.PD.SetInt(nameof(Ref.PD.rancidEggs), Ref.PD.GetInt(nameof(Ref.PD.rancidEggs)) - n); Ref.PD.SetInt(nameof(Ref.PD.jinnEggsSold), Ref.PD.GetInt(nameof(Ref.PD.jinnEggsSold)) + n); } })); } } break; // Tuk only sells eggs when you have no eggs in your inventory, to balance around hints and/or eggs case SceneNames.Waterways_03: GameObject.Find("Tuk NPC").LocateMyFSM("Conversation Control").GetState("Convo Choice").GetActionOfType <IntCompare>().integer2 = 1; break; } }