pokerogue/src/field/damage-number-handler.ts
flx-sta a07d2c57a4
[Refactor] use typescript strict-null (#3259)
* TS: enable strict-null

* fix battle-scene.ts

* fix voucher.ts

* adapt more files to strict-null

* adapt more files to strict-null ( 2)

* adapt ability.ts to strict-null

* adapt `arena.ts` to strict-null

* adapt TagAddedEvent constructor to strict-null

* adapt phases.ts.to strict-null

* adapt status-effect.ts to strict-null

* adapt `account.ts` to strict-null

* adapt `configHandler.ts` to strict-null

* adapt `ability.ts` to strict-null

* adapt `biomes.ts` to strict-null

* adapt `challenge.ts` to strict-null

* adapt `daily-run.ts` to strict-null

* adapt `nature.ts` to strict-null

* adapt `pokemon-forms.ts` to strict-null

* adapt `tainer-names.ts` to strict-null

* adapt `types.ts` to strict-null

* adapt `weather.ts` to strict-null

* adapt `egg-hatch-phase.ts` to strict-null

* adapt `evolution-phase.ts` to strict-null

* adapt `pokemon-sprite-sparkle-handler.ts` to strict-null

* adapt `evolution-phase.ts` to strict-null

* adapt `game-mode.ts` to strict-null

* adapt `utils.ts` to strict-null

* adapt `voucher-ui-handler.ts` to strict-null

* adapt `src/ui/unavailable-modal-ui-handler.ts` to strict-null

* adapt `src/ui/ui.ts` to strict-null

* adapt `src/ui/ui-theme.ts` to strict-null

* adapt `src/ui/title-ui-handler.ts` to strict-null

* adapt `src/ui/time-of-day-widget.ts` to strict-null

* adapt `src/ui/text.ts` to strict-null

* adapt `src/ui/target-select-ui-handler.ts` to strict-null

* adapt `src/ui/settings/settings-keyboard-ui-handler.ts` to strict-null

* adapt more files to strict-null (3)

* adapt more files to strict-null (4)

* adapt more files (mostly tests) to strict-null (5)

* adapt more files to strict-null (6)

* adapt more files to strict-null (7)

* Update `src/data/pokemon-evolutions.ts` for strict-null

Partial update `src/data/pokemon-species.ts` for strict-null

* adapt more files to strict-null (8)

* adapt more files to strict-null (9)

* Strict some more nulls (still a few errors remaining)

* adapt rest of the files to strict-null (9)

* fix tests (check for null instead of undefined)

* repalce a lot of `??` with bangs

And added TODO notice as usual

* fix more tests

* all tests pass now

* fix broken game-loop after trainer battle

add some console.warn for missing cases and falling back to default

* remove guessed fallback from utils.rgbHexToRgba

* add TODO for this.currentBattle = null

* adjust   getPokemonById() return to include `null`

* fix compilation errors

* add test for pokemon.trySetStatus

* `chanceMultiplier` shouldn't be optional

* allow `null` for currentPhase

* adjust hasExpSprite logic for no keymatch found

* reduce bang usage in account.updateUserInfo()

* fix new strict-null issues after merge

* fix `strict-null` issues in dropdown.ts

and sand_spit.test.ts

* fix egg-gacha

* adapt gul_missile.test.ts to strict-null

* fix move.ts strict-null

* fix i18n.ts strict-null

* fix strict-null issues

* fix baton_pass test

after accidentially breaking it

* chore: fix compiler errors

* revert accidential changes in baton_pass.test.ts

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-08-07 17:23:12 +01:00

180 lines
5.0 KiB
TypeScript

import { TextStyle, addTextObject } from "../ui/text";
import Pokemon, { DamageResult, HitResult } from "./pokemon";
import * as Utils from "../utils";
import { BattlerIndex } from "../battle";
type TextAndShadowArr = [ string | null, string | null ];
export default class DamageNumberHandler {
private damageNumbers: Map<BattlerIndex, Phaser.GameObjects.Text[]>;
constructor() {
this.damageNumbers = new Map();
}
add(target: Pokemon, amount: integer, result: DamageResult | HitResult.HEAL = HitResult.EFFECTIVE, critical: boolean = false): void {
const scene = target.scene;
if (!scene?.damageNumbersMode) {
return;
}
const battlerIndex = target.getBattlerIndex();
const baseScale = target.getSpriteScale() / 6;
const damageNumber = addTextObject(scene, target.x, -(scene.game.canvas.height / 6) + target.y - target.getSprite().height / 2, Utils.formatStat(amount, true), TextStyle.SUMMARY);
damageNumber.setName("text-damage-number");
damageNumber.setOrigin(0.5, 1);
damageNumber.setScale(baseScale);
let [ textColor, shadowColor ] : TextAndShadowArr = [ null, null ];
switch (result) {
case HitResult.SUPER_EFFECTIVE:
[ textColor, shadowColor ] = [ "#f8d030", "#b8a038" ];
break;
case HitResult.NOT_VERY_EFFECTIVE:
[ textColor, shadowColor ] = [ "#f08030", "#c03028" ];
break;
case HitResult.ONE_HIT_KO:
[ textColor, shadowColor ] = [ "#a040a0", "#483850" ];
break;
case HitResult.HEAL:
[ textColor, shadowColor ] = [ "#78c850", "#588040" ];
break;
default:
[ textColor, shadowColor ] = [ "#ffffff", "#636363" ];
break;
}
if (textColor) {
damageNumber.setColor(textColor);
}
if (shadowColor) {
if (critical) {
damageNumber.setShadowOffset(0, 0);
damageNumber.setStroke(shadowColor, 12);
} else {
damageNumber.setShadowColor(shadowColor);
}
}
scene.fieldUI.add(damageNumber);
if (!this.damageNumbers.has(battlerIndex)) {
this.damageNumbers.set(battlerIndex, []);
}
const yOffset = this.damageNumbers.get(battlerIndex)!.length * -10;
if (yOffset) {
damageNumber.y += yOffset;
}
this.damageNumbers.get(battlerIndex)!.push(damageNumber);
if (scene.damageNumbersMode === 1) {
scene.tweens.add({
targets: damageNumber,
duration: Utils.fixedInt(750),
alpha: 1,
y: "-=32"
});
scene.tweens.add({
delay: 375,
targets: damageNumber,
duration: Utils.fixedInt(625),
alpha: 0,
ease: "Sine.easeIn",
onComplete: () => {
this.damageNumbers.get(battlerIndex)!.splice(this.damageNumbers.get(battlerIndex)!.indexOf(damageNumber), 1);
damageNumber.destroy(true);
}
});
return;
}
damageNumber.setAlpha(0);
scene.tweens.chain({
targets: damageNumber,
tweens: [
{
duration: Utils.fixedInt(250),
alpha: 1,
scaleX: 0.75 * baseScale,
scaleY: 1.25 * baseScale,
y: "-=16",
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(175),
alpha: 1,
scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale,
y: "+=16",
ease: "Cubic.easeIn"
},
{
duration: Utils.fixedInt(100),
scaleX: 1.25 * baseScale,
scaleY: 0.75 * baseScale,
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(175),
scaleX: 0.875 * baseScale,
scaleY: 1.125 * baseScale,
y: "-=8",
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(50),
scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale,
y: "+=8",
ease: "Cubic.easeIn"
},
{
duration: Utils.fixedInt(100),
scaleX: 1.125 * baseScale,
scaleY: 0.875 * baseScale,
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(175),
scaleX: 0.925 * baseScale,
scaleY: 1.075 * baseScale,
y: "-=4",
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(50),
scaleX: 0.975 * baseScale,
scaleY: 1.025 * baseScale,
y: "+=4",
ease: "Cubic.easeIn"
},
{
duration: Utils.fixedInt(100),
scaleX: 1.075 * baseScale,
scaleY: 0.925 * baseScale,
ease: "Cubic.easeOut"
},
{
duration: Utils.fixedInt(25),
scaleX: baseScale,
scaleY: baseScale,
ease: "Cubic.easeOut"
},
{
delay: Utils.fixedInt(500),
alpha: 0,
onComplete: () => {
this.damageNumbers.get(battlerIndex)!.splice(this.damageNumbers.get(battlerIndex)!.indexOf(damageNumber), 1);
damageNumber.destroy(true);
}
}
]
});
}
}