diff --git a/public/images/ui/party_bg_double.png b/public/images/ui/party_bg_double.png new file mode 100644 index 00000000000..89beff1edf0 Binary files /dev/null and b/public/images/ui/party_bg_double.png differ diff --git a/src/battle-phases.ts b/src/battle-phases.ts index 0c4bd6d611f..421fe6cfb82 100644 --- a/src/battle-phases.ts +++ b/src/battle-phases.ts @@ -601,7 +601,7 @@ export class SwitchSummonPhase extends SummonPhase { } } party[this.slotIndex] = this.lastPokemon; - party[0] = switchedPokemon; + party[this.fieldIndex] = switchedPokemon; this.scene.ui.showText(`Go! ${switchedPokemon.name}!`); this.summon(); } @@ -852,7 +852,6 @@ export class SelectTargetPhase extends PokemonPhase { this.scene.unshiftPhase(new CommandPhase(this.scene, this.fieldIndex)); } else this.scene.currentBattle.turnCommands[this.fieldIndex].targets = [ cursor ]; - console.log(cursor, this.fieldIndex, this.scene.currentBattle.turnCommands[this.fieldIndex].targets) this.end(); }); } @@ -1231,15 +1230,17 @@ class MoveEffectPhase extends PokemonPhase { const hitResult = !isProtected ? target.apply(user, this.move) : HitResult.NO_EFFECT; if (hitResult !== HitResult.NO_EFFECT && hitResult !== HitResult.FAIL) { - applyMoveAttrs(MoveEffectAttr, user, target, this.move.getMove()); + const chargeEffect = !!this.move.getMove().getAttrs(ChargeAttr).find(ca => (ca as ChargeAttr).chargeEffect); + // Charge attribute with charge effect takes all effect attributes and applies them to charge stage, so ignore them if this is present + if (!chargeEffect) + applyMoveAttrs(MoveEffectAttr, user, target, this.move.getMove()); if (hitResult < HitResult.NO_EFFECT) { const flinched = new Utils.BooleanHolder(false); user.scene.applyModifiers(FlinchChanceModifier, user.isPlayer(), user, flinched); if (flinched.value) target.addTag(BattlerTagType.FLINCHED, undefined, this.move.moveId, user.id); } - // Charge attribute with charge effect takes all effect attributes and applies them to charge stage, so ignore them if this is present - if (!isProtected && !this.move.getMove().getAttrs(ChargeAttr).filter(ca => (ca as ChargeAttr).chargeEffect).length) { + if (!isProtected && !chargeEffect) { applyFilteredMoveAttrs((attr: MoveAttr) => attr instanceof MoveHitEffectAttr && (!!target.hp || (attr as MoveHitEffectAttr).selfTarget), user, target, this.move.getMove()); if (target.hp) applyPostDefendAbAttrs(PostDefendAbAttr, target, user, this.move, hitResult); @@ -1854,7 +1855,7 @@ export class SwitchPhase extends BattlePhase { super.start(); this.scene.ui.setMode(Mode.PARTY, this.isModal ? PartyUiMode.FAINT_SWITCH : PartyUiMode.POST_BATTLE_SWITCH, this.fieldIndex, (slotIndex: integer, option: PartyOption) => { - if (slotIndex && slotIndex < 6) + if (slotIndex >= this.scene.currentBattle.getBattlerCount() && slotIndex < 6) this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, this.fieldIndex, slotIndex, this.doReturn, option === PartyOption.PASS_BATON)); this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end()); }, PartyUiHandler.FilterNonFainted); diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 045eaf2b3fe..29d45b367c0 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -169,6 +169,7 @@ export default class BattleScene extends Phaser.Scene { this.loadImage('boolean_window', 'ui'); this.loadImage('party_bg', 'ui'); + this.loadImage('party_bg_double', 'ui'); this.loadAtlas('party_slot_main', 'ui'); this.loadAtlas('party_slot', 'ui'); this.loadImage('party_slot_overlay_lv', 'ui'); diff --git a/src/battle.ts b/src/battle.ts index 80805a6956a..0fae8c419db 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -55,7 +55,11 @@ export default class Battle { return Math.max(Math.round(baseLevel + Math.abs(Utils.randGauss(deviation))), 1); } - incrementTurn() { + getBattlerCount(): integer { + return this.double ? 2 : 1; + } + + incrementTurn(): void { this.turn++; this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattleTarget).map(bt => [ bt, null ])); } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 71afc24700c..40af0f2545d 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -11,7 +11,6 @@ import * as Utils from '../utils'; import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from '../data/temp-battle-stat'; import { BerryType, getBerryEffectDescription, getBerryName } from '../data/berry'; import { Unlockables } from '../system/unlockables'; -import { maxExpLevel } from '../battle-scene'; type Modifier = Modifiers.Modifier; diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 4fd059803cf..017c639b3fe 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -44,6 +44,7 @@ export default class PartyUiHandler extends MessageUiHandler { private partyUiMode: PartyUiMode; private fieldIndex: integer; + private partyBg: Phaser.GameObjects.Image; private partyContainer: Phaser.GameObjects.Container; private partySlotsContainer: Phaser.GameObjects.Container; private partySlots: PartySlot[]; @@ -97,10 +98,10 @@ export default class PartyUiHandler extends MessageUiHandler { this.partyContainer = partyContainer; - const partyBg = this.scene.add.image(0, 0, 'party_bg'); - partyContainer.add(partyBg); + this.partyBg = this.scene.add.image(0, 0, 'party_bg'); + partyContainer.add(this.partyBg); - partyBg.setOrigin(0, 1); + this.partyBg.setOrigin(0, 1); const partySlotsContainer = this.scene.add.container(0, 0); partyContainer.add(partySlotsContainer); @@ -147,6 +148,7 @@ export default class PartyUiHandler extends MessageUiHandler { this.fieldIndex = args.length > 1 ? args[1] as integer : -1; this.partyContainer.setVisible(true); + this.partyBg.setTexture(`party_bg${this.scene.currentBattle.double ? '_double' : ''}`); this.populatePartySlots(); this.setCursor(this.cursor < 6 ? this.cursor : 0); @@ -229,7 +231,7 @@ export default class PartyUiHandler extends MessageUiHandler { } else if (option === PartyOption.RELEASE) { this.clearOptions(); ui.playSelect(); - if (this.cursor) { + if (this.cursor >= this.scene.currentBattle.getBattlerCount()) { this.showText(`Do you really want to release ${pokemon.name}?`, null, () => { ui.setModeWithoutClear(Mode.CONFIRM, () => { ui.setMode(Mode.PARTY); @@ -295,12 +297,13 @@ export default class PartyUiHandler extends MessageUiHandler { success = this.setCursor(this.cursor < 6 ? this.cursor < slotCount - 1 ? this.cursor + 1 : 6 : 0); break; case Button.LEFT: - if (this.cursor && this.cursor < 6) + if (this.cursor >= this.scene.currentBattle.getBattlerCount() && this.cursor < 6) success = this.setCursor(0); break; case Button.RIGHT: - if (!this.cursor) - success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || 1 : 1); + const battlerCount = this.scene.currentBattle.getBattlerCount(); + if (this.cursor < battlerCount) + success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || battlerCount : battlerCount); break; } } @@ -414,7 +417,7 @@ export default class PartyUiHandler extends MessageUiHandler { case PartyUiMode.SWITCH: case PartyUiMode.FAINT_SWITCH: case PartyUiMode.POST_BATTLE_SWITCH: - if (this.cursor) { + if (this.cursor >= this.scene.currentBattle.getBattlerCount()) { this.options.push(PartyOption.SEND_OUT); if (this.partyUiMode !== PartyUiMode.FAINT_SWITCH && this.scene.findModifier(m => m instanceof SwitchEffectTransferModifier @@ -582,7 +585,9 @@ class PartySlot extends Phaser.GameObjects.Container { private slotHpOverlay: Phaser.GameObjects.Sprite; constructor(scene: BattleScene, slotIndex: integer, pokemon: PlayerPokemon) { - super(scene, slotIndex ? 230.5 : 64, slotIndex ? -184 + 28 * slotIndex : -124); + super(scene, slotIndex >= scene.currentBattle.getBattlerCount() ? 230.5 : 64, + slotIndex >= scene.currentBattle.getBattlerCount() ? -184 + (scene.currentBattle.double ? -38 : 0) + + (28 + (scene.currentBattle.double ? 6 : 0)) * slotIndex : -124 + (scene.currentBattle.double ? -8 : 0) + slotIndex * 64); this.slotIndex = slotIndex; this.pokemon = pokemon; @@ -591,14 +596,16 @@ class PartySlot extends Phaser.GameObjects.Container { } setup() { - const slotKey = `party_slot${this.slotIndex ? '' : '_main'}`; + const battlerCount = (this.scene as BattleScene).currentBattle.getBattlerCount(); + + const slotKey = `party_slot${this.slotIndex >= battlerCount ? '' : '_main'}`; const slotBg = this.scene.add.sprite(0, 0, slotKey, `${slotKey}${this.pokemon.hp ? '' : '_fnt'}`); this.slotBg = slotBg; this.add(slotBg); - const slotPb = this.scene.add.sprite(this.slotIndex ? -85.5 : -51, this.slotIndex ? 0 : -20.5, 'party_pb'); + const slotPb = this.scene.add.sprite(this.slotIndex >= battlerCount ? -85.5 : -51, this.slotIndex >= battlerCount ? 0 : -20.5, 'party_pb'); this.slotPb = slotPb; this.add(slotPb); @@ -613,7 +620,7 @@ class PartySlot extends Phaser.GameObjects.Container { this.add(slotInfoContainer); const slotName = addTextObject(this.scene, 0, 0, this.pokemon.name, TextStyle.PARTY); - slotName.setPositionRelative(slotBg, this.slotIndex ? 21 : 24, this.slotIndex ? 3 : 10); + slotName.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 21 : 24, this.slotIndex >= battlerCount ? 3 : 10); slotName.setOrigin(0, 0); const slotLevelLabel = this.scene.add.image(0, 0, 'party_slot_overlay_lv'); @@ -625,7 +632,7 @@ class PartySlot extends Phaser.GameObjects.Container { slotLevelText.setOrigin(0, 0.25); const slotHpBar = this.scene.add.image(0, 0, 'party_slot_hp_bar'); - slotHpBar.setPositionRelative(slotBg, this.slotIndex ? 72 : 8, this.slotIndex ? 7 : 31); + slotHpBar.setPositionRelative(slotBg, this.slotIndex >= battlerCount ? 72 : 8, this.slotIndex >= battlerCount ? 7 : 31); slotHpBar.setOrigin(0, 0); const hpRatio = this.pokemon.getHpRatio(); @@ -673,8 +680,9 @@ class PartySlot extends Phaser.GameObjects.Container { } private updateSlotTexture(): void { - this.slotBg.setTexture(`party_slot${this.slotIndex ? '' : '_main'}`, - `party_slot${this.slotIndex ? '' : '_main'}${this.transfer ? '_swap' : this.pokemon.hp ? '' : '_fnt'}${this.selected ? '_sel' : ''}`); + const battlerCount = (this.scene as BattleScene).currentBattle.getBattlerCount(); + this.slotBg.setTexture(`party_slot${this.slotIndex >= battlerCount ? '' : '_main'}`, + `party_slot${this.slotIndex >= battlerCount ? '' : '_main'}${this.transfer ? '_swap' : this.pokemon.hp ? '' : '_fnt'}${this.selected ? '_sel' : ''}`); } } diff --git a/src/ui/target-select-ui-handler.ts b/src/ui/target-select-ui-handler.ts index 57edc4001e6..fd4164b8fad 100644 --- a/src/ui/target-select-ui-handler.ts +++ b/src/ui/target-select-ui-handler.ts @@ -17,6 +17,8 @@ export default class TargetSelectUiHandler extends UiHandler { constructor(scene: BattleScene) { super(scene, Mode.TARGET_SELECT); + + this.cursor = -1; } setup(): void { } @@ -36,8 +38,6 @@ export default class TargetSelectUiHandler extends UiHandler { if (!this.targets.length) return; - console.log(this.targets); - this.setCursor(this.targets.indexOf(this.cursor) > -1 ? this.cursor : this.targets[0]); }