mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-22 20:03:21 +00:00
Add setting level to entity card
This commit is contained in:
parent
1c91a776ed
commit
254c96c2c0
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
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 { connected, spawnEntity } from "@backend/server";
|
||||
@ -28,11 +28,16 @@ interface IProps {
|
||||
interface IState {
|
||||
icon: boolean;
|
||||
count: number | string;
|
||||
level: number | string;
|
||||
|
||||
showingCount: boolean;
|
||||
}
|
||||
|
||||
const defaultState = {
|
||||
icon: true,
|
||||
count: 1
|
||||
count: 1,
|
||||
level: 1,
|
||||
showingCount: true
|
||||
};
|
||||
|
||||
class EntityCard extends React.Component<IProps, IState> {
|
||||
@ -49,10 +54,20 @@ class EntityCard extends React.Component<IProps, IState> {
|
||||
* @private
|
||||
*/
|
||||
private updateCount(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
const value = event.target.value;
|
||||
if (isNaN(parseInt(value)) && value.length > 1) return;
|
||||
let value = event.target.value;
|
||||
// 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 addCount(positive: boolean, multiple: boolean) {
|
||||
let { count } = this.state;
|
||||
if (count === "") count = 1;
|
||||
if (typeof count == "string") count = parseInt(count);
|
||||
if (count < 1) count = 1;
|
||||
let value = this.state.showingCount ?
|
||||
this.state.count : this.state.level;
|
||||
if (value === "") value = 1;
|
||||
if (typeof value == "string") value = parseInt(value);
|
||||
if (value < 1) value = 1;
|
||||
|
||||
let increment = 1;
|
||||
if (!positive) increment = -1;
|
||||
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> {
|
||||
const entity = this.props.entity?.id ?? 21010101;
|
||||
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) {
|
||||
await spawnEntity(entity, amount, 1);
|
||||
await spawnEntity(entity, amount, level);
|
||||
} 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>
|
||||
<input
|
||||
type={"text"}
|
||||
value={this.state.count}
|
||||
value={this.state.showingCount ?
|
||||
`x${notNaN(this.state.count)}` : `Lv${notNaN(this.state.level)}`}
|
||||
className={"ObjectCard_Count"}
|
||||
onChange={this.updateCount.bind(this)}
|
||||
onBlur={() => {
|
||||
@ -159,7 +182,14 @@ class EntityCard extends React.Component<IProps, IState> {
|
||||
</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
|
||||
</button>
|
||||
</div>
|
||||
|
@ -154,3 +154,14 @@ export async function copyToClipboard(text: string): Promise<void> {
|
||||
export function openUrl(url: string): void {
|
||||
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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user