From 6302ca9809c003c75e61f38f386f4ef5b07a7946 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 19 Nov 2021 18:12:10 +0100 Subject: [PATCH] Adds a bunch of abilities --- Abilities.json | 247 +++++++++++++++++++++ Scripts/Abilities/Aftermath.as | 18 ++ Scripts/Abilities/Analytic.as | 15 ++ Scripts/Abilities/AngerPoint.as | 9 + Scripts/Abilities/ChangeMoveType.as | 31 +++ Scripts/Abilities/IncreasedSTAB.as | 10 + Scripts/Abilities/SuppressWeather.as | 15 ++ Scripts/Battle/SuppressWeather.as | 21 ++ Scripts/Interfaces/Battle.astypedef | 4 +- Scripts/Interfaces/BattleHistory.astypedef | 1 + Scripts/Interfaces/ChoiceQueue.astypedef | 1 + Scripts/Interfaces/DamageSource.astypedef | 3 +- Scripts/Interfaces/PkmnScript.as | 4 + Scripts/Interfaces/Pokemon.astypedef | 2 +- 14 files changed, 378 insertions(+), 3 deletions(-) create mode 100644 Abilities.json create mode 100644 Scripts/Abilities/Aftermath.as create mode 100644 Scripts/Abilities/Analytic.as create mode 100644 Scripts/Abilities/AngerPoint.as create mode 100644 Scripts/Abilities/ChangeMoveType.as create mode 100644 Scripts/Abilities/IncreasedSTAB.as create mode 100644 Scripts/Abilities/SuppressWeather.as create mode 100644 Scripts/Battle/SuppressWeather.as diff --git a/Abilities.json b/Abilities.json new file mode 100644 index 0000000..0b1af62 --- /dev/null +++ b/Abilities.json @@ -0,0 +1,247 @@ +{ + "adaptability": { + "effect": "IncreasedStab" + }, + "aerilate": { + "effect": "ChangeMoveType", + "parameters": ["normal", "flying"] + }, + "aftermath": { + "effect": "Aftermath" + }, + "air_lock": { + "effect": "SuppressWeather" + }, + "analytic": { + "effect": "Analytic" + }, + "anger_point": { + "effect": "AngerPoint" + }, + "anticipation": {}, + "arena_trap": {}, + "aroma_veil": {}, + "aura_break": {}, + "bad_dreams": {}, + "battery": {}, + "battle_armor": {}, + "battle_bond": {}, + "beast_boost": {}, + "berserk": {}, + "big_pecks": {}, + "blaze": {}, + "bulletproof": {}, + "cheek_pouch": {}, + "chlorophyll": {}, + "clear_body": {}, + "cloud_nine": {}, + "color_change": {}, + "comatose": {}, + "competitive": {}, + "compound_eyes": {}, + "contrary": {}, + "corrosion": {}, + "cursed_body": {}, + "cute_charm": {}, + "damp": {}, + "dancer": {}, + "dark_aura": {}, + "dazzling": {}, + "defeatist": {}, + "defiant": {}, + "delta_stream": {}, + "desolate_land": {}, + "disguise": {}, + "download": {}, + "drizzle": {}, + "drought": {}, + "dry_skin": {}, + "early_bird": {}, + "effect_spore": {}, + "electric_surge": {}, + "emergency_exit": {}, + "fairy_aura": {}, + "filter": {}, + "flame_body": {}, + "flare_boost": {}, + "flash_fire": {}, + "flower_gift": {}, + "flower_veil": {}, + "fluffy": {}, + "forecast": {}, + "forewarn": {}, + "friend_guard": {}, + "frisk": {}, + "full_metal_body": {}, + "fur_coat": {}, + "gale_wings": {}, + "galvanize": {}, + "gluttony": {}, + "gooey": {}, + "grass_pelt": {}, + "grassy_surge": {}, + "guts": {}, + "harvest": {}, + "healer": {}, + "heatproof": {}, + "heavy_metal": {}, + "honey_gather": {}, + "huge_power": {}, + "hustle": {}, + "hydration": {}, + "hyper_cutter": {}, + "ice_body": {}, + "illuminate": {}, + "illusion": {}, + "immunity": {}, + "imposter": {}, + "infiltrator": {}, + "innards_out": {}, + "inner_focus": {}, + "insomnia": {}, + "intimidate": {}, + "iron_barbs": {}, + "iron_fist": {}, + "justified": {}, + "keen_eye": {}, + "klutz": {}, + "leaf_guard": {}, + "levitate": {}, + "light_metal": {}, + "lightning_rod": {}, + "limber": {}, + "liquid_ooze": {}, + "liquid_voice": {}, + "long_reach": {}, + "magic_bounce": {}, + "magic_guard": {}, + "magician": {}, + "magma_armor": {}, + "magnet_pull": {}, + "marvel_scale": {}, + "mega_launcher": {}, + "merciless": {}, + "minus": {}, + "misty_surge": {}, + "mold_breaker": {}, + "moody": {}, + "motor_drive": {}, + "moxie": {}, + "multiscale": {}, + "multitype": {}, + "mummy": {}, + "natural_cure": {}, + "no_guard": {}, + "normalize": {}, + "oblivious": {}, + "overcoat": {}, + "overgrow": {}, + "own_tempo": {}, + "parental_bond": {}, + "pickpocket": {}, + "pickup": {}, + "pixilate": {}, + "plus": {}, + "poison_heal": {}, + "poison_point": {}, + "poison_touch": {}, + "power_construct": {}, + "power_of_alchemy": {}, + "prankster": {}, + "pressure": {}, + "primordial_sea": {}, + "prism_armor": {}, + "protean": {}, + "psychic_surge": {}, + "pure_power": {}, + "queenly_majesty": {}, + "quick_feet": {}, + "rain_dish": {}, + "rattled": {}, + "receiver": {}, + "reckless": {}, + "refrigerate": {}, + "regenerator": {}, + "rivalry": {}, + "rks_system": {}, + "rock_head": {}, + "rough_skin": {}, + "run_away": {}, + "sand_force": {}, + "sand_rush": {}, + "sand_stream": {}, + "sand_veil": {}, + "sap_sipper": {}, + "schooling": {}, + "scrappy": {}, + "serene_grace": {}, + "shadow_shield": {}, + "shadow_tag": {}, + "shed_skin": {}, + "sheer_force": {}, + "shell_armor": {}, + "shield_dust": {}, + "shields_down": {}, + "simple": {}, + "skill_link": {}, + "slow_start": {}, + "slush_rush": {}, + "sniper": {}, + "snow_cloak": {}, + "snow_warning": {}, + "solar_power": {}, + "solid_rock": {}, + "soul_heart": {}, + "soundproof": {}, + "speed_boost": {}, + "stakeout": {}, + "stall": {}, + "stamina": {}, + "stance_change": {}, + "static": {}, + "steadfast": {}, + "steelworker": {}, + "stench": {}, + "sticky_hold": {}, + "storm_drain": {}, + "strong_jaw": {}, + "sturdy": {}, + "suction_cups": {}, + "super_luck": {}, + "surge_surfer": {}, + "swarm": {}, + "sweet_veil": {}, + "swift_swim": {}, + "symbiosis": {}, + "synchronize": {}, + "tangled_feet": {}, + "tangling_hair": {}, + "technician": {}, + "telepathy": {}, + "teravolt": {}, + "thick_fat": {}, + "tinted_lens": {}, + "torrent": {}, + "tough_claws": {}, + "toxic_boost": {}, + "trace": {}, + "triage": {}, + "truant": {}, + "turboblaze": {}, + "unaware": {}, + "unburden": {}, + "unnerve": {}, + "victory_star": {}, + "vital_spirit": {}, + "volt_absorb": {}, + "water_absorb": {}, + "water_bubble": {}, + "water_compaction": {}, + "water_veil": {}, + "weak_armor": {}, + "white_smoke": {}, + "wimp_out": {}, + "wonder_guard": {}, + "wonder_skin": {}, + "zen_mode": {} +} \ No newline at end of file diff --git a/Scripts/Abilities/Aftermath.as b/Scripts/Abilities/Aftermath.as new file mode 100644 index 0000000..beeba9d --- /dev/null +++ b/Scripts/Abilities/Aftermath.as @@ -0,0 +1,18 @@ +namespace Gen7 { + [Ability effect=Aftermath] + class Aftermath : PkmnScript { + void OnFaint(Pokemon@ mon, DamageSource source) override { + // If the mon fainted due to something that was not a move, ignore + if (source != DamageSource::AttackDamage){ + return; + } + // Last used attack on the target should always be the move that caused the faint if the source is AttackDamage + auto lastMoveEvent = mon.Battle.History.GetLastUsedAttackOnTarget(mon, 1); + // Check if the move is a contact move + if (lastMoveEvent.Move.UseMove.HasFlag("contact")){ + // Damage by 1/4th of the mon's max HP. + lastMoveEvent.Move.User.Damage(lastMoveEvent.Move.User.MaxHealth / 4, DamageSource::Misc); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Abilities/Analytic.as b/Scripts/Abilities/Analytic.as new file mode 100644 index 0000000..bf3b1b1 --- /dev/null +++ b/Scripts/Abilities/Analytic.as @@ -0,0 +1,15 @@ +namespace Gen7 { + [Ability effect=Analytic] + class Analytic : PkmnScript { + void OverrideBasePower(ExecutingMove@ move, Pokemon@, uint8, uint8 &inout damage) override { + // If the turnqueue of the battle is empty now, we don't have any choices to execute after this. + // This means this is the last move in the turn. + if (!move.User.Battle.TurnQueue.HasNext()){ + float expectedDamage = damage; + expectedDamage *= 1.3f; + if (expectedDamage > 255) expectedDamage = 255; + damage = uint8(expectedDamage); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Abilities/AngerPoint.as b/Scripts/Abilities/AngerPoint.as new file mode 100644 index 0000000..59d2914 --- /dev/null +++ b/Scripts/Abilities/AngerPoint.as @@ -0,0 +1,9 @@ +namespace Gen7 { + class AngerPoint : PkmnScript { + void OnIncomingHit(ExecutingMove@ move, Pokemon@ target, uint8 hit) override { + if (move.GetHitData(target, hit).IsCritical){ + target.ChangeStatBoost(Statistic::Attack, 12); + } + } + } +} \ No newline at end of file diff --git a/Scripts/Abilities/ChangeMoveType.as b/Scripts/Abilities/ChangeMoveType.as new file mode 100644 index 0000000..81bbd46 --- /dev/null +++ b/Scripts/Abilities/ChangeMoveType.as @@ -0,0 +1,31 @@ +namespace Gen7 { + [Ability effect=ChangeMoveType] + class ChangeMoveType : PkmnScript { + string _fromType; + string _toType; + bool _changedLastAttack = false; + + void OnInitialize(const narray@ parameters) override { + _fromType = parameters[0].AsString(); + _toType = parameters[1].AsString(); + } + + void ChangeAttackType(ExecutingMove@ move, Pokemon@ target, uint8 hit, uint8 &inout t) override { + auto lib = move.User.Battle.Library.StaticLibrary.TypeLibrary; + auto fromTypeId = lib.GetTypeId(_fromType); + if (fromTypeId == t){ + t = lib.GetTypeId(_toType); + _changedLastAttack = true; + } + else{ + _changedLastAttack = false; + } + } + + void ModifyDamageModifier(ExecutingMove@, Pokemon@, uint8, float &inout damageMod) override { + if (_changedLastAttack){ + damageMod *= 1.2f; + } + } + } +} \ No newline at end of file diff --git a/Scripts/Abilities/IncreasedSTAB.as b/Scripts/Abilities/IncreasedSTAB.as new file mode 100644 index 0000000..b56a26d --- /dev/null +++ b/Scripts/Abilities/IncreasedSTAB.as @@ -0,0 +1,10 @@ +namespace Gen7 { + [Ability effect=IncreasedStab] + class IncreasedStab : PkmnScript { + void OverrideSTABModifier(ExecutingMove@ move, Pokemon@ target, uint8 hit, float &inout stabMod) override { + if (move.User.HasType(move.GetHit(target, hit).Type)){ + stabMod = 2; + } + }; + } +} \ No newline at end of file diff --git a/Scripts/Abilities/SuppressWeather.as b/Scripts/Abilities/SuppressWeather.as new file mode 100644 index 0000000..02fa771 --- /dev/null +++ b/Scripts/Abilities/SuppressWeather.as @@ -0,0 +1,15 @@ +namespace Gen7 { + class SuppressWeatherAbility : PkmnScript { + void OnSwitchIn(Pokemon@ pokemon) override { + pokemon.Battle.SuppressWeather(); + pokemon.Battle.AddVolatile("SuppressWeather"); + }; + + void OnRemove() override { + auto battle = cast(GetOwner()).Battle; + battle.UnsuppressWeather(); + auto script = cast(battle.GetVolatile("SuppressWeather")); + script.Unstack(); + } + } +} \ No newline at end of file diff --git a/Scripts/Battle/SuppressWeather.as b/Scripts/Battle/SuppressWeather.as new file mode 100644 index 0000000..2029daa --- /dev/null +++ b/Scripts/Battle/SuppressWeather.as @@ -0,0 +1,21 @@ +namespace Gen7 { + [Battle effect=SuppressWeather] + class SuppressWeather : PkmnScript { + int num = 1; + + void Stack() override { + num++; + } + + void Unstack() { + num--; + if (num == 0){ + cast(GetOwner()).RemoveVolatile("SuppressWeather"); + } + } + + void BlockWeather(Battle@, bool &inout block){ + block = true; + }; + } +} \ No newline at end of file diff --git a/Scripts/Interfaces/Battle.astypedef b/Scripts/Interfaces/Battle.astypedef index 55e3cd8..8fc96e7 100644 --- a/Scripts/Interfaces/Battle.astypedef +++ b/Scripts/Interfaces/Battle.astypedef @@ -12,9 +12,11 @@ type Battle { ref@ AddVolatile(const constString &in name); ref@ GetVolatile(const constString &in name); void RemoveVolatile(const constString &in name) const; - void SetWeather(const constString &in name) const; + bool SetWeather(const constString &in name) const; void ClearWeather(const constString &in name) const; const constString& GetWeatherName() const; + void SuppressWeather() const; + void UnsuppressWeather() const; BattleSide@ GetBattleSide(uint8 index); BattleParty@ GetParty(uint8 index); BattleParty@ FindPartyForPokemon(Pokemon@ pokemon); diff --git a/Scripts/Interfaces/BattleHistory.astypedef b/Scripts/Interfaces/BattleHistory.astypedef index f4ba8f9..a9e3c6e 100644 --- a/Scripts/Interfaces/BattleHistory.astypedef +++ b/Scripts/Interfaces/BattleHistory.astypedef @@ -1,5 +1,6 @@ type BattleHistory { const HistoryElement@ TopElement { get const; }; const AttackUseHistory@ GetLastUsedAttack(uint maxTurns = 0) const; + const AttackUseHistory@ GetLastUsedAttackOnTarget(Pokemon@ target, uint maxTurns = 0) const; const DamageHistory@ GetLastDamageOnTarget(Pokemon@ target, uint maxTurns = 0) const; } diff --git a/Scripts/Interfaces/ChoiceQueue.astypedef b/Scripts/Interfaces/ChoiceQueue.astypedef index 392cce1..0015c3e 100644 --- a/Scripts/Interfaces/ChoiceQueue.astypedef +++ b/Scripts/Interfaces/ChoiceQueue.astypedef @@ -1,4 +1,5 @@ type ChoiceQueue { bool MovePokemonChoiceNext(Pokemon@ target); const BaseTurnChoice@ Peek() const; + bool HasNext() const; } diff --git a/Scripts/Interfaces/DamageSource.astypedef b/Scripts/Interfaces/DamageSource.astypedef index c3415ac..2921944 100644 --- a/Scripts/Interfaces/DamageSource.astypedef +++ b/Scripts/Interfaces/DamageSource.astypedef @@ -1,4 +1,5 @@ enum DamageSource { AttackDamage = 0, - Struggle = 1, + Misc = 1, + Struggle = 2, } diff --git a/Scripts/Interfaces/PkmnScript.as b/Scripts/Interfaces/PkmnScript.as index ecbd591..a35c35c 100644 --- a/Scripts/Interfaces/PkmnScript.as +++ b/Scripts/Interfaces/PkmnScript.as @@ -17,6 +17,7 @@ shared abstract class PkmnScript { void OnAttackMiss(ExecutingMove@, Pokemon@){}; void ChangeAttackType(ExecutingMove@, Pokemon@, uint8, uint8 &inout){}; void ChangeEffectiveness(ExecutingMove@, Pokemon@, uint8, float &inout){}; + void OnIncomingHit(ExecutingMove@, Pokemon@, uint8){}; void PreventSecondaryEffects(ExecutingMove@, Pokemon@, uint8, bool &inout){}; void OnSecondaryEffect(ExecutingMove@, Pokemon@, uint8){}; void OnAfterHits(ExecutingMove@, Pokemon@){}; @@ -38,9 +39,12 @@ shared abstract class PkmnScript { void PreventOpponentRunAway(FleeTurnChoice@, bool &inout){}; void PreventOpponentSwitch(SwitchTurnChoice@, bool &inout){}; void OnEndTurn(){}; + void OnFaint(Pokemon@, DamageSource){}; void ModifyCriticalStage(ExecutingMove@, Pokemon@, uint8, uint8 &inout){}; void OverrideCriticalModifier(ExecutingMove@, Pokemon@, uint8, float &inout){}; void OverrideSTABModifier(ExecutingMove@, Pokemon@, uint8, float &inout){}; void ModifyExperienceGain(Pokemon@, Pokemon@, uint &inout){}; void DoesShareExperience(Pokemon@, Pokemon@, bool &inout){}; + void BlockWeather(Battle@, bool &inout){}; + void OnSwitchIn(Pokemon@){}; } diff --git a/Scripts/Interfaces/Pokemon.astypedef b/Scripts/Interfaces/Pokemon.astypedef index 3d16e00..d69710c 100644 --- a/Scripts/Interfaces/Pokemon.astypedef +++ b/Scripts/Interfaces/Pokemon.astypedef @@ -8,7 +8,6 @@ type Pokemon { bool Shiny { get const; }; const Item@ HeldItem { get const; }; uint CurrentHealth { get const; }; - const constString& ActiveAbility { get const; }; bool IsFainted { get const; }; uint MaxHealth { get const; }; const Species@ DisplaySpecies { get const; }; @@ -19,6 +18,7 @@ type Pokemon { const narray@ Moves { get const; }; float Weight { get const; set; }; float Height { get const; set; }; + const constString& ActiveAbility { get const; }; bool HasHeldItem(const constString &in name) const; void SetHeldItem(const constString &in name); void SetHeldItem(const Item@ item);