Skip to content

Commit

Permalink
v1.16.4 fixes a raging bug with certain configurations. Now zombies r…
Browse files Browse the repository at this point in the history
…age properly and you can control the rage level in the settings
  • Loading branch information
pardeike committed Sep 7, 2019
1 parent 43e08cc commit 3565c04
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 39 deletions.
Binary file modified Assemblies/ZombieLand.dll
Binary file not shown.
6 changes: 6 additions & 0 deletions Languages/ChineseSimplified/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
<ZombieInstinct_Normal>正常</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>较高</ZombieInstinct_Sensitive>
<RagingZombies>群体过于庞大时丧尸会变得愤怒。</RagingZombies>
<RageLevel>愤怒程度</RageLevel>
<RageLevelVeryLow>非常低的水平</RageLevelVeryLow>
<RageLevelLow>低水平</RageLevelLow>
<RageLevelNormal>正常水平</RageLevelNormal>
<RageLevelHigh>高水平</RageLevelHigh>
<RageLevelVeryHigh>非常高的水平</RageLevelVeryHigh>

<ZombieHealthTitle>丧尸的体质</ZombieHealthTitle>
<DoubleTapRequired>丧尸会恢复伤势</DoubleTapRequired>
Expand Down
6 changes: 6 additions & 0 deletions Languages/ChineseTraditional/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
<ZombieInstinct_Normal>正常</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>較高</ZombieInstinct_Sensitive>
<RagingZombies>群體過於龐大時殭屍會變得憤怒。</RagingZombies>
<RageLevel>憤怒程度</RageLevel>
<RageLevelVeryLow>非常低的水平</RageLevelVeryLow>
<RageLevelLow>低水平</RageLevelLow>
<RageLevelNormal>正常水平</RageLevelNormal>
<RageLevelHigh>高水平</RageLevelHigh>
<RageLevelVeryHigh>非常高的水平</RageLevelVeryHigh>

<ZombieHealthTitle>殭屍的體質</ZombieHealthTitle>
<DoubleTapRequired>殭屍會恢復傷勢</DoubleTapRequired>
Expand Down
1 change: 1 addition & 0 deletions Languages/English/Keyed/Help.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
<ZombieInstinct_Normal_Help>Zombie senses reach a bit longer</ZombieInstinct_Normal_Help>
<ZombieInstinct_Sensitive_Help>Zombies are very sensitive and sense you and your trails over many cells</ZombieInstinct_Sensitive_Help>
<RagingZombies_Help>To simulate group behaviour, zombies can become enraged if a tight group of zombies gets too large. Raging zombies have red eyes and start walking towards your colonists. They will be stronger and faster than normal. Try preventing zombie hordes from becoming to large or stuck at places on the map to avoid raging zombies.</RagingZombies_Help>
<RageLevel_Help>This level controls the group size that triggers raging zombies. High levels are more dangerous and make zombies trigger more easily.</RageLevel_Help>

<!-- -->

Expand Down
6 changes: 6 additions & 0 deletions Languages/English/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@
<ZombieInstinct_Normal>Normal</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>Elevated</ZombieInstinct_Sensitive>
<RagingZombies>Zombies rage if a group gets too large</RagingZombies>
<RageLevel>Rage level</RageLevel>
<RageLevelVeryLow>Very low</RageLevelVeryLow>
<RageLevelLow>Low</RageLevelLow>
<RageLevelNormal>Normal</RageLevelNormal>
<RageLevelHigh>High</RageLevelHigh>
<RageLevelVeryHigh>Very high</RageLevelVeryHigh>

<ZombieHealthTitle>Zombie health</ZombieHealthTitle>
<DoubleTapRequired>Zombies recover from injuries</DoubleTapRequired>
Expand Down
6 changes: 6 additions & 0 deletions Languages/French/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
<ZombieInstinct_Normal>Normal</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>Elevé</ZombieInstinct_Sensitive>
<RagingZombies>Les zombies s’enragent si un groupe devient trop grand</RagingZombies>
<RageLevel>Niveau de rage</RageLevel>
<RageLevelVeryLow>Très bas</RageLevelVeryLow>
<RageLevelLow>Faible</RageLevelLow>
<RageLevelNormal>Normal</RageLevelNormal>
<RageLevelHigh>Haut</RageLevelHigh>
<RageLevelVeryHigh>Très haut</RageLevelVeryHigh>

<ZombieHealthTitle>Vitalités des zombies</ZombieHealthTitle>
<DoubleTapRequired>Les zombies se remettent de leurs blessures</DoubleTapRequired>
Expand Down
6 changes: 6 additions & 0 deletions Languages/German/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
<ZombieInstinct_Normal>Normal</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>Empfindlich</ZombieInstinct_Sensitive>
<RagingZombies>Zombies in zu grossen Gruppen werden rasend</RagingZombies>
<RageLevel>Raserei</RageLevel>
<RageLevelVeryLow>Sehr niedrig</RageLevelVeryLow>
<RageLevelLow>Niedrig</RageLevelLow>
<RageLevelNormal>Normal</RageLevelNormal>
<RageLevelHigh>Hoch</RageLevelHigh>
<RageLevelVeryHigh>Sehr hoch</RageLevelVeryHigh>

<ZombieHealthTitle>Zombiegesundheit</ZombieHealthTitle>
<DoubleTapRequired>Zombies erholen sich von Verletzungen</DoubleTapRequired>
Expand Down
6 changes: 6 additions & 0 deletions Languages/Russian/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
<ZombieInstinct_Normal>Нормальные</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>Агресивные</ZombieInstinct_Sensitive>
<RagingZombies>Zombies ярости, если толпа становится слишком большой</RagingZombies>
<RageLevel>Уровень ярости</RageLevel>
<RageLevelVeryLow>Очень низкий</RageLevelVeryLow>
<RageLevelLow>Низкий уровень</RageLevelLow>
<RageLevelNormal>Нормальный</RageLevelNormal>
<RageLevelHigh>Высокий</RageLevelHigh>
<RageLevelVeryHigh>Очень высокий</RageLevelVeryHigh>

<ZombieHealthTitle>Стойкость зомби</ZombieHealthTitle>
<DoubleTapRequired>Зомби восстанавливаются после травм</DoubleTapRequired>
Expand Down
6 changes: 6 additions & 0 deletions Languages/Turkish/Keyed/Text.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
<ZombieInstinct_Normal>Normal</ZombieInstinct_Normal>
<ZombieInstinct_Sensitive>Yükseltilmiş</ZombieInstinct_Sensitive>
<RagingZombies>Bir grup çok büyük alırsa Zombiler öfke</RagingZombies>
<RageLevel>Öfke seviyesi</RageLevel>
<RageLevelVeryLow>Çok düşük</RageLevelVeryLow>
<RageLevelLow>Düşük</RageLevelLow>
<RageLevelNormal>Normal</RageLevelNormal>
<RageLevelHigh>Yüksek</RageLevelHigh>
<RageLevelVeryHigh>Çok yüksek</RageLevelVeryHigh>

<ZombieHealthTitle>Zombi sağlığı</ZombieHealthTitle>
<DoubleTapRequired>Zombiler yaralanmaları kurtarmak</DoubleTapRequired>
Expand Down
16 changes: 9 additions & 7 deletions Source/Dialogs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,19 +297,17 @@ public static void Dialog_FloatSlider(this Listing_Standard list, string labelId
value = Widgets.HorizontalSlider(srect, value, min, max, false, null, labelId.SafeTranslate(), valstr, -1f);
}

public static void Dialog_IntSlider(this Listing_Standard list, string labelId, string format, ref int value, int min, int max)
public static void Dialog_IntSlider(this Listing_Standard list, string labelId, Func<int, string> format, ref int value, int min, int max)
{
list.Help(labelId, 32f);

list.Gap(12f);

var valstr = string.Format("{0:" + format + "}", value);

var srect = list.GetRect(24f);
srect.xMin += inset;
srect.xMax -= inset;

value = (int)(0.5f + Widgets.HorizontalSlider(srect, value, min, max, false, null, labelId.SafeTranslate(), valstr, -1f));
value = (int)(0.5f + Widgets.HorizontalSlider(srect, value, min, max, false, null, labelId.SafeTranslate(), format(value), -1f));
}

public static void Dialog_TimeSlider(this Listing_Standard list, string labelId, ref int value, int min, int max, bool fullDaysOnly = false)
Expand Down Expand Up @@ -344,7 +342,7 @@ public static void DoWindowContentsInternal(ref SettingsGroup settings, Rect inR
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, inRect.height * 4.6f);
var innerRect = new Rect(0f, 0f, firstColumnWidth - 24f, inRect.height * 4.7f);
Widgets.BeginScrollView(outerRect, ref scrollPosition, innerRect, true);

currentHelpItem = null;
Expand Down Expand Up @@ -384,7 +382,11 @@ public static void DoWindowContentsInternal(ref SettingsGroup settings, Rect inR
// Senses
list.Dialog_Enum("ZombieInstinctTitle", ref settings.zombieInstinct);
list.Dialog_Checkbox("RagingZombies", ref settings.ragingZombies);
list.Gap(20f);
var rageLevelNames = new string[] { "RageLevelVeryLow", "RageLevelLow", "RageLevelNormal", "RageLevelHigh", "RageLevelVeryHigh" };
list.Gap(4f);
if (settings.ragingZombies)
list.Dialog_IntSlider("RageLevel", level => rageLevelNames[level - 1].Translate(), ref settings.zombieRageLevel, 1, 5);
list.Gap(16f);

// Health
list.Dialog_Label("ZombieHealthTitle");
Expand Down Expand Up @@ -462,7 +464,7 @@ public static void DoWindowContentsInternal(ref SettingsGroup settings, Rect inR
// Infections
list.Dialog_Label("ZombieSerum");
list.Gap(8f);
list.Dialog_IntSlider("CorpsesExtractAmount", "0", ref settings.corpsesExtractAmount, 1, 10);
list.Dialog_IntSlider("CorpsesExtractAmount", amount => "" + amount, ref settings.corpsesExtractAmount, 1, 10);
list.Dialog_TimeSlider("CorpsesDaysToDessicated", ref settings.corpsesHoursToDessicated, 1, 120);
list.Gap(18f);

Expand Down
2 changes: 2 additions & 0 deletions Source/JobDriver_Stumble.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ void TickAction()
// --------------------------------------------------
*/

ZombieStateHandler.CheckEndRage(zombie);

if (this.ShouldDie(zombie))
return;

Expand Down
36 changes: 26 additions & 10 deletions Source/Patches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static Patches()
static readonly Dictionary<Map, HashSet<IAttackTarget>> playerHostilesWithoutZombies = new Dictionary<Map, HashSet<IAttackTarget>>();

// patch for debugging: show pheromone grid as overlay
//
/*
[HarmonyPatch(typeof(SelectionDrawer))]
[HarmonyPatch("DrawSelectionOverlays")]
static class SelectionDrawer_DrawSelectionOverlays_Patch
Expand Down Expand Up @@ -96,6 +96,7 @@ static void Postfix()
});
}
}
*/

// patch for debugging: show zombie avoidance grid
/*
Expand Down Expand Up @@ -208,12 +209,12 @@ static void Postfix(float leftX, float width, ref float curBaseY)
}

[HarmonyPatch(typeof(Verse.TickManager))]
[HarmonyPatch("TickManagerUpdate")]
[HarmonyPatch(nameof(Verse.TickManager.TickManagerUpdate))]
static class Verse_TickManager_TickManagerUpdate_Patch
{
static readonly Stopwatch watch = new Stopwatch();

static void SingleTick(Verse.TickManager manager, int num)
static void TickZombies(Verse.TickManager manager, int num)
{
_ = num;
watch.Reset();
Expand All @@ -231,25 +232,40 @@ static void SingleTick(Verse.TickManager manager, int num)
}
}

static void Prefix()
static void TickZombieWanderer()
{
_ = ZombieWanderer.processor.MoveNext();
}

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var jump = generator.DefineLabel();
var m_SingleTick = SymbolExtensions.GetMethodInfo(() => SingleTick(null, 0));
var m_TickZombieWanderer = SymbolExtensions.GetMethodInfo(() => TickZombieWanderer());
var m_TickZombies = SymbolExtensions.GetMethodInfo(() => TickZombies(null, 0));
var m_DoSingleTick = AccessTools.Method(typeof(Verse.TickManager), "DoSingleTick");

var list = instructions.ToList();
list.Insert(0, new CodeInstruction(OpCodes.Call, m_TickZombieWanderer));
var idx = list.FindIndex(code => code.operand == m_DoSingleTick);
list[idx].operand = m_SingleTick;
list.Insert(idx, new CodeInstruction(OpCodes.Ldloc_1));
if (idx >= 0)
{
list[idx].operand = m_TickZombies;
list.Insert(idx, new CodeInstruction(OpCodes.Ldloc_1));
}
else
Log.Error("Unexpected code in patch " + MethodBase.GetCurrentMethod().DeclaringType);

/*var found = false;
var valueFrom = 1000f;
var valueTo = 3000f;
foreach (var code in list)
if (code.operand == (object)1000)
code.operand = 200;
if (code.operand is float floatValue && floatValue == valueFrom)
{
code.operand = valueTo;
found = true;
}
if (found == false)
Log.Error("Float constant " + valueFrom + " not found in patch " + MethodBase.GetCurrentMethod().DeclaringType);*/

return list.AsEnumerable();
}
Expand Down Expand Up @@ -1168,7 +1184,7 @@ static void DebugGrid(StringBuilder builder)
_ = sb.Append("Zombie " + zombie.Name.ToStringShort + " at " + currPos.x + "," + currPos.z);
_ = sb.Append(", " + zombie.state.ToString().ToLower());
if (zombie.raging > 0)
_ = sb.Append(", raging ");
_ = sb.Append(", raging[" + (zombie.raging - GenTicks.TicksAbs) + "] ");
_ = sb.Append(", going to " + gotoPos.x + "," + gotoPos.z);
_ = sb.Append(" (wander dest " + wanderTo.x + "," + wanderTo.z + ")");
_ = builder.AppendLine(sb.ToString());
Expand Down
4 changes: 2 additions & 2 deletions Source/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
// 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.16.3.0")]
[assembly: AssemblyFileVersion("1.16.3.0")]
[assembly: AssemblyVersion("1.16.4.0")]
[assembly: AssemblyFileVersion("1.16.4.0")]
13 changes: 8 additions & 5 deletions Source/ZombieSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,10 @@ class SettingsGroup : IExposable, ICloneable
public int baseNumberOfZombiesinEvent = 20;
internal int extraDaysBetweenEvents = 0;
public float suicideBomberChance = 0.01f;
public int suicideBomberIntChance = 1;//unused
public float toxicSplasherChance = 0.01f;
public int toxicSplasherIntChance = 1;//unused
public float tankyOperatorChance = 0.01f;
public int tankyOperatorIntChance = 1;//unused
public float minerChance = 0.01f;
public int minerIntChance = 1;//unused
public float electrifierChance = 0.01f;
public int electrifierIntChance = 1;//unused
public float moveSpeedIdle = 0.2f;
public float moveSpeedTracking = 1.3f;
public float damageFactor = 1.0f;
Expand All @@ -92,11 +87,19 @@ class SettingsGroup : IExposable, ICloneable
public int corpsesHoursToDessicated = 1;
public bool betterZombieAvoidance = true;
public bool ragingZombies = true;
public int zombieRageLevel = 3;
public bool replaceTwinkie = true;
public bool zombiesDropBlood = true;
public bool zombiesBurnLonger = true;
public float reducedTurretConsumption = 0f;

// unused
public int suicideBomberIntChance = 1;
public int toxicSplasherIntChance = 1;
public int tankyOperatorIntChance = 1;
public int minerIntChance = 1;
public int electrifierIntChance = 1;

public object Clone()
{
return MemberwiseClone();
Expand Down
18 changes: 16 additions & 2 deletions Source/ZombieStateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,14 +587,15 @@ public static void ExecuteMove(this JobDriver_Stumble driver, Zombie zombie, Phe

// check for tight groups of zombies ========================================================
//
static readonly int[] rageLevels = new int[] { 40, 32, 21, 18, 12 };
public static void BeginRage(Zombie zombie, PheromoneGrid grid)
{
if (zombie.IsTanky) return;

if (zombie.raging == 0 && ZombieSettings.Values.ragingZombies)
{
var count = CountSurroundingZombies(zombie.Position, grid);
if (count > Constants.SURROUNDING_ZOMBIES_TO_TRIGGER_RAGE)
if (count >= rageLevels[ZombieSettings.Values.zombieRageLevel - 1])
StartRage(zombie);
return;
}
Expand All @@ -603,6 +604,15 @@ public static void BeginRage(Zombie zombie, PheromoneGrid grid)
zombie.raging = 0;
}

public static void CheckEndRage(Zombie zombie)
{
if (zombie.raging == 0)
return;

if (GenTicks.TicksAbs > zombie.raging || ZombieSettings.Values.ragingZombies == false)
zombie.raging = 0;
}

// subroutines ==============================================================================

static Thing CanIngest(Zombie zombie)
Expand Down Expand Up @@ -849,9 +859,13 @@ static int CountSurroundingZombies(IntVec3 pos, PheromoneGrid grid)
.Select(c => grid.GetZombieCount(c)).Sum();
}

static readonly float[] minRageLength = new float[] { 0.1f, 0.2f, 0.5f, 1f, 2f };
static readonly float[] maxRageLength = new float[] { 1f, 2f, 4f, 6f, 8f };
public static void StartRage(Zombie zombie)
{
zombie.raging = GenTicks.TicksAbs + (int)(GenDate.TicksPerHour * Rand.Range(1f, 8f));
var min = minRageLength[ZombieSettings.Values.zombieRageLevel - 1];
var max = maxRageLength[ZombieSettings.Values.zombieRageLevel - 1];
zombie.raging = GenTicks.TicksAbs + (int)(GenDate.TicksPerHour * Rand.Range(min, max));
Tools.CastThoughtBubble(zombie, Constants.RAGING);

if (Constants.USE_SOUND && Prefs.VolumeAmbient > 0f)
Expand Down
32 changes: 19 additions & 13 deletions Source/ZombieWanderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,25 +252,32 @@ IEnumerator Recalculate(IntVec3[] positions, bool ignoreBuildings)
}
}

public IEnumerator RecalculateAll(IntVec3[] positions, bool hasTankyZombies)
public IEnumerator RecalculateAll(IntVec3[] positions, IEnumerable<Zombie> zombies)
{
if (dirtyCells)
{
ClearCells();
dirtyCells = false;
}
if (ZombieSettings.Values.ragingZombies == false && hasTankyZombies == false) yield break;

dirtyCells = true;
// Log.Warning("recalc 1");
var it1 = Recalculate(positions, hasTankyZombies);
while (it1.MoveNext())
yield return null;
var hasRagingZombies = zombies.Any(zombie => zombie.raging > 0);
if (hasRagingZombies)
{
dirtyCells = true;
//Log.Warning("recalc 1");
var it1 = Recalculate(positions, false);
while (it1.MoveNext())
yield return null;
}

// Log.Warning("recalc 2");
var it2 = Recalculate(positions, hasTankyZombies);
while (it2.MoveNext())
yield return null;
var hasTankyZombies = zombies.Any(zombie => zombie.IsTanky);
if (hasTankyZombies)
{
//Log.Warning("recalc 2");
var it2 = Recalculate(positions, true);
while (it2.MoveNext())
yield return null;
}

publicIndex = privateIndex;
privateIndex = 1 - privateIndex;
Expand Down Expand Up @@ -332,8 +339,7 @@ public static IEnumerator Process()
yield return null;
if (colonistPositions.Any())
{
var hasTankyZombies = pawnArray.OfType<Zombie>().Any(zombie => zombie.IsTanky);
var it = info.RecalculateAll(colonistPositions, hasTankyZombies);
var it = info.RecalculateAll(colonistPositions, mapPawns.OfType<Zombie>());
while (it.MoveNext())
yield return null;
}
Expand Down

0 comments on commit 3565c04

Please sign in to comment.