diff --git a/1.3/Assemblies/VFECore.dll b/1.3/Assemblies/VFECore.dll index 26f11c13..d4e90d68 100644 Binary files a/1.3/Assemblies/VFECore.dll and b/1.3/Assemblies/VFECore.dll differ diff --git a/Source/VFECore/VFECore.csproj b/Source/VFECore/VFECore.csproj index 95996e58..0fbb629f 100644 --- a/Source/VFECore/VFECore.csproj +++ b/Source/VFECore/VFECore.csproj @@ -574,6 +574,7 @@ + @@ -751,6 +752,8 @@ + + @@ -781,6 +784,8 @@ + + diff --git a/Source/VFECore/VFECore/Comps/ThingComps/CompShieldBubble.cs b/Source/VFECore/VFECore/Comps/ThingComps/CompShieldBubble.cs index 3a335917..c0e6a3e3 100644 --- a/Source/VFECore/VFECore/Comps/ThingComps/CompShieldBubble.cs +++ b/Source/VFECore/VFECore/Comps/ThingComps/CompShieldBubble.cs @@ -31,6 +31,9 @@ public CompProperties_ShieldBubble() public Color shieldColor = Color.white; public float EnergyLossPerDamage = 1f; public bool disableRotation; + public SoundDef absorbDamageSound; + public SoundDef brokenSound; + public SoundDef resetSound; } [StaticConstructorOnStartup] @@ -287,7 +290,11 @@ public void KeepDisplaying() } private void AbsorbedDamage(DamageInfo dinfo) { - SoundDefOf.EnergyShield_AbsorbDamage.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + if (Props.absorbDamageSound != null) + Props.absorbDamageSound.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + else + SoundDefOf.EnergyShield_AbsorbDamage.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + impactAngleVect = Vector3Utility.HorizontalVectorFromAngle(dinfo.Angle); Vector3 loc = this.Pawn.TrueCenter() + impactAngleVect.RotatedBy(180f) * 0.5f; float num = Mathf.Min(10f, 2f + dinfo.Amount / 10f); @@ -307,7 +314,10 @@ protected virtual void Break() { if (this.Pawn?.Map != null && this.Pawn.Position.InBounds(this.Pawn.Map)) { - SoundDefOf.EnergyShield_Broken.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + if (Props.brokenSound != null) + Props.brokenSound.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + else + SoundDefOf.EnergyShield_Broken.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); FleckMaker.Static(this.Pawn.TrueCenter(), this.Pawn.Map, FleckDefOf.ExplosionFlash, 12f); for (int i = 0; i < 6; i++) @@ -324,7 +334,11 @@ protected virtual void Reset() { if (this.Pawn.Spawned) { - SoundDefOf.EnergyShield_Reset.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + if (Props.resetSound != null) + Props.resetSound.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + else + SoundDefOf.EnergyShield_Reset.PlayOneShot(new TargetInfo(this.Pawn.Position, this.Pawn.Map)); + FleckMaker.ThrowLightningGlow(this.Pawn.TrueCenter(), this.Pawn.Map, 3f); } diff --git a/Source/VFECore/VFECore/Defs/BackstoryDef.cs b/Source/VFECore/VFECore/Defs/BackstoryDef.cs new file mode 100644 index 00000000..1d921223 --- /dev/null +++ b/Source/VFECore/VFECore/Defs/BackstoryDef.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using HarmonyLib; +using RimWorld; +using Verse; + +namespace VFECore +{ + public class TraitEntryBackstory + { + public TraitDef defName; + + public int degree; + + public int chance; + } + public class BackstoryDef : Def + { + public override void ResolveReferences() + { + if (BackstoryDatabase.allBackstories.ContainsKey(this.saveKeyIdentifier)) + { + Log.Error(this.defName + " contains a saveKeyIdentifier value " + saveKeyIdentifier + " which is used already. It won't be added as a def. Make sure that the identifier is unique."); + return; + } + + Backstory backstory = new Backstory(); + if (this.forcedTraits?.Any() ?? false) + { + backstory.forcedTraits = new List(); + foreach (var trait in this.forcedTraits.Where(x => Rand.RangeInclusive(0, 100) < x.chance)) + { + backstory.forcedTraits.Add(new TraitEntry(trait.defName, trait.degree)); + } + } + + if (this.disallowedTraits?.Any() ?? false) + { + backstory.disallowedTraits = new List(); + foreach (var trait in this.disallowedTraits.Where(x => Rand.RangeInclusive(0, 100) < x.chance)) + { + backstory.disallowedTraits.Add(new TraitEntry(trait.defName, trait.degree)); + } + } + + backstory.SetTitle(this.title, this.title); + if (!GenText.NullOrEmpty(this.titleShort)) + { + backstory.SetTitleShort(this.titleShort, this.titleShort); + } + else + { + backstory.SetTitleShort(backstory.title, backstory.title); + } + if (!GenText.NullOrEmpty(this.baseDescription)) + { + backstory.baseDesc = this.baseDescription; + } + + Traverse.Create(backstory).Field("bodyTypeGlobal").SetValue(this.bodyTypeGlobal); + Traverse.Create(backstory).Field("bodyTypeMale").SetValue(this.bodyTypeMale); + Traverse.Create(backstory).Field("bodyTypeFemale").SetValue(this.bodyTypeFemale); + if (skillGains?.Any() ?? false) + { + var skillGainsDict = skillGains.ToDictionary(x => x.skill.defName, y => y.minLevel); + Traverse.Create(backstory).Field("skillGains").SetValue(skillGainsDict); + } + + backstory.slot = this.slot; + backstory.shuffleable = this.shuffleable; + backstory.spawnCategories = this.spawnCategories; + + if (this.workDisables.Any()) + { + foreach (var workTag in this.workDisables) + { + backstory.workDisables |= workTag; + } + } + else + { + backstory.workDisables = WorkTags.None; + } + + backstory.PostLoad(); + backstory.ResolveReferences(); + backstory.identifier = this.saveKeyIdentifier; + + if (!backstory.ConfigErrors(true).Any()) + { + BackstoryDatabase.AddBackstory(backstory); + } + else + { + foreach (var err in backstory.ConfigErrors(true)) + { + Log.Error(backstory + " - " + err); + } + } + } + + public string baseDescription; + + public string bodyTypeGlobal = ""; + + public string bodyTypeMale = "Male"; + + public string bodyTypeFemale = "Female"; + + public string title; + + public string titleShort; + + public BackstorySlot slot = BackstorySlot.Childhood; + + public bool shuffleable = true; + + public List workDisables = new List(); + + public List spawnCategories = new List(); + + public List skillGains; + + public List forcedTraits = new List(); + + public List disallowedTraits = new List(); + + public string saveKeyIdentifier; + } +} diff --git a/Source/VFECore/VFECore/MapExtender/MapGenerator_GenerateMap_Patch.cs b/Source/VFECore/VFECore/MapExtender/MapGenerator_GenerateMap_Patch.cs new file mode 100644 index 00000000..f29dfbbe --- /dev/null +++ b/Source/VFECore/VFECore/MapExtender/MapGenerator_GenerateMap_Patch.cs @@ -0,0 +1,140 @@ +using System; +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Verse; +using UnityEngine; +using RimWorld.Planet; +using HarmonyLib; + +// Copyright Sarg - Alpha Biomes 2020 & Taranchuck + +namespace VFECore +{ + [HarmonyPatch(typeof(MapGenerator), nameof(MapGenerator.GenerateMap))] + public static class MapGenerator_GenerateMap_Patch + { + public static void Postfix(Map __result) + { + DoMapSpawns(__result); + } + public static bool CanSpawnAt(IntVec3 c, Map map, ObjectSpawnsDef element) + { + if (!element.allowOnChunks) + { + foreach (var item in c.GetThingList(map)) + { + if (item?.def?.thingCategories != null) + { + foreach (var category in item.def.thingCategories) + { + if (category == ThingCategoryDefOf.Chunks || category == ThingCategoryDefOf.StoneChunks) + { + return false; + } + } + } + } + } + + TerrainDef terrain = c.GetTerrain(map); + + bool flagAllowed = true; + + foreach (string allowed in element.allowedTerrains) + { + if (terrain.defName == allowed) + { + break; + } + else flagAllowed = false; + } + if (!flagAllowed) return false; + + foreach (string notAllowed in element.disallowedTerrainTags) + { + if (terrain.HasTag(notAllowed)) + { + return false; + } + } + + if (!element.allowOnWater && terrain.IsWater) + { + return false; + } + + if (element.findCellsOutsideColony) + { + if (!OutOfCenter(c, map, 60)) + { + return false; + } + } + + return true; + } + public static void DoMapSpawns(Map map) + { + int spawnCounter = 0; + foreach (ObjectSpawnsDef element in DefDatabase.AllDefs.Where(element => element.allowedBiomes.Contains(map.Biome))) + { + if (element.spawnOnlyInPlayerMaps && !map.IsPlayerHome) + { + continue; + } + IEnumerable tmpTerrain = map.AllCells.InRandomOrder(); + if (spawnCounter == 0) + { + spawnCounter = element.numberToSpawn.RandomInRange; + } + foreach (IntVec3 c in tmpTerrain) + { + bool canSpawn = CanSpawnAt(c, map, element); + if (canSpawn) + { + Thing thing = (Thing)ThingMaker.MakeThing(element.thingDef, null); + CellRect occupiedRect = GenAdj.OccupiedRect(c, thing.Rotation, thing.def.Size); + if (occupiedRect.InBounds(map)) + { + canSpawn = true; + foreach (IntVec3 c2 in occupiedRect) + { + if (!CanSpawnAt(c2, map, element)) + { + canSpawn = false; + break; + } + } + if (canSpawn) + { + if (element.randomRotation) + { + GenPlace.TryPlaceThing(thing, c, map, ThingPlaceMode.Direct, null, null, Rot4.Random); + } + else + { + GenSpawn.Spawn(thing, c, map); + } + spawnCounter--; + } + } + } + + if (canSpawn && spawnCounter <= 0) + { + spawnCounter = 0; + break; + } + } + } + } + + public static bool OutOfCenter(IntVec3 c, Map map, int centerDist) + { + IntVec3 CenterPoint = map.Center; + return c.x < CenterPoint.x - centerDist || c.z < CenterPoint.z - centerDist || c.x >= CenterPoint.x + centerDist || c.z >= CenterPoint.z + centerDist; + } + } +} \ No newline at end of file diff --git a/Source/VFECore/VFECore/MapExtender/ObjectSpawnsDef.cs b/Source/VFECore/VFECore/MapExtender/ObjectSpawnsDef.cs new file mode 100644 index 00000000..3e1ee017 --- /dev/null +++ b/Source/VFECore/VFECore/MapExtender/ObjectSpawnsDef.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +// Copyright Sarg - Alpha Biomes 2020 & Taranchuck + +namespace VFECore +{ + public class ObjectSpawnsDef : Def + { + public ThingDef thingDef; + public bool allowOnWater; + public bool allowOnChunks; + public IntRange numberToSpawn; + public List allowedTerrains; + public List disallowedTerrainTags; + public List allowedBiomes; + public bool findCellsOutsideColony = false; + public bool spawnOnlyInPlayerMaps = false; + public bool randomRotation; + } +} diff --git a/Source/VFECore/VFECore/WeatherOverlays/WeatherOverlay_Custom.cs b/Source/VFECore/VFECore/WeatherOverlays/WeatherOverlay_Custom.cs new file mode 100644 index 00000000..0f19b23e --- /dev/null +++ b/Source/VFECore/VFECore/WeatherOverlays/WeatherOverlay_Custom.cs @@ -0,0 +1,45 @@ +using UnityEngine; +using Verse; + +namespace VFECore +{ + public class WeatherOverlayExtension : DefModExtension + { + public string overlayPath; + public string copyPropertiesFrom; + public float worldOverlayPanSpeed1; + public Vector2 worldPanDir1; + public float worldOverlayPanSpeed2; + public Vector2 worldPanDir2; + } + public class WeatherOverlay_Custom : SkyOverlay + { + public WeatherDef curWeather; + public WeatherOverlay_Custom() + { + + } + public override void TickOverlay(Map map) + { + if (curWeather != map.weatherManager.curWeather) + { + curWeather = map.weatherManager.curWeather; + var extension = curWeather.GetModExtension(); + worldOverlayPanSpeed1 = extension.worldOverlayPanSpeed1; + worldPanDir1 = extension.worldPanDir1; + worldPanDir1.Normalize(); + worldOverlayPanSpeed2 = extension.worldOverlayPanSpeed2; + worldPanDir2 = extension.worldPanDir2; + worldPanDir2.Normalize(); + worldOverlayMat = MaterialPool.MatFrom(extension.overlayPath); + var mat = MatLoader.LoadMat(extension.copyPropertiesFrom); + worldOverlayMat.CopyPropertiesFromMaterial(mat); + worldOverlayMat.shader = mat.shader; + var texture = ContentFinder.Get(extension.overlayPath); + worldOverlayMat.SetTexture("_MainTex", texture); + worldOverlayMat.SetTexture("_MainTex2", texture); + } + base.TickOverlay(map); + } + } +} diff --git a/Source/VFECore/VFECore/WeatherOverlays/WeatherOverlay_CustomTwo.cs b/Source/VFECore/VFECore/WeatherOverlays/WeatherOverlay_CustomTwo.cs new file mode 100644 index 00000000..89c7208e --- /dev/null +++ b/Source/VFECore/VFECore/WeatherOverlays/WeatherOverlay_CustomTwo.cs @@ -0,0 +1,45 @@ +using UnityEngine; +using Verse; + +namespace VFECore +{ + public class WeatherOverlayExtensionTwo : DefModExtension + { + public string overlayPath; + public string copyPropertiesFrom; + public float worldOverlayPanSpeed1; + public Vector2 worldPanDir1; + public float worldOverlayPanSpeed2; + public Vector2 worldPanDir2; + } + public class WeatherOverlay_CustomTwo : SkyOverlay + { + public WeatherDef curWeather; + public WeatherOverlay_CustomTwo() + { + + } + public override void TickOverlay(Map map) + { + if (curWeather != map.weatherManager.curWeather) + { + curWeather = map.weatherManager.curWeather; + var extension = curWeather.GetModExtension(); + worldOverlayPanSpeed1 = extension.worldOverlayPanSpeed1; + worldPanDir1 = extension.worldPanDir1; + worldPanDir1.Normalize(); + worldOverlayPanSpeed2 = extension.worldOverlayPanSpeed2; + worldPanDir2 = extension.worldPanDir2; + worldPanDir2.Normalize(); + worldOverlayMat = MaterialPool.MatFrom(extension.overlayPath); + var mat = MatLoader.LoadMat(extension.copyPropertiesFrom); + worldOverlayMat.CopyPropertiesFromMaterial(mat); + worldOverlayMat.shader = mat.shader; + var texture = ContentFinder.Get(extension.overlayPath); + worldOverlayMat.SetTexture("_MainTex", texture); + worldOverlayMat.SetTexture("_MainTex2", texture); + } + base.TickOverlay(map); + } + } +}