Castform and Cherrim Abilities

Add support for Castform and Cherrim's form changes.
Add a Weather form ability check. Current Implementation is identical to their gen 4 implementation.

Cherrim changes forms regardless of whether their ability is suppressed
Castform changes forms only if their ability is not suppressed

Nuetralizing Gas be the death of us all.
This commit is contained in:
Gwen Valentine 2024-04-23 01:29:24 -04:00
parent ece3410b89
commit 22add553a1
4 changed files with 82 additions and 6 deletions

View File

@ -2544,7 +2544,8 @@ export function initAbilities() {
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, "Plus (N)", "Boosts the Sp. Atk stat of the Pokémon if an ally with the Plus or Minus Ability is also in battle.", 3),
new Ability(Abilities.MINUS, "Minus (N)", "Boosts the Sp. Atk stat of the Pokémon if an ally with the Plus or Minus Ability is also in battle.", 3),
new Ability(Abilities.FORECAST, "Forecast (N)", "The Pokémon transforms with the weather to change its type to Water, Fire, or Ice.", 3)
new Ability(Abilities.FORECAST, "Forecast (P)", "The Pokémon transforms with the weather to change its type to Water, Fire, or Ice.", 3)
.attr(PostWeatherChangeAbAttr)
.attr(UncopiableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr),
new Ability(Abilities.STICKY_HOLD, "Sticky Hold", "Items held by the Pokémon are stuck fast and cannot be removed by other Pokémon.", 3)
@ -2706,6 +2707,7 @@ export function initAbilities() {
new Ability(Abilities.FLOWER_GIFT, "Flower Gift (P)", "Boosts the Attack and Sp. Def stats of itself and allies in harsh sunlight.", 4)
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5)
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY || WeatherType.HARSH_SUN), BattleStatMultiplierAbAttr, BattleStat.SPDEF, 1.5)
.attr(PostWeatherChangeAbAttr)
.attr(UncopiableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr)
.ignorable(),
@ -3137,6 +3139,7 @@ export function initAbilities() {
new Ability(Abilities.PROTOSYNTHESIS, "Protosynthesis", "Boosts the Pokémon's most proficient stat in harsh sunlight or if the Pokémon is holding Booster Energy.", 9)
.conditionalAttr(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN), PostSummonAddBattlerTagAbAttr, BattlerTagType.PROTOSYNTHESIS, 0, true)
.attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.PROTOSYNTHESIS, 0, WeatherType.SUNNY, WeatherType.HARSH_SUN)
.attr(UnsuppressableAbilityAbAttr)
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr),

View File

@ -7,6 +7,9 @@ import { Species } from "./enums/species";
import { StatusEffect } from "./status-effect";
import { MoveCategory, allMoves } from "./move";
import { Abilities } from "./enums/abilities";
import { WeatherType } from "./weather";
import { UnsuppressableAbilityAbAttr } from "./ability";
import { Ability } from "pokenode-ts";
export enum FormChangeItem {
NONE,
@ -228,6 +231,43 @@ export class SpeciesFormChangeActiveTrigger extends SpeciesFormChangeTrigger {
}
}
//checks the current weather in battle to determine form
export class SpeciesFormChangeWeatherTrigger extends SpeciesFormChangeTrigger {
public weatherType: WeatherType[];
public invert: boolean;
constructor(weatherType: WeatherType | WeatherType[], invert:boolean = false){
super();
if(!Array.isArray(weatherType))
weatherType = [weatherType];
this.weatherType = weatherType;
this.invert = invert;
}
canChange(pokemon: Pokemon): boolean {
if(!pokemon.scene.arena.weather){
return this.weatherType.indexOf(WeatherType.NONE) > -1 !== this.invert;
}
return this.weatherType.indexOf(pokemon.scene.arena.weather.weatherType) > -1 !== this.invert;
}
}
export class SpeciesFormChangeAbilitySuppressionTrigger extends SpeciesFormChangeTrigger {
public ability : Abilities
public invert: boolean;
constructor(ability : Abilities, invert:boolean = false){
super();
this.ability = ability
this.invert = invert;
}
canChange(pokemon: Pokemon): boolean {
return pokemon.hasAbility(this.ability) !== this.invert;
}
}
export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigger {
public statusEffects: StatusEffect[];
public invert: boolean;
@ -284,6 +324,7 @@ export class SpeciesFormChangePostMoveTrigger extends SpeciesFormChangeMoveTrigg
}
}
//Trigger for subforms having their own species form change that aren't interchangable, string check for the forms to match
export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
private formKey: string;
@ -297,6 +338,7 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
}
}
export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: SpeciesFormChange, preName: string): string {
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
const isGmax = formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1;
@ -674,6 +716,29 @@ export const pokemonFormChanges: PokemonFormChanges = {
[Species.GALAR_DARMANITAN]: [
new SpeciesFormChange(Species.GALAR_DARMANITAN, '', 'zen', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.GALAR_DARMANITAN, 'zen', '', new SpeciesFormChangeManualTrigger(), true)
],
[Species.CASTFORM]: [
//change to fire
new SpeciesFormChange(Species.CASTFORM, '', 'sunny', new SpeciesFormChangeWeatherTrigger([WeatherType.HARSH_SUN, WeatherType.SUNNY]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'rainy', 'sunny', new SpeciesFormChangeWeatherTrigger([WeatherType.HARSH_SUN, WeatherType.SUNNY]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'snowy', 'sunny', new SpeciesFormChangeWeatherTrigger([WeatherType.HARSH_SUN, WeatherType.SUNNY]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
//change to water
new SpeciesFormChange(Species.CASTFORM, '', 'rainy', new SpeciesFormChangeWeatherTrigger([WeatherType.HEAVY_RAIN, WeatherType.RAIN]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'sunny', 'rainy', new SpeciesFormChangeWeatherTrigger([WeatherType.HEAVY_RAIN, WeatherType.RAIN]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'snowy', 'rainy', new SpeciesFormChangeWeatherTrigger([WeatherType.HEAVY_RAIN, WeatherType.RAIN]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),//loving in the moonlight
//change to ice
new SpeciesFormChange(Species.CASTFORM, '', 'snowy', new SpeciesFormChangeWeatherTrigger([WeatherType.SNOW, WeatherType.HAIL]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'sunny', 'snowy', new SpeciesFormChangeWeatherTrigger([WeatherType.SNOW, WeatherType.HAIL]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'rainy', 'snowy', new SpeciesFormChangeWeatherTrigger([WeatherType.SNOW, WeatherType.HAIL]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),//having a wonderful time
//change to normal
new SpeciesFormChange(Species.CASTFORM, 'sunny', '', new SpeciesFormChangeWeatherTrigger([WeatherType.FOG, WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'rainy', '', new SpeciesFormChangeWeatherTrigger([WeatherType.FOG, WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST))),
new SpeciesFormChange(Species.CASTFORM, 'snowy', '', new SpeciesFormChangeWeatherTrigger([WeatherType.FOG, WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS]), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.FORECAST)))
],
[Species.CHERRIM]:[
//the seasonal depression pokemon
new SpeciesFormChange(Species.CHERRIM, 'overcast', 'sunshine', new SpeciesFormChangeWeatherTrigger([WeatherType.HARSH_SUN, WeatherType.SUNNY]), true),
new SpeciesFormChange(Species.CHERRIM, 'sunshine', 'overcast', new SpeciesFormChangeWeatherTrigger([WeatherType.HARSH_SUN, WeatherType.SUNNY], true), true)
]
};

View File

@ -14,6 +14,7 @@ import { ArenaTagType } from "../data/enums/arena-tag-type";
import { TrainerType } from "../data/enums/trainer-type";
import { BattlerIndex } from "../battle";
import { Moves } from "../data/enums/moves";
import { SpeciesFormChangeWeatherTrigger } from "../data/pokemon-forms";
import { TimeOfDay } from "../data/enums/time-of-day";
import { Terrain, TerrainType } from "../data/terrain";
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
@ -303,8 +304,16 @@ export class Arena {
}
this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => 'weatherTypes' in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather));
pokemon.findAndRemoveTags(t => 'weatherTypes' in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather));
applyPostWeatherChangeAbAttrs(PostWeatherChangeAbAttr, pokemon, weather);
if(this.weather){
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeWeatherTrigger, false );
}
else{
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeWeatherTrigger, true );
}
//
});
return true;

View File

@ -45,7 +45,7 @@ import { vouchers } from "./system/voucher";
import { loggedInUser, updateUserInfo } from "./account";
import { PlayerGender, SessionSaveData } from "./system/game-data";
import { addPokeballCaptureStars, addPokeballOpenParticles } from "./field/anims";
import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeManualTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangePreMoveTrigger } from "./data/pokemon-forms";
import { SpeciesFormChangeActiveTrigger, SpeciesFormChangeManualTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangePreMoveTrigger, SpeciesFormChangeWeatherTrigger} from "./data/pokemon-forms";
import { battleSpecDialogue, getCharVariantFromDialogue } from "./data/dialogue";
import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "./ui/modifier-select-ui-handler";
import { Setting } from "./system/settings";
@ -1292,7 +1292,7 @@ export class SummonPhase extends PartyMemberPokemonPhase {
if (!this.loaded || this.scene.currentBattle.battleType === BattleType.TRAINER || (this.scene.currentBattle.waveIndex % 10) === 1) {
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);
this.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeWeatherTrigger, false);
this.queuePostSummon();
}
}
@ -2796,8 +2796,7 @@ export class WeatherEffectPhase extends CommonAnimPhase {
}
this.scene.ui.showText(getWeatherLapseMessage(this.weather.weatherType), null, () => {
this.executeForAll((pokemon: Pokemon) => applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather));
this.executeForAll((pokemon: Pokemon) => applyPostWeatherLapseAbAttrs(PostWeatherLapseAbAttr, pokemon, this.weather));
super.start();
});
}