public static void OnUberStateChanged(int groupID, int stateID, byte type, float oldValue, float newValue) { if (uberStateLookup == null) { PopulateUberStates(); } UberId key = new UberId(groupID, stateID); if (uberStateLookup.TryGetValue(key, out UberState cachedState)) { UberState state = cachedState.Clone(); state.Value = CreateValue(state.Type, newValue); var value = CreateValue(state.Type, oldValue); ResolveUberStateChange(state, value); } else if (serializableUberState((UberStateType)type)) { var state = createUberStateEntry(key); state.Value = CreateValue(state.Type, oldValue); uberStateLookup.Add(key, state); state = state.Clone(); state.Value = CreateValue(state.Type, newValue); var value = CreateValue(state.Type, oldValue); ResolveUberStateChange(state, value); } }
private static void HandleSpecial(UberState state) { if (state.Name == "arenaBByteStateSerialized" && state.Value.Byte == 4) { // lumaPoolsStateGroup.arenaByteStateSerialized new UberId(5377, 1373).State().Write(state.Value); } else if (state.Name == "craftCutsceneState" && state.Value.Byte != 0) { state.Write(new UberValue((byte)3)); } else if (state.Name == "findToadQuestUberState" && state.Value.Int == 2) { Randomizer.InputUnlockCallback = () => { // this is really questionable!! var voiceState = new UberId(46462, 59806).State(); if (!(voiceState.Value.Bool)) { voiceState.Write(new UberValue(true)); Stats stats = Randomizer.Memory.PlayerStats; stats.MaxHealth += 10; stats.MaxEnergy++; Randomizer.Memory.PlayerStats = stats; Randomizer.Memory.FillEnergy(); Randomizer.Memory.FillHealth(); } } } ; }
private static UberState createUberStateEntry(UberId id) { if (!InterOp.get_uber_state_exists(id.GroupID, id.ID)) { Randomizer.Error("cuse", $"Failed to find {id} in uber state system.", false); return(null); } byte[] buffer = new byte[256]; int len = InterOp.get_uber_state_name(id.GroupID, id.ID, buffer, buffer.Length); string name = System.Text.Encoding.ASCII.GetString(buffer, 0, len); len = InterOp.get_uber_state_group_name(id.GroupID, id.ID, buffer, buffer.Length); string groupName = System.Text.Encoding.ASCII.GetString(buffer, 0, len); var s = new UberState() { ID = id.ID, GroupID = id.GroupID, Name = name, GroupName = groupName, Type = InterOp.get_uber_state_type(id.GroupID, id.ID), }; s.Value = CreateValue(s.Type, InterOp.get_uber_state_value(id.GroupID, id.ID)); return(s); }
public static void OnUberState(UberState state) { // If weapon upgrade, refresh. if (state.GroupID == 4) { Refresh(); } }
public static void Update() { if (NeedsNewGameInit) { NewGameInit(); } bool SkipListners = SkipListenersNextUpdate; SkipListenersNextUpdate = false; var memory = Randomizer.Memory; Dictionary <long, UberState> uberStates = memory.GetUberStates(); foreach (KeyValuePair <long, UberState> pair in uberStates) { try { UberState state = pair.Value; UberId key = state.GetUberId(); if (UberStates.TryGetValue(key, out UberState oldState)) { UberValue value = state.Value; UberValue oldValue = oldState.Value; if (value.Int != oldValue.Int) { var oldValFmt = oldState.FmtVal(); // get this now because we overwrite the value by reference if (ShouldRevert(state)) { Randomizer.Log($"Reverting state change of {state.Name} from {oldValFmt} to {state.FmtVal()}", false); memory.WriteUberState(oldState); continue; } HandleSpecial(state); UberStates[key].Value = state.Value; if (!SkipListners) { var pos = Randomizer.Memory.Position(); bool found = false; if (value.Int > 0) { found = SeedController.OnUberState(state); } if ((value.Int == 0 || !found) && !(state.GroupName == "statsUberStateGroup" || state.GroupName == "achievementsGroup")) { Randomizer.Log($"State change: {state.Name} {state.ID} {state.GroupName} {state.GroupID} {state.Type} {state.FmtVal()} (was {oldValFmt}, pos ({Math.Round(pos.X)},{Math.Round(pos.Y)}) )", false); } } } } else { UberStates[key] = state.Clone(); } } catch (Exception e) { Randomizer.Error($"USC.Update {pair}", e); } } }
public static void OnUberState(UberState state) { var id = state.GetUberId(); if (pickupMap.TryGetValue(id, out Pickup p)) { AHK.Print(p.ToString()); p.Grant(); Randomizer.PleaseSave = true; } }
public static void Update(bool NewGameInit = false) { var memory = Randomizer.Memory; Dictionary <long, UberState> uberStates = memory.GetUberStates(); foreach (KeyValuePair <long, UberState> pair in uberStates) { long key = pair.Key; UberState state = pair.Value; if (state.GroupName == "statsUberStateGroup" || (state.GroupName == "achievementsGroup" && state.Name == "spiritLightGainedCounter")) { continue; } if (UberStates.TryGetValue(key, out UberState oldState)) { UberValue value = state.Value; UberValue oldValue = oldState.Value; if (value.Int != oldValue.Int) { var pos = Randomizer.Memory.Position(); if (Ready) { if (value.Int > 0) { SeedController.OnUberState(state); if (!Randomizer.PleaseSave) { Randomizer.Log($"Potential pickup: {state.GroupName}.{state.Name} ({state.GroupID}, {state.ID}) at ({Math.Round(pos.X)},{Math.Round(pos.Y)}) {value.Int}", false); } } else { Randomizer.Log($"State change {state.GroupName}.{state.Name} ({state.GroupID}, {state.ID}) at ({Math.Round(pos.X)},{Math.Round(pos.Y)}): {oldValue.Int}->{value.Int}", false); } } UberStates[key].Value = state.Value; } } else { UberStates[key] = state.Clone(); } } if (!NewGameInit) { Ready = true; } }
private static bool ShouldRevert(UberState state) { if (NeedsNewGameInit || SkipListeners) { return(false); } if (state.Name == "cleanseWellspringQuestUberState" && state.Value.Int < 2 && !AHK.IniFlag("ShowShortCutscenes")) { return(true); } else if (state.Name == "findKuQuest" && state.Value.Int < 4) { return(true); } return(false); }
private static void HandleSpecial(UberState state) { if (state.Name == "arenaBByteStateSerialized" && state.Value.Byte == 4) { // lumaPoolsStateGroup.arenaByteStateSerialized new UberId(5377, 1373).State().Write(state.Value); } else if (state.Name == "craftCutsceneState" && 0 < state.Value.Byte && state.Value.Byte < 3) { state.Write(new UberValue((byte)3)); // Give diamond in the rough pickup. new UberId(23987, 14832).State().Write(new UberValue(true)); } // the below is a fix for a vanilla bug where you can just miss getting voice if you else if (state.Name == "findToadQuestUberState" && state.Value.Int == 2 || // (a) skip the kwolok cutscene too fast state.Name == "cleanseWellspringQuestUberState" && state.Value.Int == 4 // (b) come to kwolok after wellspring and get the cutscenes stacked awkwardly ) { Randomizer.InputUnlockCallback = () => { // this is really questionable!! var voiceState = new UberId(46462, 59806).State(); if (!voiceState.Value.Bool) { voiceState.Write(new UberValue(true)); InterOp.set_max_health(InterOp.get_max_health() + 10); InterOp.set_max_energy(InterOp.get_max_energy() + 1); InterOp.fill_health(); InterOp.fill_energy(); InterOp.save(); } // should happen in both branches if (SeedController.Flags.Contains(Flag.ALLWISPS)) { HintsController.ProgressWithHints(); } } } ; }
public static void ResolveUberStateChange(UberState state, UberValue old) { try { UberId key = state.GetUberId(); if (!UberStates.TryGetValue(key, out UberState oldState)) { oldState = state.Clone(); oldState.Value = old; UberStates.Add(key, oldState); } UberValue value = state.Value; if (value.Int == old.Int) { return; } var oldValFmt = old.FmtVal(state.Type); // get this now because we overwrite the value by reference if (ShouldRevert(state)) { Randomizer.Log($"Reverting state change of {state.Name} from {oldValFmt} to {state.FmtVal()}", false); oldState.Write(); return; } HandleSpecial(state); UberStates[key].Value = state.Value; var pos = InterOp.get_position(); bool found = false; if (value.Int > 0) { var id = state.GetUberId(); if (SkipUberStateMapCount.GetOrElse(key, 0) > 0) { var p = id.toCond().Pickup().Concat(id.toCond(state.ValueAsInt()).Pickup()); if (p.NonEmpty) { SkipUberStateMapCount[key] -= 1; Randomizer.Log($"Suppressed granting {p} from {id}={state.ValueAsInt()}. Will suppress {SkipUberStateMapCount[key]} more times", false, "DEBUG"); return; } } found = SeedController.OnUberState(state); } if (SyncedUberStates.Contains(key)) { Randomizer.Client.SendUpdate(key, state.ValueAsFloat()); } BonusItemController.OnUberState(state); var zone = ZoneType.Void; if (InterOp.get_game_state() == GameState.Game) { zone = InterOp.get_player_area().toZone(); } if (!NeedsNewGameInit && (value.Int == 0 || !found) && !(state.GroupName == "statsUberStateGroup" || state.GroupName == "achievementsGroup" || state.GroupID == 8 || state.GroupID == 10)) { Randomizer.Debug($"State change: {state.GroupName}.{state.Name} ({state.GroupID}|{state.ID}) {state.Type} {oldValFmt}->{state.FmtVal()} at ({Math.Round(pos.X)}, {Math.Round(pos.Y)}) in {zone}"); } //Randomizer.Debug($"{state.GroupName}.{state.Name}, {state.GroupID}, {state.ID}, {state.Type}, {oldValFmt}, {state.FmtVal()}, {zone}, {Math.Round(pos.X)},{Math.Round(pos.Y)}"); } catch (Exception e) { Randomizer.Error($"USC.Update {state}", e); } }
public static UberValue GetValue(this UberState state) => state.GetUberId().GetValue();
public UberStateModifier(UberState state, Func <UberValue, UberValue> modifier, String modstr) : base(state) { Modifier = modifier; ModStr = modstr; }
public static bool Write(this UberState state, UberValue value) { state.Value = value; InterOp.set_uber_state_value(state.GroupID, state.ID, state.ValueAsFloat()); return(true); }
public static bool Write(this UberState state) => state.Write(state.Value);
public static bool Write(this UberState state, UberValue value) { state.Value = value; Randomizer.Memory.WriteUberState(state); return(true); }
public static UberValue?ValueOpt(this UberState state) => state.GetUberId().ValueOpt();
public static UberValue ValueOr(this UberState state, UberValue value) => state.GetUberId().ValueOpt().GetValueOrDefault(value);
public UberStateSetter(UberState state, int sup = 0) { State = state; supCount = sup; }
public UberStateSetter(UberState state) => State = state;