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);
+ }
+ }
+}