From d65cc9de7df78aad04e7f9046cd4f1d209bc0fed Mon Sep 17 00:00:00 2001 From: Hisuian Zoroark <96159984+HisuianZoroark@users.noreply.github.com> Date: Mon, 19 Feb 2024 02:01:47 -0500 Subject: [PATCH] Redo Violet --- data/mods/gen9ssb/abilities.ts | 52 ++++++++++------- data/mods/gen9ssb/conditions.ts | 40 +++++++++---- data/mods/gen9ssb/moves.ts | 93 +++++++++++-------------------- data/mods/gen9ssb/random-teams.ts | 10 ++-- data/mods/gen9ssb/scripts.ts | 40 +++++++++++++ 5 files changed, 141 insertions(+), 94 deletions(-) diff --git a/data/mods/gen9ssb/abilities.ts b/data/mods/gen9ssb/abilities.ts index db671a1ae..984fe2e18 100644 --- a/data/mods/gen9ssb/abilities.ts +++ b/data/mods/gen9ssb/abilities.ts @@ -1123,31 +1123,43 @@ export const Abilities: {[k: string]: ModdedAbilityData} = { }, // Violet - scarletaeonia: { - shortDesc: "50% HP: +Flying-type, summons Scarlet Aeonia Terrain, loses item.", - name: "Scarlet Aeonia", - onStart(pokemon) { - if (pokemon.m.phaseChange) { - if (pokemon.addType('Flying')) { - this.add('-start', pokemon, 'typeadd', 'Flying', '[from] ability: Scarlet Aeonia'); + seenoevilhearnoevilspeaknoevil: { + shortDesc: "Dark Immunity; Cornerstone: Sound immunity. Wellspring: Moves never miss. Hearthflame: 1.3x bp vs male Pokemon.", + name: "See No Evil, Hear No Evil, Speak No Evil", + onTryHit(target, source, move) { + if (target !== source && move.flags['sound'] && target.species.id === 'ogerponcornerstone') { + if (!this.heal(target.baseMaxhp / 4)) { + this.add('-immune', target, '[from] ability: See No Evil, Hear No Evil, Speak No Evil'); } - this.field.setTerrain('scarletaeoniaterrain'); + return null; + } + + if (target !== source && move.type === 'Dark') { + this.add('-immune', target, '[from] ability: See No Evil, Hear No Evil, Speak No Evil'); + return null; } }, - onResidualOrder: 29, - onResidual(pokemon) { - if (!pokemon.hp) return; - if (pokemon.hp > pokemon.maxhp / 2) return; - this.add('-activate', pokemon, 'ability: Scarlet Aeonia'); - this.add(`c:|${getName('Vio͜͡let')}|The scarlet bloom flowers once more. You will witness true horror. Now, rot!`); - pokemon.m.phaseChange = true; - if (pokemon.addType('Flying')) { - this.add('-start', pokemon, 'typeadd', 'Flying', '[from] ability: Scarlet Aeonia'); + onSourceAccuracy(accuracy, target, source, move) { + if (source.species.id !== 'ogerponwellspring') return; + if (typeof accuracy !== 'number') return; + return true; + }, + onSourceModifyDamage(damage, source, target, move) { + if (source.species.id !== 'ogerponwellspring') return; + if (typeof move.accuracy === 'number' && move.accuracy < 100) { + this.debug('neutralize'); + return this.chainModify(0.75); } - pokemon.takeItem(); - this.field.setTerrain('scarletaeoniaterrain'); }, - flags: {}, + onBasePowerPriority: 24, + onBasePower(basePower, attacker, defender, move) { + if (attacker.species.id !== 'ogerponhearthflame') return; + if (defender.gender === 'M') { + this.debug('attack boost'); + return this.chainModify(1.3); + } + }, + flags: {breakable: 1}, }, // WarriorGallade diff --git a/data/mods/gen9ssb/conditions.ts b/data/mods/gen9ssb/conditions.ts index f3f1cd6dc..d1498d086 100644 --- a/data/mods/gen9ssb/conditions.ts +++ b/data/mods/gen9ssb/conditions.ts @@ -926,19 +926,39 @@ export const Conditions: {[k: string]: ModdedConditionData & {innateName?: strin violet: { noCopy: true, onStart() { - this.add(`c:|${getName('Vio͜͡let')}|...Heed my words. I am Malenia, Blade of Miquella. And I have never known defeat.`); + this.add(`c:|${getName('Vio͜͡let')}|I’m not hating you just decided to be wrong`); }, - onSourceAfterFaint(length, target, source, effect) { - if (effect?.effectType === 'Move') { - if (source?.m.phaseChange) { - this.add(`c:|${getName('Vio͜͡let')}|Let your flesh be consumed. By the scarlet rot.`); - } else { - this.add(`c:|${getName('Vio͜͡let')}|I am Malenia, Blade of Miquella.`); - } - } + onSwitchOut() { + this.add(`c:|${getName('Vio͜͡let')}|anyway…`); }, onFaint() { - this.add(`c:|${getName('Vio͜͡let')}|Your strength, extraordinary… The mark... of a true Lord…`); + this.add(`c:|${getName('Vio͜͡let')}|blatantly carried by cheating but you’ll still find a way to downplay`); + }, + innateName: "Do No Evil", + shortDesc: "When this Pokemon uses an attacking move, it transforms into the Ogerpon form of the corresponding type.", + onModifyMove(move, attacker, defender) { + if (attacker.species.baseSpecies !== 'Ogerpon' || attacker.transformed) return; + let targetForme = 'Ogerpon'; + switch (move.type) { + case 'Rock': + targetForme += '-Cornerstone'; + break; + case 'Fire': + targetForme += '-Hearthflame'; + break; + case 'Water': + targetForme += '-Wellspring'; + break; + case 'Grass': + // Do nothing + break; + default: + return; + } + if (attacker.species.name !== targetForme) { + this.add('-activate', attacker, 'ability: Do No Evil'); + attacker.formeChange(targetForme); + } }, }, warriorgallade: { diff --git a/data/mods/gen9ssb/moves.ts b/data/mods/gen9ssb/moves.ts index 43294e65d..c960a9fdf 100644 --- a/data/mods/gen9ssb/moves.ts +++ b/data/mods/gen9ssb/moves.ts @@ -2200,71 +2200,46 @@ export const Moves: {[k: string]: ModdedMoveData} = { }, // Violet - waterfowldance: { + buildingcharacter: { accuracy: 95, - basePower: 7, + basePower: 50, + basePowerCallback(pokemon, target, move) { + if (target?.terastallized) { + this.debug('BP doubled from tera'); + return move.basePower * 2; + } + return move.basePower; + }, category: "Physical", - shortDesc: "Hits 10 times. Heals 100% of damage dealt.", - name: "Waterfowl Dance", + shortDesc: "vs Tera'd opponent: 0 prio, 2x bp, removes Tera.", + name: "building character", gen: 9, - pp: 5, - priority: 0, - flags: {protect: 1, mirror: 1, heal: 1, dance: 1}, - drain: [1, 1], - onPrepareHit() { - this.attrLastMove('[anim] Sacred Sword'); - }, - multihit: 10, - multiaccuracy: true, - secondary: null, - target: "normal", - type: "Flying", - }, - scarletaeoniaterrain: { - accuracy: true, - basePower: 0, - category: "Status", - name: "Scarlet Aeonia Terrain", - shortDesc: "5 turns: Contact moves have 25% to badly psn vs grounded.", pp: 10, - priority: 0, - flags: {nonsky: 1}, - pseudoWeather: 'scarletaeoniaterrain', - condition: { - duration: 5, - durationCallback(source, effect) { - if (source?.hasItem('terrainextender')) { - return 8; - } - return 5; - }, - onFieldStart(field, source, effect) { - if (effect?.effectType === 'Ability') { - this.add('-fieldstart', 'move: Scarlet Aeonia Terrain', '[from] ability: ' + effect.name, '[of] ' + source); - } else { - this.add('-fieldstart', 'move: Scarlet Aeonia Terrain'); - } - }, - onModifyMove(move, source, target) { - if (!target?.isGrounded()) return; - if (!move?.flags['contact'] || move.target === 'self') return; - if (!move.secondaries) { - move.secondaries = []; - } - move.secondaries.push({ - chance: 25, - status: 'tox', - }); - }, - onFieldResidualOrder: 27, - onFieldResidualSubOrder: 1, - onFieldEnd() { - this.add('-fieldend', 'move: Scarlet Aeonia Terrain'); - }, + priority: 1, + onModifyPriority(move, pokemon, target) { + if (target?.terastallized) return 0; + }, + flags: {protect: 1, mirror: 1}, + onTryMove() { + this.attrLastMove('[still]'); + }, + onPrepareHit(target, source) { + this.add('-anim', source, "Esper Wing", target); + this.add('-anim', source, "Defog", source); + }, + onHit(pokemon, source) { + // TODO: Client support for removing tera without fainting + if (pokemon?.terastallized) { + this.add(`c:|${getName('Vio͜͡let')}|lol never do that ever again thanks`); + delete pokemon.terastallized; + const details = pokemon.species.name + (pokemon.level === 100 ? '' : ', L' + pokemon.level) + + (pokemon.gender === '' ? '' : ', ' + pokemon.gender) + (pokemon.set.shiny ? ', shiny' : ''); + this.add('detailschange', pokemon, details); + } }, secondary: null, - target: "all", - type: "Poison", + target: "normal", + type: "Grass", }, // WarriorGallade - TODO: Fix animations diff --git a/data/mods/gen9ssb/random-teams.ts b/data/mods/gen9ssb/random-teams.ts index 938e177f1..de5733d44 100644 --- a/data/mods/gen9ssb/random-teams.ts +++ b/data/mods/gen9ssb/random-teams.ts @@ -52,7 +52,7 @@ export const ssbSets: SSBSets = { species: 'Sprigatito', ability: 'Pawprints', item: 'Eviolite', gender: '', moves: ['Substitute', 'Protect', 'Magic Powder'], signatureMove: 'Spicier Extract', - evs: {hp: 252, def: 4, spd: 252}, nature: 'Careful', + evs: {hp: 252, def: 4, spd: 252}, nature: 'Careful', teraType: 'Water', }, aQrator: { species: 'Totodile', ability: 'Neverending fHunt', item: 'Eviolite', gender: 'F', @@ -420,10 +420,10 @@ export const ssbSets: SSBSets = { evs: {hp: 248, def: 244, spd: 16}, nature: 'Calm', teraType: 'Normal', shiny: 5, }, 'Vio͜͡let': { - species: 'Iron Valiant', ability: 'Scarlet Aeonia', item: 'Auspicious Armor', gender: 'F', - moves: ['Bitter Blade', 'Cross Poison', 'No Retreat'], - signatureMove: 'Waterfowl Dance', - evs: {atk: 252, spd: 4, spe: 252}, nature: 'Adamant', teraType: 'Fairy', shiny: true, + species: 'Ogerpon', ability: 'See No Evil, Hear No Evil, Speak No Evil', item: 'Berry Juice', gender: 'F', + moves: ['Crabhammer', 'Mighty Cleave', 'Fire Lash'], + signatureMove: 'building character', + evs: {atk: 252, spd: 4, spe: 252}, nature: 'Jolly', teraType: 'Stellar', }, WarriorGallade: { species: 'Tropius', ability: 'Primeval Harvest', item: 'Starf Berry', gender: ['M', 'M', 'F'], diff --git a/data/mods/gen9ssb/scripts.ts b/data/mods/gen9ssb/scripts.ts index 92a3addce..acdba0700 100644 --- a/data/mods/gen9ssb/scripts.ts +++ b/data/mods/gen9ssb/scripts.ts @@ -152,6 +152,46 @@ export function changeMoves(context: Battle, pokemon: Pokemon, newMoves: (string export const Scripts: ModdedBattleScriptsData = { gen: 9, inherit: 'gen9', + getActionSpeed(action) { + if (action.choice === 'move') { + let move = action.move; + if (action.zmove) { + const zMoveName = this.actions.getZMove(action.move, action.pokemon, true); + if (zMoveName) { + const zMove = this.dex.getActiveMove(zMoveName); + if (zMove.exists && zMove.isZ) { + move = zMove; + } + } + } + if (action.maxMove) { + const maxMoveName = this.actions.getMaxMove(action.maxMove, action.pokemon); + if (maxMoveName) { + const maxMove = this.actions.getActiveMaxMove(action.move, action.pokemon); + if (maxMove.exists && maxMove.isMax) { + move = maxMove; + } + } + } + // WHY DOES onModifyPriority TAKE A TARGET ARG WHEN IT IS ALWAYS NULL????? + const target = this.getTarget(action.pokemon, action.move, action.targetLoc); + // take priority from the base move, so abilities like Prankster only apply once + // (instead of compounding every time `getActionSpeed` is called) + let priority = this.dex.moves.get(move.id).priority; + // Grassy Glide priority + priority = this.singleEvent('ModifyPriority', move, null, action.pokemon, target, null, priority); + priority = this.runEvent('ModifyPriority', action.pokemon, target, move, priority); + action.priority = priority + action.fractionalPriority; + // In Gen 6, Quick Guard blocks moves with artificially enhanced priority. + if (this.gen > 5) action.move.priority = priority; + } + + if (!action.pokemon) { + action.speed = 1; + } else { + action.speed = action.pokemon.getActionSpeed(); + } + }, checkMoveMakesContact(move, attacker, defender, announcePads) { if (move.flags['contact'] && attacker.hasItem('protectivepads')) { if (announcePads) {