diff --git a/1.4/Assemblies/ResearchWhatever.dll b/1.4/Assemblies/ResearchWhatever.dll
new file mode 100644
index 0000000..4d54c21
Binary files /dev/null and b/1.4/Assemblies/ResearchWhatever.dll differ
diff --git a/1.4/Patches/firefoxpdm.ResearchableStatUpgrades.xml b/1.4/Patches/firefoxpdm.ResearchableStatUpgrades.xml
new file mode 100644
index 0000000..1b37396
--- /dev/null
+++ b/1.4/Patches/firefoxpdm.ResearchableStatUpgrades.xml
@@ -0,0 +1,33 @@
+
+
+
+ Always
+
+ Defs/ResearchProjectDef[defName="StackingRepeatable"]/modExtensions
+
+ Defs/ResearchProjectDef[defName="StackingRepeatable"]/modExtensions
+
+
+
+ true
+
+
+
+
+
+
+
+ Always
+
+ Defs/ResearchProjectDef[defName="ProductivityRepeatable"]/modExtensions
+
+ Defs/ResearchProjectDef[defName="ProductivityRepeatable"]/modExtensions
+
+
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/About/About.xml b/About/About.xml
index 0effbef..df61278 100644
--- a/About/About.xml
+++ b/About/About.xml
@@ -4,6 +4,7 @@
avilmask
1.3
+ 1.4
none
avilmask.ResearchWhatever
diff --git a/Source/ResearchWhatever13/Properties/AssemblyInfo.cs b/Source/ResearchWhatever13/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f0cb499
--- /dev/null
+++ b/Source/ResearchWhatever13/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ResearchWhatever")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ResearchWhatever")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b08c8baf-9849-4317-b2be-639354820a7d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Source/ResearchWhatever13/packages.config b/Source/ResearchWhatever13/packages.config
new file mode 100644
index 0000000..9d48740
--- /dev/null
+++ b/Source/ResearchWhatever13/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Source/ResearchWhatever14/Patches/ResearchManagerPatch.cs b/Source/ResearchWhatever14/Patches/ResearchManagerPatch.cs
new file mode 100644
index 0000000..af2b45b
--- /dev/null
+++ b/Source/ResearchWhatever14/Patches/ResearchManagerPatch.cs
@@ -0,0 +1,37 @@
+using System.Linq;
+using System.Collections.Generic;
+using HarmonyLib;
+using RimWorld;
+using Verse;
+using Verse.Sound;
+
+namespace ResearchWhatever.Patches
+{
+ [HarmonyPatch(typeof(ResearchManager), "FinishProject")]
+ public static class ResearchManager_FinishProject_ResearchWhateverPatch
+ {
+ public static void Prefix(ResearchManager __instance, ref bool doCompletionDialog)
+ {
+ if (doCompletionDialog)
+ {
+ var comp = Current.Game.GetComponent();
+ if (comp.NotifyMode == ResearchWhateverNotifyMode.rwnDefault)
+ return;
+
+ doCompletionDialog = false;
+
+ switch (comp.NotifyMode)
+ {
+ case ResearchWhateverNotifyMode.rwnLetter:
+ Find.LetterStack.ReceiveLetter("ResearchFinished".Translate(__instance.currentProj.LabelCap), __instance.currentProj.description, LetterDefOf.PositiveEvent, null, null, null, null, null);
+ break;
+ case ResearchWhateverNotifyMode.rwnNotice:
+ Messages.Message("ResearchFinished".Translate(__instance.currentProj.LabelCap).CapitalizeFirst(), MessageTypeDefOf.SilentInput);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/Source/ResearchWhatever14/Patches/StaticConstructorOnStartupUtilityPatch.cs b/Source/ResearchWhatever14/Patches/StaticConstructorOnStartupUtilityPatch.cs
new file mode 100644
index 0000000..f9d3e31
--- /dev/null
+++ b/Source/ResearchWhatever14/Patches/StaticConstructorOnStartupUtilityPatch.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using Verse;
+using HarmonyLib;
+using System.Reflection;
+using RimWorld;
+
+
+namespace ResearchWhatever
+{
+ public static class StaticConstructorOnStartupUtility_Patch
+ {
+ //[HarmonyPatch(typeof(StaticConstructorOnStartupUtility), "CallAll")]
+ [HarmonyPatch]
+ public static class StaticConstructorOnStartupUtility_CallAll_ResearchWhateverPatch
+ {
+ internal static MethodBase TargetMethod()
+ {
+ MethodBase LCallAll = AccessTools.Method("BetterLoading.Stage.InitialLoad.StageRunStaticCctors:PreCallAll");
+ if (LCallAll == null)
+ {
+ LCallAll = AccessTools.Method("Verse.StaticConstructorOnStartupUtility:CallAll");
+ if (LCallAll == null)
+ throw new Exception("Couldn't find StaticConstructorOnStartupUtility.CallAll()");
+ }
+ else
+ Log.Message("[ResearchWhatever] BetterLoading detected, workaround initiated");
+ return LCallAll;
+ }
+ //
+ public static void Postfix()
+ {
+ List list = new List(
+ from x in DefDatabase.AllDefsListForReading
+ where x.thingClass == typeof(Building_ResearchBench) || x.thingClass != null && x.thingClass.IsSubclassOf(typeof(Building_ResearchBench))
+ select x);
+
+ if (list.NullOrEmpty())
+ return;
+ else
+ foreach (var thing in list)
+ {
+ thing?.comps?.Add(new CompProperties(typeof(ResearchWhateverComp)));
+ }
+ }
+ }
+ }
+}
diff --git a/Source/ResearchWhatever14/Patches/WorkGiver_ResearcherPatch.cs b/Source/ResearchWhatever14/Patches/WorkGiver_ResearcherPatch.cs
new file mode 100644
index 0000000..8781939
--- /dev/null
+++ b/Source/ResearchWhatever14/Patches/WorkGiver_ResearcherPatch.cs
@@ -0,0 +1,83 @@
+using System.Linq;
+using System.Collections.Generic;
+using HarmonyLib;
+using RimWorld;
+using Verse;
+using Verse.Sound;
+
+namespace ResearchWhatever.Patches
+{
+ [HarmonyPatch(typeof(WorkGiver_Researcher), "ShouldSkip")]
+ public static class WorkGiver_Researcher_ShouldSkip_ResearchWhateverPatch
+ {
+ public static bool Prefix(ref bool __result)
+ {
+ __result = false;
+ return false;
+ }
+ }
+
+ [HarmonyPatch(typeof(WorkGiver_Researcher), "PotentialWorkThingRequest", MethodType.Getter)]
+ public static class WorkGiver_PotentialWorkThingRequest_ResearchWhateverPatch
+ {
+ public static bool Prefix(ref ThingRequest __result)
+ {
+ __result = ThingRequest.ForGroup(ThingRequestGroup.ResearchBench);
+ return false;
+ }
+ }
+
+ [HarmonyPatch(typeof(WorkGiver_Researcher), "HasJobOnThing")]
+ public static class WorkGiver_Researcher_HasJobOnThing_ResearchWhateverPatch
+ {
+ private static bool hasFacilities(this Building_ResearchBench bench, List requiredFacilities)
+ {
+ if (requiredFacilities.NullOrEmpty()) return true;
+ CompAffectedByFacilities comp = bench.TryGetComp();
+ if (comp == null) return false;
+
+ foreach (var rf in requiredFacilities)
+ if (comp.LinkedFacilitiesListForReading.FirstOrDefault(x => x.def == rf && comp.IsFacilityActive(x)) == null)
+ return false;
+
+ return true;
+ }
+
+ public static void Prefix(Pawn pawn, Thing t, bool forced)
+ {
+ ResearchProjectDef currentProj = Find.ResearchManager.currentProj;
+ if (currentProj != null) return;
+ Building_ResearchBench bench = t as Building_ResearchBench;
+ if (bench == null) return;
+
+ ResearchWhateverComp comp = bench.TryGetComp();
+
+ if (comp == null || !comp.Active) return;
+
+ List projects = new List(
+ from x in DefDatabase.AllDefsListForReading
+ where Find.Storyteller.difficulty.AllowedBy(x.hideWhen)
+ && !x.IsFinished
+ && x.TechprintRequirementMet
+ && x.PrerequisitesCompleted
+ && (x.requiredResearchBuilding == null || x.requiredResearchBuilding == bench.def && bench.hasFacilities(x.requiredResearchFacilities))
+ && x.GetModExtension()?.ignore != true
+ select x);
+
+ if (projects.NullOrEmpty())
+ {
+ comp.Active = false;
+ Messages.Message("ResearchWhateverNothingLeftToResearch".Translate(bench.Label).CapitalizeFirst(), new TargetInfo(bench.Position, bench.Map, false), MessageTypeDefOf.NeutralEvent);
+ return;
+ }
+ projects.SortBy(x => x.GetModExtension()?.lowPriority == true ? 100000000f + x.CostApparent : x.CostApparent);
+
+ ResearchProjectDef def = projects.First();
+ projects.TryRandomElementByWeight(x => x.CostApparent == def.CostApparent ? 1f : 0f, out def);
+ SoundDefOf.ResearchStart.PlayOneShotOnCamera(null);
+ Find.ResearchManager.currentProj = def;
+ TutorSystem.Notify_Event("StartResearchProject");
+ Messages.Message( "ResearchWhateverNewResearch".Translate(pawn.Name.ToStringFull, def.label).CapitalizeFirst(), new TargetInfo(bench.Position, bench.Map, false), MessageTypeDefOf.SilentInput);
+ }
+ }
+}
diff --git a/Source/ResearchWhatever14/Properties/AssemblyInfo.cs b/Source/ResearchWhatever14/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f0cb499
--- /dev/null
+++ b/Source/ResearchWhatever14/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ResearchWhatever")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ResearchWhatever")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b08c8baf-9849-4317-b2be-639354820a7d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Source/ResearchWhatever14/ResearchWhatever.cs b/Source/ResearchWhatever14/ResearchWhatever.cs
new file mode 100644
index 0000000..78a9d65
--- /dev/null
+++ b/Source/ResearchWhatever14/ResearchWhatever.cs
@@ -0,0 +1,17 @@
+using HarmonyLib;
+using System.Reflection;
+using Verse;
+using RimWorld;
+
+namespace ResearchWhatever
+{
+ [StaticConstructorOnStartup]
+ public class ResearchWhatever : Mod
+ {
+ public ResearchWhatever(ModContentPack content) : base(content)
+ {
+ var harmony = new Harmony("net.avilmask.rimworld.mod.ResearchWhatever");
+ harmony.PatchAll(Assembly.GetExecutingAssembly());
+ }
+ }
+}
diff --git a/Source/ResearchWhatever14/ResearchWhatever.csproj b/Source/ResearchWhatever14/ResearchWhatever.csproj
new file mode 100644
index 0000000..37ee154
--- /dev/null
+++ b/Source/ResearchWhatever14/ResearchWhatever.csproj
@@ -0,0 +1,77 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B08C8BAF-9849-4317-B2BE-639354820A7D}
+ Library
+ Properties
+ ResearchWhatever
+ ResearchWhatever
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\1.4\Assemblies\
+ TRACE
+ prompt
+ 4
+
+
+
+ packages\Lib.Harmony.2.2.2\lib\net472\0Harmony.dll
+ False
+
+
+ ..\..\..\..\..\..\..\Games\steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll
+ False
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\..\..\..\Games\steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.dll
+ False
+
+
+ ..\..\..\..\..\..\..\Games\steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll
+ False
+
+
+ ..\..\..\..\..\..\..\Games\steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/ResearchWhatever14/ResearchWhateverComp.cs b/Source/ResearchWhatever14/ResearchWhateverComp.cs
new file mode 100644
index 0000000..4402217
--- /dev/null
+++ b/Source/ResearchWhatever14/ResearchWhateverComp.cs
@@ -0,0 +1,76 @@
+using System.Collections.Generic;
+using Verse;
+using RimWorld;
+using UnityEngine;
+
+namespace ResearchWhatever
+{
+ public class ResearchWhateverComp : ThingComp
+ {
+ public bool Active
+ {
+ get { return parent?.Faction == Faction.OfPlayer && active; }
+ set { if (value == active) return; active = value; }
+ }
+
+ public override void PostExposeData()
+ {
+ Scribe_Values.Look(ref active, "active", true, false);
+ }
+
+ public override IEnumerable CompGetGizmosExtra()
+ {
+ if (parent?.Faction != Faction.OfPlayer)
+ yield break;
+ //
+ Command_Toggle command_Toggle = new Command_Toggle();
+ command_Toggle.hotKey = KeyBindingDefOf.Command_TogglePower;
+ command_Toggle.defaultLabel = "CommandResearchWhateverToggleLabel".Translate();
+ command_Toggle.icon = TexCommand.OpenLinkedQuestTex;
+ command_Toggle.isActive = (() => active);
+ command_Toggle.toggleAction = delegate ()
+ {
+ if (Event.current.button == 0)
+ Active = !Active;
+ else if (Event.current.button == 1)
+ {
+ var comp = Current.Game.GetComponent();
+ //var lable = Mute ? "CommandResearchWhateverToggleMute".Translate().CapitalizeFirst() : "CommandResearchWhateverToggleUnmute".Translate().CapitalizeFirst();
+ List list = new List();
+ list.Add(new FloatMenuOption("CommandResearchWhateverToggleDefault".Translate().CapitalizeFirst(), delegate ()
+ {
+ comp.NotifyMode = ResearchWhateverNotifyMode.rwnDefault;
+ }));
+ list.Add(new FloatMenuOption("CommandResearchWhateverToggleLetter".Translate().CapitalizeFirst(), delegate ()
+ {
+ comp.NotifyMode = ResearchWhateverNotifyMode.rwnLetter;
+ }));
+ list.Add(new FloatMenuOption("CommandResearchWhateverToggleNotice".Translate().CapitalizeFirst(), delegate ()
+ {
+ comp.NotifyMode = ResearchWhateverNotifyMode.rwnNotice;
+ }));
+ list.Add(new FloatMenuOption("CommandResearchWhateverToggleMute".Translate().CapitalizeFirst(), delegate ()
+ {
+ comp.NotifyMode = ResearchWhateverNotifyMode.rwnMute;
+ }));
+ FloatMenu floatMenu = new FloatMenu(list);
+ floatMenu.vanishIfMouseDistant = true;
+ Find.WindowStack.Add(floatMenu);
+ }
+ };
+ if (Active)
+ {
+ command_Toggle.defaultDesc = "CommandResearchWhateverToggleDescActive".Translate();
+ }
+ else
+ {
+ command_Toggle.defaultDesc = "CommandResearchWhateverToggleDescInactive".Translate();
+ }
+ yield return command_Toggle;
+ yield break;
+ }
+
+ private bool active = true;
+ }
+
+}
diff --git a/Source/ResearchWhatever14/ResearchWhateverExtansion.cs b/Source/ResearchWhatever14/ResearchWhateverExtansion.cs
new file mode 100644
index 0000000..2990846
--- /dev/null
+++ b/Source/ResearchWhatever14/ResearchWhateverExtansion.cs
@@ -0,0 +1,10 @@
+using Verse;
+
+namespace ResearchWhatever
+{
+ public class ResearchWhateverExtansion : DefModExtension
+ {
+ public bool ignore = false;
+ public bool lowPriority = false;
+ }
+}
diff --git a/Source/ResearchWhatever14/ResearchWhateverGameComp.cs b/Source/ResearchWhatever14/ResearchWhateverGameComp.cs
new file mode 100644
index 0000000..de246e8
--- /dev/null
+++ b/Source/ResearchWhatever14/ResearchWhateverGameComp.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using System.Linq;
+using Verse;
+using RimWorld;
+
+namespace ResearchWhatever
+{
+ public enum ResearchWhateverNotifyMode { rwnDefault, rwnLetter, rwnNotice, rwnMute }
+ public class ResearchWhateverGameComp : GameComponent
+ {
+ public ResearchWhateverGameComp()
+ {
+ }
+ public ResearchWhateverGameComp(Game game)
+ {
+ }
+ public override void ExposeData()
+ {
+ Scribe_Values.Look(ref notifyMode, "NotifyMode");
+ }
+ private ResearchWhateverNotifyMode notifyMode = ResearchWhateverNotifyMode.rwnDefault;
+ public ResearchWhateverNotifyMode NotifyMode { get { return notifyMode; } set { notifyMode = value; } }
+ }
+}
diff --git a/Source/ResearchWhatever14/packages.config b/Source/ResearchWhatever14/packages.config
new file mode 100644
index 0000000..12b970f
--- /dev/null
+++ b/Source/ResearchWhatever14/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/change.log b/change.log
index c4c400c..b2dbd2a 100644
--- a/change.log
+++ b/change.log
@@ -1,4 +1,7 @@
-1.0.4
+1.0.5
+- 1.4 aye;
+
+1.0.4
- now you can r-click on the toggle to mute completion notifications;
1.0.3