mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 22:58:29 +08:00
197 lines
6.3 KiB
TypeScript
197 lines
6.3 KiB
TypeScript
import React, { CSSProperties } from 'react';
|
|
import { observer } from 'mobx-react';
|
|
import { NumericInput } from '@blueprintjs/core';
|
|
import { VisibleQuestEntity, QuestObject, QuestNpc } from '../domain';
|
|
import './EntityInfoComponent.css';
|
|
|
|
const containerStyle: CSSProperties = {
|
|
width: 200,
|
|
padding: 10,
|
|
display: 'flex',
|
|
flexDirection: 'column'
|
|
};
|
|
|
|
const tableStyle: CSSProperties = {
|
|
borderCollapse: 'collapse'
|
|
};
|
|
|
|
interface Props {
|
|
entity?: VisibleQuestEntity
|
|
}
|
|
|
|
@observer
|
|
export class EntityInfoComponent extends React.Component<Props, any> {
|
|
state = {
|
|
position: {
|
|
x: null,
|
|
y: null,
|
|
z: null,
|
|
},
|
|
sectionPosition: {
|
|
x: null,
|
|
y: null,
|
|
z: null,
|
|
}
|
|
};
|
|
|
|
componentWillReceiveProps({ entity }: Props) {
|
|
if (this.props.entity !== entity) {
|
|
this.clearPositionState();
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const entity = this.props.entity;
|
|
|
|
if (entity) {
|
|
const sectionId = entity.section ? entity.section.id : entity.sectionId;
|
|
let name = null;
|
|
|
|
if (entity instanceof QuestObject) {
|
|
name = (
|
|
<tr>
|
|
<td>Object: </td><td colSpan={2}>{entity.type.name}</td>
|
|
</tr>
|
|
);
|
|
} else if (entity instanceof QuestNpc) {
|
|
name = (
|
|
<tr>
|
|
<td>NPC: </td><td>{entity.type.name}</td>
|
|
</tr>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div style={containerStyle}>
|
|
<table style={tableStyle}>
|
|
<tbody>
|
|
{name}
|
|
<tr>
|
|
<td>Section: </td><td>{sectionId}</td>
|
|
</tr>
|
|
<tr>
|
|
<td colSpan={2}>World position: </td>
|
|
</tr>
|
|
<tr>
|
|
<td colSpan={2}>
|
|
<table>
|
|
<tbody>
|
|
{this.coordRow('position', 'x')}
|
|
{this.coordRow('position', 'y')}
|
|
{this.coordRow('position', 'z')}
|
|
</tbody>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colSpan={2}>Section position: </td>
|
|
</tr>
|
|
<tr>
|
|
<td colSpan={2}>
|
|
<table>
|
|
<tbody>
|
|
{this.coordRow('sectionPosition', 'x')}
|
|
{this.coordRow('sectionPosition', 'y')}
|
|
{this.coordRow('sectionPosition', 'z')}
|
|
</tbody>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
} else {
|
|
return <div style={containerStyle} />;
|
|
}
|
|
}
|
|
|
|
private coordRow(posType: string, coord: string) {
|
|
if (this.props.entity) {
|
|
const entity = this.props.entity;
|
|
const valueStr = (this.state as any)[posType][coord];
|
|
const value = valueStr
|
|
? valueStr
|
|
// Do multiplication, rounding, division and || with zero to avoid numbers close to zero flickering between 0 and -0.
|
|
: (Math.round((entity as any)[posType][coord] * 10000) / 10000 || 0).toFixed(4);
|
|
return (
|
|
<tr>
|
|
<td>{coord.toUpperCase()}: </td>
|
|
<td>
|
|
<NumericInput
|
|
value={value}
|
|
className="pt-fill EntityInfoComponent-coord"
|
|
buttonPosition="none"
|
|
onValueChange={(this.posChange as any)[posType][coord]}
|
|
onBlur={this.coordInputBlurred} />
|
|
</td>
|
|
</tr>
|
|
);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private posChange = {
|
|
position: {
|
|
x: (value: number, valueStr: string) => {
|
|
this.posChanged('position', 'x', value, valueStr);
|
|
},
|
|
y: (value: number, valueStr: string) => {
|
|
this.posChanged('position', 'y', value, valueStr);
|
|
},
|
|
z: (value: number, valueStr: string) => {
|
|
this.posChanged('position', 'z', value, valueStr);
|
|
}
|
|
},
|
|
sectionPosition: {
|
|
x: (value: number, valueStr: string) => {
|
|
this.posChanged('sectionPosition', 'x', value, valueStr);
|
|
},
|
|
y: (value: number, valueStr: string) => {
|
|
this.posChanged('sectionPosition', 'y', value, valueStr);
|
|
},
|
|
z: (value: number, valueStr: string) => {
|
|
this.posChanged('sectionPosition', 'z', value, valueStr);
|
|
}
|
|
}
|
|
};
|
|
|
|
private posChanged(posType: string, coord: string, value: number, valueStr: string) {
|
|
if (!isNaN(value)) {
|
|
const entity = this.props.entity as any;
|
|
|
|
if (entity) {
|
|
const v = entity[posType].clone();
|
|
v[coord] = value;
|
|
entity[posType] = v;
|
|
}
|
|
}
|
|
|
|
this.setState({
|
|
[posType]: {
|
|
[coord]: valueStr
|
|
}
|
|
});
|
|
}
|
|
|
|
private coordInputBlurred = () => {
|
|
this.clearPositionState();
|
|
}
|
|
|
|
private clearPositionState() {
|
|
this.setState({
|
|
position: {
|
|
x: null,
|
|
y: null,
|
|
z: null,
|
|
},
|
|
sectionPosition: {
|
|
x: null,
|
|
y: null,
|
|
z: null,
|
|
}
|
|
});
|
|
}
|
|
}
|