Refactoring the talk npcs component.

This commit is contained in:
Sergiotarxz 2023-07-12 16:01:27 +02:00
parent c7f299eb79
commit 3530c253a1
4 changed files with 116 additions and 79 deletions

View File

@ -1,18 +1,21 @@
import * as React from 'react'
import type { Action, ActionHash } from '@lastres/action'
import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc'
import type { TalkNPCs } from '@lastres/talk-npc'
import type { StateGame, OnWordSelectCallback } from '@lastres/components/game'
import OutputPacketExecuteAction from '@lastres/output-packet/execute_action'
import OutputPacketTalk from '@lastres/output-packet/talk';
import PresentationItem from '@lastres/components/presentation-item'
import Presentation from '@lastres/components/presentation'
import TalkNPCsComponent from '@lastres/components/talk-npcs'
export interface BottomPanelProps {
websocket: WebSocket | null
actionHash: ActionHash | null
talkNPCs: TalkNPCs | null
setStateGame: (set: StateGame) => void
setOnWordSelect: (set: OnWordSelectCallback) => void
}
export interface Style {
@ -21,7 +24,7 @@ export interface Style {
export default function BottomPanel (props: BottomPanelProps): JSX.Element {
const actionHash = props.actionHash
function printListActions(): JSX.Element {
function printListActions (): JSX.Element {
if (actionHash === null) {
return <></>
}
@ -74,60 +77,6 @@ export default function BottomPanel (props: BottomPanelProps): JSX.Element {
}
</>
}
function printAvatar (npc: TalkNPC): JSX.Element {
if (npc.icon === undefined) {
return <></>
}
return <div className="avatar">
<img src={npc.icon}/><div className="shadow"/>
</div>
}
function onWordlesslyTalk (npc: TalkNPC): void {
if (props.websocket === null) {
return
}
new OutputPacketTalk(npc.identifier).send(props.websocket)
}
function printTalkNpcs (): JSX.Element {
const npcs = props.talkNPCs
if (npcs === null) {
return <></>
}
if (Object.keys(npcs).length < 1) {
return <>
<p>No hay nadie para hablar ahora.</p>
</>
}
return (
<>
<p>Disponible para hablar:</p>
{
Object.keys(npcs).map((identifier) => {
const npc = npcs[identifier]
return <div key={npc.identifier} className="talk-npc">
<div className="detail">
<div className="name-container">
{
printAvatar(npc)
}
<div className="name">
<p>{npc.name}</p>
</div>
</div>
<div className="buttons">
<button onClick={() => {
onWordlesslyTalk(npc)
}}>Hablar</button>
<button>Decir palabra</button>
</div>
</div>
</div>
})
}
</>
)
}
return (
<Presentation>
<PresentationItem>
@ -136,9 +85,8 @@ export default function BottomPanel (props: BottomPanelProps): JSX.Element {
}
</PresentationItem>
<PresentationItem>
{
printTalkNpcs()
}
<TalkNPCsComponent websocket={props.websocket}
talkNPCs={props.talkNPCs}/>
</PresentationItem>
<PresentationItem>
</PresentationItem>

View File

@ -25,6 +25,13 @@ export interface GameProps {
setWebsocket: (websocket: WebSocket | null | SetWebsocketCallback) => void
}
export enum StateGame {
MainScreen,
SelectingWord,
}
export type OnWordSelectCallback = (word: string) => void
export default function Game (props: GameProps): JSX.Element {
const selectedPJ = props.selectedPJ
if (selectedPJ === null) {
@ -51,6 +58,8 @@ export default function Game (props: GameProps): JSX.Element {
const [remainingFrames, setRemainingFrames] = React.useState<number | null>(null)
const [actionHash, setActionHash] = React.useState<ActionHash | null>(null)
const [talkNPCs, setTalkNPCs] = React.useState<TalkNPCs | null>(null)
const [onWordSelect, setOnWordSelect] = React.useState<OnWordSelectCallback | null>(null)
const [stateGame, setStateGame] = React.useState<StateGame>(StateGame.MainScreen)
const logPresentationRef = React.useRef<HTMLDivElement>(null)
const websocket = props.websocket
const setWebsocket = props.setWebsocket
@ -101,21 +110,29 @@ export default function Game (props: GameProps): JSX.Element {
return websocket
})
}, 300)
return (
<>
<UpperPanel teamPJs={teamPJs}
enemyTeamPJs={enemyTeamPJs}
isBattling={isBattling}
currentLocation={currentLocation}
connectedLocations={connectedLocations}
logLines={logLines}
websocket={websocket}
logPresentationRef={logPresentationRef}
movingTo={movingTo}
remainingFrames={remainingFrames}/>
<BottomPanel actionHash={actionHash}
websocket={websocket}
talkNPCs={talkNPCs}/>
</>
)
if (stateGame === StateGame.SelectingWord) {
return <></>
}
if (stateGame === StateGame.MainScreen) {
return (
<>
<UpperPanel teamPJs={teamPJs}
enemyTeamPJs={enemyTeamPJs}
isBattling={isBattling}
currentLocation={currentLocation}
connectedLocations={connectedLocations}
logLines={logLines}
websocket={websocket}
logPresentationRef={logPresentationRef}
movingTo={movingTo}
remainingFrames={remainingFrames}/>
<BottomPanel actionHash={actionHash}
websocket={websocket}
talkNPCs={talkNPCs}
setOnWordSelect={setOnWordSelect}
setStateGame={setStateGame}/>
</>
)
}
return <></>
}

View File

@ -0,0 +1,62 @@
import * as React from 'react'
import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc'
import OutputPacketTalk from '@lastres/output-packet/talk'
export interface TalkNPCsComponentProps {
talkNPCs: TalkNPCs | null
websocket: WebSocket | null
}
export default function TalkNPCsComponent (props: TalkNPCsComponentProps): JSX.Element {
const npcs = props.talkNPCs
function onWordlesslyTalk (npc: TalkNPC): void {
if (props.websocket === null) {
return
}
new OutputPacketTalk(npc.identifier).send(props.websocket)
}
function printAvatar (npc: TalkNPC): JSX.Element {
if (npc.icon === undefined) {
return <></>
}
return <div className="avatar">
<img src={npc.icon}/><div className="shadow"/>
</div>
}
if (npcs === null) {
return <></>
}
if (Object.keys(npcs).length < 1) {
return <>
<p>No hay nadie para hablar ahora.</p>
</>
}
return (
<>
<p>Disponible para hablar:</p>
{
Object.keys(npcs).map((identifier) => {
const npc = npcs[identifier]
return <div key={npc.identifier} className="talk-npc">
<div className="detail">
<div className="name-container">
{
printAvatar(npc)
}
<div className="name">
<p>{npc.name}</p>
</div>
</div>
<div className="buttons">
<button onClick={() => {
onWordlesslyTalk(npc)
}}>Hablar</button>
<button>Decir palabra</button>
</div>
</div>
</div>
})
}
</>
)
}

File diff suppressed because one or more lines are too long