/// <summary> /// Load an SL_Type object from XML. /// </summary> public static object LoadFromXml(string path) { if (!File.Exists(path)) { SL.Log("LoadFromXml :: Trying to load an XML but path doesnt exist: " + path); return(null); } try { var type = GetBaseTypeOfXmlDocument(path); object ret; using (var file = File.OpenRead(path)) { ret = LoadFromXml(file, type); } return(ret); } catch (Exception e) { SL.LogError($"Exception reading the XML file: '{path}'!"); SL.LogInnerException(e); return(null); } }
// ================ Main Setup ==================== internal void Awake() { Instance = this; new SL(); SL.Log($"Version {SL.VERSION} starting..."); /* setup Harmony */ var harmony = new Harmony(SL.GUID); harmony.PatchAll(); /* SceneManager.sceneLoaded event */ SceneManager.sceneLoaded += SL.Instance.SceneLoaded; /* Initialize custom textures callbacks */ CustomTextures.Init(); /* Setup keybinding */ CustomKeybindings.AddAction(UIManager.MENU_TOGGLE_KEY, KeybindingsCategory.CustomKeybindings); }
internal void Internal_Apply() { // add uid to CustomCharacters callback dictionary if (!string.IsNullOrEmpty(this.UID)) { if (CustomCharacters.Templates.ContainsKey(this.UID)) { SL.LogError("Trying to register an SL_Character Template, but one is already registered with this UID: " + UID); return; } CustomCharacters.Templates.Add(this.UID, this); } if (this.LootableOnDeath && this.DropTableUIDs?.Length > 0 && !this.DropPouchContents) { SL.LogWarning($"SL_Character '{UID}' has LootableOnDeath=true and DropTableUIDs set, but DropPouchContents is false!" + $"You should set DropPouchContents to true in this case or change your template behaviour. Forcing DropPouchContents to true."); this.DropPouchContents = true; } OnPrepare(); SL.Log("Prepared SL_Character '" + Name + "' (" + UID + ")."); }
private static IEnumerator LoadAudioFromFileCoroutine(string filePath, SLPack pack, Action <AudioClip> onClipLoaded) { var name = Path.GetFileNameWithoutExtension(filePath); var request = UnityWebRequestMultimedia.GetAudioClip($@"file://{Path.GetFullPath(filePath)}", AudioType.WAV); yield return(request.SendWebRequest()); while (!request.isDone) { yield return(null); } if (!string.IsNullOrEmpty(request.error)) { SL.LogWarning(request.error); yield break; } SL.Log($"Loaded audio clip: {Path.GetFileName(filePath)}"); var clip = DownloadHandlerAudioClip.GetContent(request); FinalizeAudioClip(clip, name, pack); onClipLoaded?.Invoke(clip); }
public override void SerializeStats(ItemStats stats) { base.SerializeStats(stats); try { var eStats = stats as EquipmentStats; Impact_Resistance = eStats.ImpactResistance; Damage_Protection = eStats.GetDamageProtection(DamageType.Types.Physical); Stamina_Use_Penalty = eStats.StaminaUsePenalty; Mana_Use_Modifier = eStats.ManaUseModifier; Mana_Regen = eStats.ManaRegenBonus; Movement_Penalty = eStats.MovementPenalty; Pouch_Bonus = eStats.PouchCapacityBonus; Heat_Protection = eStats.HeatProtection; Cold_Protection = eStats.ColdProtection; Corruption_Protection = eStats.CorruptionResistance; Health_Regen = eStats.HealthRegenBonus; Cooldown_Reduction = eStats.CooldownReduction; BarrierProtection = eStats.BarrierProtection; GlobalStatusEffectResistance = eStats.GlobalStatusEffectResistance; StaminaRegenModifier = eStats.StaminaRegenModifier; Damage_Bonus = At.GetField(eStats, "m_damageAttack") as float[]; Damage_Resistance = At.GetField(eStats, "m_damageResistance") as float[]; Impact_Bonus = eStats.ImpactModifier; } catch (Exception e) { SL.Log("Exception getting EquipmentStats of " + stats.name + "\r\n" + e.Message + "\r\n" + e.StackTrace); } }
public static void BuildPrefabDictionary() { if (m_initDone) { return; } var vfxSystems = Resources.FindObjectsOfTypeAll <VFXSystem>(); foreach (var vfx in vfxSystems) { var name = GetVFXSystemEnum(vfx); if (name == VFXPrefabs.NONE) { SL.Log("Couldn't parse vfx prefab to enum: " + vfx.transform.GetGameObjectPath()); } else if (!VfxPrefabCache.ContainsKey(name)) { bool wasActive = vfx.gameObject.activeSelf; vfx.gameObject.SetActive(false); var copy = GameObject.Instantiate(vfx.gameObject); GameObject.DontDestroyOnLoad(copy); copy.SetActive(false); VfxPrefabCache.Add(name, copy); vfx.gameObject.SetActive(wasActive); } } m_initDone = true; }
public override void ApplyToComponent <T>(T component) { bool anyValid = false; var list = new List <ImbueEffectPreset>(); foreach (var id in this.ImbuePresetIDs) { var preset = ResourcesPrefabManager.Instance.GetEffectPreset(id) as ImbueEffectPreset; if (preset) { anyValid = true; list.Add(preset); } } if (!anyValid && !AnyImbue) { SL.Log("SL_ImbueEffectORCondition : Could not find any valid Imbue Preset ID!"); return; } var comp = component as ImbueEffectORCondition; comp.ImbueEffectPresets = list.ToArray(); comp.AnyImbue = this.AnyImbue; comp.WeaponToCheck = this.WeaponToCheck; }
public void ApplyRows(int treeID) { if (!this.m_object) { SL.Log("Trying to apply SL_SkillSchool but it is not created yet! Call CreateBaseSchool first!"); return; } var school = m_object.GetComponent <SkillSchool>(); At.SetField(school, "m_branches", new List <SkillBranch>()); At.SetField(school, "m_skillSlots", new List <BaseSkillSlot>()); for (int i = 0; i < 6; i++) { if (m_object.transform.Find("Row" + i) is Transform row) { UnityEngine.Object.DestroyImmediate(row.gameObject); } } foreach (var row in this.SkillRows) { row.ApplyToSchoolTransform(m_object.transform, treeID); } m_object.transform.parent = SkillTreeHolder.Instance.transform; m_object.SetActive(true); }
internal static void CheckPrefabDictionaries() { //// This debug is for when we need to dump prefab names for enums. //// Only needs to be run on updates. //SL_ShootBlast.DebugBlastNames(); //SL_ShootProjectile.DebugProjectileNames(); //SL_PlayVFX.DebugVfxNames(); // Once names have been dumped after an update and enums built, we only need this. SL_ShootBlast.BuildBlastsDictionary(); SL_ShootProjectile.BuildProjectileDictionary(); SL_PlayVFX.BuildPrefabDictionary(); foreach (var vfx in SL_ShootProjectile.ProjectilePrefabCache.Values) { vfx.transform.parent = SL.CloneHolder; } foreach (var vfx in SL_PlayVFX.VfxPrefabCache.Values) { vfx.transform.parent = SL.CloneHolder; } foreach (var vfx in SL_ShootBlast.BlastPrefabCache.Values) { vfx.transform.parent = SL.CloneHolder; } SL.Log("Built FX prefab dictionaries"); }
public static Texture2D ForceReadTexture(Texture2D tex) { try { FilterMode origFilter = tex.filterMode; tex.filterMode = FilterMode.Point; var rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32); rt.filterMode = FilterMode.Point; RenderTexture.active = rt; Graphics.Blit(tex, rt); var _newTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false); _newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0); _newTex.Apply(false, false); RenderTexture.active = null; tex.filterMode = origFilter; return(_newTex); } catch (Exception e) { SL.Log("Exception on ForceReadTexture: " + e.ToString()); return(default);
public static void BuildProjectileDictionary() { if (m_initDone) { return; } foreach (var projectile in Resources.FindObjectsOfTypeAll <Projectile>()) { var name = GetProjectilePrefabEnum(projectile); if (name == ProjectilePrefabs.NONE) { SL.Log("Couldn't parse projectile prefab: " + projectile.name); } else if (!ProjectilePrefabCache.ContainsKey(name)) { bool wasActive = projectile.gameObject.activeSelf; projectile.gameObject.SetActive(false); var copy = GameObject.Instantiate(projectile.gameObject); GameObject.DontDestroyOnLoad(copy); copy.SetActive(false); ProjectilePrefabCache.Add(name, copy); projectile.gameObject.SetActive(wasActive); } } m_initDone = true; }
public override void ApplyToComponent <T>(T component) { var comp = component as ProximityCondition; comp.ProximityDist = this.MaxDistance; comp.Offset = this.Offset; comp.OrMode = this.OrMode; comp.ProximityAngle = this.ProximityAngle; var list = new List <Skill.ItemRequired>(); foreach (var req in this.RequiredItems) { Item item = ResourcesPrefabManager.Instance.GetItemPrefab(req.ItemID); if (!item) { SL.Log("SkillItemReq: Couldn't find an item with the ID " + req.ItemID); continue; } list.Add(new Skill.ItemRequired() { Item = item, Quantity = req.Quantity, Consume = req.Consume }); } comp.ProximityItemReq = list.ToArray(); }
/// <summary> /// Helper to take a VFXSystem and get the VFXSystemPrefabs enum value for it (if valid). /// </summary> /// <param name="vfx">The vfx system</param> public static VFXPrefabs GetVFXSystemEnum(VFXSystem vfx) { if (Enum.TryParse(GetSafeVFXName(vfx), out VFXPrefabs name)) { return(name); } SL.Log("PlayVFX: could not get name for " + vfx.name); return(VFXPrefabs.NONE); }
// ======== SL Setup ======== internal static void Setup(bool isFirstSetup = true) { var start = Time.realtimeSinceStartup; if (isFirstSetup) { CloneHolder = new GameObject("SL_CloneHolder").transform; GameObject.DontDestroyOnLoad(CloneHolder.gameObject); CloneHolder.hideFlags |= HideFlags.HideAndDontSave; CloneHolder.gameObject.SetActive(false); SLRPCManager.Setup(); PlayerSaveExtension.LoadExtensionTypes(); CheckPrefabDictionaries(); TryInvoke(BeforePacksLoaded); } else { ResetForHotReload(); } // Load SL Packs SLPackManager.LoadAllPacks(isFirstSetup); if (isFirstSetup) { foreach (var pack in SL.s_packs) { pack.Value.TryApplyItemTextureBundles(); } } // Invoke OnPacksLoaded and cleanup PacksLoaded = true; Log("SideLoader Setup Finished"); Log("-------------------------"); SL.Log("SL Setup took " + (Time.realtimeSinceStartup - start) + " seconds"); if (isFirstSetup) { if (OnPacksLoaded != null) { TryInvoke(OnPacksLoaded); Log("Finished invoking OnPacksLoaded."); } /* Setup UI */ UIManager.Init(); } }
// main actual spawn method internal Character InternalSpawn(Vector3 position, Vector3 rotation, string characterUID, string extraRpcData, bool loadingFromSave) { characterUID = characterUID ?? this.UID; if (CharacterManager.Instance.GetCharacter(characterUID) is Character existing) { SL.Log("Trying to spawn a character UID " + characterUID + " but one already exists with that UID!"); return(existing); } return(CustomCharacters.SpawnCharacter(this, position, rotation, characterUID, extraRpcData, loadingFromSave).GetComponent <Character>()); }
public static void InitializePatch(InputManager_Base __instance) { //s_userData = __instance.userData; foreach (var keybindInfo in s_customKeyDict.Values) { // This actually creates the new actions: AddRewiredAction(__instance.userData, keybindInfo.name, keybindInfo.category, keybindInfo.type, out int actionID); keybindInfo.actionID = actionID; SL.Log($"Set up custom keybinding '{keybindInfo.name}', actionID: " + keybindInfo.actionID); } }
/// <summary> Clone's an items current visual prefab (and materials), then sets this item's visuals to the new cloned prefab. </summary> public static GameObject CloneVisualPrefab(Item item, VisualPrefabType type, bool logging = false) { var prefab = GetOrigItemVisuals(item, type); if (!prefab) { if (logging) { SL.Log("Error, no VisualPrefabType defined or could not find visual prefab of that type!"); } return(null); } return(CloneAndSetVisuals(item, prefab.gameObject, type)); }
public static void DebugVfxNames() { SL.Log("----------- VFXSystems ------------ "); var vfxsystems = Resources.FindObjectsOfTypeAll <VFXSystem>(); var names = new List <string>(); foreach (var vfx in vfxsystems) { var safename = GetSafeVFXName(vfx); if (!names.Contains(safename)) { names.Add(safename); } } File.WriteAllLines("vfxsystems.txt", names.ToArray()); }
internal void Internal_ApplyTemplate() { if (string.IsNullOrEmpty(this.UID)) { SL.LogWarning("Cannot prepare an SL_DropTable with a null or empty UID!"); return; } if (s_registeredTables.ContainsKey(this.UID)) { SL.LogWarning("Trying to register an SL_DropTable but one already exists with this UID: " + this.UID); return; } s_registeredTables.Add(this.UID, this); SL.Log("Registered SL_DropTable '" + this.UID + "'"); }
public static Texture2D LoadTexture(byte[] data, bool mipmap, bool linear) { Texture2D tex = new Texture2D(4, 4, TextureFormat.DXT5, mipmap, linear); try { tex.LoadImage(data); } catch (Exception e) { SL.Log("Error loading texture! Message: " + e.Message + "\r\nStack: " + e.StackTrace); } tex.filterMode = FilterMode.Bilinear; return(tex); }
public static SL_EffectCondition ParseCondition(EffectCondition component) { Type slType = Serializer.GetBestSLType(component.GetType()); if (slType != null && !slType.IsAbstract) { var holder = Activator.CreateInstance(slType) as SL_EffectCondition; holder.Invert = component.Invert; holder.SerializeEffect(component); return(holder); } else { SL.Log(component.ToString() + " is not supported yet, sorry!"); return(null); } }
public EffectCondition ApplyToTransform(Transform transform) { Type componentType = Serializer.GetGameType(this.GetType()); if (componentType != null) { var comp = transform.gameObject.AddComponent(componentType) as EffectCondition; comp.Invert = this.Invert; ApplyToComponent(comp); return(comp); } else { SL.Log("Could not get Game type for SL_type: " + this.ToString()); return(null); } }
/// <summary> /// Returns the game's actual Tag for the string you provide, if it exists. /// </summary> /// <param name="TagName">Eg "Food", "Blade", etc...</param> /// <param name="logging">Whether to log error messages to debug console or not (if tag doesnt exist)</param> /// <returns></returns> public static Tag GetTag(string TagName, bool logging = true) { var tags = (Tag[])At.GetField(TagSourceManager.Instance, "m_tags"); var tag = tags.FirstOrDefault(x => x.TagName == TagName); if (tag.TagName == TagName) { return(tag); } else { if (logging) { SL.Log("GetTag :: Could not find a tag by the name: " + TagName); } return(Tag.None); } }
internal static void OnSceneLoaded() { if (PhotonNetwork.isNonMasterClientInRoom) { return; } SL.Log("Checking SL_ItemSpawns..."); s_activeSavableSpawns.Clear(); Dictionary <string, ItemSpawnInfo> savedData = null; if (!SL.WasLastSceneReset) { savedData = LoadItemSpawnData(); } foreach (var spawn in s_registeredSpawnSources.Values) { // Check if already spawned if (savedData != null && savedData.ContainsKey(spawn.IdentifierName)) { var data = savedData[spawn.IdentifierName]; s_activeSavableSpawns.Add(data); var item = ItemManager.Instance.GetItem(data.ItemUID); if (item && string.IsNullOrEmpty(item.MostRecentOwnerUID)) { // item hasn't been picked up yet, update it to current template settings. s_registeredSpawnSources[spawn.IdentifierName].ApplyToItem(item); } continue; } // else, new spawn if (spawn.SceneToSpawnIn == SceneManagerHelper.ActiveSceneName) { spawn.GenerateItem(); } } }
/// <summary>Serialize an effect and get the equivalent SL_Effect.</summary> public static SL_Effect ParseEffect(Effect effect) { Type slType = Serializer.GetBestSLType(effect.GetType()); if (slType != null && !slType.IsAbstract) { var holder = Activator.CreateInstance(slType) as SL_Effect; holder.Delay = effect.Delay; holder.OverrideCategory = effect.OverrideEffectCategory; holder.SyncType = effect.SyncType; holder.SerializeEffect(effect); return(holder); } else { SL.Log(effect.ToString() + " is not supported yet, sorry!"); return(null); } }
internal virtual void ApplyItemVisualSettings(ItemVisual itemVisual, Transform visuals) { SL.Log($"Applying ItemVisuals settings to " + visuals.name); if (Position != null) { visuals.localPosition = (Vector3)Position; } if (Rotation != null) { visuals.eulerAngles = (Vector3)Rotation; } if (PositionOffset != null) { visuals.localPosition += (Vector3)PositionOffset; } if (RotationOffset != null) { visuals.eulerAngles += (Vector3)RotationOffset; } }
/// <summary> /// Internal use for setting a required slot. /// </summary> /// <param name="comp">The component that this SkillSlot is setting. Not the required slot.</param> public void SetRequiredSlot(BaseSkillSlot comp) { bool success = false; var reqrow = RequiredSkillSlot.x; var reqcol = RequiredSkillSlot.y; if (comp.transform.root.Find("Row" + reqrow) is Transform reqrowTrans && reqrowTrans.Find("Col" + reqcol) is Transform reqcolTrans) { var reqslot = reqcolTrans.GetComponent <BaseSkillSlot>(); if (reqslot) { At.SetField(comp, "m_requiredSkillSlot", reqslot); success = true; } } if (!success) { SL.Log("Could not set required slot. Maybe it's not set yet?"); } }
public override void ApplyToComponent <T>(T component) { var comp = component as Summon; if (this.SummonPrefabType == PrefabTypes.Resource) { if (Resources.Load <GameObject>(Prefab) is GameObject prefab) { comp.SummonedPrefab = prefab.transform; } else { SL.Log("Could not find Resources asset: " + this.Prefab + "!"); return; } } else { if (int.TryParse(this.Prefab, out int id) && ResourcesPrefabManager.Instance.GetItemPrefab(id) is Item item) { comp.SummonedPrefab = item.transform; } else { SL.Log("Could not find an Item with the ID " + this.Prefab + ", or that is not a valid ID!"); return; } } comp.BufferSize = this.BufferSize; comp.LimitOfOne = this.LimitOfOne; comp.InstantiationMode = this.SummonMode; comp.PositionType = this.PositionType; comp.MinDistance = this.MinDistance; comp.MaxDistance = this.MaxDistance; comp.SameDirAsSummoner = this.SameDirectionAsSummoner; comp.SummonLocalForward = this.SummonLocalForward; comp.IgnoreOnDestroy = this.IgnoreOnDestroy; }
/// <summary>Replace a global sound with the provided AudioClip.</summary> public static void ReplaceAudio(GlobalAudioManager.Sounds sound, AudioClip clip) { if (!GAMInstance) { SL.LogWarning("Cannot find GlobalAudioManager Instance!"); return; } if (ReplacedClips.Contains(sound)) { SL.Log($"The Sound clip '{sound}' has already been replaced, replacing again..."); } try { DoReplaceClip(sound, clip); } catch (Exception e) { SL.LogError($"Exception replacing clip '{sound}'.\r\nMessage: {e.Message}\r\nStack: {e.StackTrace}"); } }
public SL_ItemDropChance GetDropForDiceRoll(int diceRoll) { if (diceRoll < 0 || diceRoll > MaxDiceValue) { SL.Log("ERROR: Roll " + diceRoll + " is <0 or >" + MaxDiceValue); return(null); } if (m_dropRanges == null) { GetDropRanges(); } for (int i = 0; i < m_dropRanges.Count; i++) { var entry = m_dropRanges.ElementAt(i); // if dice roll was within range if (entry.Key <= diceRoll && entry.Value >= diceRoll) { // if there is a NoDrop chance if (NoDrop_DiceValue > 0) { if (i == 0) { return(null); // Index was 0 so it was a no-drop. } else { i--; // NoDrop was set, so remove 1 from index to get the real drop index. } } return(Drops[i]); } } return(null); }