Skip to content

Commit

Permalink
Merge a39e0c9 into 99b0762
Browse files Browse the repository at this point in the history
  • Loading branch information
Pokachi authored Jun 1, 2021
2 parents 99b0762 + a39e0c9 commit 63dd692
Show file tree
Hide file tree
Showing 4 changed files with 328 additions and 83 deletions.
155 changes: 131 additions & 24 deletions DifficultyMod/Core/DifficultyPatcher.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Boardgame;
using Boardgame.AIDirector;
using Boardgame.BoardEntities;
using Boardgame.Cards;
using Boardgame.Data;
Expand Down Expand Up @@ -31,7 +32,7 @@ public static int ModifyEnemyHPMultiplier(int defaultHP, PieceConfig pieceConfig

if (pieceConfig.HasPieceType(DataKeys.PieceType.Enemy))
{
return (int) (defaultHP * DifficultySettings.EnemyHPMultiplier);
return defaultHP * DifficultySettings.EnemyHPMultiplier < 0 ? 0 : (int) (defaultHP * DifficultySettings.EnemyHPMultiplier);
}

return defaultHP;
Expand All @@ -48,12 +49,29 @@ public static int ModifyEnemyAttackMultiplier(int defaultAttack, PieceConfig pie

if (pieceConfig.HasPieceType(DataKeys.PieceType.Enemy))
{
return (int) (defaultAttack * DifficultySettings.EnemyAttackMultiplier);
return defaultAttack * DifficultySettings.EnemyAttackMultiplier < 0 ? 0 : (int) (defaultAttack * DifficultySettings.EnemyAttackMultiplier);
}

return defaultAttack;
}

public static int ModifyEnemyMoveMultiplier(int defaultMove, PieceConfig pieceConfig)
{

// Do not modify the Attack if the game is public (i.e. anyone can join without room code)
if (!IsPrivateGame())
{
return defaultMove;
}

if (pieceConfig.HasPieceType(DataKeys.PieceType.Enemy))
{
return defaultMove * DifficultySettings.EnemyMoveMultiplier < 1 ? 1 : (int)(defaultMove * DifficultySettings.EnemyMoveMultiplier);
}

return defaultMove;
}

private static bool IsPrivateGame()
{
CreateGameMode gameMode = (CreateGameMode) typeof(GameStateMachine).GetField("createGameMode", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(StateMachine);
Expand All @@ -63,7 +81,9 @@ private static bool IsPrivateGame()
[HarmonyPatch(typeof(Piece), "CreatePiece")]
class EnemyHPMultiplierPatcher
{
static MethodInfo m_MyExtraMethod = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyEnemyHPMultiplier), new[] { typeof(int), typeof(PieceConfig) });
static MethodInfo modifyEnemyHP = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyEnemyHPMultiplier), new[] { typeof(int), typeof(PieceConfig) });
static MethodInfo modifyEnemyAttack = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyEnemyAttackMultiplier), new[] { typeof(int), typeof(PieceConfig) });
static MethodInfo modifyEnemMove = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyEnemyMoveMultiplier), new[] { typeof(int), typeof(PieceConfig) });

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
Expand All @@ -77,39 +97,32 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst
yield return instruction;

yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Call, m_MyExtraMethod);
yield return new CodeInstruction(OpCodes.Call, modifyEnemyHP);

continue;
}
}

yield return instruction;
}
}
}
if (strOperand.Contains("get_AttackDamage"))
{
yield return instruction;

[HarmonyPatch(typeof(Piece), "CreatePiece")]
class EnemyAttackMultiplierPatcher
{
static MethodInfo m_MyExtraMethod = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyEnemyAttackMultiplier), new[] { typeof(int), typeof(PieceConfig) });
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Call, modifyEnemyAttack);

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Callvirt)
{
string strOperand = instruction.operand.ToString();
if (strOperand.Contains("get_AttackDamage"))
continue;
}

if (strOperand.Contains("get_MoveRange"))
{
yield return instruction;

yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Call, m_MyExtraMethod);
yield return new CodeInstruction(OpCodes.Call, modifyEnemMove);

continue;
}
}

yield return instruction;
}
}
Expand Down Expand Up @@ -192,16 +205,110 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst
[HarmonyPatch(typeof(PieceConfig), "CanOpenDoor", MethodType.Getter)]
class EnemyCanOpenDoorTogglePatcher
{
static void Postfix(ref bool __result)
static void Postfix(ref bool __result, ref PieceConfig __instance)
{
if (IsPrivateGame())
{
if (!DifficultySettings.EnemyCanOpenDoors)
if (!DifficultySettings.EnemyCanOpenDoors && __instance.HasPieceType(DataKeys.PieceType.Enemy))
{
__result = false;
}
}
}
}

public static int ModifyPowerIndex(int defaultPI, AIDirectorContext context)
{
// Do not modify the Attack if the game is public (i.e. anyone can join without room code)
if (!IsPrivateGame())
{
return defaultPI;
}

int powerIndexOnBoard = context.dataHelper.PowerIndexOnBoard(false, false);

return (int)((defaultPI + powerIndexOnBoard) * DifficultySettings.EnemyCountMultiplier - powerIndexOnBoard);
}

[HarmonyPatch(typeof(AIDirectorController2), "DynamicSpawning")]
class EnemyRespawnPatcher
{
static bool Prefix()
{
if (IsPrivateGame())
{
if (!DifficultySettings.EnemyCanRespawn)
{
return false;
}
}
return true;
}

static MethodInfo m_MyExtraMethod = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyPowerIndex), new[] { typeof(int), typeof(AIDirectorContext) });

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
bool foundStart = false;
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Callvirt)
{
string strOperand = instruction.operand.ToString();
if (strOperand.Contains("DifficultPowerIndexDelta"))
{
foundStart = true;
}
} else if (foundStart && instruction.opcode == OpCodes.Ldloc_0) {
foundStart = false;


yield return instruction;

yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, m_MyExtraMethod);

continue;
}

yield return instruction;
}
}
}

[HarmonyPatch(typeof(AIDirectorController2), "HandleDiscoveredZone")]
class EnemySpawnPatcher
{
static MethodInfo m_MyExtraMethod = AccessTools.Method(typeof(DifficultyPatcher), nameof(ModifyPowerIndex), new[] { typeof(int), typeof(AIDirectorContext) });

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
bool foundStart = false;
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Callvirt)
{
string strOperand = instruction.operand.ToString();
if (strOperand.Contains("DifficultPowerIndexDelta"))
{
foundStart = true;
}
}
else if (foundStart && instruction.opcode == OpCodes.Ldloc_0)
{
foundStart = false;

yield return instruction;

yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, m_MyExtraMethod);

continue;
}

yield return instruction;
}
}
}
}
}
91 changes: 91 additions & 0 deletions DifficultyMod/Core/DifficultySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public static class DifficultySettings
private const string MELON_PREF_CARD_SALE_MULTIPLIER_NAME = "CardSaleMultiplier";
private const string MELON_PREF_CARD_COST_MULTIPLIER_NAME = "CardCostMultiplier";
private const string MELON_PREF_ENEMY_CAN_OPEN_DOOR_TOGGLE_NAME = "EnemyCanOpenDoorToggle";
private const string MELON_PREF_ENEMY_RESPAWN_TOGGLE_NAME = "EnemyRespawnToggle";
private const string MELON_PREF_ENEMY_COUNT_MULTIPLIER_NAME = "EnemyCountMultiplier";
private const string MELON_PREF_ENEMY_MOVE_MULTIPLIER_NAME = "EnemyMoveMultiplier";

private const float ENEMY_HP_MULTIPLIER_MIN = 0.25f;
private const float ENEMY_HP_MULTIPLIER_MAX = 5f;
Expand All @@ -26,6 +29,10 @@ public static class DifficultySettings
private const float CARD_SALE_MULTIPLIER_MAX = 5f;
private const float CARD_COST_MULTIPLIER_MIN = 0.1f;
private const float CARD_COST_MULTIPLIER_MAX = 5f;
private const float ENEMY_COUNT_MULTIPLIER_MIN = 0.25f;
private const float ENEMY_COUNT_MULTIPLIER_MAX = 10f;
private const float ENEMY_MOVE_MULTIPLIER_MIN = 0.25f;
private const float ENEMY_MOVE_MULTIPLIER_MAX = 5f;

public static void RegisterSettings()
{
Expand All @@ -37,9 +44,36 @@ public static void RegisterSettings()
MelonPreferences.CreateEntry(MELON_PREF_NAME, MELON_PREF_CARD_SALE_MULTIPLIER_NAME, 1f, "Gold Gained From Selling Cards");
MelonPreferences.CreateEntry(MELON_PREF_NAME, MELON_PREF_CARD_COST_MULTIPLIER_NAME, 1f, "Gold Cost When Buying Cards");
MelonPreferences.CreateEntry(MELON_PREF_NAME, MELON_PREF_ENEMY_CAN_OPEN_DOOR_TOGGLE_NAME, true, "Enemy Can Open Doors");
MelonPreferences.CreateEntry(MELON_PREF_NAME, MELON_PREF_ENEMY_RESPAWN_TOGGLE_NAME, true, "Enemy Can Respawn");
MelonPreferences.CreateEntry(MELON_PREF_NAME, MELON_PREF_ENEMY_COUNT_MULTIPLIER_NAME, 1f, "Enemy Spawn Rate");
MelonPreferences.CreateEntry(MELON_PREF_NAME, MELON_PREF_ENEMY_MOVE_MULTIPLIER_NAME, 1f, "Enemy Movement Range");
}

#region Properties
public static float EnemyMoveMultiplier
{
get
{
return MelonPreferences.GetEntryValue<float>(MELON_PREF_NAME, MELON_PREF_ENEMY_MOVE_MULTIPLIER_NAME);
}
set
{
MelonPreferences.SetEntryValue(MELON_PREF_NAME, MELON_PREF_ENEMY_MOVE_MULTIPLIER_NAME, value);
}
}

public static float EnemyCountMultiplier
{
get
{
return MelonPreferences.GetEntryValue<float>(MELON_PREF_NAME, MELON_PREF_ENEMY_COUNT_MULTIPLIER_NAME);
}
set
{
MelonPreferences.SetEntryValue(MELON_PREF_NAME, MELON_PREF_ENEMY_COUNT_MULTIPLIER_NAME, value);
}
}

public static float EnemyHPMultiplier
{
get
Expand Down Expand Up @@ -127,9 +161,60 @@ public static bool EnemyCanOpenDoors
MelonPreferences.SetEntryValue(MELON_PREF_NAME, MELON_PREF_ENEMY_CAN_OPEN_DOOR_TOGGLE_NAME, value);
}
}

public static bool EnemyCanRespawn
{
get
{
return MelonPreferences.GetEntryValue<bool>(MELON_PREF_NAME, MELON_PREF_ENEMY_RESPAWN_TOGGLE_NAME);
}
set
{
MelonPreferences.SetEntryValue(MELON_PREF_NAME, MELON_PREF_ENEMY_RESPAWN_TOGGLE_NAME, value);
}
}
#endregion Properties

#region Property_Modifier
public static void DecreaseEnemyMoveMultiplier(Action<float> callBack)
{
if (EnemyMoveMultiplier > ENEMY_MOVE_MULTIPLIER_MIN)
{
EnemyMoveMultiplier = (float)Math.Round(EnemyMoveMultiplier - 0.25f, 2); ; ;
}

callBack(EnemyMoveMultiplier);
}

public static void IncreaseEnemyMoveMultiplier(Action<float> callBack)
{
if (EnemyMoveMultiplier < ENEMY_MOVE_MULTIPLIER_MAX)
{
EnemyMoveMultiplier = (float)Math.Round(EnemyMoveMultiplier + 0.25f, 2); ;
}

callBack(EnemyMoveMultiplier);
}
public static void DecreaseEnemyCountMultiplier(Action<float> callBack)
{
if (EnemyCountMultiplier > ENEMY_COUNT_MULTIPLIER_MIN)
{
EnemyCountMultiplier = (float)Math.Round(EnemyCountMultiplier - 0.25f, 2);
}

callBack(EnemyCountMultiplier);
}

public static void IncreaseEnemyCountMultiplier(Action<float> callBack)
{
if (EnemyCountMultiplier < ENEMY_COUNT_MULTIPLIER_MAX)
{
EnemyCountMultiplier = (float)Math.Round(EnemyCountMultiplier + 0.25f, 2);
}

callBack(EnemyCountMultiplier);
}

public static void DecreaseEnemyHPMultiplier(Action<float> callBack)
{
if (EnemyHPMultiplier > ENEMY_HP_MULTIPLIER_MIN)
Expand Down Expand Up @@ -255,6 +340,12 @@ public static void ToggleEnemyCanOpenDoor(Action<bool> callBack)
EnemyCanOpenDoors = !EnemyCanOpenDoors;
callBack(EnemyCanOpenDoors);
}

public static void ToggleEnemyCanRespawn(Action<bool> callBack)
{
EnemyCanRespawn = !EnemyCanRespawn;
callBack(EnemyCanRespawn);
}
#endregion Property_Modifier
}
}
Loading

0 comments on commit 63dd692

Please sign in to comment.