private float CalculateBasePower(PBEBattlePokemon user, PBEBattlePokemon[] targets, IPBEMoveData mData, PBEType moveType) { float basePower; #region Get move's base power switch (mData.Effect) { case PBEMoveEffect.CrushGrip: { basePower = Math.Max(1, targets.Select(t => (float)mData.Power * t.HP / t.MaxHP).Average()); break; } case PBEMoveEffect.Eruption: { basePower = Math.Max(1, mData.Power * user.HP / user.MaxHP); break; } case PBEMoveEffect.Flail: { int val = 48 * user.HP / user.MaxHP; if (val < 2) { basePower = 200; } else if (val < 4) { basePower = 150; } else if (val < 8) { basePower = 100; } else if (val < 16) { basePower = 80; } else if (val < 32) { basePower = 40; } else { basePower = 20; } break; } case PBEMoveEffect.Frustration: { basePower = Math.Max(1, (byte.MaxValue - user.Friendship) / 2.5f); break; } case PBEMoveEffect.GrassKnot: { basePower = targets.Select(t => { if (t.Weight >= 200.0f) { return(120f); } else if (t.Weight >= 100.0f) { return(100f); } else if (t.Weight >= 50.0f) { return(80f); } else if (t.Weight >= 25.0f) { return(60f); } else if (t.Weight >= 10.0f) { return(40f); } return(20f); }).Average(); break; } case PBEMoveEffect.HeatCrash: { basePower = targets.Select(t => { float relative = user.Weight / t.Weight; if (relative < 2) { return(40f); } else if (relative < 3) { return(60f); } else if (relative < 4) { return(80f); } else if (relative < 5) { return(100f); } return(120f); }).Average(); break; } case PBEMoveEffect.HiddenPower: { basePower = user.IndividualValues !.GetHiddenPowerBasePower(Settings); break; } case PBEMoveEffect.Magnitude: { int val = _rand.RandomInt(0, 99); byte magnitude; if (val < 5) // Magnitude 4 - 5% { magnitude = 4; basePower = 10; } else if (val < 15) // Magnitude 5 - 10% { magnitude = 5; basePower = 30; } else if (val < 35) // Magnitude 6 - 20% { magnitude = 6; basePower = 50; } else if (val < 65) // Magnitude 7 - 30% { magnitude = 7; basePower = 70; } else if (val < 85) // Magnitude 8 - 20% { magnitude = 8; basePower = 90; } else if (val < 95) // Magnitude 9 - 10% { magnitude = 9; basePower = 110; } else // Magnitude 10 - 5% { magnitude = 10; basePower = 150; } BroadcastMagnitude(magnitude); break; } case PBEMoveEffect.Punishment: { basePower = Math.Max(1, Math.Min(200, targets.Select(t => mData.Power + (20f * t.GetPositiveStatTotal())).Average())); break; } case PBEMoveEffect.Return: { basePower = Math.Max(1, user.Friendship / 2.5f); break; } case PBEMoveEffect.StoredPower: { basePower = mData.Power + (20 * user.GetPositiveStatTotal()); break; } default: { basePower = Math.Max(1, (int)mData.Power); break; } } #endregion // Technician goes before any other power boosts if (user.Ability == PBEAbility.Technician && basePower <= 60) { basePower *= 1.5f; } #region Item-specific power boosts switch (moveType) { case PBEType.Bug: { switch (user.Item) { case PBEItem.InsectPlate: case PBEItem.SilverPowder: { basePower *= 1.2f; break; } case PBEItem.BugGem: { BroadcastItem(user, user, PBEItem.BugGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Dark: { switch (user.Item) { case PBEItem.BlackGlasses: case PBEItem.DreadPlate: { basePower *= 1.2f; break; } case PBEItem.DarkGem: { BroadcastItem(user, user, PBEItem.DarkGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Dragon: { switch (user.Item) { case PBEItem.AdamantOrb: { if (user.OriginalSpecies == PBESpecies.Dialga) { basePower *= 1.2f; } break; } case PBEItem.DracoPlate: case PBEItem.DragonFang: { basePower *= 1.2f; break; } case PBEItem.GriseousOrb: { if (user.OriginalSpecies == PBESpecies.Giratina && user.RevertForm == PBEForm.Giratina_Origin) { basePower *= 1.2f; } break; } case PBEItem.LustrousOrb: { if (user.OriginalSpecies == PBESpecies.Palkia) { basePower *= 1.2f; } break; } case PBEItem.DragonGem: { BroadcastItem(user, user, PBEItem.DragonGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Electric: { switch (user.Item) { case PBEItem.Magnet: case PBEItem.ZapPlate: { basePower *= 1.2f; break; } case PBEItem.ElectricGem: { BroadcastItem(user, user, PBEItem.ElectricGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Fighting: { switch (user.Item) { case PBEItem.BlackBelt: case PBEItem.FistPlate: { basePower *= 1.2f; break; } case PBEItem.FightingGem: { BroadcastItem(user, user, PBEItem.FightingGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Fire: { switch (user.Item) { case PBEItem.Charcoal: case PBEItem.FlamePlate: { basePower *= 1.2f; break; } case PBEItem.FireGem: { BroadcastItem(user, user, PBEItem.FireGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Flying: { switch (user.Item) { case PBEItem.SharpBeak: case PBEItem.SkyPlate: { basePower *= 1.2f; break; } case PBEItem.FlyingGem: { BroadcastItem(user, user, PBEItem.FlyingGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Ghost: { switch (user.Item) { case PBEItem.GriseousOrb: { if (user.OriginalSpecies == PBESpecies.Giratina && user.RevertForm == PBEForm.Giratina_Origin) { basePower *= 1.2f; } break; } case PBEItem.SpellTag: case PBEItem.SpookyPlate: { basePower *= 1.2f; break; } case PBEItem.GhostGem: { BroadcastItem(user, user, PBEItem.GhostGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Grass: { switch (user.Item) { case PBEItem.MeadowPlate: case PBEItem.MiracleSeed: case PBEItem.RoseIncense: { basePower *= 1.2f; break; } case PBEItem.GrassGem: { BroadcastItem(user, user, PBEItem.GrassGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Ground: { switch (user.Item) { case PBEItem.EarthPlate: case PBEItem.SoftSand: { basePower *= 1.2f; break; } case PBEItem.GroundGem: { BroadcastItem(user, user, PBEItem.GroundGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Ice: { switch (user.Item) { case PBEItem.IciclePlate: case PBEItem.NeverMeltIce: { basePower *= 1.2f; break; } case PBEItem.IceGem: { BroadcastItem(user, user, PBEItem.IceGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.None: { break; } case PBEType.Normal: { switch (user.Item) { case PBEItem.SilkScarf: { basePower *= 1.2f; break; } case PBEItem.NormalGem: { BroadcastItem(user, user, PBEItem.NormalGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Poison: { switch (user.Item) { case PBEItem.PoisonBarb: case PBEItem.ToxicPlate: { basePower *= 1.2f; break; } case PBEItem.PoisonGem: { BroadcastItem(user, user, PBEItem.PoisonGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Psychic: { switch (user.Item) { case PBEItem.MindPlate: case PBEItem.OddIncense: case PBEItem.TwistedSpoon: { basePower *= 1.2f; break; } case PBEItem.PsychicGem: { BroadcastItem(user, user, PBEItem.PsychicGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Rock: { switch (user.Item) { case PBEItem.HardStone: case PBEItem.RockIncense: case PBEItem.StonePlate: { basePower *= 1.2f; break; } case PBEItem.RockGem: { BroadcastItem(user, user, PBEItem.RockGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Steel: { switch (user.Item) { case PBEItem.AdamantOrb: { if (user.OriginalSpecies == PBESpecies.Dialga) { basePower *= 1.2f; } break; } case PBEItem.IronPlate: case PBEItem.MetalCoat: { basePower *= 1.2f; break; } case PBEItem.SteelGem: { BroadcastItem(user, user, PBEItem.SteelGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } case PBEType.Water: { switch (user.Item) { case PBEItem.LustrousOrb: { if (user.OriginalSpecies == PBESpecies.Palkia) { basePower *= 1.2f; } break; } case PBEItem.MysticWater: case PBEItem.SeaIncense: case PBEItem.SplashPlate: case PBEItem.WaveIncense: { basePower *= 1.2f; break; } case PBEItem.WaterGem: { BroadcastItem(user, user, PBEItem.WaterGem, PBEItemAction.Consumed); basePower *= 1.5f; break; } } break; } default: throw new ArgumentOutOfRangeException(nameof(moveType)); } #endregion #region Move-specific power boosts switch (mData.Effect) { case PBEMoveEffect.Acrobatics: { if (user.Item == PBEItem.None) { basePower *= 2.0f; } break; } case PBEMoveEffect.Brine: { if (Array.FindIndex(targets, t => t.HP <= t.HP / 2) != -1) { basePower *= 2.0f; } break; } case PBEMoveEffect.Facade: { if (user.Status1 == PBEStatus1.Burned || user.Status1 == PBEStatus1.Paralyzed || user.Status1 == PBEStatus1.Poisoned || user.Status1 == PBEStatus1.BadlyPoisoned) { basePower *= 2.0f; } break; } case PBEMoveEffect.Hex: { if (Array.FindIndex(targets, t => t.Status1 != PBEStatus1.None) != -1) { basePower *= 2.0f; } break; } case PBEMoveEffect.Payback: { if (Array.FindIndex(targets, t => t.HasUsedMoveThisTurn) != -1) { basePower *= 2.0f; } break; } case PBEMoveEffect.Retaliate: { if (user.Team.MonFaintedLastTurn) { basePower *= 2.0f; } break; } case PBEMoveEffect.SmellingSalt: { if (Array.FindIndex(targets, t => t.Status1 == PBEStatus1.Paralyzed) != -1) { basePower *= 2.0f; } break; } case PBEMoveEffect.Venoshock: { if (Array.FindIndex(targets, t => t.Status1 == PBEStatus1.Poisoned || t.Status1 == PBEStatus1.BadlyPoisoned) != -1) { basePower *= 2.0f; } break; } case PBEMoveEffect.WakeUpSlap: { if (Array.FindIndex(targets, t => t.Status1 == PBEStatus1.Asleep) != -1) { basePower *= 2.0f; } break; } case PBEMoveEffect.WeatherBall: { if (ShouldDoWeatherEffects() && Weather != PBEWeather.None) { basePower *= 2.0f; } break; } } #endregion #region Weather-specific power boosts if (ShouldDoWeatherEffects()) { switch (Weather) { case PBEWeather.HarshSunlight: { if (moveType == PBEType.Fire) { basePower *= 1.5f; } else if (moveType == PBEType.Water) { basePower *= 0.5f; } break; } case PBEWeather.Rain: { if (moveType == PBEType.Water) { basePower *= 1.5f; } else if (moveType == PBEType.Fire) { basePower *= 0.5f; } break; } case PBEWeather.Sandstorm: { if (user.Ability == PBEAbility.SandForce && (moveType == PBEType.Rock || moveType == PBEType.Ground || moveType == PBEType.Steel)) { basePower *= 1.3f; } break; } } } #endregion #region Other power boosts if (user.Status2.HasFlag(PBEStatus2.HelpingHand)) { basePower *= 1.5f; } if (user.Ability == PBEAbility.FlareBoost && mData.Category == PBEMoveCategory.Special && user.Status1 == PBEStatus1.Burned) { basePower *= 1.5f; } if (user.Ability == PBEAbility.ToxicBoost && mData.Category == PBEMoveCategory.Physical && (user.Status1 == PBEStatus1.Poisoned || user.Status1 == PBEStatus1.BadlyPoisoned)) { basePower *= 1.5f; } if (user.Item == PBEItem.LifeOrb) { basePower *= 1.3f; } if (user.Ability == PBEAbility.IronFist && mData.Flags.HasFlag(PBEMoveFlag.AffectedByIronFist)) { basePower *= 1.2f; } if (user.Ability == PBEAbility.Reckless && mData.Flags.HasFlag(PBEMoveFlag.AffectedByReckless)) { basePower *= 1.2f; } if (user.Item == PBEItem.MuscleBand && mData.Category == PBEMoveCategory.Physical) { basePower *= 1.1f; } if (user.Item == PBEItem.WiseGlasses && mData.Category == PBEMoveCategory.Special) { basePower *= 1.1f; } #endregion return(basePower); }