import { Campaign , CampaignState } from "./Campaign" ; import { GameObject , GameScene } from "./scenes/GameScene" ; import { NPC } from "./entities/NPC" ; import { rndItem } from "./util" ; import { ScriptedDialogJSON } from "../assets/dummy.texts.json" ; import { SpeechBubble } from "./SpeechBubble" ; export class Greeting implements GameObject { public greetingRange = 120 ; private currentMatchingGreetings : string [ ] = [ ] ; private greetingActive = false ; private greetingAlreadyShown = false ; private speechBubble = new SpeechBubble ( this . scene , this . npc . x , this . npc . y ) ; constructor ( private scene , public npc , private dialogData ) { this . updateMatchingData ( this . campaign . states ) ; this . campaign . onStatesChanged . connect ( this . updateMatchingData , this ) ; } public get dialogActive ( ) : boolean { return ! ! this . scene . player . playerConversation ; } public get campaign ( ) : Campaign { return this . scene . game . campaign ; } public draw ( ctx ) { if ( this . greetingActive ) { this . speechBubble . draw ( ctx ) ; } } public update ( ) { this . speechBubble . update ( this . npc . x , this . npc . y ) ; const isInRange = this . npc . scene . player . distanceTo ( this . npc ) < this . greetingRange ; if ( isInRange && ! this . greetingActive && ! this . greetingAlreadyShown && ! this . dialogActive ) { this . setRandomGreeting ( ) ; this . greetingActive = this . greetingAlreadyShown = true ; this . speechBubble . show ( ) ; } else if ( ! isInRange ) { this . greetingActive = false ; this . greetingAlreadyShown = false ; this . speechBubble . hide ( ) ; } } private setRandomGreeting ( ) { const message = this . currentMatchingGreetings . length > 0 ? rndItem ( this . currentMatchingGreetings ) : "" ; this . speechBubble . setMessage ( message ) ; } private updateMatchingData ( states ) { const matchingGreetingSelector = this . findMatchingSelectorByStates ( this . dialogData . greetings , states ) ; if ( matchingGreetingSelector ) { this . currentMatchingGreetings = this . dialogData . greetings [ matchingGreetingSelector ] ; this . setRandomGreeting ( ) ; } else { this . greetingActive = false ; this . currentMatchingGreetings = [ ] ; } } private findMatchingSelectorByStates ( data , currentCampaignStates ) { const stateSelectors = [ ] ; for ( const key in data ) { stateSelectors . push ( key . split ( " " ) ) ; } let bestMatchingSelector = null ; stateSelectors . sort ( ( a , b ) => { return b . length - a . length ; } ) ; for ( const selector of stateSelectors ) { if ( containsArray ( currentCampaignStates , selector ) ) { bestMatchingSelector = selector . join ( " " ) ; break ; } } return bestMatchingSelector ; } } function containsArray ( arr1 , arr2 ) { return arr2 . every ( value => arr1 . indexOf ( value ) !== - 1 ) ; }