Make trainer switch AI aware of arena traps
This commit is contained in:
parent
7ddd834786
commit
203ba1646d
|
@ -948,15 +948,16 @@ export default class BattleScene extends Phaser.Scene {
|
||||||
if (init) {
|
if (init) {
|
||||||
const biomeKey = getBiomeKey(biome);
|
const biomeKey = getBiomeKey(biome);
|
||||||
|
|
||||||
this.arenaBg.setTexture(`${biomeKey}_bg`);
|
|
||||||
this.arenaBg.pipelineData['terrainColorRatio'] = this.arena.getBgTerrainColorRatioForBiome();
|
|
||||||
this.arenaBgTransition.setTexture(`${biomeKey}_bg`);
|
|
||||||
this.arenaPlayer.setBiome(biome);
|
this.arenaPlayer.setBiome(biome);
|
||||||
this.arenaPlayerTransition.setBiome(biome);
|
this.arenaPlayerTransition.setBiome(biome);
|
||||||
this.arenaEnemy.setBiome(biome);
|
this.arenaEnemy.setBiome(biome);
|
||||||
this.arenaNextEnemy.setBiome(biome);
|
this.arenaNextEnemy.setBiome(biome);
|
||||||
|
this.arenaBg.setTexture(`${biomeKey}_bg`);
|
||||||
|
this.arenaBgTransition.setTexture(`${biomeKey}_bg`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.arenaBg.pipelineData = { terrainColorRatio: this.arena.getBgTerrainColorRatioForBiome() };
|
||||||
|
|
||||||
return this.arena;
|
return this.arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,10 @@ export class ArenaTrapTag extends ArenaTag {
|
||||||
activateTrap(pokemon: Pokemon): boolean {
|
activateTrap(pokemon: Pokemon): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMatchupScoreMultiplier(pokemon: Pokemon): number {
|
||||||
|
return pokemon.isGrounded() ? 1 : Phaser.Math.Linear(0, 1 / Math.pow(2, this.layers), Math.min(pokemon.getHpRatio(), 0.5) * 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpikesTag extends ArenaTrapTag {
|
class SpikesTag extends ArenaTrapTag {
|
||||||
|
@ -216,6 +220,14 @@ class ToxicSpikesTag extends ArenaTrapTag {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMatchupScoreMultiplier(pokemon: Pokemon): number {
|
||||||
|
if (pokemon.isGrounded() || !pokemon.canSetStatus(StatusEffect.POISON, true))
|
||||||
|
return 1;
|
||||||
|
if (pokemon.isOfType(Type.POISON))
|
||||||
|
return 1.25;
|
||||||
|
return super.getMatchupScoreMultiplier(pokemon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DelayedAttackTag extends ArenaTag {
|
class DelayedAttackTag extends ArenaTag {
|
||||||
|
@ -251,7 +263,7 @@ class StealthRockTag extends ArenaTrapTag {
|
||||||
arena.scene.queueMessage(`Pointed stones float in the air\naround ${source.getOpponentDescriptor()}!`);
|
arena.scene.queueMessage(`Pointed stones float in the air\naround ${source.getOpponentDescriptor()}!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
activateTrap(pokemon: Pokemon): boolean {
|
getDamageHpRatio(pokemon: Pokemon): number {
|
||||||
const effectiveness = pokemon.getAttackTypeEffectiveness(Type.ROCK);
|
const effectiveness = pokemon.getAttackTypeEffectiveness(Type.ROCK);
|
||||||
|
|
||||||
let damageHpRatio: number;
|
let damageHpRatio: number;
|
||||||
|
@ -277,6 +289,12 @@ class StealthRockTag extends ArenaTrapTag {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return damageHpRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
activateTrap(pokemon: Pokemon): boolean {
|
||||||
|
const damageHpRatio = this.getDamageHpRatio(pokemon);
|
||||||
|
|
||||||
if (damageHpRatio) {
|
if (damageHpRatio) {
|
||||||
const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio);
|
const damage = Math.ceil(pokemon.getMaxHp() * damageHpRatio);
|
||||||
pokemon.scene.queueMessage(`Pointed stones dug into\n${pokemon.name}!`);
|
pokemon.scene.queueMessage(`Pointed stones dug into\n${pokemon.name}!`);
|
||||||
|
@ -285,6 +303,11 @@ class StealthRockTag extends ArenaTrapTag {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMatchupScoreMultiplier(pokemon: Pokemon): number {
|
||||||
|
const damageHpRatio = this.getDamageHpRatio(pokemon);
|
||||||
|
return Phaser.Math.Linear(super.getMatchupScoreMultiplier(pokemon), 1, 1 - Math.pow(damageHpRatio, damageHpRatio));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TrickRoomTag extends ArenaTag {
|
export class TrickRoomTag extends ArenaTag {
|
||||||
|
|
|
@ -264,7 +264,7 @@ export class SeedTag extends BattlerTag {
|
||||||
private sourceIndex: integer;
|
private sourceIndex: integer;
|
||||||
|
|
||||||
constructor(sourceId: integer) {
|
constructor(sourceId: integer) {
|
||||||
super(BattlerTagType.SEEDED, BattlerTagLapseType.AFTER_MOVE, 1, Moves.LEECH_SEED, sourceId);
|
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
|
|
|
@ -488,6 +488,14 @@ export class Arena {
|
||||||
: this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
|
: this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findTags(tagPredicate: (t: ArenaTag) => boolean): ArenaTag[] {
|
||||||
|
return this.findTagsOnSide(tagPredicate, ArenaTagSide.BOTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
findTagsOnSide(tagPredicate: (t: ArenaTag) => boolean, side: ArenaTagSide): ArenaTag[] {
|
||||||
|
return this.tags.filter(t => tagPredicate && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
|
||||||
|
}
|
||||||
|
|
||||||
lapseTags(): void {
|
lapseTags(): void {
|
||||||
this.tags.filter(t => !(t.lapse(this))).forEach(t => {
|
this.tags.filter(t => !(t.lapse(this))).forEach(t => {
|
||||||
t.onRemove(this);
|
t.onRemove(this);
|
||||||
|
@ -662,7 +670,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
|
||||||
const hasProps = getBiomeHasProps(biome);
|
const hasProps = getBiomeHasProps(biome);
|
||||||
const biomeKey = getBiomeKey(biome);
|
const biomeKey = getBiomeKey(biome);
|
||||||
const baseKey = `${biomeKey}_${this.player ? 'a' : 'b'}`;
|
const baseKey = `${biomeKey}_${this.player ? 'a' : 'b'}`;
|
||||||
|
|
||||||
this.base.setTexture(baseKey);
|
this.base.setTexture(baseKey);
|
||||||
|
|
||||||
if (this.base.texture.frameTotal > 1) {
|
if (this.base.texture.frameTotal > 1) {
|
||||||
|
|
|
@ -8,6 +8,8 @@ import { EnemyPokemon } from "./pokemon";
|
||||||
import * as Utils from "../utils";
|
import * as Utils from "../utils";
|
||||||
import { PersistentModifier } from "../modifier/modifier";
|
import { PersistentModifier } from "../modifier/modifier";
|
||||||
import { trainerNamePools } from "../data/trainer-names";
|
import { trainerNamePools } from "../data/trainer-names";
|
||||||
|
import { ArenaTagType } from "#app/data/enums/arena-tag-type";
|
||||||
|
import { ArenaTag, ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
|
||||||
|
|
||||||
export enum TrainerVariant {
|
export enum TrainerVariant {
|
||||||
DEFAULT,
|
DEFAULT,
|
||||||
|
@ -272,7 +274,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE): [integer, integer][] {
|
getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] {
|
||||||
if (trainerSlot && !this.isDouble())
|
if (trainerSlot && !this.isDouble())
|
||||||
trainerSlot = TrainerSlot.NONE;
|
trainerSlot = TrainerSlot.NONE;
|
||||||
|
|
||||||
|
@ -288,6 +290,8 @@ export default class Trainer extends Phaser.GameObjects.Container {
|
||||||
score /= 2;
|
score /= 2;
|
||||||
}
|
}
|
||||||
score /= playerField.length;
|
score /= playerField.length;
|
||||||
|
if (forSwitch && !p.isOnField())
|
||||||
|
this.scene.arena.findTagsOnSide(t => t instanceof ArenaTrapTag, ArenaTagSide.ENEMY).map(t => score *= (t as ArenaTrapTag).getMatchupScoreMultiplier(p));
|
||||||
ret = [ party.indexOf(p), score ];
|
ret = [ party.indexOf(p), score ];
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1715,7 +1715,7 @@ export class EnemyCommandPhase extends FieldPhase {
|
||||||
|
|
||||||
return this.end();
|
return this.end();
|
||||||
} else if (!trapTag && !trapped.value) {
|
} else if (!trapTag && !trapped.value) {
|
||||||
const partyMemberScores = trainer.getPartyMemberMatchupScores(enemyPokemon.trainerSlot);
|
const partyMemberScores = trainer.getPartyMemberMatchupScores(enemyPokemon.trainerSlot, true);
|
||||||
|
|
||||||
if (partyMemberScores.length) {
|
if (partyMemberScores.length) {
|
||||||
const matchupScores = opponents.map(opp => enemyPokemon.getMatchupScore(opp));
|
const matchupScores = opponents.map(opp => enemyPokemon.getMatchupScore(opp));
|
||||||
|
|
|
@ -163,8 +163,8 @@ void main() {
|
||||||
color = vec4(blendHardLight(color.rgb, dayNightTint), color.a);
|
color = vec4(blendHardLight(color.rgb, dayNightTint), color.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (terrainColorRatio > 0.0 && 1.0 - terrainColorRatio < outTexCoord.y) {
|
if (terrainColorRatio > 0.0 && (1.0 - terrainColorRatio) < outTexCoord.y) {
|
||||||
if (color.a > 0.0 && terrainColor.r > 0.0 && terrainColor.g > 0.0 && terrainColor.b > 0.0) {
|
if (color.a > 0.0 && (terrainColor.r > 0.0 || terrainColor.g > 0.0 || terrainColor.b > 0.0)) {
|
||||||
color.rgb = mix(color.rgb, blendHue(color.rgb, terrainColor), 1.0);
|
color.rgb = mix(color.rgb, blendHue(color.rgb, terrainColor), 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ export default class FieldSpritePipeline extends Phaser.Renderer.WebGL.Pipelines
|
||||||
onBind(gameObject: Phaser.GameObjects.GameObject): void {
|
onBind(gameObject: Phaser.GameObjects.GameObject): void {
|
||||||
super.onBind();
|
super.onBind();
|
||||||
|
|
||||||
const sprite = (gameObject as Phaser.GameObjects.Sprite);
|
const sprite = gameObject as Phaser.GameObjects.Sprite | Phaser.GameObjects.NineSlice;
|
||||||
const scene = sprite.scene as BattleScene;
|
const scene = sprite.scene as BattleScene;
|
||||||
|
|
||||||
const data = sprite.pipelineData;
|
const data = sprite.pipelineData;
|
||||||
|
|
Loading…
Reference in New Issue