mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-16 13:22:18 +02:00
type hints
This commit is contained in:
parent
5dd017fa30
commit
aa91ae4c49
@ -119,6 +119,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
public fusionPaletteSwaps: boolean = true;
|
public fusionPaletteSwaps: boolean = true;
|
||||||
public enableTouchControls: boolean = false;
|
public enableTouchControls: boolean = false;
|
||||||
public enableVibration: boolean = false;
|
public enableVibration: boolean = false;
|
||||||
|
public typeHints: integer = 0;
|
||||||
public abSwapped: boolean = false;
|
public abSwapped: boolean = false;
|
||||||
|
|
||||||
public disableMenu: boolean = false;
|
public disableMenu: boolean = false;
|
||||||
|
@ -943,6 +943,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return !this.isOfType(Type.FLYING, true) && !this.hasAbility(Abilities.LEVITATE);
|
return !this.isOfType(Type.FLYING, true) && !this.hasAbility(Abilities.LEVITATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isStabMove(move: Move): boolean {
|
||||||
|
if (move.category === MoveCategory.STATUS) return false;
|
||||||
|
|
||||||
|
const type = move.type;
|
||||||
|
const types = this.getTypes();
|
||||||
|
const teraType = this.getTeraType();
|
||||||
|
const matchesSourceType = types[0] === type || (types.length > 1 && types[1] === type);
|
||||||
|
|
||||||
|
return (teraType === Type.UNKNOWN && matchesSourceType) || (teraType !== Type.UNKNOWN && teraType === type);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier | undefined {
|
||||||
|
if (move.getMove().category === MoveCategory.STATUS) return undefined;
|
||||||
|
return this.getAttackMoveEffectiveness(source, move);
|
||||||
|
}
|
||||||
|
|
||||||
getAttackMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier {
|
getAttackMoveEffectiveness(source: Pokemon, move: PokemonMove): TypeDamageMultiplier {
|
||||||
const typeless = !!move.getMove().getAttrs(TypelessAttr).length;
|
const typeless = !!move.getMove().getAttrs(TypelessAttr).length;
|
||||||
const typeMultiplier = new Utils.NumberHolder(this.getAttackTypeEffectiveness(move.getMove().type, source));
|
const typeMultiplier = new Utils.NumberHolder(this.getAttackTypeEffectiveness(move.getMove().type, source));
|
||||||
@ -1096,11 +1112,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
let shinyThreshold = new Utils.IntegerHolder(32);
|
let shinyThreshold = new Utils.IntegerHolder(32);
|
||||||
if (thresholdOverride === undefined) {
|
if (thresholdOverride === undefined) {
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer())
|
||||||
if (new Date() < new Date('2024-05-21'))
|
|
||||||
shinyThreshold.value *= 3;
|
|
||||||
this.scene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
this.scene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
shinyThreshold.value = thresholdOverride;
|
shinyThreshold.value = thresholdOverride;
|
||||||
|
|
||||||
@ -1376,6 +1389,57 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return this.battleInfo.updateInfo(this, instant);
|
return this.battleInfo.updateInfo(this, instant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateNameColor() {
|
||||||
|
const nameColor = this.getNameColor();
|
||||||
|
if (nameColor === undefined) return;
|
||||||
|
|
||||||
|
this.battleInfo.updateNameColor(nameColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
getNameColor(): string | undefined {
|
||||||
|
const typeHints = this.scene.typeHints;
|
||||||
|
if (typeHints === 0) return undefined;
|
||||||
|
const opponents = this.getOpponents();
|
||||||
|
|
||||||
|
const opponentMoveEffectivenessList = opponents.map((opponent) => {
|
||||||
|
return opponent.getMoveset().map((move) => {
|
||||||
|
return this.getMoveEffectiveness(opponent, move);
|
||||||
|
});
|
||||||
|
}).flat().filter((effectiveness) => effectiveness !== undefined);
|
||||||
|
|
||||||
|
const moveEffectivenessList = opponents.map((opponent) => {
|
||||||
|
return this.getMoveset().map((move) => {
|
||||||
|
return opponent.getMoveEffectiveness(this, move);
|
||||||
|
});
|
||||||
|
}).flat().filter((effectiveness) => effectiveness !== undefined);
|
||||||
|
|
||||||
|
const fullHints = typeHints === 2;
|
||||||
|
|
||||||
|
if (fullHints && opponentMoveEffectivenessList.some((effectiveness) => effectiveness === 8)) {
|
||||||
|
return 'darkred';
|
||||||
|
} else if (fullHints && opponentMoveEffectivenessList.some((effectiveness) => effectiveness === 4)) {
|
||||||
|
return 'red';
|
||||||
|
} else if (fullHints && opponentMoveEffectivenessList.some((effectiveness) => effectiveness === 2)) {
|
||||||
|
return 'crimson';
|
||||||
|
} else if (moveEffectivenessList.some((effectiveness) => effectiveness === 8)) {
|
||||||
|
return 'darkgreen';
|
||||||
|
} else if (moveEffectivenessList.some((effectiveness) => effectiveness === 4)) {
|
||||||
|
return 'green';
|
||||||
|
} else if (moveEffectivenessList.some((effectiveness) => effectiveness === 2)) {
|
||||||
|
return 'lightgreen';
|
||||||
|
} else if (fullHints && opponentMoveEffectivenessList.every((effectiveness) => effectiveness === 0)) {
|
||||||
|
return 'yellow';
|
||||||
|
} else if (fullHints && opponentMoveEffectivenessList.every((effectiveness) => effectiveness === 0.125)) {
|
||||||
|
return 'darkblue';
|
||||||
|
} else if (fullHints && opponentMoveEffectivenessList.every((effectiveness) => effectiveness === 0.25)) {
|
||||||
|
return 'blue';
|
||||||
|
} else if (fullHints && opponentMoveEffectivenessList.every((effectiveness) => effectiveness === 0.5)) {
|
||||||
|
return 'lightblue';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'white';
|
||||||
|
}
|
||||||
|
|
||||||
toggleStats(visible: boolean): void {
|
toggleStats(visible: boolean): void {
|
||||||
this.battleInfo.toggleStats(visible);
|
this.battleInfo.toggleStats(visible);
|
||||||
}
|
}
|
||||||
@ -1526,11 +1590,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier.value) === 0;
|
const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier.value) === 0;
|
||||||
const sourceTypes = source.getTypes();
|
const sourceTypes = source.getTypes();
|
||||||
const matchesSourceType = sourceTypes[0] === type || (sourceTypes.length > 1 && sourceTypes[1] === type);
|
const matchesSourceType = sourceTypes[0] === type || (sourceTypes.length > 1 && sourceTypes[1] === type);
|
||||||
|
|
||||||
let stabMultiplier = new Utils.NumberHolder(1);
|
let stabMultiplier = new Utils.NumberHolder(1);
|
||||||
if (sourceTeraType === Type.UNKNOWN && matchesSourceType)
|
if (source.isStabMove(move)) {
|
||||||
stabMultiplier.value += 0.5;
|
|
||||||
else if (sourceTeraType !== Type.UNKNOWN && sourceTeraType === type)
|
|
||||||
stabMultiplier.value += 0.5;
|
stabMultiplier.value += 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
applyAbAttrs(StabBoostAbAttr, source, null, stabMultiplier);
|
applyAbAttrs(StabBoostAbAttr, source, null, stabMultiplier);
|
||||||
|
|
||||||
|
@ -1573,6 +1573,10 @@ export class CheckSwitchPhase extends BattlePhase {
|
|||||||
|
|
||||||
const pokemon = this.scene.getPlayerField()[this.fieldIndex];
|
const pokemon = this.scene.getPlayerField()[this.fieldIndex];
|
||||||
|
|
||||||
|
this.scene.getParty().forEach((pokemon) => {
|
||||||
|
pokemon.updateNameColor();
|
||||||
|
});
|
||||||
|
|
||||||
if (this.scene.field.getAll().indexOf(pokemon) === -1) {
|
if (this.scene.field.getAll().indexOf(pokemon) === -1) {
|
||||||
this.scene.unshiftPhase(new SummonMissingPhase(this.scene, this.fieldIndex));
|
this.scene.unshiftPhase(new SummonMissingPhase(this.scene, this.fieldIndex));
|
||||||
super.end();
|
super.end();
|
||||||
@ -1651,6 +1655,10 @@ export class TurnInitPhase extends FieldPhase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.scene.getParty().forEach((pokemon) => {
|
||||||
|
pokemon.updateNameColor();
|
||||||
|
});
|
||||||
|
|
||||||
this.scene.pushPhase(new TurnStartPhase(this.scene));
|
this.scene.pushPhase(new TurnStartPhase(this.scene));
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
|
@ -28,7 +28,8 @@ export enum Setting {
|
|||||||
Gamepad_Support = "GAMEPAD_SUPPORT",
|
Gamepad_Support = "GAMEPAD_SUPPORT",
|
||||||
Swap_A_and_B = "SWAP_A_B", // Swaps which gamepad button handles ACTION and CANCEL
|
Swap_A_and_B = "SWAP_A_B", // Swaps which gamepad button handles ACTION and CANCEL
|
||||||
Touch_Controls = "TOUCH_CONTROLS",
|
Touch_Controls = "TOUCH_CONTROLS",
|
||||||
Vibration = "VIBRATION"
|
Vibration = "VIBRATION",
|
||||||
|
Type_Hints = "TYPE_HINTS"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingOptions {
|
export interface SettingOptions {
|
||||||
@ -61,7 +62,8 @@ export const settingOptions: SettingOptions = {
|
|||||||
[Setting.Gamepad_Support]: ['Auto', 'Disabled'],
|
[Setting.Gamepad_Support]: ['Auto', 'Disabled'],
|
||||||
[Setting.Swap_A_and_B]: ['Enabled', 'Disabled'],
|
[Setting.Swap_A_and_B]: ['Enabled', 'Disabled'],
|
||||||
[Setting.Touch_Controls]: ['Auto', 'Disabled'],
|
[Setting.Touch_Controls]: ['Auto', 'Disabled'],
|
||||||
[Setting.Vibration]: ['Auto', 'Disabled']
|
[Setting.Vibration]: ['Auto', 'Disabled'],
|
||||||
|
[Setting.Type_Hints]: ['Off', 'Partial', 'Full']
|
||||||
};
|
};
|
||||||
|
|
||||||
export const settingDefaults: SettingDefaults = {
|
export const settingDefaults: SettingDefaults = {
|
||||||
@ -86,7 +88,8 @@ export const settingDefaults: SettingDefaults = {
|
|||||||
[Setting.Gamepad_Support]: 0,
|
[Setting.Gamepad_Support]: 0,
|
||||||
[Setting.Swap_A_and_B]: 1, // Set to 'Disabled' by default
|
[Setting.Swap_A_and_B]: 1, // Set to 'Disabled' by default
|
||||||
[Setting.Touch_Controls]: 0,
|
[Setting.Touch_Controls]: 0,
|
||||||
[Setting.Vibration]: 0
|
[Setting.Vibration]: 0,
|
||||||
|
[Setting.Type_Hints]: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const reloadSettings: Setting[] = [Setting.UI_Theme, Setting.Language, Setting.Sprite_Set];
|
export const reloadSettings: Setting[] = [Setting.UI_Theme, Setting.Language, Setting.Sprite_Set];
|
||||||
@ -171,6 +174,9 @@ export function setSetting(scene: BattleScene, setting: Setting, value: integer)
|
|||||||
case Setting.Vibration:
|
case Setting.Vibration:
|
||||||
scene.enableVibration = settingOptions[setting][value] !== 'Disabled' && hasTouchscreen();
|
scene.enableVibration = settingOptions[setting][value] !== 'Disabled' && hasTouchscreen();
|
||||||
break;
|
break;
|
||||||
|
case Setting.Type_Hints:
|
||||||
|
scene.typeHints = value;
|
||||||
|
break;
|
||||||
case Setting.Language:
|
case Setting.Language:
|
||||||
if (value) {
|
if (value) {
|
||||||
if (scene.ui) {
|
if (scene.ui) {
|
||||||
|
@ -551,6 +551,10 @@ export default class BattleInfo extends Phaser.GameObjects.Container {
|
|||||||
this.lastName = pokemon.name;
|
this.lastName = pokemon.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateNameColor(color: string) {
|
||||||
|
this.nameText.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
updatePokemonExp(pokemon: Pokemon, instant?: boolean, levelDurationMultiplier: number = 1): Promise<void> {
|
updatePokemonExp(pokemon: Pokemon, instant?: boolean, levelDurationMultiplier: number = 1): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const levelUp = this.lastLevel < pokemon.level;
|
const levelUp = this.lastLevel < pokemon.level;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import BattleScene from "../battle-scene";
|
import BattleScene from "../battle-scene";
|
||||||
import { addTextObject, TextStyle } from "./text";
|
import { addTextObject, TextStyle } from "./text";
|
||||||
import { Type } from "../data/type";
|
import { Type, TypeDamageMultiplier } from "../data/type";
|
||||||
import { Command } from "./command-ui-handler";
|
import { Command } from "./command-ui-handler";
|
||||||
import { Mode } from "./ui";
|
import { Mode } from "./ui";
|
||||||
import UiHandler from "./ui-handler";
|
import UiHandler from "./ui-handler";
|
||||||
@ -9,6 +9,7 @@ import { CommandPhase } from "../phases";
|
|||||||
import { MoveCategory } from "#app/data/move.js";
|
import { MoveCategory } from "#app/data/move.js";
|
||||||
import i18next from '../plugins/i18n';
|
import i18next from '../plugins/i18n';
|
||||||
import {Button} from "../enums/buttons";
|
import {Button} from "../enums/buttons";
|
||||||
|
import Pokemon, { PokemonMove } from "#app/field/pokemon.js";
|
||||||
|
|
||||||
export default class FightUiHandler extends UiHandler {
|
export default class FightUiHandler extends UiHandler {
|
||||||
private movesContainer: Phaser.GameObjects.Container;
|
private movesContainer: Phaser.GameObjects.Container;
|
||||||
@ -189,15 +190,79 @@ export default class FightUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
displayMoves() {
|
displayMoves() {
|
||||||
const moveset = (this.scene.getCurrentPhase() as CommandPhase).getPokemon().getMoveset();
|
const pokemon = (this.scene.getCurrentPhase() as CommandPhase).getPokemon();
|
||||||
for (let m = 0; m < 4; m++) {
|
const moveset = pokemon.getMoveset();
|
||||||
const moveText = addTextObject(this.scene, m % 2 === 0 ? 0 : 100, m < 2 ? 0 : 16, '-', TextStyle.WINDOW);
|
|
||||||
if (m < moveset.length)
|
for (let moveIndex = 0; moveIndex < 4; moveIndex++) {
|
||||||
moveText.setText(moveset[m].getName());
|
const moveText = addTextObject(this.scene, moveIndex % 2 === 0 ? 0 : 100, moveIndex < 2 ? 0 : 16, '-', TextStyle.WINDOW);
|
||||||
|
|
||||||
|
if (moveIndex < moveset.length) {
|
||||||
|
const pokemonMove = moveset[moveIndex];
|
||||||
|
moveText.setText(pokemonMove.getName());
|
||||||
|
|
||||||
|
if (this.scene.typeHints > 0) {
|
||||||
|
this.setTypeHints(pokemon, pokemonMove, moveText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.movesContainer.add(moveText);
|
this.movesContainer.add(moveText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setTypeHints(pokemon: Pokemon, pokemonMove: PokemonMove, moveText: Phaser.GameObjects.Text) {
|
||||||
|
const opponents = pokemon.getOpponents();
|
||||||
|
if (opponents.length < 1) return;
|
||||||
|
|
||||||
|
const move = pokemonMove.getMove();
|
||||||
|
const moveEffectivenessList = opponents.map((opponent) => opponent.getMoveEffectiveness(pokemon, pokemonMove));
|
||||||
|
|
||||||
|
let text = moveText.text;
|
||||||
|
const effectivenessTextList = moveEffectivenessList.map((effectiveness) => this.getMoveEffectivenessText(effectiveness));
|
||||||
|
|
||||||
|
if (effectivenessTextList.every((text) => text === effectivenessTextList[0])) {
|
||||||
|
if (moveEffectivenessList[0] !== 1) {
|
||||||
|
text += effectivenessTextList[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
moveEffectivenessList.forEach((effectiveness) => {
|
||||||
|
text += this.getMoveEffectivenessText(effectiveness);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
moveText.setText(text);
|
||||||
|
|
||||||
|
const stab = pokemon.isStabMove(move);
|
||||||
|
if (stab) moveText.setFontStyle('bold');
|
||||||
|
|
||||||
|
const moveColors = moveEffectivenessList.sort((a, b) => b - a).map((effectiveness) => this.getMoveColor(effectiveness));
|
||||||
|
moveText.setColor(moveColors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getMoveEffectivenessText(moveEffectiveness?: TypeDamageMultiplier): string {
|
||||||
|
if (moveEffectiveness === undefined) return '';
|
||||||
|
return ` ${moveEffectiveness}x`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getMoveColor(moveEffectiveness?: TypeDamageMultiplier): string {
|
||||||
|
switch (moveEffectiveness) {
|
||||||
|
case 0:
|
||||||
|
return 'black';
|
||||||
|
case 0.125:
|
||||||
|
return 'darkred';
|
||||||
|
case 0.25:
|
||||||
|
return 'red';
|
||||||
|
case 0.5:
|
||||||
|
return 'crimson';
|
||||||
|
case 2:
|
||||||
|
return 'lightgreen';
|
||||||
|
case 4:
|
||||||
|
return 'green';
|
||||||
|
case 8:
|
||||||
|
return 'darkgreen';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'white';
|
||||||
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
super.clear();
|
super.clear();
|
||||||
this.clearMoves();
|
this.clearMoves();
|
||||||
|
@ -870,6 +870,9 @@ class PartySlot extends Phaser.GameObjects.Container {
|
|||||||
slotName.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 21 : 24, this.slotIndex >= battlerCount ? 2 : 10);
|
slotName.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 21 : 24, this.slotIndex >= battlerCount ? 2 : 10);
|
||||||
slotName.setOrigin(0, 0);
|
slotName.setOrigin(0, 0);
|
||||||
|
|
||||||
|
const color = this.pokemon.getNameColor();
|
||||||
|
if (color !== undefined) slotName.setColor(color);
|
||||||
|
|
||||||
const slotLevelLabel = this.scene.add.image(0, 0, 'party_slot_overlay_lv');
|
const slotLevelLabel = this.scene.add.image(0, 0, 'party_slot_overlay_lv');
|
||||||
slotLevelLabel.setPositionRelative(slotName, 8, 12);
|
slotLevelLabel.setPositionRelative(slotName, 8, 12);
|
||||||
slotLevelLabel.setOrigin(0, 0);
|
slotLevelLabel.setOrigin(0, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user