diff --git a/play.pokemonshowdown.com/src/battle-team-editor.tsx b/play.pokemonshowdown.com/src/battle-team-editor.tsx index 0f758eff4..19123b3c3 100644 --- a/play.pokemonshowdown.com/src/battle-team-editor.tsx +++ b/play.pokemonshowdown.com/src/battle-team-editor.tsx @@ -9,7 +9,7 @@ import preact from "../js/lib/preact"; import { type Team } from "./client-main"; import { PSTeambuilder } from "./panel-teamdropdown"; -import { Dex, type ModdedDex, toID, type ID } from "./battle-dex"; +import { Dex, type ModdedDex, toID, type ID, PSUtils } from "./battle-dex"; import { DexSearch, type SearchRow, type SearchType } from "./battle-dex-search"; import { PSSearchResults } from "./battle-searchresults"; import { BattleNatures, BattleStatNames, type StatName } from "./battle-dex-data"; @@ -346,9 +346,11 @@ class TeamEditorState extends PSModel { return coverage as Record; } teamDefensiveCoverage() { - const counters: Record> = {} as any; + type Counter = { type: Dex.TypeName, resists: number, neutrals: number, weaknesses: number }; + const counters: Record = {} as any; for (const type of this.dex.types.names()) { counters[type] = { + type, resists: 0, neutrals: 0, weaknesses: 0, @@ -1130,28 +1132,28 @@ class TeamTextbox extends preact.Component<{ editor: TeamEditorState, onChange?: > )} + {this.innerFocus && ( +
+ + {this.innerFocus.type === 'stats' ? ( + + ) : this.innerFocus.type === 'details' ? ( + + ) : ( + + )} +
+ )} - {this.innerFocus && ( -
- - {this.innerFocus.type === 'stats' ? ( - - ) : this.innerFocus.type === 'details' ? ( - - ) : ( - - )} -
- )} ; } } @@ -1246,6 +1248,7 @@ class TeamWizard extends preact.Component<{ ; } while (set.moves.length < 4) set.moves.push(''); + const overfull = set.moves.length > 4 ? ' overfull' : ''; const editor = this.props.editor; const species = editor.dex.species.get(set.species); @@ -1285,10 +1288,11 @@ class TeamWizard extends preact.Component<{
- @@ -1369,9 +1373,18 @@ class TeamWizard extends preact.Component<{ if (slot) { // intentional; we're _removing_ from the slot const i = parseInt(slot) - 1; - if (set.moves[i]) set.moves[i] = ''; - if (i === set.moves.length - 1) { - while (!set.moves[set.moves.length - 1]) set.moves.pop(); + if (set.moves[i]) { + set.moves[i] = ''; + // remove empty slots at the end + if (i === set.moves.length - 1) { + while (set.moves.length > 4 && !set.moves[set.moves.length - 1]) { + set.moves.pop(); + } + } + // if we have more than 4 moves, move the last move into the newly-cleared slot + if (set.moves.length > 4 && i < set.moves.length - 1) { + set.moves[i] = set.moves.pop()!; + } } } else if (set.moves.includes(name)) { set.moves.splice(set.moves.indexOf(name), 1); @@ -1576,28 +1589,32 @@ class TeamWizard extends preact.Component<{ } renderDefensiveCoverage() { const { editor } = this.props; - const counters = editor.teamDefensiveCoverage(); + const counters = Object.values(editor.teamDefensiveCoverage()); + PSUtils.sortBy(counters, counter => [counter.resists, -counter.weaknesses]); const good = [], medium = [], bad = []; - const renderTypeDefensive = (type: Dex.TypeName) => ( - <>{type}: {counters[type].weaknesses} weaknesses, {counters[type].resists} resists + const renderTypeDefensive = (counter: typeof counters[number]) => ( + + {counter.type} + {counter.resists} resist{counter.resists === 1 ? '' : 's'} + {counter.weaknesses} weakness{counter.weaknesses === 1 ? '' : 'es'} + ); - for (const [type, counter] of Object.entries(counters)) { + for (const counter of counters) { if (counter.resists > 0) { - good.push(renderTypeDefensive(type as Dex.TypeName),
); + good.push(renderTypeDefensive(counter)); } else if (counter.weaknesses <= 0) { - medium.push(renderTypeDefensive(type as Dex.TypeName),
); + medium.push(renderTypeDefensive(counter)); } else { - bad.push(renderTypeDefensive(type as Dex.TypeName),
); + bad.push(renderTypeDefensive(counter)); } } bad.pop(); - return
+ return
-

Defensive coverage

- {bad} + Defensive coverage + {bad}
See all
- {medium} - {good} + {bad}{medium}{good}
; } override render() { diff --git a/play.pokemonshowdown.com/src/battle-tooltips.ts b/play.pokemonshowdown.com/src/battle-tooltips.ts index c2414a6f6..1e2306b11 100644 --- a/play.pokemonshowdown.com/src/battle-tooltips.ts +++ b/play.pokemonshowdown.com/src/battle-tooltips.ts @@ -156,7 +156,8 @@ export class BattleTooltips { // tooltips // Touch delay, pressing finger more than that time will cause the tooltip to open. // Shorter time will cause the button to click - static LONG_TAP_DELAY = 1000; // ms + static LONG_TAP_DELAY = 500; // ms + static LONG_CLICK_DELAY = 700; // ms static longTapTimeout = 0; static elem: HTMLDivElement | null = null; static parentElem: HTMLElement | null = null; @@ -243,13 +244,12 @@ export class BattleTooltips { if (BattleTooltips.isLocked) BattleTooltips.hideTooltip(); const target = e.currentTarget as HTMLElement; this.showTooltip(target); - // let factor = (e.type === 'mousedown' && target.tagName === 'BUTTON' ? 2 : 1); - const factor = 1; + const isClick = (e.type === 'mousedown' && target.tagName === 'BUTTON'); BattleTooltips.longTapTimeout = setTimeout(() => { BattleTooltips.longTapTimeout = 0; this.lockTooltip(); - }, BattleTooltips.LONG_TAP_DELAY * factor); + }, isClick ? BattleTooltips.LONG_CLICK_DELAY : BattleTooltips.LONG_TAP_DELAY); }; showTooltipEvent = (e: Event) => { diff --git a/play.pokemonshowdown.com/src/panel-teamdropdown.tsx b/play.pokemonshowdown.com/src/panel-teamdropdown.tsx index 74f0c1d4e..3b8ae724c 100644 --- a/play.pokemonshowdown.com/src/panel-teamdropdown.tsx +++ b/play.pokemonshowdown.com/src/panel-teamdropdown.tsx @@ -6,7 +6,7 @@ */ import { PS, type Team } from "./client-main"; -import { PSPanelWrapper, PSRoomPanel } from "./panels"; +import { PSIcon, PSPanelWrapper, PSRoomPanel } from "./panels"; import { Dex, type ModdedDex, toID, type ID } from "./battle-dex"; import { BattleNatures, BattleStatIDs, BattleStatNames, type StatNameExceptHP } from "./battle-dex-data"; @@ -609,9 +609,10 @@ export function TeamBox(props: { team: Team | null, noLink?: boolean, button?: b if (!team.packedTeam) { icons = (empty team); } else { - icons = PSTeambuilder.packedTeamNames(team.packedTeam).map(species => - // can't use PSIcon, weird interaction with iconCache - + icons = PSTeambuilder.packedTeamNames(team.packedTeam).map(pokemon => + // can't use , weird interaction with iconCache + // don't try this at home; I'm a trained professional + PSIcon({ pokemon }) ); } team.iconCache = icons; diff --git a/play.pokemonshowdown.com/style/teambuilder.css b/play.pokemonshowdown.com/style/teambuilder.css index 1b4662ef2..f7239de01 100644 --- a/play.pokemonshowdown.com/style/teambuilder.css +++ b/play.pokemonshowdown.com/style/teambuilder.css @@ -596,6 +596,12 @@ you can't delete it by pressing Backspace */ .set-button .set-ability .button, .set-button .set-item .button { height: 40px; } +.set-button .set-moves .button { + line-height: 18px; +} +.set-button .set-moves .button.overfull { + line-height: normal; +} .set-button .set-details .button { height: 60px; } @@ -626,7 +632,8 @@ you can't delete it by pressing Backspace */ -webkit-overflow-scrolling: touch; } .team-focus-editor .tabbar { - overflow: auto; + /* note to self: make this scrollable later */ + /* overflow: auto; */ white-space: nowrap; } .tabbar .button.picontab { diff --git a/play.pokemonshowdown.com/testclient-beta.html b/play.pokemonshowdown.com/testclient-beta.html index 1925cd586..b4be643b1 100644 --- a/play.pokemonshowdown.com/testclient-beta.html +++ b/play.pokemonshowdown.com/testclient-beta.html @@ -154,6 +154,8 @@ + +