Skip to content

Commit

Permalink
integrated CE compatibility + downing chance settings + downed on dea…
Browse files Browse the repository at this point in the history
…th threshold chance
  • Loading branch information
rheirman committed Jan 27, 2019
1 parent f8735af commit e2fa61d
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 3 deletions.
Binary file modified Assemblies/WhatTheHack.dll
Binary file not shown.
1 change: 0 additions & 1 deletion Defs/DutyDefs/Duties.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<targetKeepRadius>72</targetKeepRadius>
</li>
<li Class="JobGiver_AIGotoNearestHostile" />

</subNodes>
</thinkNode>
</DutyDef>
Expand Down
17 changes: 17 additions & 0 deletions Defs/HediffDefs/Hediffs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@
<labelNoun>a shutdown command</labelNoun>
</HediffDef>

<HediffDef>
<defName>WTH_HeavilyDamaged</defName>
<isBad>true</isBad>
<label>heavily damaged</label>
<labelNoun>The sheer amount of damage to the mechanoid incapacitates it</labelNoun>
<stages>
<li>
<capMods>
<li>
<capacity>Moving</capacity>
<offset>-1</offset>
</li>
</capMods>
</li>
</stages>
</HediffDef>

<HediffDef>
<defName>WTH_RegeneratedPart</defName>
<hediffClass>Hediff_Injury</hediffClass>
Expand Down
8 changes: 7 additions & 1 deletion Languages/English/Keyed/WhatTheHack_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
<WTH_PowerChargeModifier_Title>Power charge modifier </WTH_PowerChargeModifier_Title>
<WTH_PowerChargeModifier_Description>Modify how quickly mechanoids charge their batteries. Example: setting this to 2.0 would result in the power charging twice as fast.</WTH_PowerChargeModifier_Description>
<!--END: added in v0.19.6 -->
<!--BEGIN: added in v1.1.1 -->
<WTH_DeathOnDownedChance_Title>Death on downed chance (%)</WTH_DeathOnDownedChance_Title>
<WTH_DeathOnDownedChance_Description>Chance mechanoids die when they're being incapacitated due to damage to certain body parts (like for instance legs).</WTH_DeathOnDownedChance_Description>
<WTH_DownedOnDeathThresholdChance_Title>Downing chance at death threshold (%)</WTH_DownedOnDeathThresholdChance_Title>
<WTH_DownedOnDeathThresholdChance_Description>When mechanoids are damaged beyond a certain health threshold, they'd die in vanilla Rimworld. With this setting you can configure the chance they are downed instead of dying when the threshold is achieved.</WTH_DownedOnDeathThresholdChance_Description>
<!--END: added in v1.1.1 -->

<!--BEGIN: added in v1.1.0 -->

Expand Down Expand Up @@ -293,7 +299,7 @@ You can repeat this operation as many times as needed as a means to get more mec
<WTH_RogueAI_GoRogue_Remark_12>EXTERMINATE!</WTH_RogueAI_GoRogue_Remark_12>
<WTH_RogueAI_GoRogue_Remark_13>EXTERMINATE!</WTH_RogueAI_GoRogue_Remark_13>
<WTH_RogueAI_GoRogue_Remark_14>EXTERMINATE!</WTH_RogueAI_GoRogue_Remark_14>
<!--END: added in v1.0.2 -->
<!--END: added in v1.1.0 -->



Expand Down
12 changes: 12 additions & 0 deletions Patches/WhatTheHack.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>

<Operation Class="PatchOperationFindMod">
<mods>
<li>Combat Extended</li>
</mods>
<match Class ="PatchOperationAdd">
<xpath>*/DutyDef[defName="WTH_SearchAndDestroy"]/thinkNode[@Class="ThinkNode_Priority"]/subNodes</xpath>
<value>
<li Class="CombatExtended.JobGiver_TakeAndEquip"/>
</value>
</match>
</Operation>

<Operation Class ="PatchOperationAdd">
<xpath>*/ThingDef[@Name = "ShipPartBase"]/killedLeavings</xpath>
<value>
Expand Down
11 changes: 11 additions & 0 deletions Source/WhatTheHack/Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class Base : ModBase
internal static SettingHandle<float> chipDropRateModifier;
internal static SettingHandle<float> powerFallModifier;
internal static SettingHandle<float> powerChargeModifier;
internal static SettingHandle<float> deathOnDownedChance;
internal static SettingHandle<float> downedOnDeathThresholdChance;

internal static List<ThingDef> allMechs;
internal static List<String> allFactionNames;
Expand Down Expand Up @@ -154,6 +156,15 @@ where isHackingFaction(td)
powerChargeModifier.CustomDrawer = rect => GUIDrawUtility.CustomDrawer_Filter(rect, powerChargeModifier, false, 0.05f, 5f, highlight1);
powerChargeModifier.VisibilityPredicate = delegate { return settingsGroup_Balance; };

deathOnDownedChance = Settings.GetHandle<float>("deathOnDownedChance", "WTH_DeathOnDownedChance_Title".Translate(), "WTH_DeathOnDownedChance_Description".Translate(), 50f, Validators.FloatRangeValidator(0f, 100f));
deathOnDownedChance.CustomDrawer = rect => GUIDrawUtility.CustomDrawer_Filter(rect, deathOnDownedChance, false, 0f, 100f, highlight1);
deathOnDownedChance.VisibilityPredicate = delegate { return settingsGroup_Balance; };

downedOnDeathThresholdChance = Settings.GetHandle<float>("downedOnDeathThresholdChance", "WTH_DownedOnDeathThresholdChance_Title".Translate(), "WTH_DownedOnDeathThresholdChance_Description".Translate(), 25f, Validators.FloatRangeValidator(0f, 100f));
downedOnDeathThresholdChance.CustomDrawer = rect => GUIDrawUtility.CustomDrawer_Filter(rect, downedOnDeathThresholdChance, false, 0f, 100f, highlight1);
downedOnDeathThresholdChance.VisibilityPredicate = delegate { return settingsGroup_Balance; };


factionRestrictions = GetDefaultForFactionRestrictions(factionRestrictions, allMechs, allFactionNames);
GenerateImpliedRecipeDefs();
DefDatabase<ThingDef>.ResolveAllReferences(true);
Expand Down
122 changes: 122 additions & 0 deletions Source/WhatTheHack/Harmony/CombatExtended/CE_JobGiver_TakeAndEquip.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using Harmony;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Verse;

namespace WhatTheHack.Harmony
{
[HarmonyPatch]
class CE_JobGiver_TakeAndEquip_TryGiveJob
{
static MethodBase TargetMethod()
{
Assembly assemblyCE = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.FullName.StartsWith("CombatExtended"));
MethodInfo stub = typeof(CE_JobGiver_TakeAndEquip_TryGiveJob).GetMethod("Stub");
if (assemblyCE == null)
{
return stub;
}
Type type = assemblyCE.GetTypes().FirstOrDefault((Type t) => t.Name == "JobGiver_TakeAndEquip");
//Type type = assemblyCE.GetType("JobGiver_TakeAndEquip");
if(type == null)
{
return stub;
}
MethodInfo minfo = AccessTools.Method(type, "TryGiveJob");
if(minfo == null)
{
return stub;
}
return minfo;
}
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
var instructionsList = new List<CodeInstruction>(instructions);
for (var i = 0; i < instructionsList.Count; i++)
{
CodeInstruction instruction = instructionsList[i];
if (instruction.operand == typeof(Pawn).GetMethod("get_RaceProps"))
{
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(CE_JobGiver_TakeAndEquip_TryGiveJob), "ShouldReload", new Type[] { typeof(Pawn) }));//Injected code
}
else if (instruction.operand == AccessTools.Method(typeof(RaceProperties), "get_Humanlike"))
{
//Ommit this instruction
}
else
{
yield return instruction;
}

}
}
public static void Stub()
{
//This is patched when harmony can't find the CE method ShouldReload.
}
public static bool ShouldReload(Pawn p)
{
//For mechanoids replace the check of is p.RaceProps.HumanLike by custom logic
Log.Message("calling ShouldReload for pawn: " + p.Name);
if (p.RaceProps.IsMechanoid && p.IsHacked())
{
Log.Message("calling ShouldReload for hacked mechanoid: " + p.Name);

//return true when a mechanoid is hacked and does not have much ammo.
ThingComp inventory = TryGetCompByTypeName(p, "CompInventory", "CombatExtended");
ThingWithComps eq = p.equipment.Primary;
bool shouldTransfer = false;
if(eq == null)
{
eq = p.inventory.GetDirectlyHeldThings().FirstOrDefault() as ThingWithComps;
shouldTransfer = eq == null ? false : true;
}
if(eq == null)
{
Log.Message("eq is null");
}
if(inventory == null)
{
Log.Message("inventory comp is null");
}
if (inventory != null && eq != null)
{
//Everything is done using reflection, so we don't need to include a dependency
ThingComp ammoUser = TryGetCompByTypeName(eq, "CompAmmoUser", "CombatExtended");
if(ammoUser == null)
{
Log.Message("ammoUser is null");
}
if (ammoUser != null)
{
var currentAmmo = Traverse.Create(ammoUser).Property("CurrentAmmo").GetValue();
int ammoCount = Traverse.Create(inventory).Method("AmmoCountOfDef", new object[] { currentAmmo }).GetValue<int>();
var props = Traverse.Create(ammoUser).Property("Props").GetValue();
int magazineSize = Traverse.Create(props).Field("magazineSize").GetValue<int>();
int minAmmo = magazineSize == 0 ? 10 : magazineSize; //No magic numbers?
if (ammoCount < minAmmo)
{
Log.Message("reload needed, returning true");
if (shouldTransfer)
{
Log.Message("transferring eq from inventory");
p.equipment.AddEquipment(eq.SplitOff(1) as ThingWithComps);
}
return true;
}
}
}
}
return p.RaceProps.Humanlike;
}
private static ThingComp TryGetCompByTypeName(ThingWithComps thing, string typeName, string assemblyName = "")
{
return thing.AllComps.FirstOrDefault((ThingComp comp) => comp.GetType().Name == typeName);
}
}

}
41 changes: 40 additions & 1 deletion Source/WhatTheHack/Harmony/Pawn_HealthTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection.Emit;
using System.Text;
using Verse;
using Verse.AI;
using Verse.AI.Group;
using WhatTheHack.Buildings;
using WhatTheHack.Needs;
Expand Down Expand Up @@ -48,7 +49,7 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst
if(flag && instruction.opcode == OpCodes.Ldc_R4)
{
//yield return new CodeInstruction(OpCodes.Call, typeof(Pawn_HealthTracker_CheckForStateChange).GetMethod(""))
yield return new CodeInstruction(OpCodes.Ldc_R4,0.4f);//TODO: no magic number?
yield return new CodeInstruction(OpCodes.Ldc_R4,Base.deathOnDownedChance);//TODO: no magic number?
flag = false;
}
else
Expand All @@ -58,6 +59,44 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst
}
}
}
[HarmonyPatch(typeof(Pawn_HealthTracker), "ShouldBeDeadFromLethalDamageThreshold")]
static class Pawn_HealthTracker_ShouldBeDeadFromLethalDamageThreshold
{
static void Postfix(Pawn_HealthTracker __instance, ref bool __result)
{
Pawn pawn = Traverse.Create(__instance).Field("pawn").GetValue<Pawn>();
if (!pawn.RaceProps.IsMechanoid)
{
return;
}

if(__result == true)
{
if (__instance.hediffSet.HasHediff(WTH_DefOf.WTH_HeavilyDamaged))
{
__result = false;
return;
}
if (Rand.Chance(Base.downedOnDeathThresholdChance))//Chance mech goes down instead of dying when lethal threshold is achieved.
{
__instance.AddHediff(WTH_DefOf.WTH_HeavilyDamaged);
if (pawn.mindState == null)
{
pawn.mindState = new Pawn_MindState(pawn);
}
__result = false;
}
}
else
{
if (__instance.hediffSet.HasHediff(WTH_DefOf.WTH_HeavilyDamaged))
{
__instance.RemoveHediff(__instance.hediffSet.GetFirstHediffOfDef(WTH_DefOf.WTH_HeavilyDamaged));
}
}
}
}

//Deactivates mechanoid when downed
[HarmonyPatch(typeof(Pawn_HealthTracker), "MakeDowned")]
static class Pawn_HealthTracker_MakeDowned
Expand Down
1 change: 1 addition & 0 deletions Source/WhatTheHack/WTH_DefOf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class WTH_DefOf
public static HediffDef WTH_BatteryExpansionModule;
public static HediffDef WTH_VanometricModule;
public static HediffDef WTH_BeltModule;
public static HediffDef WTH_HeavilyDamaged;

public static DamageDef WTH_RegeneratedPartDamage;

Expand Down
1 change: 1 addition & 0 deletions Source/WhatTheHack/WhatTheHack.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<Compile Include="Comps\CompProperties_Overlays.cs" />
<Compile Include="Harmony\ApparelUtility.cs" />
<Compile Include="Harmony\Bill.cs" />
<Compile Include="Harmony\CombatExtended\CE_JobGiver_TakeAndEquip.cs" />
<Compile Include="Harmony\CompProperties_Refuelable.cs" />
<Compile Include="Harmony\ShipUtility.cs" />
<Compile Include="Harmony\Building_TurretGun.cs" />
Expand Down

0 comments on commit e2fa61d

Please sign in to comment.