/// <summary>Registers the item into it's registry</summary> public override IdentifiableItem Register() { Build(); foreach (Identifiable.Id id in Prefabs.Keys) { IdentifiableRegistry.CategorizeId(id); if (GameContext.Instance.MessageDirector.Get("actor", "l." + id.ToString().ToLower()) == null) { LanguageController.AddActorTranslation("l." + id.ToString().ToLower(), DefTranslation[id]); } LookupRegistry.RegisterIdentifiablePrefab(Prefabs[id]); VacEntry = VacItemDefinition.CreateVacItemDefinition(id, Color, Icon ? Icon : SRObjects.MissingIcon); LookupRegistry.RegisterVacEntry(VacEntry); VacEntries.Add(id, VacEntry); if (IsVacuumableOverride || Size == Vacuumable.Size.NORMAL) { AmmoRegistry.RegisterPlayerAmmo(PlayerState.AmmoMode.DEFAULT, id); } if (IsRefineryResource) { AmmoRegistry.RegisterRefineryResource(id); } AmmoRegistry.RegisterSiloAmmo(ValidSiloAmmo, id); } VacEntry = null; return(this); }
private static void Awake_Postfix(LookupDirector @this, Dictionary <Identifiable.Id, GameObject> p_identifiablePrefabDict, Dictionary <Gadget.Id, GadgetDefinition> p_gadgetDefinitionDict, Dictionary <Identifiable.Id, VacItemDefinition> p_vacItemDict) { //& Injects main game content IdentifiableRegistry.InjectPrefabs(p_identifiablePrefabDict); GadgetRegistry.InjectGadgets(p_gadgetDefinitionDict); IdentifiableRegistry.InjectVacEntries(p_vacItemDict); }
private static void RegisterActor_Postfix(long actorId, GameObject gameObj, Dictionary <long, ActorModel> p_actors) { Identifiable.Id id = Identifiable.GetId(gameObj); if (!IdentifiableRegistry.IsIdentifiableRegistered(id)) { return; } IDRegistry.RegisterActor(actorId); }
public static Identifiable.Id CraftLargo(this LookupDirector director, Identifiable.Id slimeA, Identifiable.Id slimeB, Action <SlimeDefinition> extraLargoBehaviour = null, Predicate <Identifiable.Id> canBeTarr = null, Predicate <Identifiable.Id> forceLargo = null) { if (director.LargoExists(slimeA, slimeB)) { return(Identifiable.Id.NONE); } string prefabName = "slime" + slimeA.ToString().Replace("_SLIME", "").ToUpper()[0] + slimeA.ToString().Replace("_SLIME", "").ToLower().Substring(1) + slimeB.ToString().Replace("_SLIME", "").ToUpper()[0] + slimeB.ToString().Replace("_SLIME", "").ToLower().Substring(1); string name = slimeA.ToString().Replace("_SLIME", "") + slimeB.ToString().Replace("_SLIME", "") + "_LARGO"; Identifiable.Id largoID = IdentifiableRegistry.CreateIdentifiableId(EnumPatcher.GetFirstFreeValue(typeof(Identifiable.Id)), name); SlimeDefinitions defs = GameContext.Instance.SlimeDefinitions; SlimeDefinition curr = defs.GetSlimeByIdentifiableId(slimeA); SlimeDefinition other = defs.GetSlimeByIdentifiableId(slimeB); bool largofyState = curr.CanLargofy; curr.CanLargofy = true; if (!other.CanLargofy && !(forceLargo?.Invoke(slimeB) ?? false)) { return(Identifiable.Id.NONE); } bool largofyStateB = other.CanLargofy; other.CanLargofy = true; SlimeDefinition largoDef = defs.GetLargoByBaseSlimes(curr, other); largoDef.IdentifiableId = largoID; curr.CanLargofy = largofyState; other.CanLargofy = largofyStateB; if (!(canBeTarr?.Invoke(slimeB) ?? true)) { largoDef.Diet.EatMap.RemoveAll((entry) => entry.becomesId == Identifiable.Id.TARR_SLIME); largoDef.Diet.EatMap.RemoveAll((entry) => entry.becomesId == Identifiable.Id.GLITCH_TARR_SLIME); } extraLargoBehaviour?.Invoke(largoDef); SlimeTemplate largoTemplate = new SlimeTemplate(prefabName, largoDef).SetVacSize(Vacuumable.Size.LARGE) .SetTranslation(curr.Name + " " + other.Name + " Largo").Create(); LookupRegistry.RegisterIdentifiablePrefab(largoTemplate.ToPrefab()); return(largoID); }
/// <summary> /// Called before GameContext.Awake() /// </summary> internal static void PreLoad() { if (isPreInitialized) { return; } isPreInitialized = true; Debug.Log("SRML has successfully invaded the game!"); prefabParent = new GameObject("PrefabParent").transform; prefabParent.gameObject.SetActive(false); GameObject.DontDestroyOnLoad(prefabParent.gameObject); foreach (var v in Assembly.GetExecutingAssembly().GetTypes()) { System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(v.TypeHandle); } HarmonyPatcher.PatchAll(); try { SRModLoader.InitializeMods(); } catch (Exception e) { Debug.LogError(e); ErrorGUI.CreateError($"{e.GetType().Name}: {e.Message}"); return; } FileLogger.Init(); Console.Console.Init(); HarmonyOverrideHandler.PatchAll(); try { SRModLoader.PreLoadMods(); } catch (Exception e) { Debug.LogError(e); ErrorGUI.CreateError($"{e.Message}"); return; } IdentifiableRegistry.CategorizeAllIds(); GadgetRegistry.CategorizeAllIds(); ReplacerCache.ClearCache(); HarmonyPatcher.Instance.Patch(typeof(GameContext).GetMethod("Start"), prefix: new HarmonyMethod(typeof(Main).GetMethod("Load", BindingFlags.NonPublic | BindingFlags.Static))); }
/// <summary> /// Generates all the IDs for the largos. /// <para>NOTE that all IDs are generated even if they don't get used.</para> /// </summary> /// <param name="slimeToLargo">ID of the slime to create largos</param> public static void GenerateLargoIDs(Identifiable.Id slimeToLargo) { foreach (Identifiable.Id id in Identifiable.SLIME_CLASS) { if (GetLargoID(slimeToLargo, id) != Identifiable.Id.NONE) { continue; } string name = $"{slimeToLargo.ToString().Replace("_SLIME", "")}_{id.ToString().Replace("_SLIME", "")}_LARGO"; var newVal = EnumPatcher.GetFirstFreeValue(typeof(Identifiable.Id)); IdentifiableRegistry.CreateIdentifiableId(newVal, name, false); } }
private static bool GetContents_Prefix(SiloStorage.StorageType type, ref HashSet <Identifiable.Id> @return) { FieldInfo cacheField = typeof(StorageTypeExtensions).GetField("getContentsCache", BindingFlags.Static | BindingFlags.NonPublic); Dictionary <SiloStorage.StorageType, HashSet <Identifiable.Id> > cache = cacheField?.GetValue(null) as Dictionary <SiloStorage.StorageType, HashSet <Identifiable.Id> >; if (cache != null && cache.ContainsKey(type)) { @return = cache[type]; return(false); } HashSet <Identifiable.Id> idSet = new HashSet <Identifiable.Id>(Identifiable.idComparer); switch (type) { case SiloStorage.StorageType.NON_SLIMES: IdentifiableRegistry.PopulateHashSet(idSet, IdentifiableType.NON_SLIME, IdentifiableType.ORNAMENT, IdentifiableType.ECHO, IdentifiableType.ECHO_NOTE); break; case SiloStorage.StorageType.PLORT: IdentifiableRegistry.PopulateHashSet(idSet, IdentifiableType.PLORT); break; case SiloStorage.StorageType.FOOD: IdentifiableRegistry.PopulateHashSet(idSet, IdentifiableType.FOOD, IdentifiableType.CHICK); break; case SiloStorage.StorageType.CRAFTING: IdentifiableRegistry.PopulateHashSet(idSet, IdentifiableType.PLORT, IdentifiableType.CRAFT); break; case SiloStorage.StorageType.ELDER: IdentifiableRegistry.PopulateHashSet(idSet, IdentifiableType.ELDER); break; } idSet.Remove(Identifiable.Id.QUICKSILVER_PLORT); AmmoRegistry.InjectStorageAmmo(type, idSet); cache?.Add(type, idSet); cacheField?.SetValue(null, cache); @return = idSet; return(false); }
internal static void PreLoadMods() { CurrentLoadingStep = LoadingStep.PRELOAD; Console.Console.Reload += Main.Reload; foreach (var modid in loadOrder) { var mod = Mods[modid]; try { EnumHolderResolver.RegisterAllEnums(mod.EntryType.Module); ConfigManager.PopulateConfigs(mod); mod.PreLoad(); } catch (Exception e) { throw new Exception($"Error pre-loading mod '{modid}'!\n{e.GetType().Name}: {e}"); } } IdentifiableRegistry.CategorizeAllIds(); GadgetRegistry.CategorizeAllIds(); }
internal Identifiable.Id CraftLargo(bool canBeTarr, Identifiable.Id slimeA, Identifiable.Id slimeB, System.Action <SlimeDefinition> extraLargoBehaviour = null) { if (GameContext.Instance.LookupDirector.LargoExists(slimeA, slimeB)) { return(Identifiable.Id.NONE); } string prefabName = mainObject.Name + slimeB.ToString().Replace("_SLIME", "").ToUpper()[0] + slimeB.ToString().Replace("_SLIME", "").ToLower().Substring(1); string name = slimeA.ToString().Replace("_SLIME", "") + slimeB.ToString().Replace("_SLIME", "") + "_LARGO"; Identifiable.Id largoID = IdentifiableRegistry.CreateIdentifiableId(EnumPatcher.GetFirstFreeValue(typeof(Identifiable.Id)), name); SlimeDefinitions defs = GameContext.Instance.SlimeDefinitions; SlimeDefinition other = defs.GetSlimeByIdentifiableId(slimeB); if (!other.CanLargofy) { return(Identifiable.Id.NONE); } SlimeDefinition largoDef = defs.GetLargoByBaseSlimes(definition, other); largoDef.IdentifiableId = largoID; if (!canBeTarr) { largoDef.Diet.EatMap.RemoveAll((entry) => entry.becomesId == Identifiable.Id.TARR_SLIME); largoDef.Diet.EatMap.RemoveAll((entry) => entry.becomesId == Identifiable.Id.GLITCH_TARR_SLIME); } extraLargoBehaviour?.Invoke(largoDef); SlimeTemplate largoTemplate = new SlimeTemplate(prefabName, largoDef).SetFeralState(canBeFeral).SetGlitchState(canBeAGlitch) .SetVacSize(Vacuumable.Size.LARGE).SetTranslation(definition.Name + " " + other.Name + " Largo").Create(); LookupRegistry.RegisterIdentifiablePrefab(largoTemplate.ToPrefab()); return(largoID); }
private static bool IsGuuIdentifiable(Identifiable.Id id) => IdentifiableRegistry.IsIdentifiableRegistered(id);
private static bool IsGuuIdentifiable <V>(KeyValuePair <Identifiable.Id, V> pair) => IdentifiableRegistry.IsIdentifiableRegistered(pair.Key);
//! Patch: SavedGame.Save internal static void Save(GameV12 original) { GuuCore.LOGGER.Log("Attempting to save modded save file"); gameState = new GameV12(); //& Strip Summary if (IdentifiableRegistry.IsIdentifiableRegistered(original.summary.iconId)) { gameState.summary.iconId = original.summary.iconId; original.summary.iconId = FALLBACK_ICON; } //# Strip Game Mode //& Strip World StripByMatch(original.world.lastOfferRancherIds, gameState.world.lastOfferRancherIds, IsGuuID); StripByMatch(original.world.pendingOfferRancherIds, gameState.world.pendingOfferRancherIds, IsGuuID); //# Strip Weather StripByMatch(original.world.offers, gameState.world.offers, pair => IsGuuID(pair.Value.rancherId) || IsGuuID(pair.Value.offerId) || ExchangeRegistry.IsOfferTypeRegistered(pair.Key)); foreach (ExchangeDirector.OfferType type in original.world.offers.Keys) { ExchangeOfferV04 ori = original.world.offers[type]; ExchangeOfferV04 mod = new ExchangeOfferV04(); StripByMatch(ori.requests, mod.requests, request => IsGuuIdentifiable(request.id) || ExchangeRegistry.IsNonIdenRegistered(request.nonIdentReward)); StripByMatch(ori.rewards, mod.rewards, reward => IsGuuIdentifiable(reward.id) || ExchangeRegistry.IsNonIdenRegistered(reward.nonIdentReward)); gameState.world.offers.Add(type, mod); } StripByMatch(original.world.econSaturations, gameState.world.econSaturations, IsGuuIdentifiable); StripByMatch(original.world.teleportNodeActivations, gameState.world.teleportNodeActivations, IsGuuID); StripByMatch(original.world.liquidSourceUnits, gameState.world.liquidSourceUnits, IsGuuID); StripByMatch(original.world.gordos, gameState.world.gordos, IsGuuID); foreach (KeyValuePair <string, GordoV01> gordo in original.world.gordos.Where(pair => pair.Value.fashions.Exists(IsGuuIdentifiable))) { gameState.world.gordos.Add(gordo.Key, new GordoV01()); StripByMatch(gordo.Value.fashions, gameState.world.gordos[gordo.Key].fashions, IsGuuIdentifiable); } StripByMatch(original.world.placedGadgets, gameState.world.placedGadgets, IsGuuID); foreach (string id in original.world.placedGadgets.Keys) { PlacedGadgetV08 ori = original.world.placedGadgets[id]; PlacedGadgetV08 mod = new PlacedGadgetV08(); if (IsGuuGadget(ori.gadgetId)) { mod.gadgetId = ori.gadgetId; ori.gadgetId = Gadget.Id.NONE; } foreach (AmmoDataV02 ammo in ori.ammo) { AmmoDataV02 mAmmo = new AmmoDataV02(); if (IsGuuIdentifiable(ammo.id)) { mAmmo.id = ammo.id; ammo.id = Identifiable.Id.NONE; } //# Strip Emotion Data } if (IsGuuIdentifiable(ori.baitTypeId)) { mod.baitTypeId = ori.baitTypeId; ori.baitTypeId = Identifiable.Id.NONE; } if (IsGuuIdentifiable(ori.gordoTypeId)) { mod.gordoTypeId = ori.gordoTypeId; ori.gordoTypeId = Identifiable.Id.NONE; } StripByMatch(ori.fashions, mod.fashions, IsGuuIdentifiable); if (ori.drone != null) { mod.drone = new DroneGadgetV01 { drone = new DroneV05() }; AmmoDataV02 ammo = ori.drone.drone.ammo; AmmoDataV02 mAmmo = mod.drone.drone.ammo; if (IsGuuIdentifiable(ammo.id)) { mAmmo.id = ammo.id; ammo.id = Identifiable.Id.NONE; } //# Strip Emotion Data StripByMatch(ori.drone.drone.fashions, mod.drone.drone.fashions, IsGuuIdentifiable); } gameState.world.placedGadgets.Add(id, mod); } StripByMatch(original.world.treasurePods, gameState.world.treasurePods, IsGuuID); foreach (KeyValuePair <string, TreasurePodV01> pod in original.world.treasurePods.Where(pair => pair.Value.spawnQueue.Exists(IsGuuIdentifiable))) { gameState.world.treasurePods.Add(pod.Key, new TreasurePodV01()); StripByMatch(pod.Value.spawnQueue, gameState.world.treasurePods[pod.Key].spawnQueue, IsGuuIdentifiable); } StripByMatch(original.world.switches, gameState.world.switches, IsGuuID); StripByMatch(original.world.puzzleSlotsFilled, gameState.world.puzzleSlotsFilled, IsGuuID); StripByMatch(original.world.occupiedPhaseSites, gameState.world.occupiedPhaseSites, IsGuuID); StripByMatch(original.world.quicksilverEnergyGenerators, gameState.world.quicksilverEnergyGenerators, IsGuuID); StripByMatch(original.world.oasisStates, gameState.world.oasisStates, IsGuuID); StripByMatch(original.world.activeGingerPatches, gameState.world.activeGingerPatches, IsGuuID); StripByMatch(original.world.echoNoteGordos, gameState.world.echoNoteGordos, IsGuuID); //? Slimeulation StripByMatch(original.world.glitch.teleporters, gameState.world.glitch.teleporters, IsGuuID); StripByMatch(original.world.glitch.nodes, gameState.world.glitch.nodes, IsGuuID); StripByMatch(original.world.glitch.impostoDirectors, gameState.world.glitch.impostoDirectors, IsGuuID); StripByMatch(original.world.glitch.impostos, gameState.world.glitch.impostos, IsGuuID); StripByMatch(original.world.glitch.slimes, gameState.world.glitch.slimes, IsGuuID); StripByMatch(original.world.glitch.storage, gameState.world.glitch.storage, IsGuuID); StripByMatch(original.world.glitch.storage, gameState.world.glitch.storage, pair => IsGuuIdentifiable(pair.Value.id)); //& Strip Player //# Strip Game Mode if (IsGuuIdentifiable(original.player.gameIconId)) { gameState.player.gameIconId = original.player.gameIconId; original.player.gameIconId = FALLBACK_ICON; } StripByMatch(original.player.upgrades, gameState.player.upgrades, IsGuuUpgrade); StripByMatch(original.player.ammo, gameState.player.ammo, pair => AmmoRegistry.IsAmmoModeRegistered(pair.Key)); foreach (KeyValuePair <PlayerState.AmmoMode, List <AmmoDataV02> > ammoList in original.player.ammo) { List <AmmoDataV02> moddedList = new List <AmmoDataV02>(); foreach (AmmoDataV02 ammo in ammoList.Value) { AmmoDataV02 data = new AmmoDataV02(); if (IsGuuIdentifiable(ammo.id)) { data.id = ammo.id; ammo.id = Identifiable.Id.NONE; } //# Strip Emotions moddedList.Add(data); } if (moddedList.Count > 0) { gameState.player.ammo[ammoList.Key] = moddedList; } } foreach (MailV02 mail in original.player.mail) { MailV02 mod = new MailV02 { messageKey = string.Empty, mailType = MailDirector.Type.UPGRADE }; if (MailRegistry.IsTypeRegistered(mail.mailType)) { mod.mailType = mail.mailType; mail.mailType = MailDirector.Type.PERSONAL; } if (MailRegistry.IsMailRegistered(mail.messageKey)) { mod.messageKey = mail.messageKey; if (mod.mailType == MailDirector.Type.UPGRADE) { mod.mailType = mail.mailType; } mail.mailType = MailDirector.Type.UPGRADE; } gameState.player.mail.Add(mod); } StripByMatch(original.player.availUpgrades, gameState.player.availUpgrades, IsGuuUpgrade); StripByMatch(original.player.upgradeLocks, gameState.player.upgradeLocks, IsGuuUpgrade); StripByMatch(original.player.progress, gameState.player.progress, pair => ProgressRegistry.IsTypeRegistered(pair.Key)); StripByMatch(original.player.delayedProgress, gameState.player.delayedProgress, pair => ProgressRegistry.IsTrackerRegistered(pair.Key)); StripByMatch(original.player.blueprints, gameState.player.blueprints, IsGuuGadget); StripByMatch(original.player.availBlueprints, gameState.player.availBlueprints, IsGuuGadget); StripByMatch(original.player.blueprintLocks, gameState.player.blueprintLocks, IsGuuGadget); StripByMatch(original.player.gadgets, gameState.player.gadgets, IsGuuGadget); StripByMatch(original.player.craftMatCounts, gameState.player.craftMatCounts, IsGuuIdentifiable); //# Strip Region Set ID && Player Pos //# Strip Unlocked Zone //? Decorizer StripByMatch(original.player.decorizer.contents, gameState.player.decorizer.contents, IsGuuIdentifiable); StripByMatch(original.player.decorizer.settings, gameState.player.decorizer.settings, IsGuuID); StripByMatch(original.player.decorizer.settings, gameState.player.decorizer.settings, pair => IsGuuIdentifiable(pair.Value.selected)); //& Strip Ranch //# Strip Plots StripByMatch(original.ranch.accessDoorStates, gameState.ranch.accessDoorStates, IsGuuID); StripByMatch(original.ranch.palettes, gameState.ranch.palettes, pair => ChromaPackRegistry.IsTypeRegistered(pair.Key) || ChromaPackRegistry.IsPaletteRegistered(pair.Value)); StripByMatch(original.ranch.ranchFastForward, gameState.ranch.ranchFastForward, IsGuuID); //& Strip Actors StripByMatch(original.actors, gameState.actors, actor => IsGuuID(actor.actorId)); foreach (ActorDataV09 actor in original.actors) { ActorDataV09 newActor = new ActorDataV09(); // ReSharper disable once ReplaceWithSingleAssignment.False bool hasData = false; //# Strip Emotions if (actor.fashions.Exists(IsGuuIdentifiable)) { hasData = true; StripByMatch(actor.fashions, newActor.fashions, IsGuuIdentifiable); } //# Strip Region Set && Position if (hasData) { gameState.actors.Add(newActor); } } //& Strip Pedia //# Strip Unlocked IDs //# Strip Completed Tuts //# Strip Popup Queue //& Strip Achievements //# Strip Float Stats //# Strip Double Stats //# Strip Int Stats //# Strip ID Stats by Key foreach (KeyValuePair <AchievementsDirector.GameIdDictStat, Dictionary <Identifiable.Id, int> > idDictStat in original.achieve.gameIdDictStatDict.Where(pair => pair.Value.Count(pair2 => IsGuuIdentifiable(pair2.Key)) > 0)) { gameState.achieve.gameIdDictStatDict[idDictStat.Key] = new Dictionary <Identifiable.Id, int>(); StripByMatch(idDictStat.Value, gameState.achieve.gameIdDictStatDict[idDictStat.Key], IsGuuIdentifiable); } //& Strip Holidays StripByMatch(original.holiday.eventGordos, gameState.holiday.eventGordos, IsGuuID); StripByMatch(original.holiday.eventEchoNoteGordos, gameState.holiday.eventEchoNoteGordos, IsGuuID); //& Strip Appearances StripByMatch(original.appearances.unlocks, gameState.appearances.unlocks, IsGuuIdentifiable); //# Strip Unlocks based on Appearance Sets StripByMatch(original.appearances.selections, gameState.appearances.selections, IsGuuIdentifiable); //# Strip Selections based on Appearance Sets //& Strip Instruments //# Strip Unlocks //# Strip Selection // TODO: Strip content from the original }