// // Harmony Library Patches // /// <summary> Patches GetEnemyInstance so that SoG can create modded enemy instances. </summary> private static bool GetEnemyInstance_PrefixPatch(ref Enemy __result, EnemyCodex.EnemyTypes enType, Level.WorldRegion enOverrideContent) { if (!enType.IsModEnemy()) { return(true); // Executes original method } EnemyDescription xDesc = EnemyCodex.denxDescriptionDict[enType]; __result = new Enemy() { xEnemyDescription = xDesc, enType = enType }; __result.xRenderComponent.xOwnerObject = __result; ModEnemyData xModData = ModLibrary.EnemyDetails[enType]; xModData.InstanceBuilder?.Invoke(__result); __result.xBaseStats.iLevel = __result.xEnemyDescription.iLevel; __result.xBaseStats.iHP = (__result.xBaseStats.iBaseMaxHP = __result.xEnemyDescription.iMaxHealth); if (__result.xEnemyDescription.enCategory == EnemyDescription.Category.Regular) { __result.rcRegularHPRenderComponent = new RegularEnemyHPRenderComponent(__result); } __result.xRenderComponent.bReSortHeight = true; __result.xRenderComponent.GetCurrentAnimation().Reset(); foreach (DropChance xDrop in __result.xEnemyDescription.lxLootTable) { __result.lxLootTable.Add(new DropChance(xDrop.iChance, xDrop.enItemToDrop, xDrop.iRolls)); ItemCodex.GetItemDescription(xDrop.enItemToDrop); } return(false); // Skips original method }
// TO DO: Consider transforming this into a transpile /// <summary> Patches _Enemy_MakeElite so that SoG can scale modded enemy instances if they're elite. </summary> private static bool _Enemy_MakeElite_PrefixPatch(ref bool __result, Enemy xEn, bool bAttachEffect) { __result = false; if (!xEn.enType.IsModEnemy()) { return(true); // Executes original method } if (xEn.xBehaviour.bIsElite) { return(false); // Skips original method (No changes needed) } ModEnemyData xModData = ModLibrary.EnemyDetails[xEn.enType]; if (xModData.EliteBuilder != null) { xModData.EliteBuilder(xEn); __result = true; } if (__result) { Game1 xGame = Utils.GetTheGame(); xEn.xBehaviour.bIsElite = true; if (xGame.xStateMaster.enGameMode == StateMaster.GameModes.RogueLike && RogueLikeMode.randLevelLoadStuff.Next(Math.Max(20 - xGame.xGameSessionData.xRogueLikeSession.iCurrentFloor * 2, 5)) == 0) { xEn.lxLootTable.Add(new DropChance(100000, ItemCodex.ItemTypes._KeyItem_RoguelikeEssence)); } if (xModData.bGrantEliteBonuses) { xEn.xBaseStats.iBaseMaxHP = (int)((float)xEn.xBaseStats.iBaseMaxHP * (0.75f + 0.25f * (float)CAS.NumberOfPlayers)); xEn.xBaseStats.iHP = xEn.xBaseStats.iMaxHP; foreach (PlayerView xView in xGame.dixPlayers.Values) { if (xView.xEquipment.HasBadge(PinCodex.PinType.ElitesIncreaseATKMATKPermanentlyButAlsoStronger)) { xView.xEntity.xBaseStats.dxfModifiedResistanceVsTarget[xEn] = 1.5f; } } } if (CAS.GameMode == StateMaster.GameModes.Story) { if (xModData.bGrantEliteBonuses && !xEn.bSuppressEliteDropBonus) { xEn.iBonusMoney = xEn.xBaseStats.iLevel * 20; foreach (DropChance x in xEn.lxLootTable) { x.iChance *= 5; } xEn.xBaseStats.iLevel += 3; } xEn.sOverrideName = RogueLikeMode.GetSuperSuffix(xEn.xEnemyDescription.sFullName, xEn.enType); } if (bAttachEffect) { SortedAnimated xEffe = xGame._EffectMaster_AddEffect(new SortedAnimated(xEn.xTransform.v2Pos, SortedAnimated.SortedAnimatedEffects.BuffEffectEliteEnemy)) as SortedAnimated; xEffe.xRenderComponent.xTransform = xEn.xRenderComponent.xTransform; xEn.xEliteEffect = xEffe; if (xEn.enType == EnemyCodex.EnemyTypes.Desert_Solem) { xEffe.xRenderComponent.fScale = 1.5f; } xGame._EntityMaster_AddWatcher(new Watchers.EnemyAttachedEffectWatcher(xEn, xEffe)); } } return(false); // Skips original method }