Add Terestallization mechanics

Add Terestallization mechanics; implement Stellar type; fix bug with held item weights
This commit is contained in:
Flashfyre committed 2024-02-17 00:40:03 -05:00
1 parent 5ec199a428
commit dadc08d16e
60 files changed
+3585 -2258

No files matched your search

+3 -3
View File
@@ -322,7 +322,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (hitResult < HitResult.NO_EFFECT) {
const type = move.getMove().type;
const pokemonTypes = pokemon.getTypes();
const pokemonTypes = pokemon.getTypes(true);
if (pokemonTypes.length !== 1 || pokemonTypes[0] !== type) {
pokemon.summonData.types = [ type ];
return true;
@@ -333,7 +333,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
}
getTriggerMessage(pokemon: Pokemon, ...args: any[]): string {
return getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nmade it the ${Utils.toReadableString(Type[pokemon.getTypes()[0]])} type!`);
return getPokemonMessage(pokemon, `'s ${pokemon.getAbility().name}\nmade it the ${Utils.toReadableString(Type[pokemon.getTypes(true)[0]])} type!`);
}
}
@@ -656,7 +656,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
const targets = pokemon.getOpponents();
let target: Pokemon;
if (targets.length > 1)
pokemon.scene.executeWithSeedOffset(() => target = Phaser.Math.RND.pick(targets), pokemon.scene.currentBattle.waveIndex);
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else
target = targets[0];
+2 -2
View File
@@ -6,6 +6,7 @@ import * as Utils from "../utils";
import { BattlerIndex } from "../battle";
import stringify, { Element } from "json-stable-stringify";
import { Moves } from "./enums/moves";
import { getTypeRgb } from "./type";
//import fs from 'vite-plugin-fs/browser';
export enum AnimFrameTarget {
@@ -764,8 +765,7 @@ export abstract class BattleAnim {
const spriteSource = isUser ? userSprite : targetSprite;
if ((isUser ? u : t) === sprites.length) {
let sprite: Phaser.GameObjects.Sprite;
sprite = scene.addFieldSprite(0, 0, spriteSource.texture, spriteSource.frame.name);
sprite.setPipeline(scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: true });
sprite = scene.addPokemonSprite(isUser ? user : target, 0, 0, spriteSource.texture, spriteSource.frame.name, true);
[ 'spriteColors', 'fusionSpriteColors' ].map(k => sprite.pipelineData[k] = (isUser ? user : target).getSprite().pipelineData[k]);
spriteSource.on('animationupdate', (_anim, frame) => sprite.setFrame(frame.textureFrame));
scene.field.add(sprite);
+2 -2
View File
@@ -98,7 +98,7 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta
let ret: Species;
scene.executeWithSeedOffset(() => {
ret = Phaser.Math.RND.pick(legendarySpecies);
ret = Utils.randSeedItem(legendarySpecies);
}, Utils.getSunday(new Date(timestamp)).getTime(), EGG_SEED.toString());
return ret;
@@ -109,7 +109,7 @@ export function getTypeGachaTypeForTimestamp(scene: BattleScene, timestamp: inte
let ret: Type;
scene.executeWithSeedOffset(() => {
ret = Phaser.Math.RND.pick(types);
ret = Utils.randSeedItem(types);
}, Utils.getSunday(new Date(timestamp)).getTime(), EGG_SEED.toString());
return ret;
+1 -1
View File
@@ -1813,7 +1813,7 @@ export class CopyTypeAttr extends MoveEffectAttr {
if (!super.apply(user, target, move, args))
return false;
user.summonData.types = target.getTypes();
user.summonData.types = target.getTypes(true);
user.scene.queueMessage(getPokemonMessage(user, `'s type\nchanged to match ${target.name}'s!`));
+1 -1
View File
@@ -841,7 +841,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.GOGOAT, 32, null, null)
],
[Species.PANCHAM]: [
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.ESPURR]: [
new SpeciesFormEvolution(Species.MEOWSTIC, '', '', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)),
+1
View File
@@ -2372,6 +2372,7 @@ export const speciesStarters = {
[Species.TOGEPI]: 3,
[Species.NATU]: 2,
[Species.MAREEP]: 3,
[Species.MARILL]: 4,
[Species.HOPPIP]: 1,
[Species.AIPOM]: 3,
[Species.SUNKERN]: 1,
+42 -5
View File
@@ -11,6 +11,7 @@ import { Species } from "./enums/species";
import { tmSpecies } from "./tms";
import { Type } from "./type";
import { initTrainerTypeDialogue } from "./dialogue";
import { PersistentModifier, TerastallizeModifier } from "../modifier/modifier";
export enum TrainerPoolTier {
COMMON,
@@ -163,6 +164,7 @@ export const trainerPartyTemplates = {
type PartyTemplateFunc = (scene: BattleScene) => TrainerPartyTemplate;
type PartyMemberFunc = (scene: BattleScene, level: integer) => EnemyPokemon;
type GenModifiersFunc = (party: EnemyPokemon[]) => PersistentModifier[];
export interface PartyMemberFuncs {
[key: integer]: PartyMemberFunc
@@ -183,6 +185,7 @@ export class TrainerConfig {
public encounterBgm: string;
public femaleEncounterBgm: string;
public victoryBgm: string;
public genModifiersFunc: GenModifiersFunc;
public modifierRewardFuncs: ModifierTypeFunc[] = [];
public partyTemplates: TrainerPartyTemplate[];
public partyTemplateFunc: PartyTemplateFunc;
@@ -325,11 +328,16 @@ export class TrainerConfig {
return this;
}
setGenModifiersFunc(genModifiersFunc: GenModifiersFunc): TrainerConfig {
this.genModifiersFunc = genModifiersFunc;
return this;
}
setModifierRewardFuncs(...modifierTypeFuncs: (() => ModifierTypeFunc)[]): TrainerConfig {
this.modifierRewardFuncs = modifierTypeFuncs.map(func => () => {
const modifierTypeFunc = func();
const modifierType = modifierTypeFunc();
modifierType.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifierTypeFunc);
modifierType.withIdFromFunc(modifierTypeFunc);
return modifierType;
});
return this;
@@ -352,6 +360,10 @@ export class TrainerConfig {
this.setStaticParty();
this.setBattleBgm('battle_gym');
this.setVictoryBgm('victory_gym');
this.setGenModifiersFunc(party => {
const waveIndex = party[0].scene.currentBattle.waveIndex;
return getRandomTeraModifiers(party, waveIndex >= 100 ? 1 : 0, specialtyTypes.length ? specialtyTypes : null);
});
return this;
}
@@ -373,6 +385,7 @@ export class TrainerConfig {
this.setStaticParty();
this.setBattleBgm('battle_elite');
this.setVictoryBgm('victory_gym');
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 2, specialtyTypes.length ? specialtyTypes : null));
return this;
}
@@ -390,6 +403,7 @@ export class TrainerConfig {
this.setStaticParty();
this.setBattleBgm('battle_champion');
this.setVictoryBgm('victory_champion');
this.setGenModifiersFunc(party => getRandomTeraModifiers(party, 3));
return this;
}
@@ -447,7 +461,7 @@ function getGymLeaderPartyTemplate(scene: BattleScene) {
function getRandomPartyMemberFunc(speciesPool: Species[], postProcess?: (enemyPokemon: EnemyPokemon) => void): PartyMemberFunc {
return (scene: BattleScene, level: integer) => {
const species = getPokemonSpecies(Phaser.Math.RND.pick(speciesPool)).getSpeciesForLevel(level, true, true, scene.currentBattle.trainer.config.isBoss);
const species = getPokemonSpecies(Utils.randSeedItem(speciesPool)).getSpeciesForLevel(level, true, true, scene.currentBattle.trainer.config.isBoss);
return scene.addEnemyPokemon(getPokemonSpecies(species), level, true, undefined, undefined, postProcess);
};
}
@@ -461,6 +475,17 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt
};
}
function getRandomTeraModifiers(party: EnemyPokemon[], count: integer, types?: Type[]): PersistentModifier[] {
const ret: PersistentModifier[] = [];
const partyMemberIndexes = new Array(party.length).fill(null).map((_, i) => i);
for (let t = 0; t < Math.min(count, party.length); t++) {
const randomIndex = Utils.randSeedItem(partyMemberIndexes);
partyMemberIndexes.splice(partyMemberIndexes.indexOf(randomIndex), 1);
ret.push(modifierTypes.TERA_SHARD().generateType(null, [ Utils.randSeedItem(types ? types : party[randomIndex].getTypes()) ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(party[randomIndex]) as PersistentModifier);
}
return ret;
}
export const trainerConfigs: TrainerConfigs = {
[TrainerType.UNKNOWN]: new TrainerConfig(0).setHasGenders(),
[TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER)
@@ -753,7 +778,11 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ]))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540),
.setSpeciesFilter(species => species.baseTotal >= 540)
.setGenModifiersFunc(party => {
const starter = party[0];
return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ];
}),
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_5)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ]))
@@ -762,7 +791,11 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.RAYQUAZA ], p => {
p.setBoss();
p.pokeball = PokeballType.MASTER_BALL;
})),
}))
.setGenModifiersFunc(party => {
const starter = party[0];
return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ];
}),
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setName('Finn').setHasGenders('Ivy').setTitle('Rival').setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm('final').setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_6)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT ]))
@@ -772,7 +805,11 @@ export const trainerConfigs: TrainerConfigs = {
p.setBoss();
p.pokeball = PokeballType.MASTER_BALL;
p.formIndex = 1;
})),
}))
.setGenModifiersFunc(party => {
const starter = party[0];
return [ modifierTypes.TERA_SHARD().generateType(null, [ starter.species.type1 ]).withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(starter) as PersistentModifier ];
}),
};
(function() {
+49 -1
View File
@@ -17,7 +17,8 @@ export enum Type {
ICE,
DRAGON,
DARK,
FAIRY
FAIRY,
STELLAR
};
export type TypeDamageMultiplier = 0 | 0.25 | 0.5 | 1 | 2 | 4;
@@ -491,5 +492,52 @@ export function getTypeDamageMultiplier(attackType: integer, defType: integer):
default:
return 0;
}
case Type.STELLAR:
return 1;
}
}
export function getTypeRgb(type: Type): [ integer, integer, integer ] {
switch (type) {
case Type.NORMAL:
return [ 168, 168, 120 ];
case Type.FIGHTING:
return [ 192, 48, 40 ];
case Type.FLYING:
return [ 168, 144, 240 ];
case Type.POISON:
return [ 160, 64, 160 ];
case Type.GROUND:
return [ 224, 192, 104 ];
case Type.ROCK:
return [ 184, 160, 56 ];
case Type.BUG:
return [ 168, 184, 32 ];
case Type.GHOST:
return [ 112, 88, 152 ];
case Type.STEEL:
return [ 184, 184, 208 ];
case Type.FIRE:
return [ 240, 128, 48 ];
case Type.WATER:
return [ 104, 144, 240 ];
case Type.GRASS:
return [ 120, 200, 80 ];
case Type.ELECTRIC:
return [ 248, 208, 48 ];
case Type.PSYCHIC:
return [ 248, 88, 136 ];
case Type.ICE:
return [ 152, 216, 216 ];
case Type.DRAGON:
return [ 112, 56, 248 ];
case Type.DARK:
return [ 112, 88, 72 ];
case Type.FAIRY:
return [ 232, 136, 200 ];
case Type.STELLAR:
return [ 255, 255, 255 ];
default:
return [ 0, 0, 0 ];
}
}