Add setting level to entity card

This commit is contained in:
KingRainbow44 2023-05-13 00:04:15 -04:00
parent 1c91a776ed
commit 254c96c2c0
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
2 changed files with 56 additions and 15 deletions

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import type { Entity as EntityType, EntityInfo } from "@backend/types"; import type { Entity as EntityType, EntityInfo } from "@backend/types";
import { copyToClipboard, entityIcon } from "@app/utils"; import { copyToClipboard, entityIcon, notNaN } from "@app/utils";
import "@css/widgets/ObjectCard.scss"; import "@css/widgets/ObjectCard.scss";
import { connected, spawnEntity } from "@backend/server"; import { connected, spawnEntity } from "@backend/server";
@ -28,11 +28,16 @@ interface IProps {
interface IState { interface IState {
icon: boolean; icon: boolean;
count: number | string; count: number | string;
level: number | string;
showingCount: boolean;
} }
const defaultState = { const defaultState = {
icon: true, icon: true,
count: 1 count: 1,
level: 1,
showingCount: true
}; };
class EntityCard extends React.Component<IProps, IState> { class EntityCard extends React.Component<IProps, IState> {
@ -49,10 +54,20 @@ class EntityCard extends React.Component<IProps, IState> {
* @private * @private
*/ */
private updateCount(event: React.ChangeEvent<HTMLInputElement>) { private updateCount(event: React.ChangeEvent<HTMLInputElement>) {
const value = event.target.value; let value = event.target.value;
if (isNaN(parseInt(value)) && value.length > 1) return; // Remove non-numeric characters.
value = value.replace(/[^0-9]/g, "");
this.setState({ count: value }); let numeric = parseInt(value);
if (isNaN(numeric) && value.length > 1) return;
// Check if the value should be a level.
if (!this.state.showingCount && numeric > 200)
numeric = 200;
const updated: any = this.state.showingCount ?
{ count: numeric } : { level: numeric };
this.setState(updated);
} }
/** /**
@ -63,18 +78,24 @@ class EntityCard extends React.Component<IProps, IState> {
* @private * @private
*/ */
private addCount(positive: boolean, multiple: boolean) { private addCount(positive: boolean, multiple: boolean) {
let { count } = this.state; let value = this.state.showingCount ?
if (count === "") count = 1; this.state.count : this.state.level;
if (typeof count == "string") count = parseInt(count); if (value === "") value = 1;
if (count < 1) count = 1; if (typeof value == "string") value = parseInt(value);
if (value < 1) value = 1;
let increment = 1; let increment = 1;
if (!positive) increment = -1; if (!positive) increment = -1;
if (multiple) increment *= 10; if (multiple) increment *= 10;
count = Math.max(1, count + increment); value = Math.max(1, value + increment);
// Check if the value should be a level.
if (!this.state.showingCount && value > 200)
value = 200;
this.setState({ count }); const updated: any = this.state.showingCount ?
{ count: value } : { level: value };
this.setState(updated);
} }
/** /**
@ -84,11 +105,12 @@ class EntityCard extends React.Component<IProps, IState> {
private async summonAtPlayer(): Promise<void> { private async summonAtPlayer(): Promise<void> {
const entity = this.props.entity?.id ?? 21010101; const entity = this.props.entity?.id ?? 21010101;
const amount = typeof this.state.count == "string" ? parseInt(this.state.count) : this.state.count; const amount = typeof this.state.count == "string" ? parseInt(this.state.count) : this.state.count;
const level = typeof this.state.level == "string" ? parseInt(this.state.level) : this.state.level;
if (connected) { if (connected) {
await spawnEntity(entity, amount, 1); await spawnEntity(entity, amount, level);
} else { } else {
await copyToClipboard(spawn.monster(entity, amount, 1)); await copyToClipboard(spawn.monster(entity, amount, level));
} }
} }
@ -138,7 +160,8 @@ class EntityCard extends React.Component<IProps, IState> {
</div> </div>
<input <input
type={"text"} type={"text"}
value={this.state.count} value={this.state.showingCount ?
`x${notNaN(this.state.count)}` : `Lv${notNaN(this.state.level)}`}
className={"ObjectCard_Count"} className={"ObjectCard_Count"}
onChange={this.updateCount.bind(this)} onChange={this.updateCount.bind(this)}
onBlur={() => { onBlur={() => {
@ -159,7 +182,14 @@ class EntityCard extends React.Component<IProps, IState> {
</div> </div>
</div> </div>
<button className={"ObjectCard_Submit"} onClick={this.summonAtPlayer.bind(this)}> <button
className={"ObjectCard_Submit"}
onClick={this.summonAtPlayer.bind(this)}
onContextMenu={(e) => {
e.preventDefault();
this.setState({ showingCount: !this.state.showingCount });
}}
>
Summon Summon
</button> </button>
</div> </div>

View File

@ -154,3 +154,14 @@ export async function copyToClipboard(text: string): Promise<void> {
export function openUrl(url: string): void { export function openUrl(url: string): void {
window.open(url, "_blank"); window.open(url, "_blank");
} }
/**
* Checks if a value is NaN.
* Returns an empty string if it is.
*
* @param value The value to check.
*/
export function notNaN(value: number | string): string {
const number = parseInt(value.toString());
return isNaN(number) ? "" : number.toString();
}