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

+41 -2
View File
@@ -59,6 +59,11 @@ export class ModifierType {
this.tier = tier;
}
withIdFromFunc(func: ModifierTypeFunc): ModifierType {
this.id = Object.keys(modifierTypes).find(k => modifierTypes[k] === func);
return this;
}
newModifier(...args: any[]): Modifier {
return this.newModifierFunc(this, args);
}
@@ -615,6 +620,20 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
}
}
export class TerastallizeModifierType extends PokemonHeldItemModifierType implements GeneratedPersistentModifierType {
private teraType: Type;
constructor(teraType: Type) {
super(`${Utils.toReadableString(Type[teraType])} Tera Shard`, `${Utils.toReadableString(Type[teraType])} Terastallizes the holder for up to 10 battles`, (type, args) => new Modifiers.TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), null, 'tera_shard');
this.teraType = teraType;
}
getPregenArgs(): any[] {
return [ this.teraType ];
}
}
export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemModifierType {
constructor(name: string, chancePercent: integer, iconImage?: string, group?: string, soundName?: string) {
super(name, `Upon attacking, there is a ${chancePercent}% chance the foe's held item will be stolen`, (type, args) => new Modifiers.ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), iconImage, group, soundName);
@@ -670,7 +689,8 @@ export const modifierTypes = {
FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(),
MEGA_BRACELET: () => new ModifierType('Mega Bracelet', 'Mega stones become available', (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)),
DYNAMAX_BAND: () => new ModifierType('Dynamax Band', 'Gigantamaxing becomes available', (type, _args) => new Modifiers.GigantamaxAccessModifier(type)),
DYNAMAX_BAND: () => new ModifierType('Dynamax Band', 'Max Mushrooms become available', (type, _args) => new Modifiers.GigantamaxAccessModifier(type)),
TERA_ORB: () => new ModifierType('Tera Orb', 'Tera Shards become available', (type, _args) => new Modifiers.TerastallizeAccessModifier(type)),
MAP: () => new ModifierType('Map', 'Allows you to choose your destination at a crossroads', (type, _args) => new Modifiers.MapModifier(type)),
@@ -721,6 +741,20 @@ export const modifierTypes = {
ATTACK_TYPE_BOOSTER: () => new AttackTypeBoosterModifierTypeGenerator(),
TERA_SHARD: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs)
return new TerastallizeModifierType(pregenArgs[0] as Type);
if (!party[0].scene.getModifiers(Modifiers.TerastallizeAccessModifier).length)
return null;
let type: Type;
if (!Utils.randInt(3)) {
const partyMemberTypes = party.map(p => p.getTypes(false, true)).flat();
type = Utils.randSeedItem(partyMemberTypes);
} else
type = Utils.randSeedInt(64) ? Utils.randSeedInt(18) as Type : Type.STELLAR;
return new TerastallizeModifierType(type);
}),
BERRY: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs)
return new BerryModifierType(pregenArgs[0] as BerryType);
@@ -902,6 +936,7 @@ const modifierPool = {
return Math.min(Math.ceil(highestPartyLevel / 20), 4);
}),
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3),
new WeightedModifierType(modifierTypes.TERA_SHARD, 1),
new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.SPLICED_ENDLESS && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0),
new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 6 : 0),
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
@@ -934,6 +969,7 @@ const modifierPool = {
new WeightedModifierType(modifierTypes.OVAL_CHARM, 2),
new WeightedModifierType(modifierTypes.ABILITY_CHARM, 2),
new WeightedModifierType(modifierTypes.IV_SCANNER, 2),
new WeightedModifierType(modifierTypes.TERA_ORB, 3),
new WeightedModifierType(modifierTypes.EXP_BALANCE, 1),
new WeightedModifierType(modifierTypes.FORM_CHANGE_ITEM, 1),
new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode !== GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 3 : 0),
@@ -1054,7 +1090,10 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod
pool[t].reduce((total: integer, modifierType: WeightedModifierType) => {
const weightedModifierType = modifierType as WeightedModifierType;
const existingModifiers = party[0].scene.findModifiers(m => (m.type.generatorId || m.type.id) === weightedModifierType.modifierType.id, player);
const weight = !existingModifiers.length || existingModifiers.filter(m => m.stackCount < m.getMaxStackCount(party[0].scene, true)).length
const weight = !existingModifiers.length
|| weightedModifierType.modifierType instanceof PokemonHeldItemModifierType
|| (weightedModifierType.modifierType instanceof ModifierTypeGenerator && weightedModifierType.modifierType.generateType(party) instanceof PokemonHeldItemModifierType)
|| existingModifiers.find(m => m.stackCount < m.getMaxStackCount(party[0].scene, true))
? weightedModifierType.weight instanceof Function
? (weightedModifierType.weight as Function)(party)
: weightedModifierType.weight as integer
+114 -2
View File
@@ -265,7 +265,7 @@ export abstract class LapsingPersistentModifier extends PersistentModifier {
this.battlesLeft = battlesLeft;
}
lapse(): boolean {
lapse(args: any[]): boolean {
return !!--this.battlesLeft;
}
@@ -281,6 +281,10 @@ export abstract class LapsingPersistentModifier extends PersistentModifier {
return container;
}
getBattlesLeft(): integer {
return this.battlesLeft;
}
getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number {
return 99;
}
@@ -404,6 +408,24 @@ export class GigantamaxAccessModifier extends PersistentModifier {
}
}
export class TerastallizeAccessModifier extends PersistentModifier {
constructor(type: ModifierType, stackCount?: integer) {
super(type, stackCount);
}
clone(): TerastallizeAccessModifier {
return new TerastallizeAccessModifier(this.type, this.stackCount);
}
apply(args: any[]): boolean {
return true;
}
getMaxStackCount(scene: BattleScene): integer {
return 1;
}
}
export abstract class PokemonHeldItemModifier extends PersistentModifier {
public pokemonId: integer;
@@ -481,6 +503,85 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
abstract getMaxHeldItemCount(pokemon: Pokemon): integer
}
export abstract class LapsingPokemonHeldItemModifier extends PokemonHeldItemModifier {
protected battlesLeft: integer;
constructor(type: ModifierTypes.ModifierType, pokemonId: integer, battlesLeft?: integer, stackCount?: integer) {
super(type, pokemonId, stackCount);
this.battlesLeft = battlesLeft;
}
lapse(args: any[]): boolean {
return !!--this.battlesLeft;
}
getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container {
const container = super.getIcon(scene, forSummary);
if (this.getPokemon(scene).isPlayer()) {
const battleCountText = addTextObject(scene, 27, 0, this.battlesLeft.toString(), TextStyle.PARTY, { fontSize: '66px', color: '#f89890' });
battleCountText.setShadow(0, 0, null);
battleCountText.setStroke('#984038', 16)
battleCountText.setOrigin(1, 0);
container.add(battleCountText);
}
return container;
}
getBattlesLeft(): integer {
return this.battlesLeft;
}
getMaxStackCount(scene: BattleScene, forThreshold?: boolean): number {
return 1;
}
}
export class TerastallizeModifier extends LapsingPokemonHeldItemModifier {
public teraType: Type;
constructor(type: ModifierTypes.TerastallizeModifierType, pokemonId: integer, teraType: Type, battlesLeft?: integer, stackCount?: integer) {
super(type, pokemonId, battlesLeft || 10, stackCount);
this.teraType = teraType;
}
matchType(modifier: Modifier): boolean {
if (modifier instanceof TerastallizeModifier && modifier.teraType === this.teraType)
return true;
return false;
}
clone(): TerastallizeModifier {
return new TerastallizeModifier(this.type as ModifierTypes.TerastallizeModifierType, this.pokemonId, this.teraType, this.battlesLeft, this.stackCount);
}
getArgs(): any[] {
return [ this.pokemonId, this.teraType, this.battlesLeft ];
}
apply(args: any[]): boolean {
const pokemon = args[0] as Pokemon;
pokemon.updateSpritePipelineData();
return true;
}
lapse(args: any[]): boolean {
const ret = super.lapse(args);
if (!ret) {
const pokemon = args[0] as Pokemon;
pokemon.updateSpritePipelineData();
}
return ret;
}
getMaxHeldItemCount(pokemon: Pokemon): integer {
return 1;
}
}
export class PokemonBaseStatModifier extends PokemonHeldItemModifier {
protected stat: Stat;
@@ -1323,8 +1424,19 @@ export class PokemonFormChangeItemModifier extends PokemonHeldItemModifier {
apply(args: any[]): boolean {
const pokemon = args[0] as Pokemon;
const active = args[1] as boolean;
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
let switchActive = this.active && !active;
if (switchActive)
this.active = false;
const ret = pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeItemTrigger);
if (switchActive)
this.active = true;
return ret;
}
getMaxHeldItemCount(pokemon: Pokemon): integer {