watermelen671 Posted December 3, 2019 Author Share Posted December 3, 2019 16 hours ago, MF99K said: one thing I don't really understand is why they're doing blocking on the temp animations when they're gonna tween the keyframes anyways. why not let the temp anims just be the tweened keyframes without cleanup/easing? I...have no idea what you just said but okay! 3 Link to comment Share on other sites More sharing options...
ResettePlayer Posted December 3, 2019 Share Posted December 3, 2019 Was there an updated lore entries file at some point? The one I have is from last year. 2 Link to comment Share on other sites More sharing options...
MF99K Posted December 4, 2019 Share Posted December 4, 2019 On 12/2/2019 at 1:45 PM, MF99K said: one thing I don't really understand is why they're doing blocking on the temp animations when they're gonna tween the keyframes anyways. why not let the temp anims just be the tweened keyframes without cleanup/easing? Â tbh I don't understand the point of blocking animation at all. 15 hours ago, watermelen671 said: I...have no idea what you just said but okay! Devie Mae on left = fully tweened Devie Mae on right = blocked animation (keyframes/breakdown, etc only) 1 Link to comment Share on other sites More sharing options...
Dovahkick Posted December 4, 2019 Share Posted December 4, 2019 (edited) Okay, so the wiki for ONI has been updated and it shows the overjoyed reaction results. https://oxygennotincluded.gamepedia.com/Duplicant#Joy_Responses The Super Productive one seems to be quite a worthy one, especially for miners...but you can't beat the power of Ballon Artists! Edited December 4, 2019 by Dovahkick Link to comment Share on other sites More sharing options...
watermelen671 Posted December 4, 2019 Author Share Posted December 4, 2019 5 hours ago, Dovahkick said: The Super Productive one seems to be quite a worthy one, especially for miners...but you can't beat the power of Ballon Artists! Well yeah, they have a chance of instantly completing any job that takes more than one second to complete. Speaking of...I should probably work on the rest of the Joy Responses. >.< Link to comment Share on other sites More sharing options...
watermelen671 Posted December 4, 2019 Author Share Posted December 4, 2019 So...just in case curious people are wondering, you can use my animations and everything that's posted here on the ONI wiki. Anyways here are all of the stickers: Spoiler Spoiler Also, did you know that there's a scrapped Joy Reaction? Or at least what I think is a Joy Reaction... Also, I'm just snooping through the files and I can't help but wonder... Spoiler // TUNING.DUPLICANTSTATS.TEMPERATURE.INTERNAL public class INTERNAL { public const float IDEAL = 310.15f; public const float THRESHOLD_HYPOTHERMIA = 308.15f; public const float THRESHOLD_HYPERTHERMIA = 312.15f; public const float THRESHOLD_FATAL_HOT = 320.15f; public const float THRESHOLD_FATAL_COLD = 300.15f; } I'm assuming that the "f" is just a stand-in for whatever unit value it's for...and it's obviously in Kelvin. Also that's a REALLY tight temperature threshold to maintain!  ...huh. Spoiler // STRINGS.DUPLICANTS.STATUSITEMS.MANUALLYCONTROLLED public class MANUALLYCONTROLLED { public static LocString NAME = "Manual control"; public static LocString TOOLTIP = "This Duplicant is under manual control and cannot act independently"; } // STRINGS.DUPLICANTS.STATUSITEMS.MANUALCONTROLIDLE public class MANUALCONTROLIDLE { public static LocString NAME = "Manual idle"; public static LocString TOOLTIP = "This Duplicant is manually controlled and will be idle until given a task"; } // STRINGS.DUPLICANTS.STATUSITEMS.MANUALCONTROLGOTO public class MANUALCONTROLGOTO { public static LocString NAME = "Manual movement"; public static LocString TOOLTIP = "This Duplicant is manually controlled and has been ordered to a specific location"; } // STRINGS.DUPLICANTS.STATUSITEMS.MANUALCONTROLCHORE public class MANUALCONTROLCHORE { public static LocString NAME = "Manually task"; public static LocString TOOLTIP = "This Duplicant is manually controlled and has been ordered to perform a specific task"; } I guess this was where this anim originated:  5 1 Link to comment Share on other sites More sharing options...
maradyne Posted December 5, 2019 Share Posted December 5, 2019 54 minutes ago, watermelen671 said: manual control color me excited Link to comment Share on other sites More sharing options...
watermelen671 Posted December 5, 2019 Author Share Posted December 5, 2019 (edited) 14 hours ago, maradyne said: color me excited Well return back to black and white because that was from an older version of the game...not sure if it's in the current one though. Edited December 5, 2019 by watermelen671 1 Link to comment Share on other sites More sharing options...
minespatch Posted December 5, 2019 Share Posted December 5, 2019 2 hours ago, watermelen671 said: The alicorn seems to be a new addition. Link to comment Share on other sites More sharing options...
goboking Posted December 5, 2019 Share Posted December 5, 2019 17 hours ago, watermelen671 said: Also, did you know that there's a scrapped Joy Reaction? Or at least what I think is a Joy Reaction... Well? Don't leave us hanging? What is it? Link to comment Share on other sites More sharing options...
watermelen671 Posted December 5, 2019 Author Share Posted December 5, 2019 Just now, goboking said: Well? Don't leave us hanging? What is it? DETERMINED ...that's all I know really. Here are its animations: Spoiler  2 Link to comment Share on other sites More sharing options...
watermelen671 Posted December 5, 2019 Author Share Posted December 5, 2019 (edited) 21 hours ago, maradyne said: color me excited 21 hours ago, watermelen671 said: Well return back to black and white because that was from an older version of the game...not sure if it's in the current one though. You may now be colored once again: // STRINGS.BUILDING.STATUSITEMS.MANUALLYCONTROLLED public class MANUALLYCONTROLLED { public static LocString NAME = "Manually Controlled"; public static LocString TOOLTIP = "This Duplicant is under my control"; } Also more stuff I've found...interesting... WARNING!! LOTS OF TEXT BELOW, LIKE, BROWSER LAG AMOUNTS OF TEXT! Spoiler NOISE: Spoiler // DuplicantNoiseLevels using TUNING; public static void SetupNoiseLevels() { SoundEventVolumeCache.instance.AddVolume("anim_eat_floor_kanim", "Chew_food_gross", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_eat_floor_kanim", "Chew_food_first", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_eat_overeat_kanim", "Chew_food_gross", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_eat_overeat_kanim", "Chew_food_first", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_eat_table_kanim", "Chew_food_gross", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_eat_table_kanim", "Chew_food_first", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_mop_dirtywater_kanim", "Mop_liquid", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_loco_destructive_kanim", "Ladder_footstep", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_loco_new_kanim", "Ladder_footstep", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_loco_wounded_kanim", "Ladder_footstep", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("anim_expel_kanim", "Expel_waste", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("anim_interacts_apothecary_kanim", "Apothecary_grind", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("anim_interrupt_binge_eat_kanim", "Hungry_tooth_chomps", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("anim_out_of_reach_binge_eat_kanim", "Hungry_tooth_chomps", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("anim_interrupt_binge_eat_kanim", "Stomach_grumble", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("anim_emotes_default_kanim", "Bodyfall_rock", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_loco_new_kanim", "Bodyfall_rock", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_incapacitated_kanim", "Bodyfall_rock", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_interacts_portal_kanim", "Bodyfall_rock", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_interacts_generatormanual_kanim", "Bodyfall_rock", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_equip_clothing_kanim", "Dressed_impact", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_healing_bed_kanim", "Healed_impact", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_interacts_outhouse_kanim", "Plunge_toilet", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_interrupt_vomiter_kanim", "Burp", NOISE_POLLUTION.CREATURES.TIER4); SoundEventVolumeCache.instance.AddVolume("anim_break_kanim", "Throw_gears", NOISE_POLLUTION.CREATURES.TIER5); SoundEventVolumeCache.instance.AddVolume("anim_interacts_sculpture_kanim", "Hammer_sculpture", NOISE_POLLUTION.CREATURES.TIER5); SoundEventVolumeCache.instance.AddVolume("anim_break_kanim", "Kick_building", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_emotes_default_kanim", "Kick_building", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_loco_destructive_kanim", "Destructive_Punch", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_out_of_reach_destructive_low_kanim", "Destructive_Punch", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_out_of_reach_destructive_low_kanim", "Destructive_Headbash", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_out_of_reach_destructive_high_kanim", "Destructive_Punch", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_out_of_reach_destructive_high_kanim", "Destructive_Headbash", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("anim_sneeze_kanim", "Dupe_sneeze", NOISE_POLLUTION.CREATURES.TIER6); SoundEventVolumeCache.instance.AddVolume("FloorSoundEvent", "footstep", NOISE_POLLUTION.CREATURES.TIER1); SoundEventVolumeCache.instance.AddVolume("FloorSoundEvent", "land", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("FloorSoundEvent", "jump", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("FloorSoundEvent", "climb", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("FloorSoundEvent", "scoot", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "sleep_inhale", NOISE_POLLUTION.CREATURES.TIER0); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "sleep_exhale", NOISE_POLLUTION.CREATURES.TIER0); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_crying", NOISE_POLLUTION.CREATURES.TIER0); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_land", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_jump", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_die", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_sick", NOISE_POLLUTION.CREATURES.TIER2); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_meh", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_flinch", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_destructive_rage", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_woohoo", NOISE_POLLUTION.CREATURES.TIER5); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_incapacitated", NOISE_POLLUTION.CREATURES.TIER5); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_vomit", NOISE_POLLUTION.CREATURES.TIER5); SoundEventVolumeCache.instance.AddVolume("VoiceSoundEvent", "voice_falling", NOISE_POLLUTION.CREATURES.TIER5); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "DigLaser_gun", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "BuildLaser_gun", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "WaterLaser_gun", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "PaintLaser_gun", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "HarvestLaser_object", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "AttackLaser_gun", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "CollectLaser_gun_shoot", NOISE_POLLUTION.CREATURES.TIER3); SoundEventVolumeCache.instance.AddVolume("LaserSoundEvent", "CollectLaser_gun", NOISE_POLLUTION.CREATURES.TIER3); } // AudioEventManager using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class AudioEventManager : KMonoBehaviour { public enum NoiseEffect { Peaceful = 0, Quiet = 36, TossAndTurn = 45, WakeUp = 60, Passive = 80, Active = 106 } public struct PolluterDisplay { public string name; public float value; public IPolluter provider; } public const float NO_NOISE_EFFECTORS = 0f; public const float MIN_LOUDNESS_THRESHOLD = 1f; private static AudioEventManager instance; private List<Pair<float, NoiseSplat>> removeTime = new List<Pair<float, NoiseSplat>>(); private Dictionary<int, List<Polluter>> freePool = new Dictionary<int, List<Polluter>>(); private Dictionary<int, List<Polluter>> inusePool = new Dictionary<int, List<Polluter>>(); private HashSet<NoiseSplat> splats = new HashSet<NoiseSplat>(); private UniformGrid<NoiseSplat> spatialSplats = new UniformGrid<NoiseSplat>(); private List<PolluterDisplay> polluters = new List<PolluterDisplay>(); public static AudioEventManager Get() { if (instance == null) { if (App.IsExiting) { return null; } GameObject gameObject = GameObject.Find("/AudioEventManager"); if (gameObject == null) { gameObject = new GameObject(); gameObject.name = "AudioEventManager"; } instance = gameObject.GetComponent<AudioEventManager>(); if (instance == null) { instance = gameObject.AddComponent<AudioEventManager>(); } } return instance; } protected override void OnSpawn() { base.OnPrefabInit(); spatialSplats.Reset(Grid.WidthInCells, Grid.HeightInCells, 16, 16); } public static float LoudnessToDB(float loudness) { return (!(loudness > 0f)) ? 0f : (10f * Mathf.Log10(loudness)); } public static float DBToLoudness(float src_db) { return Mathf.Pow(10f, src_db / 10f); } public float GetDecibelsAtCell(int cell) { float loudness = Grid.Loudness[cell]; float num = LoudnessToDB(loudness); return Mathf.Round(num * 2f) / 2f; } public static string GetLoudestNoisePolluterAtCell(int cell) { float num = float.NegativeInfinity; string result = null; AudioEventManager audioEventManager = Get(); Vector2I vector2I = Grid.CellToXY(cell); Vector2 pos = new Vector2(vector2I.x, vector2I.y); IEnumerator enumerator = audioEventManager.spatialSplats.GetAllIntersecting(pos).GetEnumerator(); try { while (enumerator.MoveNext()) { NoiseSplat noiseSplat = (NoiseSplat)enumerator.Current; float loudness = noiseSplat.GetLoudness(cell); if (loudness > num) { result = noiseSplat.GetProvider().GetName(); } } return result; } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } } public void ClearNoiseSplat(NoiseSplat splat) { if (splats.Contains(splat)) { splats.Remove(splat); spatialSplats.Remove(splat); } } public void AddSplat(NoiseSplat splat) { splats.Add(splat); spatialSplats.Add(splat); } public NoiseSplat CreateNoiseSplat(Vector2 pos, int dB, int radius, string name, GameObject go) { Polluter polluter = GetPolluter(radius); polluter.SetAttributes(pos, dB, go, name); NoiseSplat noiseSplat = new NoiseSplat(polluter); polluter.SetSplat(noiseSplat); return noiseSplat; } public List<PolluterDisplay> GetPollutersForCell(int cell) { polluters.Clear(); Vector2I vector2I = Grid.CellToXY(cell); Vector2 pos = new Vector2(vector2I.x, vector2I.y); IEnumerator enumerator = spatialSplats.GetAllIntersecting(pos).GetEnumerator(); try { while (enumerator.MoveNext()) { NoiseSplat noiseSplat = (NoiseSplat)enumerator.Current; float loudness = noiseSplat.GetLoudness(cell); if (!(loudness <= 0f)) { PolluterDisplay item = default(PolluterDisplay); item.name = noiseSplat.GetName(); item.value = LoudnessToDB(loudness); item.provider = noiseSplat.GetProvider(); polluters.Add(item); } } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } return polluters; } private void RemoveExpiredSplats() { if (removeTime.Count > 1) { removeTime.Sort((Pair<float, NoiseSplat> a, Pair<float, NoiseSplat> b) => a.first.CompareTo(b.first)); } int num = -1; for (int i = 0; i < removeTime.Count; i++) { Pair<float, NoiseSplat> pair = removeTime[i]; if (pair.first > Time.time) { break; } Pair<float, NoiseSplat> pair2 = removeTime[i]; NoiseSplat second = pair2.second; if (second != null) { IPolluter provider = second.GetProvider(); FreePolluter(provider as Polluter); } num = i; } for (int num2 = num; num2 >= 0; num2--) { removeTime.RemoveAt(num2); } } private void Update() { RemoveExpiredSplats(); } private Polluter GetPolluter(int radius) { Polluter polluter = null; if (!freePool.ContainsKey(radius)) { freePool.Add(radius, new List<Polluter>()); } if (freePool[radius].Count > 0) { polluter = freePool[radius][0]; freePool[radius].RemoveAt(0); } else { polluter = new Polluter(radius); } if (!inusePool.ContainsKey(radius)) { inusePool.Add(radius, new List<Polluter>()); } inusePool[radius].Add(polluter); return polluter; } private void FreePolluter(Polluter pol) { if (pol != null) { pol.Clear(); Debug.Assert(inusePool[pol.radius].Contains(pol)); inusePool[pol.radius].Remove(pol); freePool[pol.radius].Add(pol); } } public void PlayTimedOnceOff(Vector2 pos, int dB, int radius, string name, GameObject go, float time = 1f) { if (dB > 0 && radius > 0 && time > 0f) { Polluter polluter = GetPolluter(radius); polluter.SetAttributes(pos, dB, go, name); AddTimedInstance(polluter, time); } } private void AddTimedInstance(Polluter p, float time) { NoiseSplat noiseSplat = new NoiseSplat(p, time + Time.time); p.SetSplat(noiseSplat); removeTime.Add(new Pair<float, NoiseSplat>(time + Time.time, noiseSplat)); } private static void SoundLog(long itemId, string message) { Debug.Log(" [" + itemId + "] \t" + message); } } // BaseNodeEditor using NodeEditorFramework; using ProcGen.Noise; using System; using UnityEngine; [Node(true, "Noise/Base Noise Node", new Type[] { typeof(NoiseNodeCanvas) })] public class BaseNodeEditor : Node { private const string Id = "baseNodeEditor"; public virtual Type GetObjectType => typeof(BaseNodeEditor); public override string GetID => "baseNodeEditor"; protected SampleSettings settings { get { NoiseNodeCanvas noiseNodeCanvas = NodeEditor.curNodeCanvas as NoiseNodeCanvas; if (noiseNodeCanvas != null) { return noiseNodeCanvas.settings; } return null; } } public virtual NoiseBase GetTarget() { return null; } public override Node Create(Vector2 pos) { return null; } protected override void NodeGUI() { GUILayout.BeginHorizontal(); if (Inputs != null) { GUILayout.BeginVertical(); foreach (NodeInput input in Inputs) { input.DisplayLayout(); } GUILayout.EndVertical(); } if (Outputs != null) { GUILayout.BeginVertical(); foreach (NodeOutput output in Outputs) { output.DisplayLayout(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); if (GUI.changed) { NodeEditor.RecalculateFrom(this); } } } // NoisePolluter using Klei.AI; using STRINGS; using System; using System.Collections.Generic; using UnityEngine; [SkipSaveFileSerialization] public class NoisePolluter : KMonoBehaviour, IPolluter { public const string ID = "NoisePolluter"; public int radius; public int noise; public AttributeInstance dB; public AttributeInstance dBRadius; private NoiseSplat splat; public System.Action refreshCallback; public Action<object> refreshPartionerCallback; public Action<object> onCollectNoisePollutersCallback; public bool isMovable; [MyCmpReq] public OccupyArea occupyArea; private static readonly EventSystem.IntraObjectHandler<NoisePolluter> OnActiveChangedDelegate = new EventSystem.IntraObjectHandler<NoisePolluter>(delegate(NoisePolluter component, object data) { component.OnActiveChanged(data); }); public string sourceName { get; private set; } public bool active { get; private set; } public static bool IsNoiseableCell(int cell) { return Grid.IsValidCell(cell) && (Grid.IsGas(cell) || !Grid.IsSubstantialLiquid(cell)); } public void ResetCells() { if (radius == 0) { Debug.LogFormat("[{0}] has a 0 radius noise, this will disable it", GetName()); } } public void SetAttributes(Vector2 pos, int dB, GameObject go, string name) { sourceName = name; noise = dB; } public int GetRadius() { return radius; } public int GetNoise() { return noise; } public GameObject GetGameObject() { return base.gameObject; } public void SetSplat(NoiseSplat new_splat) { splat = new_splat; } public void Clear() { if (splat != null) { splat.Clear(); splat = null; } } public Vector2 GetPosition() { return base.transform.GetPosition(); } public void SetActive(bool active = true) { if (!active && splat != null) { AudioEventManager.Get().ClearNoiseSplat(splat); splat.Clear(); } this.active = active; } public void Refresh() { if (active) { if (splat != null) { AudioEventManager.Get().ClearNoiseSplat(splat); splat.Clear(); } KSelectable component = GetComponent<KSelectable>(); string name = (!(component != null)) ? base.name : component.GetName(); GameObject gameObject = GetComponent<KMonoBehaviour>().gameObject; splat = AudioEventManager.Get().CreateNoiseSplat(GetPosition(), noise, radius, name, gameObject); } } private void OnActiveChanged(object data) { bool isActive = ((Operational)data).IsActive; SetActive(isActive); Refresh(); } public void SetValues(EffectorValues values) { noise = values.amount; radius = values.radius; } protected override void OnSpawn() { base.OnSpawn(); if (radius == 0 || noise == 0) { Debug.LogWarning("Noisepollutor::OnSpawn [" + GetName() + "] noise: [" + noise + "] radius: [" + radius + "]"); UnityEngine.Object.Destroy(this); return; } ResetCells(); Operational component = GetComponent<Operational>(); if (component != null) { Subscribe(824508782, OnActiveChangedDelegate); } refreshCallback = Refresh; refreshPartionerCallback = delegate { Refresh(); }; onCollectNoisePollutersCallback = OnCollectNoisePolluters; Attributes attributes = this.GetAttributes(); Db db = Db.Get(); dB = attributes.Add(db.BuildingAttributes.NoisePollution); dBRadius = attributes.Add(db.BuildingAttributes.NoisePollutionRadius); if (noise != 0 && radius != 0) { AttributeModifier modifier = new AttributeModifier(db.BuildingAttributes.NoisePollution.Id, noise, UI.TOOLTIPS.BASE_VALUE); AttributeModifier modifier2 = new AttributeModifier(db.BuildingAttributes.NoisePollutionRadius.Id, radius, UI.TOOLTIPS.BASE_VALUE); attributes.Add(modifier); attributes.Add(modifier2); } else { Debug.LogWarning("Noisepollutor::OnSpawn [" + GetName() + "] radius: [" + radius + "] noise: [" + noise + "]"); } KBatchedAnimController component2 = GetComponent<KBatchedAnimController>(); isMovable = (component2 != null && component2.isMovable); Singleton<CellChangeMonitor>.Instance.RegisterCellChangedHandler(base.transform, OnCellChange, "NoisePolluter.OnSpawn"); AttributeInstance attributeInstance = dB; attributeInstance.OnDirty = (System.Action)Delegate.Combine(attributeInstance.OnDirty, refreshCallback); AttributeInstance attributeInstance2 = dBRadius; attributeInstance2.OnDirty = (System.Action)Delegate.Combine(attributeInstance2.OnDirty, refreshCallback); if (component != null) { OnActiveChanged(component.IsActive); } } private void OnCellChange() { Refresh(); } private void OnCollectNoisePolluters(object data) { List<NoisePolluter> list = (List<NoisePolluter>)data; list.Add(this); } public string GetName() { if (string.IsNullOrEmpty(sourceName)) { sourceName = GetComponent<KSelectable>().GetName(); } return sourceName; } protected override void OnCleanUp() { base.OnCleanUp(); if (base.isSpawned) { if (dB != null) { AttributeInstance attributeInstance = dB; attributeInstance.OnDirty = (System.Action)Delegate.Remove(attributeInstance.OnDirty, refreshCallback); AttributeInstance attributeInstance2 = dBRadius; attributeInstance2.OnDirty = (System.Action)Delegate.Remove(attributeInstance2.OnDirty, refreshCallback); } if (isMovable) { Singleton<CellChangeMonitor>.Instance.UnregisterCellChangedHandler(base.transform, OnCellChange); } } if (splat != null) { AudioEventManager.Get().ClearNoiseSplat(splat); splat.Clear(); } } public float GetNoiseForCell(int cell) { return splat.GetDBForCell(cell); } public List<Descriptor> GetEffectDescriptions() { List<Descriptor> list = new List<Descriptor>(); if (dB != null && dBRadius != null) { float totalValue = dB.GetTotalValue(); float totalValue2 = dBRadius.GetTotalValue(); string str = (noise <= 0) ? UI.BUILDINGEFFECTS.TOOLTIPS.NOISE_POLLUTION_DECREASE : UI.BUILDINGEFFECTS.TOOLTIPS.NOISE_POLLUTION_INCREASE; str = str + "\n\n" + dB.GetAttributeValueTooltip(); string arg = GameUtil.AddPositiveSign(totalValue.ToString(), totalValue > 0f); Descriptor item = new Descriptor(string.Format(UI.BUILDINGEFFECTS.NOISE_CREATED, arg, totalValue2), string.Format(str, arg, totalValue2)); list.Add(item); } else if (noise != 0) { string format = (noise < 0) ? UI.BUILDINGEFFECTS.TOOLTIPS.NOISE_POLLUTION_DECREASE : UI.BUILDINGEFFECTS.TOOLTIPS.NOISE_POLLUTION_INCREASE; string arg2 = GameUtil.AddPositiveSign(noise.ToString(), noise > 0); Descriptor item2 = new Descriptor(string.Format(UI.BUILDINGEFFECTS.NOISE_CREATED, arg2, radius), string.Format(format, arg2, radius)); list.Add(item2); } return list; } public List<Descriptor> GetDescriptors(BuildingDef def) { return GetEffectDescriptions(); } public List<Descriptor> GetDescriptors(GameObject go) { return GetEffectDescriptions(); } }  The code for the demo timer is still in the game. Spoiler // AquaSuitConfig using Klei.AI; using STRINGS; using System.Collections.Generic; using TUNING; using UnityEngine; public class AquaSuitConfig : IEquipmentConfig { public const string ID = "Aqua_Suit"; public EquipmentDef CreateEquipmentDef() { Dictionary<string, float> dictionary = new Dictionary<string, float>(); dictionary.Add(SimHashes.DirtyWater.ToString(), 300f); List<AttributeModifier> list = new List<AttributeModifier>(); list.Add(new AttributeModifier(TUNING.EQUIPMENT.ATTRIBUTE_MOD_IDS.INSULATION, TUNING.EQUIPMENT.SUITS.AQUASUIT_INSULATION, STRINGS.EQUIPMENT.PREFABS.AQUA_SUIT.NAME)); list.Add(new AttributeModifier(TUNING.EQUIPMENT.ATTRIBUTE_MOD_IDS.ATHLETICS, TUNING.EQUIPMENT.SUITS.AQUASUIT_ATHLETICS, STRINGS.EQUIPMENT.PREFABS.AQUA_SUIT.NAME)); list.Add(new AttributeModifier(TUNING.EQUIPMENT.ATTRIBUTE_MOD_IDS.MAX_UNDERWATER_TRAVELCOST, TUNING.EQUIPMENT.SUITS.AQUASUIT_UNDERWATER_TRAVELCOST, STRINGS.EQUIPMENT.PREFABS.AQUA_SUIT.NAME)); string id = "Aqua_Suit"; string sLOT = TUNING.EQUIPMENT.SUITS.SLOT; SimHashes outputElement = SimHashes.Water; float mass = TUNING.EQUIPMENT.SUITS.AQUASUIT_MASS; string anim = "suit_water_slow_kanim"; string sNAPON = TUNING.EQUIPMENT.SUITS.SNAPON; string buildOverride = "body_water_slow_kanim"; int buildOverridePriority = 6; List<AttributeModifier> attributeModifiers = list; Tag[] additional_tags = new Tag[1] { GameTags.Suit }; EquipmentDef equipmentDef = EquipmentTemplates.CreateEquipmentDef(id, sLOT, outputElement, mass, anim, sNAPON, buildOverride, buildOverridePriority, attributeModifiers, null, IsBody: false, EntityTemplates.CollisionShape.CIRCLE, 0.325f, 0.325f, additional_tags); equipmentDef.RecipeDescription = STRINGS.EQUIPMENT.PREFABS.AQUA_SUIT.RECIPE_DESC; return equipmentDef; } public void DoPostConfigure(GameObject go) { SuitTank suitTank = go.AddComponent<SuitTank>(); suitTank.underwaterSupport = true; suitTank.element = "Oxygen"; suitTank.amount = 11f; go.GetComponent<KPrefabID>().AddTag(GameTags.Clothes); } }  CRINGE MONITOR Spoiler // CringeMonitor public class CringeMonitor : GameStateMachine<CringeMonitor, CringeMonitor.Instance> { public new class Instance : GameInstance { private StatusItem statusItem; public Instance(IStateMachineTarget master) : base(master) { } public void SetCringeSourceData(object data) { string name = (string)data; statusItem = new StatusItem("CringeSource", name, string.Empty, null, allow_multiples: false, StatusItem.IconType.Exclamation, NotificationType.BadMinor, SimViewMode.None, SimViewMode.None); } public StatusItem GetStatusItem() { return statusItem; } } private static readonly string[] CringeAnims = new string[3] { "cringe_pre", "cringe_loop", "cringe_pst" }; public State idle; public State cringe; public override void InitializeStates(out BaseState default_state) { default_state = idle; idle.EventHandler(GameHashes.Cringe, TriggerCringe); cringe.ToggleChore((Instance smi) => new EmoteChore(smi.master, Db.Get().ChoreTypes.EmoteHighPriority, "anim_cringe", CringeAnims, smi.GetStatusItem), idle).ScheduleGoTo(3f, idle); } private void TriggerCringe(Instance smi, object data) { smi.SetCringeSourceData(data); smi.GoTo(cringe); } }  Volgus Spoiler // GroneHog using KSerialization; using System.Runtime.Serialization; using UnityEngine; [SerializationConfig(MemberSerialization.OptIn)] public class GroneHog : StateMachineComponent<GroneHog.StatesInstance>, ISaveLoadableJson { public class StatesInstance : GameStateMachine<States, StatesInstance, GroneHog>.GameInstance { public StatesInstance(GroneHog master) : base(master) { } } public class States : GameStateMachine<States, StatesInstance, GroneHog> { public class GroundedState : State { public State idle; public State idle_alt; public State move; public State move_flee; public State startle; public State jump; public State harvest; public State death; } public GroundedState grounded = new GroundedState(); public State fall = new State(); public override void InitializeStates(out BaseState default_state) { default_state = grounded.idle; grounded.Update(delegate(StatesInstance smi) { int num = Grid.PosToCell(smi.transform.position + Vector3.down); if (Grid.IsValidCell(num) && !Grid.Solid[num]) { smi.GoTo(fall); } }).EventHandler(GameHashes.WorkStarted, delegate(StatesInstance smi) { smi.master.FightOrFlight(); }).EventTransition(GameHashes.Harvest, grounded.death); grounded.idle.Enter(delegate(StatesInstance smi) { smi.Play("idle", KAnim.PlayMode.Loop); if (!smi.master.fleeing && Random.Range(0f, 100f) > 80f) { smi.master.ReverseDirection(); } if (!smi.master.fleeing && smi.master.mMound != null && CreatureHelpers.CrewNearby(smi.transform)) { smi.GoTo(grounded.startle); } else if (smi.master.GetMoveTarget() != smi.transform.position) { if (!smi.master.fleeing) { smi.ScheduleGoTo(smi.master.moveSpeed, grounded.move); } else if (smi.master.AtMound() && smi.master.mMound.HogEnter()) { smi.master.EnterMound(); } else { smi.ScheduleGoTo(0f, grounded.move_flee); } } else { smi.ScheduleGoTo(smi.master.moveSpeed, grounded.idle_alt); } }); grounded.idle_alt.Enter(delegate(StatesInstance smi) { if (!smi.master.fleeing && smi.master.mMound != null && CreatureHelpers.CrewNearby(smi.transform)) { smi.GoTo(grounded.startle); } else { smi.ScheduleGoTo(smi.master.moveSpeed, grounded.idle); } }); grounded.move.Enter(delegate(StatesInstance smi) { if (!smi.master.fleeing && smi.master.mMound != null && CreatureHelpers.CrewNearby(smi.master.transform)) { smi.GoTo(grounded.startle); } else { Vector3 moveTarget4 = smi.master.GetMoveTarget(); float y5 = moveTarget4.y; Vector3 position6 = smi.transform.position; if (y5 != position6.y) { smi.GoTo(grounded.jump); } else { float x2 = moveTarget4.x; Vector3 position7 = smi.transform.position; if (Mathf.Abs(x2 - position7.x) < 2f) { smi.Play("walk", KAnim.PlayMode.Loop); smi.master.mover.MoveToTarget(smi.master.GetMoveTarget(), smi.master.moveSpeed); } else { smi.GoTo(grounded.jump); } } CreatureHelpers.FlipAnim(smi.master.anim, smi.master.Heading); smi.ScheduleGoTo(smi.master.moveSpeed, grounded.idle); } }); grounded.move_flee.Enter(delegate(StatesInstance smi) { smi.master.SetDirectionToMound(); Vector3 moveTarget3 = smi.master.GetMoveTarget(reverseDirectionIfNecessary: false); float y4 = moveTarget3.y; Vector3 position4 = smi.transform.position; if (y4 != position4.y) { smi.GoTo(grounded.jump); } else { float x = moveTarget3.x; Vector3 position5 = smi.transform.position; if (Mathf.Abs(x - position5.x) < 2f) { smi.Play("run"); smi.master.mover.MoveToTarget(smi.master.GetMoveTarget(), smi.master.fleeMoveSpeed); } else { smi.GoTo(grounded.jump); } } CreatureHelpers.FlipAnim(smi.master.anim, smi.master.Heading); smi.ScheduleGoTo(smi.master.fleeMoveSpeed, grounded.idle); }); grounded.jump.Enter(delegate(StatesInstance smi) { Vector3 moveTarget2 = smi.master.GetMoveTarget(); CreatureHelpers.FlipAnim(smi.master.anim, smi.master.Heading); float y = moveTarget2.y; Vector3 position = smi.transform.position; if (y - position.y >= 2f) { smi.Play("jump_2"); } else { float y2 = moveTarget2.y; Vector3 position2 = smi.transform.position; if (y2 - position2.y >= 1f) { smi.Play("jump"); } else { float y3 = moveTarget2.y; Vector3 position3 = smi.transform.position; if (y3 - position3.y < 0f) { smi.Play("jump_down"); } else { smi.Play("jump_cross"); } } } smi.ScheduleGoTo(smi.master.jumpDuration, grounded.idle); }).Exit(delegate(StatesInstance smi) { Vector3 moveTarget = smi.master.GetMoveTarget(); smi.master.mover.TeleportToTarget(moveTarget, 0f); }); grounded.startle.Enter(delegate(StatesInstance smi) { smi.master.fleeing = true; smi.master.mover.StopMovement(); smi.master.harvestable.ForceCancelHarvest(); smi.Play("startle"); smi.ScheduleGoTo(smi.master.moveSpeed, grounded.idle); }); grounded.harvest.Enter(delegate(StatesInstance smi) { smi.master.mover.StopMovement(); smi.master.harvestPosition = smi.transform.position; smi.Play("harvest", KAnim.PlayMode.Loop); }).EventTransition(GameHashes.WorkAborted, grounded.idle); grounded.harvest.Update(delegate(StatesInstance smi) { smi.transform.SetPosition(smi.master.harvestPosition); }); grounded.death.Enter(delegate(StatesInstance smi) { smi.Play("death"); smi.master.death(); }).EventHandler(GameHashes.Butcher, delegate(StatesInstance smi) { smi.Schedule(0.1f, delegate { Util.KDestroyGameObject(smi.gameObject); }); }); fall.ToggleGravity(grounded.idle); } } [MyCmpAdd] private KBatchedAnimController anim; [MyCmpAdd] private SimpleMover mover; [MyCmpAdd] private ElementEmitter emitter; [MyCmpAdd] private BoxCollider2D mCollider; [MyCmpAdd] private Harvestable harvestable; private Vector2 Heading; private float moveSpeed = 0.75f; private float fleeMoveSpeed = 0.5f; private float jumpDuration = 1f; [Serialize] private Ref<GroneHogMound> moundRef = new Ref<GroneHogMound>(); private bool fleeing; private Vector3 harvestPosition; public GroneHogMound mMound { get { return moundRef.Get(); } set { moundRef.Set(value); } } public void SetMound(GroneHogMound mound) { mMound = mound; } protected override void OnSpawn() { base.OnSpawn(); base.smi.GoTo(base.smi.sm.grounded.idle); } private void OnEnable() { fleeing = false; if (Random.Range(0f, 100f) > 50f) { Heading = Vector2.right; } else { Heading = Vector2.left; } base.smi.GoTo(base.smi.sm.grounded.idle_alt); } public bool AtMound() { if (mMound != null && Grid.PosToCell(transform.position) == Grid.PosToCell(mMound.transform.position)) { return true; } return false; } private void EnterMound() { if (SelectTool.Instance.selected != null && SelectTool.Instance.selected.gameObject == base.gameObject) { SelectTool.Instance.Select(null); } base.gameObject.SetActive(value: false); } private Vector3 GetMoveTarget(bool reverseDirectionIfNecessary = true) { Vector3 walkMoveTarget = CreatureHelpers.GetWalkMoveTarget(transform, Heading); if (reverseDirectionIfNecessary && walkMoveTarget == transform.position) { ReverseDirection(); } return walkMoveTarget; } private void FightOrFlight() { if (mMound != null && GetMoveTarget(reverseDirectionIfNecessary: false) != transform.position) { fleeing = true; SetDirectionToMound(); base.smi.GoTo(base.smi.sm.grounded.startle); } else { base.smi.GoTo(base.smi.sm.grounded.harvest); } } private void SetDirectionToMound() { if (!(mMound != null)) { return; } Vector3 position = mMound.transform.position; float x = position.x; Vector3 position2 = transform.position; if (x < position2.x) { Heading = Vector3.left; return; } Vector3 position3 = mMound.transform.position; float x2 = position3.x; Vector3 position4 = transform.position; if (x2 > position4.x) { Heading = Vector3.right; } } private void death() { if (mMound != null) { mMound.gameObject.Trigger(1623392196, this); } } private void ReverseDirection() { Heading.x *= -1f; } [OnDeserialized] private void OnDeserialized() { if (moundRef != null) { moundRef.Get<GroneHogMound>().RestoreHog(base.gameObject); } } } // GroneHogMound using KSerialization; using System.Collections.Generic; using UnityEngine; [SerializationConfig(MemberSerialization.OptIn)] public class GroneHogMound : StateMachineComponent<GroneHogMound.StatesInstance>, ISaveLoadableJson { public class StatesInstance : GameStateMachine<States, StatesInstance, GroneHogMound>.GameInstance { public StatesInstance(GroneHogMound smi) : base(smi) { } } public class States : GameStateMachine<States, StatesInstance, GroneHogMound> { public class HarvestableStates : State { public State idle; public State enter; public State idle_alt; public State respawn; } public HarvestableStates harvestableStates; public State collapse; public override void InitializeStates(out BaseState default_state) { default_state = harvestableStates.idle; harvestableStates.Update(delegate(StatesInstance smi) { if (!Grid.Solid[Grid.CellBelow(Grid.PosToCell(smi.transform.position))]) { smi.GoTo(collapse); } }).EventTransition(GameHashes.Harvest, collapse); harvestableStates.idle.Enter(delegate(StatesInstance smi) { smi.Play("idle"); smi.ScheduleGoTo(smi.master.RespawnTime, harvestableStates.respawn); }).EventTransition(GameHashes.Died, harvestableStates.idle_alt); harvestableStates.idle.GoTo(harvestableStates.idle); harvestableStates.enter.PlayAnim("enter").ScheduleGoTo(1f, harvestableStates.idle); harvestableStates.respawn.Enter(delegate(StatesInstance smi) { if (smi.master.activeHogs() < smi.master.maxHogs && !CreatureHelpers.CrewNearby(smi.transform, 7)) { smi.Play("exit"); smi.master.SpawnHog(); smi.ScheduleGoTo(3f, harvestableStates.idle); } else { smi.GoTo(harvestableStates.idle); } }); collapse.Enter(delegate(StatesInstance smi) { if (SelectTool.Instance.selected != null && SelectTool.Instance.selected.gameObject == smi.gameObject) { SelectTool.Instance.Select(null); } smi.master.collapsing = true; smi.Play("collapse"); smi.master.ReleaseAllHogs(); smi.Schedule(3f, delegate { smi.master.Cleanup(); }); }); } } private bool collapsing; public GameObject mHog; public string hogPrefabID = "GroneHog"; private float RespawnTime = 5f; private int maxHogs = 3; private List<GameObject> hogs; protected override void OnPrefabInit() { RestoreHogsList(); base.OnPrefabInit(); } private void RestoreHogsList() { if (hogs == null) { hogs = new List<GameObject>(); } } public void SpawnHog() { if (hogPrefabID == null) { return; } while (hogs.Count < maxHogs) { hogs.Add(null); } for (int i = 0; i < maxHogs; i++) { if (hogs[i] == null) { mHog = Scenario.SpawnPrefab(Grid.PosToCell(base.gameObject), 0, 0, hogPrefabID); mHog.SetActive(value: true); mHog.GetComponent<GroneHog>().SetMound(this); hogs[i] = mHog; return; } } for (int j = 0; j < maxHogs; j++) { if (hogs[j] != null && !hogs[j].activeSelf) { EnableHog(hogs[j]); } } } private void ReleaseAllHogs() { foreach (GameObject hog in hogs) { if (hog != null && !hog.activeSelf) { EnableHog(hog); } } } public void RestoreHog(GameObject restoredHog) { RestoreHogsList(); for (int i = 0; i < hogs.Count; i++) { if (hogs[i] == null) { hogs[i] = restoredHog; return; } } hogs.Add(restoredHog); } private int activeHogs() { int num = 0; foreach (GameObject hog in hogs) { if (hog != null && hog.activeSelf) { num++; } } return num; } private void Cleanup() { Util.KDestroyGameObject(base.gameObject); } protected override void OnSpawn() { base.OnSpawn(); base.smi.StartSM(); Grid.Objects[Grid.PosToCell(base.gameObject), 3] = base.gameObject; } protected void EnableHog(GameObject hog) { hog.SetActive(value: true); } public bool HogEnter() { if (!collapsing) { base.smi.GoTo(base.smi.sm.harvestableStates.enter); return true; } return false; } }  Fervine Spoiler // HeatBulb using KSerialization; using UnityEngine; public class HeatBulb : KMonoBehaviour { [SerializeField] private float minTemperature; [SerializeField] private float kjConsumptionRate; [SerializeField] private float lightKJConsumptionRate; [SerializeField] private Vector2I minCheckOffset; [SerializeField] private Vector2I maxCheckOffset; [MyCmpGet] private Light2D lightSource; [MyCmpGet] private KBatchedAnimController kanim; [Serialize] private float kjConsumed; protected override void OnSpawn() { base.OnSpawn(); kanim.Play("off"); } private void SimUpdate(float dt) { float num = kjConsumptionRate * dt; Vector2I vector2I = maxCheckOffset - minCheckOffset + 1; int num2 = vector2I.x * vector2I.y; float num3 = num / (float)num2; Grid.PosToXY(transform.position, out int x, out int y); for (int i = minCheckOffset.y; i <= maxCheckOffset.y; i++) { for (int j = minCheckOffset.x; j <= maxCheckOffset.x; j++) { int num4 = Grid.XYToCell(x + j, y + i); if (Grid.IsValidCell(num4)) { Sim.Cell cell = Grid.Cell[num4]; if (cell.temperature > minTemperature) { kjConsumed += num3; SimMessages.ModifyEnergy(num4, 0f - num3, SimMessages.EnergySourceID.HeatBulb); } } } } float num5 = lightKJConsumptionRate * dt; if (kjConsumed > num5) { if (!lightSource.enabled) { kanim.Play("open"); kanim.Queue("on"); lightSource.enabled = true; } kjConsumed -= num5; } else { if (lightSource.enabled) { kanim.Play("close"); kanim.Queue("off"); } lightSource.enabled = false; } } }  Mystery Egg Spoiler // MysteryEgg using KSerialization; using System.Collections.Generic; using UnityEngine; [SerializationConfig(MemberSerialization.OptIn)] public class MysteryEgg : StateMachineComponent<MysteryEgg.StatesInstance>, ISaveLoadableJson { public class StatesInstance : GameStateMachine<States, StatesInstance, MysteryEgg>.GameInstance { public StatesInstance(MysteryEgg smi) : base(smi) { } } public class States : GameStateMachine<States, StatesInstance, MysteryEgg> { public class GroundedState : State { public State idle; } public class IncubatingState : State { public State idle; public State idle_alt; public State wiggle_small; public State wiggle_large; public State wiggle_hatch; } public GroundedState grounded; public IncubatingState incubating; public State hatch_pst; public State dead; public State fall; public override void InitializeStates(out BaseState default_state) { default_state = grounded.idle; base.serializable = true; grounded.EventTransition(GameHashes.TooHotFatal, dead, (StatesInstance smi) => smi.master.alive && smi.timeinstate > 0f).EventTransition(GameHashes.TooColdFatal, dead, (StatesInstance smi) => smi.master.alive && smi.timeinstate > 0f).EventTransition(GameHashes.OnStore, incubating.idle, (StatesInstance smi) => smi.master.transform.parent.GetComponent<EggIncubator>() != null) .Update(delegate(StatesInstance smi) { int num2 = Grid.PosToCell(smi.transform.position + Vector3.down); if (Grid.IsValidCell(num2) && !Grid.Solid[num2]) { smi.GoTo(fall); } }); grounded.idle.PlayAnim("idle").Enter(delegate(StatesInstance smi) { int num = Grid.PosToCell(smi.transform.position + Vector3.down); if (Grid.IsValidCell(num) && !Grid.Solid[num]) { smi.GoTo(fall); } }); incubating.EventTransition(GameHashes.OnStorageChange, grounded.idle, (StatesInstance smi) => smi.master.transform.parent == null || smi.master.transform.parent.GetComponent<EggIncubator>() == null); incubating.idle_alt.Enter(delegate(StatesInstance smi) { smi.GoTo(grounded.idle); }); incubating.wiggle_small.PlayAnim("wiggle_small").OnAnimQueueComplete(grounded.idle); incubating.wiggle_large.PlayAnim("wiggle_large").OnAnimQueueComplete(grounded.idle); incubating.wiggle_hatch.PlayAnim("hatch").OnAnimQueueComplete(hatch_pst); incubating.idle.PlayAnim("idle").Enter(delegate(StatesInstance smi) { smi.master.incubator = smi.master.transform.parent.GetComponent<EggIncubator>(); if (smi.master.maturity > 1200f) { smi.ScheduleGoTo(3f, incubating.wiggle_hatch); } else if (smi.master.maturity > 1020f) { smi.ScheduleGoTo(3f, incubating.wiggle_large); } else if (smi.master.maturity > 150f) { smi.ScheduleGoTo(3f, incubating.wiggle_small); } else { smi.ScheduleGoTo(3f, incubating.idle_alt); } }).Update(delegate(StatesInstance smi) { if (smi.master.incubator != null && smi.master.incubator.operational.IsOperational) { smi.master.maturity += smi.deltatime * smi.master.matureRate; } }); hatch_pst.PlayAnim("hatch_pst").Enter(delegate(StatesInstance smi) { smi.master.HatchCreature(); smi.Schedule(2f, delegate { Util.KDestroyGameObject(smi.gameObject); }); }); dead.PlayAnim("dead").Enter(delegate(StatesInstance smi) { smi.Schedule(5f, delegate { Util.KDestroyGameObject(smi.gameObject); }); }); fall.ToggleGravity(grounded.idle).PlayAnim("idle", KAnim.PlayMode.Loop); } } [MyCmpAdd] private KBatchedAnimController anim; [MyCmpAdd] private CircleCollider2D mCollider; public bool alive = true; private float maturity; private float matureRate = 1f; private EggIncubator incubator; [Serialize] private bool initialized; private Dictionary<string, int> HatchPossibilities = new Dictionary<string, int>(); protected override void OnSpawn() { HatchPossibilities.Add("Hatch", 2); HatchPossibilities.Add("Glom", 1); HatchPossibilities.Add("Puft", 4); base.OnSpawn(); GetComponent<KPrefabID>().AddTag(GameTags.Egg); if (!initialized) { HandleVector<System.Action>.Handle handle = Game.Instance.callbackManager.Add(delegate { base.smi.StartSM(); base.smi.master.initialized = true; }); SimMessages.ReplaceElement(Grid.PosToCell(base.gameObject), SimHashes.Dirt, CellEventLogger.Instance.ObjectSetSimOnSpawn, Random.Range(1000f, 3000f), -1f, handle.index); handle.index = -1; } else { base.smi.StartSM(); } } private void HatchCreature() { int num = 0; int num2 = 0; foreach (KeyValuePair<string, int> hatchPossibility in HatchPossibilities) { num += hatchPossibility.Value; num2++; } float num3 = Random.Range(0, num); string name = string.Empty; float num4 = 0f; foreach (KeyValuePair<string, int> hatchPossibility2 in HatchPossibilities) { if (num4 + (float)hatchPossibility2.Value >= num3) { name = hatchPossibility2.Key; break; } num4 += (float)hatchPossibility2.Value; } int rootCell = Grid.PosToCell(transform.position); GameObject gameObject = Scenario.SpawnPrefab(rootCell, 0, 1, name); PopFXManager.Instance.SpawnFX(PopFXManager.Instance.sprite_Plus, gameObject.GetProperName(), gameObject.transform); gameObject.SetActive(value: true); EggIncubator component = transform.parent.GetComponent<EggIncubator>(); if ((bool)component) { component.RemoveHatchedEgg(base.gameObject); } } }  Oh that's cool...it's like the precursor to ranching, where you'd get a mystery egg and it'd give you either a hatch, puft or a morb. Greedy Green/Anvari Plant Spoiler // GreedyGreen using System.Collections.Generic; using UnityEngine; public class GreedyGreen : StateMachineComponent<GreedyGreen.StatesInstance> { public class StatesInstance : GameStateMachine<States, StatesInstance, GreedyGreen>.GameInstance { public StatesInstance(GreedyGreen smi) : base(smi) { } } public class States : GameStateMachine<States, StatesInstance, GreedyGreen> { public class HarvestableState : State { public State idle; public State grow; public State harvest; public State death; } public HarvestableState harvestable; public override void InitializeStates(out BaseState default_state) { default_state = harvestable; harvestable.EventTransition(GameHashes.Harvest, harvestable.harvest); harvestable.Enter(delegate(StatesInstance smi) { int num = Grid.PosToCell(smi.master); if (smi.master.PlantableCell(num)) { int rootCell = num; smi.master.rootCell = rootCell; smi.master.partitionerEntry = GameScenePartitioner.Instance.Add("GreedyGreens.Harvestable", smi.gameObject, num, GameScenePartitioner.Instance.solidChangedMask.mask, smi.master.OnDugOut); } else if (Grid.Solid[Grid.CellBelow(num)]) { smi.master.rootCell = Grid.CellBelow(num); smi.transform.SetPosition(smi.transform.position + Vector3.down); smi.master.partitionerEntry = GameScenePartitioner.Instance.Add("GreedyGreens.Harvestable", smi.gameObject, Grid.PosToCell(smi.gameObject), GameScenePartitioner.Instance.solidChangedMask.mask, smi.master.OnDugOut); } else { Util.KDestroyGameObject(smi.master.gameObject); } smi.master.SetCollider(); smi.GoTo(harvestable.idle); }); harvestable.idle.Enter(delegate(StatesInstance smi) { smi.master.MarkTiles(); smi.master.SetCollider(); smi.master.consumer.sampleCellOffset = smi.master.GrowDirection * smi.master.growthState.Maturity; smi.master.consumer.enabled = true; smi.master.growthState.GrowingEnabled = true; }).EventTransition(GameHashes.GrowthStateMature, harvestable.grow); harvestable.harvest.Enter(delegate(StatesInstance smi) { smi.master.Emit(); smi.master.harvestable.ForceCancelHarvest(); smi.GoTo(harvestable.death); }); harvestable.grow.Enter(delegate(StatesInstance smi) { smi.master.Spread(Grid.PosToCell(smi.transform.position)); smi.master.Mature(); smi.ScheduleGoTo(1f, harvestable.idle); }); harvestable.death.Enter(delegate(StatesInstance smi) { smi.master.growthState.GrowingEnabled = false; smi.master.plantRenderer.SetDead(is_dead: true); smi.Schedule(2f, delegate { smi.master.CleanUp(); }); }); } } [MyCmpAdd] private PlantRenderer plantRenderer; [MyCmpAdd] private Harvestable harvestable; [MyCmpAdd] private ElementConsumer consumer; [MyCmpAdd] private ElementEmitter emitter; [MyCmpAdd] private GrowthState growthState; private GameScenePartitionerEntry partitionerEntry; private int[] markedTiles; public int rootCell; private Vector3 GrowDirection = Vector3.up; private List<int> OccupiedCells = new List<int>(); protected override void OnPrefabInit() { base.OnPrefabInit(); for (int i = 0; i < 7; i++) { if (Random.Range(0, 100) > 50) { growthState.ForceMaturity(growthState.Maturity + 1); Mature(); } } } protected override void OnSpawn() { base.OnSpawn(); base.smi.StartSM(); } private void OnDugOut(object param) { if (!Grid.Solid[Grid.PosToCell(transform.position)]) { Emit(); base.smi.GoTo(base.smi.sm.harvestable.death); } } private void Emit() { PopFXManager.Instance.SpawnFX(PopFXManager.Instance.sprite_Resource, "Stored CO2 Released", base.gameObject.transform); float mass = Mathf.Max(1f, base.smi.master.consumer.consumedMass); base.smi.master.consumer.consumedMass = 0f; emitter.ForceEmit(mass, -1f); } private void Mature() { if (!CellIsClear(nextGrowCell())) { growthState.Regress(1); } plantRenderer.SetStage(growthState.Maturity); SetMaturityDisplayed(); } private int TopOfVineCell() { Vector3 pos = transform.position + growthState.Maturity * GrowDirection; return Grid.PosToCell(pos); } private int nextGrowCell() { Vector3 pos = transform.position + (growthState.Maturity + 1) * GrowDirection; return Grid.PosToCell(pos); } private void EnableGrow() { growthState.GrowingEnabled = true; } private void DisableGrow() { growthState.GrowingEnabled = false; } private void CleanUp() { Debug.Log("Clean up"); if (partitionerEntry != null) { partitionerEntry.Release(); } growthState.Regress(growthState.Maturity); Util.KDestroyGameObject(base.gameObject); } private void SetMaturityDisplayed() { plantRenderer.SetStage(growthState.Maturity); consumer.sampleCellOffset = Vector3.up * growthState.Maturity; MarkTiles(); SetCollider(); } private void MarkTiles() { for (int i = 0; i < OccupiedCells.Count; i++) { if (Grid.Objects[OccupiedCells[i], 22] == base.gameObject) { Grid.Objects[OccupiedCells[i], 22] = null; } if (Grid.Objects[OccupiedCells[i], 3] == base.gameObject) { Grid.Objects[OccupiedCells[i], 3] = null; } } OccupiedCells.Clear(); OccupiedCells.Add(Grid.PosToCell(base.gameObject.transform.position)); Grid.Objects[Grid.PosToCell(base.gameObject.transform.position), 22] = base.gameObject; Grid.Objects[Grid.PosToCell(base.gameObject.transform.position), 3] = base.gameObject; for (int j = 1; j < growthState.Maturity; j++) { OccupiedCells.Add(Grid.PosToCell(base.gameObject.transform.position + GrowDirection * j)); Grid.Objects[Grid.PosToCell(base.gameObject.transform.position + GrowDirection * j), 22] = base.gameObject; Grid.Objects[Grid.PosToCell(base.gameObject.transform.position + GrowDirection * j), 3] = base.gameObject; } } private void SetCollider() { BoxCollider2D component = GetComponent<BoxCollider2D>(); if (growthState.Maturity == 0) { component.size = Vector2.one; component.offset = Vector2.zero; } else { component.size = new Vector2(1f, growthState.Maturity + 1); component.offset = new Vector2(0f, Mathf.Clamp((growthState.Maturity + 1) / 2, 1, growthState.Maturity)); } } private void Spread(int startCell) { int cell = Grid.CellLeft(startCell); int cell2 = Grid.CellRight(startCell); int cell3 = Grid.PosToCell(Grid.CellToPos(cell2, 0f, 0f - GrowDirection.y, 0f)); int cell4 = Grid.PosToCell(Grid.CellToPos(cell, 0f, 0f - GrowDirection.y, 0f)); int cell5 = Grid.PosToCell(Grid.CellToPos(cell2, 0f, GrowDirection.y, 0f)); int cell6 = Grid.PosToCell(Grid.CellToPos(cell, 0f, GrowDirection.y, 0f)); if (PlantableCell(cell)) { GameObject gameObject = Scenario.SpawnPrefab(cell, 0, 0, "GreedyGreen"); gameObject.SetActive(value: true); } else if (PlantableCell(cell4)) { GameObject gameObject2 = Scenario.SpawnPrefab(cell, 0, (int)(0f - GrowDirection.y), "GreedyGreen"); gameObject2.SetActive(value: true); } else if (PlantableCell(cell6)) { GameObject gameObject3 = Scenario.SpawnPrefab(cell, 0, (int)GrowDirection.y, "GreedyGreen"); gameObject3.SetActive(value: true); } if (PlantableCell(cell2)) { GameObject gameObject4 = Scenario.SpawnPrefab(cell2, 0, 0, "GreedyGreen"); gameObject4.SetActive(value: true); } else if (PlantableCell(cell3)) { GameObject gameObject5 = Scenario.SpawnPrefab(cell2, 0, (int)(0f - GrowDirection.y), "GreedyGreen"); gameObject5.SetActive(value: true); } else if (PlantableCell(cell5)) { GameObject gameObject6 = Scenario.SpawnPrefab(cell2, 0, (int)GrowDirection.y, "GreedyGreen"); gameObject6.SetActive(value: true); } } private bool PlantableCell(int cell) { if (Grid.Solid[cell] && !Grid.Solid[Grid.CellAbove(cell)] && Grid.Objects[cell, 22] == null && Grid.Objects[cell, 1] == null && Grid.Objects[cell, 3] == null) { return true; } return false; } private bool CellIsClear(int cell) { if (!Grid.Solid[cell] && Grid.Objects[cell, 22] == null && Grid.Objects[cell, 1] == null && Grid.Objects[cell, 3] == null) { return true; } return false; } }  Okay so this is also cool...apparently it sucks up CO2 as it grows, and when it finishes spreading out, all of that stored CO2 will be released. At least I think that's what it does. Do with this information what you will...I dunno if it's even useful for anybody. Edited December 5, 2019 by watermelen671 1 Link to comment Share on other sites More sharing options...
Sasza22 Posted December 5, 2019 Share Posted December 5, 2019 1 hour ago, watermelen671 said: Volgus So the code for them isn`t fully gone. Maybe some modder will be able to bring them back to life. Link to comment Share on other sites More sharing options...
watermelen671 Posted December 5, 2019 Author Share Posted December 5, 2019 5 minutes ago, Sasza22 said: So the code for them isn`t fully gone. Maybe some modder will be able to bring them back to life. Oh no, the code for them has been completely scrubbed from the most recent versions. I'm a dirty peasant and have...acquired an old build of the game. Link to comment Share on other sites More sharing options...
watermelen671 Posted December 6, 2019 Author Share Posted December 6, 2019 Since apparently I didn't post the overheating anim for the hot tub... 1 1 Link to comment Share on other sites More sharing options...
thewreckedangle Posted December 6, 2019 Share Posted December 6, 2019 On 12/4/2019 at 11:08 PM, watermelen671 said: ....my animations... ok maybe i'm missing something here but.. like.. your animations? 2 Link to comment Share on other sites More sharing options...
watermelen671 Posted December 7, 2019 Author Share Posted December 7, 2019 16 hours ago, thewreckedangle said: ok maybe i'm missing something here but.. like.. your animations? Yes...they're mine! Paws off! I'm gonna make a patent and then NONE of you will ever be able to touch it! *Evil Laughter* Spoiler Joking aside...basically they're my animations by technicality. I didn't make the original animations, and I will never claim to. However I've taken them out of the game's files, extracted them, compiled them together and more often than not having to basically remake them. So, in that sense they are "my" animations. It's the same thing with my critter sheet. I didn't make the critters but I did take them from the game's files, assembled them and arranged them in an arguably aesthetically appealing manner. It's proprietary by proxy. Spoiler Hopefully that makes sense and if it doesn't I'll try to explain it better.  1 Link to comment Share on other sites More sharing options...
minespatch Posted December 12, 2019 Share Posted December 12, 2019 @watermelen671 Can I get a bigger version of the textile loom? The wiki version is so tiny. Link to comment Share on other sites More sharing options...
watermelen671 Posted December 12, 2019 Author Share Posted December 12, 2019 2 hours ago, minespatch said: @watermelen671 Can I get a bigger version of the textile loom? The wiki version is so tiny. Sure I'll get right on that. As a side note, I was finally able to export that loading screen anim! ... You've got to be kidding me. 2 Link to comment Share on other sites More sharing options...
watermelen671 Posted December 13, 2019 Author Share Posted December 13, 2019 Oi, stupid forums not working... Let's try this again... @minespatch here be yer clothing factory: And here's the old clothing factory:  1 1 Link to comment Share on other sites More sharing options...
minespatch Posted December 13, 2019 Share Posted December 13, 2019 4 minutes ago, watermelen671 said: here be yer clothing factory: Thanks so much, I'm coloring my drawing of that, and will have to wing the colors of this thing: Link to comment Share on other sites More sharing options...
watermelen671 Posted December 13, 2019 Author Share Posted December 13, 2019 1 1 Link to comment Share on other sites More sharing options...
Xenologist Posted December 13, 2019 Share Posted December 13, 2019 1 hour ago, watermelen671 said: Where is this anim from? Link to comment Share on other sites More sharing options...
Sanchozz Posted December 13, 2019 Share Posted December 13, 2019 6 hours ago, Xenologist said: Where is this anim from? this is from very first alfa 1 Link to comment Share on other sites More sharing options...
watermelen671 Posted December 14, 2019 Author Share Posted December 14, 2019 On 12/13/2019 at 6:04 AM, Sanchozz said: this is from very first alfa Actually it's not. Spoiler It's from the third Alpha build. But yeah...still really hecking old. I call it the "Pre-Thermal" Build. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now