Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redo Violet #84

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 32 additions & 20 deletions data/mods/gen9ssb/abilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 30 additions & 10 deletions data/mods/gen9ssb/conditions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
93 changes: 34 additions & 59 deletions data/mods/gen9ssb/moves.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions data/mods/gen9ssb/random-teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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'],
Expand Down
40 changes: 40 additions & 0 deletions data/mods/gen9ssb/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading