import React from 'react' ; import { styled } from '@csegames/linaria/react' ; import { engineEvents } from 'lib/engineEvents' ; import { HealthBar } from './HealthBar' ; import { InteractionBar } from './InteractionBar' ; import { PlayerDifferentiator } from './PlayerDifferentiator' ; import { Objective } from './Objective' ; const OBJECTIVE_INDICATORS = [ 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' ] ; interface ContainerProps extends React . HTMLProps < HTMLDivElement > { worldUIState : WorldUIState ; } const WorldUIContainer = styled . div `
  position: fixed;
  pointer-events: none;
  width: ${ ( props ) => props . worldUIState . width }px;
  height: ${ ( props ) => props . worldUIState . height }px;
  top: ${ ( props ) => props . worldUIState . y }px;
  left: ${ ( props ) => props . worldUIState . x }px;
  overflow: hidden;
` ; export enum WorldUIWidgetType { Default , ProgressBar , HealthBar , InteractionBar , PlayerDifferentiator , Objective } export interface WorldUIState { type : WorldUIWidgetType ; id : number ; x : number ; y : number ; width : number ; height : number ; html ? : string ; } export interface ProgressBarState extends WorldUIState { type : WorldUIWidgetType . ProgressBar ; percent : number ; } export interface HealthBarState extends WorldUIState { type : WorldUIWidgetType . HealthBar ; name : string ; kind : HealthBarKind ; current : number ; max : number ; } export interface InteractionBarState extends WorldUIState { type : WorldUIWidgetType . InteractionBar ; name : string ; description : string ; gameplayType : ItemGameplayType ; iconClass : string ; iconURL : string ; progress ? : number ; keybind ? : Binding ; } export interface PlayerDifferentiatorState extends WorldUIState { type : WorldUIWidgetType . PlayerDifferentiator ; differentiator : number ; } export interface ObjectiveState extends WorldUIState { type : WorldUIWidgetType . Objective ; objectiveState : ObjectiveEntityState ; indicator : string ; } export type WorldUIType = WorldUIState | ProgressBarState | HealthBarState | InteractionBarState | PlayerDifferentiatorState ; export interface State { worldUIs : { [ id ] : WorldUIType ; } ; } export class WorldUI extends React . Component < { } , State > { constructor ( props ) { super ( props ) ; this . state = { worldUIs : { } , } ; } public render ( ) { return ( < > { Object . values ( this . state . worldUIs ) . map ( this . renderWorldUI ) } < />); } public componentDidMount ( ) { engineEvents . onUpdateWorldUI ( this . handleUpdateWorldUI ) ; engineEvents . onRemoveWorldUI ( this . handleRemoveWorldUI ) ; engineEvents . onUpdateProgressBar ( this . handleUpdateProgressBar ) ; engineEvents . onUpdateHealthBar ( this . handleUpdateHealthBar ) ; engineEvents . onUpdateInteractionBar ( this . handleUpdateInteractionBar ) ; engineEvents . onUpdateObjective ( this . handleUpdateObjective ) ; } private renderWorldUI = ( worldUI ) => { switch ( worldUI . type ) { case WorldUIWidgetType . ProgressBar : { return null ; } case WorldUIWidgetType . HealthBar : { return ( < WorldUIContainer worldUIState = { worldUI } > < HealthBar state = { worldUI as HealthBarState } /> < /WorldUIContainer>); } case WorldUIWidgetType . InteractionBar : { return ( < WorldUIContainer worldUIState = { worldUI } > < InteractionBar state = { worldUI as InteractionBarState } /> < /WorldUIContainer>); } case WorldUIWidgetType . PlayerDifferentiator : { return ( < WorldUIContainer worldUIState = { worldUI } > < PlayerDifferentiator state = { worldUI as PlayerDifferentiatorState } /> < /WorldUIContainer>); } case WorldUIWidgetType . Objective : { return ( < WorldUIContainer worldUIState = { worldUI } > < Objective state = { worldUI as ObjectiveState } /> < /WorldUIContainer>); } default : { if ( ! worldUI . html ) return null ; return ( < WorldUIContainer worldUIState = { worldUI } dangerouslySetInnerHTML = { { __html : worldUI . html } } > < /WorldUIContainer>); } } } ; private handleUpdateWorldUI = ( id , x , y , width , height , html ) => { const newWorldUIState = { type : WorldUIWidgetType . Default , id , x , y , width , height , html , } ; this . createOrUpdateWorldUI ( newWorldUIState ) ; } ; private handleRemoveWorldUI = ( id ) => { this . removeWorldUI ( id ) ; } ; private handleUpdateProgressBar = ( id , x , y , width , height , percent ) => { const newProgressBarState = cloneDeep ( { type : WorldUIWidgetType . ProgressBar , id , x , y , width , height , percent , } ) ; this . createOrUpdateWorldUI ( newProgressBarState ) ; } ; private handleUpdateHealthBar = ( id , x , y , width , height , name , kind , current , max ) => { const newHealthBarState = cloneDeep ( { type : WorldUIWidgetType . HealthBar , id , x , y , width , height , name , kind , current , max , } ) ; this . createOrUpdateWorldUI ( newHealthBarState ) ; } ; private handleUpdateInteractionBar = ( id , x , y , width , height , name , description , gameplayType , iconClass , iconURL , progress ? , keybind ? ) => { const newInteractionBarState = cloneDeep ( { type : WorldUIWidgetType . InteractionBar , id , x , y , width , height , name , description , gameplayType , iconClass , iconURL , progress , keybind , } ) ; this . createOrUpdateWorldUI ( newInteractionBarState ) ; } ; private handleUpdateObjective = ( id , x , y , width , height , objectiveState ) => { const objectiveStateCopy = cloneDeep ( objectiveState ) ; const newObjectiveState = { type : WorldUIWidgetType . Objective , id , x , y , width , height , objectiveState : objectiveStateCopy , indicator : OBJECTIVE_INDICATORS [ objectiveStateCopy . objective . indicator ] , } ; this . createOrUpdateWorldUI ( newObjectiveState ) ; } ; private createOrUpdateWorldUI = ( newWorldUI ) => { const worldUIs = cloneDeep ( this . state . worldUIs ) ; worldUIs [ newWorldUI . id ] = newWorldUI ; this . setState ( { worldUIs } ) ; } ; private removeWorldUI = ( id ) => { const worldUIs = cloneDeep ( this . state . worldUIs ) ; delete worldUIs [ id ] ; this . setState ( { worldUIs } ) ; } ; }