Skip to content

Commit

Permalink
V4.0 fixes settings handling, adds ZombielandSupport class handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pardeike committed May 15, 2023
1 parent ba48675 commit 5299cb7
Show file tree
Hide file tree
Showing 21 changed files with 188 additions and 95 deletions.
2 changes: 1 addition & 1 deletion About/Manifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Manifest>
<identifier>net.pardeike.rimworld.mod.zombieland</identifier>
<version>3.10.0.0</version>
<version>4.0.0.0</version>
<targetVersions>
<li>1.4.0</li>
</targetVersions>
Expand Down
Binary file modified Assemblies/ZombieLand.dll
Binary file not shown.
1 change: 1 addition & 0 deletions Languages/English/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@

<ZombieActionsTitle>Actions</ZombieActionsTitle>
<ZombieSettingsReset>Restore default settings</ZombieSettingsReset>
<FactoryResetButton>Factory Reset</FactoryResetButton>
<ResetButton>Reset</ResetButton>
<UninstallZombieland>Remove Zombieland from current game</UninstallZombieland>
<ConfirmUninstallZombieland>If you continue, you can choose a new save file name and you will return to the main menu after the game is saved. The new save can be loaded without Zombieland.\n\nDo you really want to remove all Zombieland content from the current game?</ConfirmUninstallZombieland>
Expand Down
3 changes: 0 additions & 3 deletions Source/BrainzThought.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ZombieLand
{
Expand Down
1 change: 0 additions & 1 deletion Source/CETools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ static MethodBase TargetMethod()

static bool Prefix(Building_Turret ___turret, ref bool __result)
{
Log.Warning($"TryReduceAmmoCount {___turret}");
if (___turret == null)
return true;
if (Rand.Chance(ZombieSettings.Values.reducedTurretConsumption))
Expand Down
3 changes: 0 additions & 3 deletions Source/Chainsaw.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,7 @@ public override void Tick()
swinging = true;
inactiveCounter = 0;
if (angle == -1f)
{
angle = pawn.Rotation.AsAngle;
Log.Warning($"angle set to rotation {angle}");
}

var idx = (int)angle / 45;
var things = affectedCells[idx].Where(victim => (pawn.DrawPos - victim.DrawPos).MagnitudeHorizontalSquared() <= 2f);
Expand Down
1 change: 0 additions & 1 deletion Source/ColorData.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using UnityEngine;

namespace ZombieLand
Expand Down
78 changes: 78 additions & 0 deletions Source/Customization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Verse;

namespace ZombieLand
{
// To support Zombieland in your mod, define a class called ZombielandSupport (no namespace!) in your mod and add the following:

// public static bool? CanBecomeZombie(Pawn pawn)
// If defined, this method will be called to determine if a pawn can become a zombie
// You are supposed to return true if the pawn can become a zombie, false if not and null if you don't care

// public static bool? AttractsZombies(Pawn pawn)
// If defined, this method will be called to determine if zombies are attracted to a pawn or ignore the pawn
// You are supposed to return true if the pawn attracts zombies, false if not and null if you don't care

public class Customization
{
private delegate bool CanBecomeZombie(Pawn pawn);
private delegate bool AttractsZombies(Pawn pawn);

private static readonly List<CanBecomeZombie> canBecomeZombieEvaluators = new();
private static readonly List<AttractsZombies> attractsZombiesEvaluators = new();

public static void Init()
{
MethodInfo method;
AppDomain.CurrentDomain.GetAssemblies()
.Select(asm => asm.GetType("ZombielandSupport", false))
.OfType<Type>()
.Do(type =>
{
method = AccessTools.Method(type, nameof(CanBecomeZombie));
if (method == null)
return;
var canBecomeZombie = (CanBecomeZombie)Delegate.CreateDelegate(typeof(CanBecomeZombie), method, false);
if (canBecomeZombie != null)
canBecomeZombieEvaluators.Add(canBecomeZombie);
method = AccessTools.Method(type, nameof(AttractsZombies));
if (method == null)
return;
var attractsZombies = (AttractsZombies)Delegate.CreateDelegate(typeof(AttractsZombies), method, false);
if (attractsZombies != null)
attractsZombiesEvaluators.Add(attractsZombies);
});
}

public static bool CannotBecomeZombie(Pawn pawn)
{
return canBecomeZombieEvaluators.Count > 0 && canBecomeZombieEvaluators.Any(evaluator => evaluator(pawn) == false);
}

public static bool DoesAttractsZombies(Pawn pawn)
{
if (pawn == null) return false;
if (pawn is Zombie) return false;
if (pawn.Spawned == false) return false;
if (pawn.Dead) return false;
if (pawn.health.Downed) return false;
if (pawn.RaceProps.IsFlesh == false) return false;
if (AlienTools.IsFleshPawn(pawn) == false) return false;
if (SoSTools.IsHologram(pawn)) return false;
if (pawn.InfectionState() >= InfectionState.Infecting) return false;
if (attractsZombiesEvaluators.Count > 0 && attractsZombiesEvaluators.Any(evaluator => evaluator(pawn) == false)) return false;
return ZombieSettings.Values.attackMode switch
{
AttackMode.Everything => true,
AttackMode.OnlyHumans => pawn.RaceProps.Humanlike,
AttackMode.OnlyColonists => pawn.RaceProps.Humanlike && pawn.IsColonist,
_ => false,
};
}
}
}
4 changes: 2 additions & 2 deletions Source/DialogTimeHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static Rect Draw(ref List<SettingsKeyFrame> settingsOverTime, Rect inRect
var vOffset = inRect.yMin;
var width = (int)inRect.width - 26; // scrollbar space
var n = settingsOverTime.Count;
if (n == 1 && selectedKeyframe == -1)
selectedKeyframe = 0;
if (selectedKeyframe >= n)
selectedKeyframe = n - 1;

var availableWidth = width - labelWidth * n;
var spacing = n == 1 ? 0 : availableWidth / (n - 1);
Expand Down
2 changes: 2 additions & 0 deletions Source/Dialog_ZombieDebugActionMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ private static void ApplyAddZombieBite()

var def = HediffDef.Named("ZombieBite");
var bite = (Hediff_Injury_ZombieBite)HediffMaker.MakeHediff(def, pawn, bodyPart);
if (bite.TendDuration?.ZombieInfector == null)
continue;

bite.mayBecomeZombieWhenDead = true;
bite.TendDuration.ZombieInfector.MakeHarmfull();
Expand Down
6 changes: 4 additions & 2 deletions Source/Gizmos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ public static Gizmo ZombieAvoidance(Pawn pawn)
var autoAvoidZombies = config.autoAvoidZombies;
var description = autoAvoidZombies ? "AutoAvoidZombiesEnabledDescription" : "AutoAvoidZombiesDisabledDescription";

var doesAttract = Customization.DoesAttractsZombies(pawn);
return new Command_Action
{
disabled = doesAttract == false,
defaultDesc = description.Translate(),
icon = autoAvoidZombies ? AvoidingEnabled : AvoidingDisabled,
icon = autoAvoidZombies && doesAttract ? AvoidingEnabled : AvoidingDisabled,
activateSound = autoAvoidZombies ? SoundDefOf.Designate_ZoneAdd : SoundDefOf.Designate_ZoneDelete,
action = config.ToggleAutoAvoidZombies
action = doesAttract ? config.ToggleAutoAvoidZombies : null
};
}

Expand Down
3 changes: 3 additions & 0 deletions Source/HediffComp_Zombie_Infecter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public override void CompPostPostAdd(DamageInfo? dinfo)
|| parent.Part.def == null)
return;

if (Customization.CannotBecomeZombie(pawn))
return;

if (parent.Part.def.IsSolid(parent.Part, pawn.health.hediffSet.hediffs))
return;
if (pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(parent.Part))
Expand Down
3 changes: 3 additions & 0 deletions Source/HediffComp_Zombie_TendDuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public HediffComp_Zombie_Infecter ZombieInfector
if (SoSTools.IsHologram(pawn))
return null;

if (Customization.CannotBecomeZombie(pawn))
return null;

_zombieInfector = parent.comps
.OfType<HediffComp_Zombie_Infecter>()
.FirstOrDefault();
Expand Down
2 changes: 2 additions & 0 deletions Source/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public ZombielandMod(ModContentPack content) : base(content)
LongEventHandler.ExecuteWhenFinished(() =>
{
_ = GetSettings<ZombieSettingsDefaults>();
if (ZombieSettingsDefaults.group == null)
Tools.ResetSettings();
IsLoadingDefaults = false;
});

Expand Down
52 changes: 31 additions & 21 deletions Source/Patches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static Patches()
{
CETools.Init(harmony);
AlienTools.Init();
Customization.Init();
});

// for debugging
Expand Down Expand Up @@ -2388,7 +2389,7 @@ static void Prefix(Thing __instance, IntVec3 value)
}

// leave pheromone trail
if (pawn.InfectionState() < InfectionState.Infecting)
if (pawn.InfectionState() < InfectionState.Infecting && Customization.DoesAttractsZombies(pawn))
{
var now = Tools.Ticks();
var radius = Tools.RadiusForPawn(pawn);
Expand Down Expand Up @@ -4472,33 +4473,42 @@ static void Prefix(Pawn __instance)
}

var pawn = __instance;
var raceProps = pawn.RaceProps;

if (pawn.RaceProps.Humanlike)
{
var hediffSet = pawn.health.hediffSet;
if (raceProps.Humanlike == false || raceProps.IsFlesh == false)
return;

if (AlienTools.IsFleshPawn(pawn) == false || SoSTools.IsHologram(pawn))
return;

if (Customization.CannotBecomeZombie(pawn))
return;

var hediffSet = pawn.health?.hediffSet;
if (hediffSet == null)
return;

// flag zombie bites to be infectious when pawn dies
pawn.GetHediffsList<Hediff_Injury_ZombieBite>()
.Where(zombieBite => zombieBite.TendDuration.GetInfectionState() >= InfectionState.BittenInfectable)
.Do(zombieBite => zombieBite.mayBecomeZombieWhenDead = true);
// flag zombie bites to be infectious when pawn dies
pawn.GetHediffsList<Hediff_Injury_ZombieBite>()
.Where(zombieBite => zombieBite.TendDuration.GetInfectionState() >= InfectionState.BittenInfectable)
.Do(zombieBite => zombieBite.mayBecomeZombieWhenDead = true);

// if death means becoming a zombie, install zombie infection
if (ZombieSettings.Values.hoursAfterDeathToBecomeZombie > -1)
// if death means becoming a zombie, install zombie infection
if (ZombieSettings.Values.hoursAfterDeathToBecomeZombie > -1)
{
try
{
try
{
var brain = hediffSet.GetBrain();
if (brain != null)
{
var hediff = HediffMaker.MakeHediff(CustomDefs.ZombieInfection, pawn, brain) as Hediff_ZombieInfection;
hediff.InitializeExpiringDate();
hediffSet.AddDirect(hediff, null, null);
}
}
catch
var brain = hediffSet.GetBrain();
if (brain != null)
{
var hediff = HediffMaker.MakeHediff(CustomDefs.ZombieInfection, pawn, brain) as Hediff_ZombieInfection;
hediff.InitializeExpiringDate();
hediffSet.AddDirect(hediff, null, null);
}
}
catch
{
}
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions Source/SettingsDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace ZombieLand
{
static class SettingsDialog
{
public static readonly float totalEstimatedHeight = 3700f;
public static Vector2 scrollPosition = Vector2.zero;

public static void DoWindowContentsInternal(ref SettingsGroup settings, ref List<SettingsKeyFrame> settingsOverTime, Rect inRect)
Expand All @@ -19,15 +20,14 @@ public static void DoWindowContentsInternal(ref SettingsGroup settings, ref List
var secondColumnWidth = inRect.width - Listing.ColumnSpacing - firstColumnWidth;

var outerRect = new Rect(inRect.x, inRect.y, firstColumnWidth, inRect.height);
var innerRect = new Rect(0f, 0f, firstColumnWidth - 24f, 3600);
var innerRect = new Rect(0f, 0f, firstColumnWidth - 24f, totalEstimatedHeight);

outerRect = DialogTimeHeader.Draw(ref settingsOverTime, outerRect);

Widgets.BeginScrollView(outerRect, ref scrollPosition, innerRect, true);

DialogExtensions.ResetHelpItem();
var headerColor = Color.yellow;
var inGame = Current.Game != null && Current.ProgramState == ProgramState.Playing;

var list = new Listing_Standard();
list.Begin(innerRect);
Expand Down Expand Up @@ -304,8 +304,9 @@ public static void DoWindowContentsInternal(ref SettingsGroup settings, ref List
{
list.Dialog_Label("ZombieActionsTitle", headerColor);
list.Gap(8f);
list.Dialog_Button("ZombieSettingsReset", "ResetButton", false, settings.Reset);
if (inGame)
var resetTitle = Tools.OnMainScreen() ? "FactoryResetButton" : "ResetButton";
list.Dialog_Button("ZombieSettingsReset", resetTitle, false, Tools.ResetSettings);
if (Current.ProgramState == ProgramState.Playing)
list.Dialog_Button("UninstallZombieland", "UninstallButton", true, Dialog_SaveThenUninstall.Run);
}
}
Expand Down Expand Up @@ -376,7 +377,7 @@ public static void DoWindowContentsInternal(ref SettingsGroup settings, ref List
DialogExtensions.shouldFocusNow = null;
}

if (Current.ProgramState == ProgramState.Playing)
if (Tools.OnMainScreen() == false)
{
var ticks = Find.TickManager.TicksGame;
ZombieSettings.Values = ZombieSettings.CalculateInterpolation(ZombieSettings.ValuesOverTime, ticks);
Expand Down
31 changes: 26 additions & 5 deletions Source/Tools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,27 @@ public static void EnableTwinkie(bool enable)
.Do(meal => meal.graphicInt = null);
}

public static bool OnMainScreen() => Current.Game == null;

public static void ResetSettings()
{
if (OnMainScreen())
{
ZombieSettingsDefaults.group = new();
ZombieSettingsDefaults.groupOverTime = new() { new() { values = ZombieSettingsDefaults.group.MakeCopy() } };
}
else
{
ZombieSettings.Values = ZombieSettingsDefaults.group.MakeCopy();
ZombieSettings.ValuesOverTime = ZombieSettingsDefaults.groupOverTime.Select(kf => kf.Copy()).ToList();
}

SettingsDialog.scrollPosition = Vector2.zero;
DialogTimeHeader.Reset();
DialogExtensions.shouldFocusNow = DialogExtensions.searchWidget.controlName;
DialogExtensions.searchWidget.Reset();
}

public static bool IsBroken(this Thing t)
{
var compBreakable = t.TryGetComp<CompBreakable>();
Expand Down Expand Up @@ -278,10 +299,7 @@ public static bool ShouldAvoidZombies(Pawn pawn = null)
if (pawn == null)
return ZombieSettings.Values.betterZombieAvoidance;

if (pawn is Zombie || pawn.RaceProps.Humanlike == false)
return false;

if (pawn.InfectionState() == InfectionState.Infecting)
if (Customization.DoesAttractsZombies(pawn) == false)
return false;

if (pawn.IsColonist == false)
Expand Down Expand Up @@ -524,6 +542,9 @@ public static void ConvertToZombie(ThingWithComps thing, Map map, bool force = f
|| SoSTools.IsHologram(pawn))
return;

if (Customization.CannotBecomeZombie(pawn))
return;

var wasPlayer = pawn.Faction?.IsPlayer ?? false;
var pawnName = pawn.Name;
if (force == false && (pawn.health == null || pawnName == emptyName))
Expand Down Expand Up @@ -806,7 +827,7 @@ public static bool Attackable(Zombie zombie, AttackMode mode, Thing thing)

if (thing is Pawn target)
{
if (target.Dead || target.health.Downed)
if (Customization.DoesAttractsZombies(target) == false)
return false;
if (target.equipment?.Primary is Chainsaw chainsaw && chainsaw.running && zombie.IsActiveElectric == false)
return Rand.Chance(chainsaw.CounterHitChance());
Expand Down
1 change: 0 additions & 1 deletion Source/ZombieGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using UnityEngine;
using Verse;
using Verse.AI;
using Verse.Noise;
using static ZombieLand.Patches;

namespace ZombieLand
Expand Down
2 changes: 1 addition & 1 deletion Source/ZombieLand.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<OutputPath>..\1.4\Assemblies\</OutputPath>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<Version>3.10.0.0</Version>
<Version>4.0.0.0</Version>
<Copyright>Copyright © 2017</Copyright>
<Configurations>Release;Debug</Configurations>
</PropertyGroup>
Expand Down
Loading

0 comments on commit 5299cb7

Please sign in to comment.