From 83bb7819cf0c1a5aee841c01914f7201ce49e8fe Mon Sep 17 00:00:00 2001 From: WarriorGallade <100499523+WarriorGallade@users.noreply.github.com> Date: Fri, 23 Feb 2024 07:42:18 +0530 Subject: [PATCH] Add Two of Roses (#95) Co-authored-by: Kris Johnson <11083252+KrisXV@users.noreply.github.com> --- data/mods/gen9ssb/abilities.ts | 41 +++++++++++++++++++ data/mods/gen9ssb/conditions.ts | 65 +++++++++++++++++++++++++++++++ data/mods/gen9ssb/moves.ts | 46 ++++++++++++++++++++++ data/mods/gen9ssb/random-teams.ts | 6 +++ 4 files changed, 158 insertions(+) diff --git a/data/mods/gen9ssb/abilities.ts b/data/mods/gen9ssb/abilities.ts index 421f59167..e849d4f44 100644 --- a/data/mods/gen9ssb/abilities.ts +++ b/data/mods/gen9ssb/abilities.ts @@ -1363,6 +1363,47 @@ export const Abilities: {[k: string]: ModdedAbilityData} = { flags: {}, }, + // Two of Roses + aswesee: { + name: "As We See", + desc: "Once per turn, when any active Pokemon has a stat boosted, this Pokemon has a 50% chance of copying it and a 15% chance to raise another random stat.", + shortDesc: "1x per turn: Stat gets boosted -> 50% chance to copy, 15% to raise another.", + onFoeAfterBoost(boost, target, source, effect) { // Opportunist + if (this.randomChance(1, 2)) { + if (effect && ['As We See', 'Mirror Herb', 'Opportunist'].includes(effect.name)) return; + const pokemon = this.effectState.target; + const positiveBoosts: Partial = {}; + let i: BoostID; + for (i in boost) { + if (boost[i]! > 0) { + positiveBoosts[i] = boost[i]; + } + } + if (Object.keys(positiveBoosts).length < 1) return; + this.boost(positiveBoosts, pokemon); + this.effectState.triggered = true; + } + }, + onResidual(target, source, effect) { + if (this.randomChance(15, 100) && this.effectState.triggered) { + const stats: BoostID[] = []; + const boost: SparseBoostsTable = {}; + let statPlus: BoostID; + for (statPlus in target.boosts) { + if (statPlus === 'accuracy' || statPlus === 'evasion') continue; + if (target.boosts[statPlus] < 6) { + stats.push(statPlus); + } + } + const randomStat: BoostID | undefined = stats.length ? this.sample(stats) : undefined; + if (randomStat) boost[randomStat] = 1; + this.boost(boost, target, target); + } + this.effectState.triggered = false; + }, + flags: {}, + }, + // UT galeguard: { shortDesc: "Only damaged by direct attacks; Flying moves +1 priority.", diff --git a/data/mods/gen9ssb/conditions.ts b/data/mods/gen9ssb/conditions.ts index 4f17d74c1..a9ff1ded9 100644 --- a/data/mods/gen9ssb/conditions.ts +++ b/data/mods/gen9ssb/conditions.ts @@ -1110,6 +1110,71 @@ export const Conditions: {[k: string]: ModdedConditionData & {innateName?: strin this.add(`c:|${getName('trace')}|How disappointingly short a dream lasts.`); }, }, + twoofroses: { + noCopy: true, + onStart(pokemon) { + this.add(`c:|${getName('Two of Roses')}|I'm here! I'm uhh- Yes! Also hi! Happy to be here.`); + this.singleEvent('WeatherChange', this.effect, this.effectState, pokemon); + this.singleEvent('TerrainChange', this.effect, this.effectState, pokemon); + }, + onSwitchOut() { + this.add(`c:|${getName('Two of Roses')}|Pfft! I prefer lurking anyway.`); + }, + onFaint() { + this.add(`c:|${getName('Two of Roses')}|It matters not how much we try but only that we try. For if the tides swell the dunes of a timeless existence, and our strength wanes in the coming unlight- And if we are to be as the forsaken namesakes before us, for the yesterday that never came and the tomorrow that is forever promised, know this; We dilly, so they do not dally...`); + }, + innateName: "Wonderer", + shortDesc: "This Pokemon's secondary type changes based on the active weather or terrain, monotype if neither.", + onWeatherChange(target, source, sourceEffect) { + const currentWeather = this.field.getWeather().id; + const currentTerrain = this.field.getTerrain().id; + const types = target.hasType; + let type = 'Dark'; + if (!currentWeather && !currentTerrain && !types('Dark')) { + type = 'Dark'; + } else if (currentWeather) { + if (['raindance', 'primordialsea'].includes(currentWeather) && !types('Water')) { + type = 'Water'; + } else if (['sunnyday', 'desolateland'].includes(currentWeather) && !types('Fire')) { + type = 'Fire'; + } else if (['sandstorm', 'deserteddunes'].includes(currentWeather) && !types('Rock')) { + type = 'Rock'; + } else if (['hail', 'snow'].includes(currentWeather) && !types('Ice')) { + type = 'Ice'; + } else { + // do nothing if it's not the 4 primary weathers...unless there are more? + } + } + target.addType(type); + this.add('-start', target, 'typeadd', type, '[from] ability: Wonderer'); + }, + onTerrainChange(target, source, sourceEffect) { + const currentWeather = this.field.getWeather().id; + const currentTerrain = this.field.getTerrain().id; + let type = 'Dark'; + const types = target.hasType; + if (!currentWeather && !currentTerrain && !types('Dark')) { + type = 'Dark'; + } else if (currentTerrain) { + if (currentTerrain === 'electricterrain') { + target.setType('Electric'); + type = ''; + } else if (currentTerrain === 'psychicterrain' && !types('Psychic')) { + type = 'Psychic'; + } else if (currentTerrain === 'grassyterrain' && !types('Grass')) { + type = 'Grass'; + } else if (currentTerrain === 'mistyterrain' && !types('Fairy')) { + type = 'Fairy'; + } else if (!types('Ghost')) { // custom terrains + type = 'Ghost'; + } + } + if (type) { + target.addType(type); + this.add('-start', target, 'typeadd', type, '[from] ability: Wonderer'); + } + }, + }, ut: { noCopy: true, onStart() { diff --git a/data/mods/gen9ssb/moves.ts b/data/mods/gen9ssb/moves.ts index 4e662d01c..25ead8ec2 100644 --- a/data/mods/gen9ssb/moves.ts +++ b/data/mods/gen9ssb/moves.ts @@ -2567,6 +2567,52 @@ export const Moves: {[k: string]: ModdedMoveData} = { type: "Psychic", }, + // Two of Roses + dillydally: { + accuracy: 90, + basePower: 40, + category: "Physical", + shortDesc: "2 hits, +1 random stat/hit. Type = User 2nd type.", + name: "Dilly Dally", + pp: 20, + priority: 0, + multihit: 2, + flags: {protect: 1, contact: 1}, + type: "???", + onTryMove() { + this.attrLastMove('[still]'); + }, + onModifyType(move, pokemon) { + let type = pokemon.getTypes()[pokemon.getTypes().length - 1]; + if (type === "Bird" || type === undefined) type = "???"; + if (type === "Stellar") type = pokemon.getTypes()[pokemon.getTypes(false, true).length - 1]; + move.type = type; + }, + secondary: { + chance: 100, + onHit(target, source, move) { + const stats: BoostID[] = []; + const boost: SparseBoostsTable = {}; + let statPlus: BoostID; + for (statPlus in source.boosts) { + if (statPlus === 'accuracy' || statPlus === 'evasion') continue; + if (source.boosts[statPlus] < 6) { + stats.push(statPlus); + } + } + const randomStat: BoostID | undefined = stats.length ? this.sample(stats) : undefined; + if (randomStat) boost[randomStat] = 1; + this.boost(boost, source, source); + }, + }, + onPrepareHit(target, source) { + this.add('-anim', source, 'Volt Tackle', source); + this.add('-anim', source, 'Extreme Speed', target); + }, + target: "normal", + }, + + // UT wingover: { accuracy: 100, diff --git a/data/mods/gen9ssb/random-teams.ts b/data/mods/gen9ssb/random-teams.ts index fad83a33d..7d235c9e1 100644 --- a/data/mods/gen9ssb/random-teams.ts +++ b/data/mods/gen9ssb/random-teams.ts @@ -474,6 +474,12 @@ export const ssbSets: SSBSets = { signatureMove: 'Chronostasis', evs: {spa: 252, spd: 4, spe: 252}, ivs: {atk: 0}, nature: 'Modest', teraType: 'Psychic', }, + 'Two of Roses': { + species: 'Luxray', ability: 'As We See', item: 'Mirror Herb', gender: 'M', + moves: ['Knock Off', 'Supercell Slam', 'Trailblaze'], + signatureMove: 'Dilly Dally', + evs: {atk: 252, spd: 4, spe: 252}, nature: 'Jolly', teraType: 'Flying', shiny: 1024, + }, UT: { species: 'Talonflame', ability: 'Gale Guard', item: 'Life Orb', gender: 'M', moves: ['Brave Bird', 'Roost', ['Swords Dance', 'Flare Blitz', 'Will-O-Wisp']],